Select.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <div class="flex flex-col gap-4">
  3. <template v-if="id && name">
  4. <div
  5. v-for="part in data"
  6. :key="part[id]"
  7. class="flex gap-2 cursor-pointer select-none"
  8. @click="selected = part[id]"
  9. >
  10. <svg
  11. class="min-w-[32px] min-h-[32px]"
  12. width="32"
  13. height="32"
  14. viewBox="0 0 32 32"
  15. fill="none"
  16. xmlns="http://www.w3.org/2000/svg"
  17. >
  18. <path
  19. class="duration-200"
  20. :stroke="selected === part[id] ? '#FF4646' : '#EDE8D8'"
  21. d="M27.9999 16C27.9999 22.6275 22.6273 28 15.9999 28C9.37246 28 3.99988 22.6275 3.99988 16C3.99988 9.37259 9.37246 4 15.9999 4C22.6273 4 27.9999 9.37259 27.9999 16Z"
  22. stroke-width="2.66667"
  23. />
  24. <path
  25. v-if="selected === part[id]"
  26. :stroke="selected === part[id] ? '#FF4646' : '#EDE8D8'"
  27. class="zoom-show duration-200"
  28. d="M11.9999 15.9999L14.2436 18.2437C14.4772 18.4773 14.8559 18.4773 15.0895 18.2437L19.9999 13.3333"
  29. stroke-width="2.66667"
  30. stroke-linecap="round"
  31. stroke-linejoin="round"
  32. />
  33. </svg>
  34. <p
  35. class="text-[20px] duration-150"
  36. :class="{
  37. 'text-primary': selected === part[id],
  38. }"
  39. >
  40. {{ part[name] }}
  41. </p>
  42. </div>
  43. </template>
  44. <template v-else>
  45. <div
  46. v-for="(text, idx) in data"
  47. :key="idx"
  48. class="flex gap-2"
  49. @click="selected = text"
  50. >
  51. <svg
  52. width="32"
  53. height="32"
  54. viewBox="0 0 32 32"
  55. fill="none"
  56. xmlns="http://www.w3.org/2000/svg"
  57. >
  58. <path
  59. class="duration-200"
  60. d="M27.9999 16C27.9999 22.6275 22.6273 28 15.9999 28C9.37246 28 3.99988 22.6275 3.99988 16C3.99988 9.37259 9.37246 4 15.9999 4C22.6273 4 27.9999 9.37259 27.9999 16Z"
  61. :stroke="selected === text ? '#FF4646' : '#EDE8D8'"
  62. stroke-width="2.66667"
  63. />
  64. <path
  65. v-if="selected === text"
  66. class="zoom-show duration-200"
  67. d="M11.9999 15.9999L14.2436 18.2437C14.4772 18.4773 14.8559 18.4773 15.0895 18.2437L19.9999 13.3333"
  68. :stroke="selected === text ? '#FF4646' : '#EDE8D8'"
  69. stroke-width="2.66667"
  70. stroke-linecap="round"
  71. stroke-linejoin="round"
  72. />
  73. </svg>
  74. <p
  75. class="text-xl duration-150"
  76. :class="{
  77. 'text-primary': selected === text,
  78. }"
  79. >
  80. {{ text }}
  81. </p>
  82. </div>
  83. </template>
  84. </div>
  85. </template>
  86. <script setup lang="ts">
  87. defineProps<{
  88. id?: string
  89. name?: string
  90. data: object[] | string[]
  91. }>()
  92. const selected = defineModel<string | object | number>('selected', { default: undefined })
  93. </script>
  94. <style scoped>
  95. @keyframes zoomShow {
  96. 0% {
  97. opacity: 0;
  98. transform: scale(0.5);
  99. }
  100. 100% {
  101. opacity: 1;
  102. transform: scale(1);
  103. }
  104. }
  105. .zoom-show {
  106. animation: zoomShow ease-in-out 200ms;
  107. }
  108. </style>