index.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <script setup lang="ts">
  2. import { ref, computed } from "vue";
  3. import { emitter } from "@/utils/mitt";
  4. import { onClickOutside } from "@vueuse/core";
  5. import Close from "@iconify-icons/ep/close";
  6. const target = ref(null);
  7. const show = ref<Boolean>(false);
  8. const iconClass = computed(() => {
  9. return [
  10. "mr-[20px]",
  11. "outline-none",
  12. "width-[20px]",
  13. "height-[20px]",
  14. "rounded-[4px]",
  15. "cursor-pointer",
  16. "transition-colors",
  17. "hover:bg-[#0000000f]",
  18. "dark:hover:bg-[#ffffff1f]",
  19. "dark:hover:text-[#ffffffd9]"
  20. ];
  21. });
  22. onClickOutside(target, (event: any) => {
  23. if (event.clientX > target.value.offsetLeft) return;
  24. show.value = false;
  25. });
  26. emitter.on("openPanel", () => {
  27. show.value = true;
  28. });
  29. </script>
  30. <template>
  31. <div :class="{ show: show }" class="right-panel-container">
  32. <div class="right-panel-background" />
  33. <div ref="target" class="right-panel bg-bg_color">
  34. <div class="right-panel-items">
  35. <div class="project-configuration">
  36. <h4 class="dark:text-white">项目配置</h4>
  37. <span title="关闭配置" :class="iconClass">
  38. <IconifyIconOffline
  39. class="dark:text-white"
  40. width="20px"
  41. height="20px"
  42. :icon="Close"
  43. @click="show = !show"
  44. />
  45. </span>
  46. </div>
  47. <div
  48. class="border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]"
  49. />
  50. <slot />
  51. </div>
  52. </div>
  53. </div>
  54. </template>
  55. <style>
  56. .showright-panel {
  57. position: relative;
  58. width: calc(100% - 15px);
  59. overflow: hidden;
  60. }
  61. </style>
  62. <style lang="scss" scoped>
  63. .right-panel-background {
  64. position: fixed;
  65. top: 0;
  66. left: 0;
  67. z-index: -1;
  68. background: rgb(0 0 0 / 20%);
  69. opacity: 0;
  70. transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
  71. }
  72. .right-panel {
  73. position: fixed;
  74. top: 0;
  75. right: 0;
  76. z-index: 40000;
  77. width: 100%;
  78. max-width: 315px;
  79. height: 100vh;
  80. box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
  81. transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
  82. transform: translate(100%);
  83. }
  84. .show {
  85. transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
  86. .right-panel-background {
  87. z-index: 20000;
  88. width: 100%;
  89. height: 100%;
  90. opacity: 1;
  91. }
  92. .right-panel {
  93. transform: translate(0);
  94. }
  95. }
  96. .handle-button {
  97. position: absolute;
  98. top: 45%;
  99. left: -48px;
  100. z-index: 0;
  101. width: 48px;
  102. height: 48px;
  103. font-size: 24px;
  104. line-height: 48px;
  105. color: #fff;
  106. text-align: center;
  107. pointer-events: auto;
  108. cursor: pointer;
  109. background: rgb(24 144 255);
  110. border-radius: 6px 0 0 6px !important;
  111. i {
  112. font-size: 24px;
  113. line-height: 48px;
  114. }
  115. }
  116. .right-panel-items {
  117. height: calc(100vh - 60px);
  118. margin-top: 60px;
  119. overflow-y: auto;
  120. }
  121. .project-configuration {
  122. position: fixed;
  123. top: 15px;
  124. display: flex;
  125. align-items: center;
  126. justify-content: space-between;
  127. width: 100%;
  128. height: 30px;
  129. margin-left: 10px;
  130. }
  131. :deep(.el-divider--horizontal) {
  132. width: 90%;
  133. margin: 20px auto 0;
  134. }
  135. </style>