edvoyui-component-library-test-flight 0.0.21 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/EUIButton.vue.d.ts.map +1 -0
  2. package/dist/library-vue-ts.cjs.js +4 -3
  3. package/dist/library-vue-ts.es.js +3 -8
  4. package/dist/library-vue-ts.umd.js +4 -3
  5. package/dist/select/EUISelect.vue.d.ts.map +1 -0
  6. package/package.json +4 -2
  7. package/src/App.vue +16 -0
  8. package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
  9. package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
  10. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
  11. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
  12. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
  13. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
  14. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
  15. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
  16. package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
  17. package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
  18. package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
  19. package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
  20. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
  21. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
  22. package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
  23. package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
  24. package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
  25. package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
  26. package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
  27. package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
  28. package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
  29. package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
  30. package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
  31. package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
  32. package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
  33. package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
  34. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
  35. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
  36. package/src/assets/scss/body.scss +15 -0
  37. package/src/assets/svg/ChevronDownSolid.vue +19 -0
  38. package/src/assets/svg/ChevronDownStroke.vue +22 -0
  39. package/src/assets/svg/SortArrow.vue +24 -0
  40. package/src/assets/svg/Student.vue +30 -0
  41. package/src/assets/svg/partner.vue +33 -0
  42. package/src/assets/svg/people.vue +25 -0
  43. package/src/assets/vue.svg +1 -0
  44. package/src/components/HelloWorld.vue +999 -0
  45. package/src/components/accordion/EUIAccordion.stories.ts +157 -0
  46. package/src/components/accordion/EUIAccordion.vue +90 -0
  47. package/src/components/avatar/EUIAvatar.stories.ts +157 -0
  48. package/src/components/avatar/EUIAvatar.vue +96 -0
  49. package/src/components/button/EUIButton.stories.ts +252 -0
  50. package/src/components/button/EUIButton.vue +151 -0
  51. package/src/components/checkbox/EUICheckbox.stories.ts +58 -0
  52. package/src/components/checkbox/EUICheckbox.vue +103 -0
  53. package/src/components/datepicker/EUIDatepicker.stories.ts +236 -0
  54. package/src/components/datepicker/EUIDatepicker.vue +185 -0
  55. package/src/components/delete.vue +108 -0
  56. package/src/components/dropdown/EUIMultiDropdown.stories.ts +187 -0
  57. package/src/components/dropdown/EUIMultiDropdown.vue +129 -0
  58. package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
  59. package/src/components/errorMessage/EUIErrorMessage.stories.ts +41 -0
  60. package/src/components/errorMessage/EUIErrorMessage.vue +25 -0
  61. package/src/components/index.ts +46 -0
  62. package/src/components/input/EUIInput.stories.ts +174 -0
  63. package/src/components/input/EUIInput.vue +169 -0
  64. package/src/components/inputNormal/EUIInputNormal.stories.ts +164 -0
  65. package/src/components/inputNormal/EUIInputNormal.vue +161 -0
  66. package/src/components/loader/EUICircleLoader.vue +31 -0
  67. package/src/components/loader/EUICubeLoader.vue +237 -0
  68. package/src/components/loader/EUILoader.stories.ts +99 -0
  69. package/src/components/loader/EUILoader.vue +17 -0
  70. package/src/components/loader/EUISquareLoader.vue +47 -0
  71. package/src/components/modal/EUIModal.stories.ts +372 -0
  72. package/src/components/modal/EUIModal.vue +163 -0
  73. package/src/components/pillSelect/EUIPillSelect.stories.ts +74 -0
  74. package/src/components/pillSelect/EUIPillSelect.vue +149 -0
  75. package/src/components/popover/EUIPopover.stories.ts +247 -0
  76. package/src/components/popover/EUIPopover.vue +159 -0
  77. package/src/components/radio/EUIRadio.stories.ts +54 -0
  78. package/src/components/radio/EUIRadio.vue +78 -0
  79. package/src/components/searchInput/EUISearch.stories.ts +24 -0
  80. package/src/components/searchInput/EUISearch.vue +215 -0
  81. package/src/components/select/EUISelect.scss +0 -0
  82. package/src/components/select/EUISelect.stories.ts +49 -0
  83. package/src/components/select/EUISelect.vue +682 -0
  84. package/src/components/selectSearch/EUISelectSearch.vue +23 -0
  85. package/src/components/slideover/EUISlideover.stories.ts +318 -0
  86. package/src/components/slideover/EUISlideover.vue +207 -0
  87. package/src/components/stepperTimeline/EUIStepperHorizontal.vue +112 -0
  88. package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +54 -0
  89. package/src/components/stepperTimeline/EUIStepperTimeline.vue +16 -0
  90. package/src/components/stepperTimeline/EUIStepperVertical.vue +112 -0
  91. package/src/components/table/EUIDashboardTable.vue +482 -0
  92. package/src/components/table/EUIPageLimit.vue +66 -0
  93. package/src/components/table/EUIPagination.vue +175 -0
  94. package/src/components/table/EUIStudentPagination.vue +172 -0
  95. package/src/components/table/EUITable.stories.ts +190 -0
  96. package/src/components/table/EUITable.vue +508 -0
  97. package/src/components/table/EUITableCheckbox.vue +97 -0
  98. package/src/components/tabs/EUITabs.vue +128 -0
  99. package/src/components/tabs/EUItabs.stories.ts +123 -0
  100. package/src/components/tag/EUITag.stories.ts +46 -0
  101. package/src/components/tag/EUITag.vue +46 -0
  102. package/src/components/telephone/EUITelephone.stories.ts +202 -0
  103. package/src/components/telephone/EUITelephone.vue +280 -0
  104. package/src/components/textArea/EUITextArea.stories.ts +82 -0
  105. package/src/components/textArea/EUITextArea.vue +122 -0
  106. package/src/components/timeLine/EUITimeLine.stories.ts +247 -0
  107. package/src/components/timeLine/EUITimeLine.vue +43 -0
  108. package/src/components/timeLine/EUITimeLineItem.vue +124 -0
  109. package/src/components/toggle/EUIToggle.stories.ts +63 -0
  110. package/src/components/toggle/EUIToggle.vue +99 -0
  111. package/src/components/tooltip/EUITooltip.stories.ts +53 -0
  112. package/src/components/tooltip/EUITooltip.vue +108 -0
  113. package/src/data/books.ts +163 -0
  114. package/src/data/tab.ts +33 -0
  115. package/src/data/table.ts +5392 -0
  116. package/src/main.ts +5 -0
  117. package/src/utils/lodash.ts +9 -0
  118. package/src/utils/types.ts +9 -0
  119. package/src/vite-env.d.ts +5 -0
  120. package/dist/EUISelect.vue.d.ts.map +0 -1
  121. package/dist/button/EUIButton.vue.d.ts.map +0 -1
  122. package/dist/library-vue-ts.css +0 -1
  123. package/dist/style.scss +0 -118
  124. /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
  125. /package/dist/{EUISelect.vue.d.ts → select/EUISelect.vue.d.ts} +0 -0
@@ -0,0 +1,682 @@
1
+ <template>
2
+ <div :class="isUseCustomSelect ? 'isUseCustomSelect' : ''">
3
+ <vSelect
4
+ v-model="selected"
5
+ :filter="isFussySeach ? fuseSearch : undefined"
6
+ :options="items"
7
+ :label="searchLabel"
8
+ :name="name"
9
+ :value="selected"
10
+ :placeholder="showPlaceholder"
11
+ :multiple="multiple"
12
+ :taggable="taggable"
13
+ :push-tags="pushtags"
14
+ :deselect-from-dropdown="true"
15
+ append-to-body
16
+ :searchable="searchable"
17
+ :calculate-position="withPopper"
18
+ :loading="loading"
19
+ :disabled="disabled"
20
+ :selectable="selectedLimit"
21
+ :class="[ isUseCustomSelect ? 'customselect' : 'rounded-2xl border border-gray-200 focus-within:border-purple-600 focus-within:ring-inset focus-within:ring-1 focus-within:ring-purple-600 z-10 focus-within:rounded', disabled ? 'opacity-25' : '', 'group relative min-h-14 w-full bg-white cursor-pointer overflow-hidden' ]"
22
+ :clearable="isUseCustomSelect ? clearable : undefined"
23
+ :no-drop="nodropDown"
24
+ @search="search($event)"
25
+ @option:selected="change($event)"
26
+ @option:deselected="deselected($event)"
27
+ @option:created="handleOptionCreate"
28
+ >
29
+ <template #header>
30
+ <div
31
+ :class="[
32
+ inputValue
33
+ ? 'top-3.5 text-xs text-gray-400 cursor-default max-w-max'
34
+ : 'top-1/2 text-sm text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-transparent ring-0 ring-gray-200 group-hover:top-3.5 group-hover:py-0 group-hover:h-auto bg-white group-hover:text-xs group-hover:min-w-max w-11/12 group-hover:-translate-y-1/2 group-hover:text-gray-400',
35
+ disabled ? ' cursor-not-allowed' : '',
36
+ required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
37
+ ]"
38
+ class="absolute text-left font-medium inset-x-0 px-4 z-10 -translate-y-1/2 duration-200 group-focus-within:top-3.5 group-focus-within:text-xs group-focus-within:text-gray-400 rounded-2xl group-focus-within:bg-transparent group-focus-within:-translate-y-1/2 group-focus-within:ring-transparent group-focus-within:h-auto group-focus-within:py-0 capitalize leading-[normal]"
39
+ >
40
+ {{ startCaseText(label) }}
41
+ </div>
42
+ </template>
43
+ <template #selected-option="{ name: nameText, iconlink }">
44
+ <div
45
+ :class="
46
+ isUseCustomSelect
47
+ ? 'break-words flex items-start'
48
+ : 'flex items-center'
49
+ "
50
+ >
51
+ <img
52
+ v-if="
53
+ name == 'country' ? getFlag({ nameText, iconlink }) : iconlink
54
+ "
55
+ :class="isUseCustomSelect ? 'w-6 mr-1 flex-initial' : 'w-6 mr-2'"
56
+ :src="
57
+ name == 'country' ? getFlag({ nameText, iconlink }) : iconlink
58
+ "
59
+ :alt="nameText"
60
+ />
61
+ {{ isStartCaseText ? startCaseText(nameText) : nameText }}
62
+ </div>
63
+ </template>
64
+ <template #option="{ name: nameText, iconlink }">
65
+ <div class="flex items-center">
66
+ <img
67
+ v-if="iconlink"
68
+ class="w-6 mr-2"
69
+ :src="iconlink"
70
+ :alt="nameText"
71
+ />
72
+
73
+ {{ isStartCaseText ? startCaseText(nameText) : nameText }}
74
+ </div>
75
+ </template>
76
+ <template #spinner="{ loading: _loading }">
77
+ <div
78
+ v-if="loading || _loading"
79
+ style="border-left-color: rgba(107, 30, 190, 0.71)"
80
+ class="vs__spinner"
81
+ />
82
+ </template>
83
+ <template v-if="isSelectAll" #list-header>
84
+ <div v-if="items.length !== selected?.length">
85
+ <button
86
+ class="w-full px-6 py-2 text-sm font-medium text-gray-600 transition duration-75 hover:font-bold hover:text-gray-900 text-start"
87
+ @click.prevent="selectAll"
88
+ >
89
+ Select All
90
+ </button>
91
+ </div>
92
+ </template>
93
+ </vSelect>
94
+ <EUIErrorMessage :errors="errors" :name="name" class="mt-2" />
95
+ </div>
96
+ </template>
97
+
98
+ <script setup lang="ts">
99
+ import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
100
+ import vSelect from "vue-select";
101
+ import "vue-select/dist/vue-select.css";
102
+ import { createPopper } from "@popperjs/core";
103
+ import Fuse from "fuse.js";
104
+ import _, { startCase } from "lodash";
105
+ import {
106
+ computed,
107
+ onBeforeUnmount,
108
+ onMounted,
109
+ PropType,
110
+ ref,
111
+ toRefs,
112
+ watch,
113
+ } from "vue";
114
+ import "./EUISelect.scss";
115
+ import { ValidationErrors } from "../../utils/types";
116
+
117
+ type VirtualElement = {
118
+ getBoundingClientRect: () => ClientRect | DOMRect;
119
+ contextElement?: Element;
120
+ };
121
+
122
+ const showPlaceholder = computed(() => {
123
+ const label = props.placeholder || `Select ${name}`;
124
+ const labelReq = props.required ? "*" : "";
125
+ return `${label} ${labelReq}`;
126
+ });
127
+
128
+ const startCaseText = (x: string) => {
129
+ return startCase(x);
130
+ };
131
+
132
+ const selected = ref<any>([]);
133
+ const nodropDown = ref(false);
134
+ const props = defineProps({
135
+ clearable: {
136
+ type: Boolean,
137
+ default: true,
138
+ },
139
+ isUseCustomSelect: {
140
+ type: Boolean,
141
+ required: false,
142
+ default: false,
143
+ },
144
+ customWidth: {
145
+ type: String,
146
+ default: "",
147
+ required: false,
148
+ },
149
+ customOffset:{
150
+ type: Array as PropType<any>,
151
+ required: false,
152
+ },
153
+ className: {
154
+ type: Array as PropType<string[]>,
155
+ required: false,
156
+ default: () => [],
157
+ },
158
+ errors: {
159
+ type: Object as PropType<ValidationErrors>,
160
+ required: false,
161
+ default: () => {},
162
+ },
163
+ items: {
164
+ type: Array as PropType<any>,
165
+ required: true,
166
+ },
167
+ placeholder: {
168
+ type: String,
169
+ default: "",
170
+ },
171
+ label: {
172
+ type: String,
173
+ default: "Select an option...",
174
+ required: false,
175
+ },
176
+ searchLabel: {
177
+ type: String,
178
+ default: "name",
179
+ required: false,
180
+ },
181
+ name: {
182
+ type: String,
183
+ default: "",
184
+ required: false,
185
+ },
186
+ modelValue: {
187
+ type: [Object, Array, String],
188
+ required: true,
189
+ default: () => {},
190
+ },
191
+ value: {
192
+ type: [Object, Array, String],
193
+ required: true,
194
+ default: () => {},
195
+ },
196
+ multiple: {
197
+ type: Boolean,
198
+ required: false,
199
+ default: false,
200
+ },
201
+ multipleLimit:{
202
+ type: Number,
203
+ required: false,
204
+ default: false
205
+ },
206
+ disabled: {
207
+ type: Boolean as PropType<boolean>,
208
+ required: false,
209
+ default: false,
210
+ },
211
+ isStartCaseText: {
212
+ type: Boolean as PropType<boolean>,
213
+ required: false,
214
+ default: false,
215
+ },
216
+ isFussySeach: {
217
+ type: Boolean,
218
+ required: false,
219
+ default: false,
220
+ },
221
+ keys: {
222
+ type: Array as PropType<string[]>,
223
+ required: false,
224
+ default: () => ["e", "label", "value"],
225
+ },
226
+ loading: {
227
+ type: Boolean,
228
+ required: false,
229
+ default: false,
230
+ },
231
+ isSelectAll: {
232
+ type: Boolean,
233
+ required: false,
234
+ default: false,
235
+ },
236
+ taggable: {
237
+ type: Boolean,
238
+ required: false,
239
+ default: false,
240
+ },
241
+ pushtags: {
242
+ type: Boolean,
243
+ required: false,
244
+ default: false,
245
+ },
246
+ required: {
247
+ type: Boolean,
248
+ default: false,
249
+ },
250
+ searchable: {
251
+ type: Boolean,
252
+ required: false,
253
+ default: true,
254
+ },
255
+ });
256
+
257
+ const {
258
+ modelValue,
259
+ isFussySeach,
260
+ clearable,
261
+ isUseCustomSelect,
262
+ items,
263
+ keys,
264
+ loading,
265
+ multiple,
266
+ isStartCaseText,
267
+ isSelectAll,
268
+ required,
269
+ } = toRefs(props);
270
+ const emit = defineEmits([
271
+ "update:modelValue",
272
+ "update:searchString",
273
+ "change",
274
+ "deselected",
275
+ "search",
276
+ "tag",
277
+ "selectedOption",
278
+ ]);
279
+
280
+ const selectAll = (e: Event) => {
281
+ if (e.target) {
282
+ selected.value = [{ _id: "6565d869eb1b7cf8745d6beb", name: "All" }];
283
+ nodropDown.value = true;
284
+ }
285
+ };
286
+
287
+ watch(selected, (newValue) => {
288
+ emit("update:modelValue", newValue);
289
+ if (newValue === null || !newValue) {
290
+ emit("deselected", newValue);
291
+ }
292
+ });
293
+
294
+ const change = (newValue: any) => {
295
+ emit("change", newValue);
296
+ };
297
+
298
+ const deselected = (newValue: any) => {
299
+ emit("deselected", newValue);
300
+ if (newValue.name === "All") {
301
+ nodropDown.value = false;
302
+ }
303
+ };
304
+
305
+ watch(modelValue, (newValue:any) => {
306
+ selected.value = newValue;
307
+ });
308
+
309
+ const search = (x: string) => {
310
+ emit("update:searchString", x);
311
+ emit("search", x);
312
+ };
313
+
314
+ const selectWidth = computed(() => props.customWidth)
315
+ const offsetValue = computed(() => props.customOffset)
316
+
317
+ const withPopper = (
318
+ dropdownList: HTMLElement,
319
+ component: { $refs: { toggle: Element | VirtualElement } },
320
+ { width }: any
321
+ ) => {
322
+ const newwidth = selectWidth.value || width; //setcustom width '400px'
323
+ const newOffset = offsetValue.value || [0,3]; //setcustom Offset '[123, -1]'
324
+ const customWidth = isUseCustomSelect.value ? newwidth : width;
325
+ dropdownList.style.width = customWidth;
326
+ const offsetValues = isUseCustomSelect.value ? newOffset : [0, 3];
327
+ const popper = createPopper(component.$refs.toggle, dropdownList, {
328
+ placement: "bottom",
329
+ modifiers: [
330
+ {
331
+ name: "offset",
332
+ options: {
333
+ offset: offsetValues,
334
+ },
335
+ },
336
+ ],
337
+ });
338
+ return () => popper.destroy();
339
+ };
340
+
341
+ const fuseSearch = (
342
+ options: readonly unknown[],
343
+ search: string | any[] | Fuse.Expression
344
+ ) => {
345
+ const fuse: any = new Fuse(options, {
346
+ keys: keys.value,
347
+ shouldSort: true,
348
+ });
349
+
350
+ return search ? fuse.search(search).map((item: any) => item) : fuse?.list;
351
+ };
352
+
353
+ onMounted(() => {
354
+ selected.value = props.value;
355
+ });
356
+
357
+ onBeforeUnmount(() => {
358
+ selected.value = null;
359
+ });
360
+
361
+ const slectedChipbg = computed(() => (props.multiple ? "#f3e8ff" : ""));
362
+ const slectedChiptextColor = computed(() => (props.multiple ? "#7e22ce" : ""));
363
+ const slectedChipHeight = computed(() => (props.multiple ? "fit-content" : ""));
364
+
365
+ const dropDownIcon = computed(() => (props.clearable ? "flex" : "none"));
366
+
367
+ const selectBG = computed(() => {
368
+ if (selected.value?.length === 0 || !!_.isEmpty(selected.value)) {
369
+ return "#ffffff";
370
+ }
371
+ return "transparent";
372
+ });
373
+ const selectHeight = computed(() => {
374
+ if (selected.value?.length === 0 || _.isEmpty(selected.value)) {
375
+ return "54px";
376
+ }
377
+
378
+ let heightValue;
379
+
380
+ if (props.multiple) {
381
+ heightValue = "32px";
382
+ } else if (isUseCustomSelect.value) {
383
+ heightValue = "fit-content";
384
+ } else {
385
+ heightValue = "54px";
386
+ }
387
+
388
+ return heightValue;
389
+ });
390
+
391
+ const selectedMultiple = computed(() => {
392
+ if (selected.value?.length === 0 || _.isEmpty(selected.value)) {
393
+ return "0px";
394
+ }
395
+
396
+ let heightValue;
397
+
398
+ if (isUseCustomSelect.value || props.multiple) {
399
+ heightValue = "24px";
400
+ } else {
401
+ heightValue = "2px";
402
+ }
403
+
404
+ return heightValue;
405
+ });
406
+
407
+ const selectFocus = computed(() => (props.multiple ? "8px" : "8px"));
408
+
409
+ const selectRequited = computed(() =>
410
+ props.required
411
+ ? "-webkit-linear-gradient(left, #374151 0%, #374151 92%,red 8%,red 100%)"
412
+ : "-webkit-linear-gradient(left, #374151 50%, #374151 50%)"
413
+ );
414
+
415
+ interface Iflag {
416
+ nameText: string;
417
+ iconlink: string;
418
+ }
419
+
420
+ interface IKeyValueRef {
421
+ value: string;
422
+ name: string;
423
+ key: string;
424
+ }
425
+
426
+ const getFlag = computed(() => {
427
+ return (x: Iflag) =>
428
+ items.value?.find((item: IKeyValueRef) => item.name === x.nameText)
429
+ ?.iconlink;
430
+ });
431
+
432
+ const inputValue = computed(() => {
433
+ // return !!(props.modelValue || selected.value);
434
+ const modelValue = props.modelValue;
435
+ const selectedValue = selected.value;
436
+ if (modelValue) return true;
437
+ if (Array.isArray(selectedValue)) return !!selectedValue.length;
438
+ if (selectedValue && typeof selectedValue === 'object') return !!Object.keys(selectedValue).length;
439
+ return !!selectedValue;
440
+ });
441
+
442
+ const handleOptionCreate = (e: any) => {
443
+ emit("selectedOption", e);
444
+ };
445
+
446
+ const isSelectable = computed(() => {
447
+ return !props.multipleLimit || (selected.value?.length ?? 0) < props.multipleLimit;
448
+ });
449
+
450
+ const selectedLimit = () => {
451
+ if(!props.multipleLimit) return true
452
+
453
+ if(props.multipleLimit) {
454
+ return isSelectable.value
455
+ }
456
+ }
457
+
458
+
459
+ // const handlers = (e: Event) => {
460
+ // console.log("@e", e);
461
+ // // e.preventDefault();
462
+ // };
463
+ </script>
464
+ <style lang="scss">
465
+ .scrollbar {
466
+ &--hide {
467
+ @apply overflow-y-auto;
468
+ &::-webkit-scrollbar {
469
+ @apply w-0 h-full;
470
+ }
471
+ &::-webkit-scrollbar-track {
472
+ @apply bg-transparent rounded-full;
473
+ }
474
+ &::-webkit-scrollbar-thumb {
475
+ @apply bg-transparent rounded-full;
476
+ }
477
+ }
478
+ &--thin {
479
+ @apply overflow-y-auto transition delay-300 ease-in;
480
+ &::-webkit-scrollbar {
481
+ @apply w-1 h-full;
482
+ }
483
+ &::-webkit-scrollbar-track {
484
+ @apply bg-transparent rounded-full;
485
+ }
486
+ &::-webkit-scrollbar-thumb {
487
+ @apply bg-transparent rounded-full;
488
+ }
489
+ &:hover::-webkit-scrollbar-thumb {
490
+ @apply bg-gray-500;
491
+ }
492
+ }
493
+ }
494
+
495
+ .vs__search:focus {
496
+ padding-top: v-bind(selectFocus);
497
+ }
498
+ .vs--single.vs--open .vs__selected,
499
+ .vs--single.vs--loading .vs__selected {
500
+ @apply opacity-0;
501
+ }
502
+ .vs__dropdown {
503
+ &-toggle {
504
+ @apply px-1 py-0 border-transparent;
505
+ &[aria-expanded="true"] {
506
+ @apply bg-transparent;
507
+ }
508
+ }
509
+ &-option {
510
+ @apply py-2 text-sm font-medium;
511
+ &--selected {
512
+ @apply bg-purple-100 text-purple-700;
513
+ }
514
+ &--highlight {
515
+ @apply bg-gray-100 text-black font-semibold;
516
+ }
517
+ }
518
+ &-menu {
519
+ @apply max-h-64 py-0;
520
+ }
521
+ }
522
+ .vs__no-options {
523
+ @apply py-3 font-medium text-base;
524
+ }
525
+
526
+ .vs__selected-options {
527
+ @apply group-focus:bg-transparent focus-within:bg-transparent border-transparent;
528
+ background-color: v-bind(selectBG);
529
+ min-height: v-bind(selectHeight);
530
+ margin-top: v-bind(selectedMultiple);
531
+ span.vs__selected {
532
+ background: v-bind(slectedChipbg) !important;
533
+ color: v-bind(slectedChiptextColor) !important;
534
+ height: v-bind(slectedChipHeight) !important;
535
+ @apply rounded-sm pl-2 text-sm font-medium bg-gray-200 border-transparent;
536
+
537
+ button.vs__deselect {
538
+ @apply p-1;
539
+ }
540
+ &:hover button.vs__deselect svg {
541
+ @apply fill-current text-red-600;
542
+ }
543
+ }
544
+ }
545
+
546
+ .v-select.vs--multiple {
547
+ .vs__selected-options {
548
+ margin-top: v-bind(selectedMultiple);
549
+ }
550
+ }
551
+
552
+ .vs {
553
+ &__search {
554
+ @apply placeholder-gray-500 placeholder:text-sm placeholder:font-medium placeholder:leading-loose;
555
+ &:focus {
556
+ @apply text-sm font-medium;
557
+ }
558
+ }
559
+ &__selected {
560
+ @apply text-sm font-medium;
561
+ }
562
+ }
563
+
564
+ .v-select.drop-up.vs--open .vs__dropdown-toggle {
565
+ border-radius: 0 0 4px 4px;
566
+ border-top-color: transparent;
567
+ border-bottom-color: rgba(60, 60, 60, 0.26);
568
+ }
569
+
570
+ [data-popper-placement="top"] {
571
+ border-radius: 4px 4px 0 0;
572
+ border-top-style: solid;
573
+ border-bottom-style: none;
574
+ box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.15);
575
+ }
576
+
577
+ :root {
578
+ --vs-dropdown-option--active-bg: #7e22ce;
579
+ --vs-dropdown-option--active-color: #eeeeee;
580
+ }
581
+
582
+ .v-select input::-webkit-input-placeholder {
583
+ width: fit-content;
584
+ background: v-bind(selectRequited);
585
+ -webkit-background-clip: text;
586
+ -webkit-text-fill-color: transparent;
587
+ @apply appearance-none;
588
+ }
589
+
590
+ .isUseCustomSelect {
591
+ .v-select.customselect {
592
+ .vs__search:focus {
593
+ padding-top: v-bind(selectFocus);
594
+ }
595
+ .vs--single.vs--open .vs__selected,
596
+ .vs--single.vs--loading .vs__selected {
597
+ @apply opacity-0;
598
+ }
599
+ .vs__dropdown {
600
+ &-toggle {
601
+ @apply px-1 py-0 border-transparent;
602
+ &[aria-expanded="true"] {
603
+ @apply bg-transparent;
604
+ }
605
+ }
606
+ &-option {
607
+ @apply py-2 text-sm font-medium;
608
+ &--selected {
609
+ @apply bg-purple-100 text-purple-700;
610
+ }
611
+ &--highlight {
612
+ @apply bg-gray-100 text-black font-semibold;
613
+ }
614
+ }
615
+ &-menu {
616
+ @apply max-h-64 py-0;
617
+ }
618
+ }
619
+ .vs__no-options {
620
+ @apply py-3 font-medium text-base;
621
+ }
622
+
623
+ .vs__selected-options {
624
+ @apply group-focus:bg-transparent focus-within:bg-transparent border-transparent scrollbar--thin;
625
+ background-color: v-bind(selectBG);
626
+ min-height: v-bind(selectHeight);
627
+ margin-top: v-bind(selectedMultiple);
628
+ max-height: 54px;
629
+ span.vs__selected {
630
+ background: v-bind(slectedChipbg) !important;
631
+ color: v-bind(slectedChiptextColor) !important;
632
+ height: v-bind(slectedChipHeight) !important;
633
+ @apply rounded p-0.5 pl-1 text-xs font-medium bg-gray-200 border-transparent;
634
+
635
+ button.vs__deselect {
636
+ @apply p-0.5;
637
+ }
638
+ &:hover button.vs__deselect svg {
639
+ @apply fill-current text-red-600;
640
+ }
641
+ }
642
+ }
643
+
644
+ .vs {
645
+ &__search {
646
+ @apply placeholder-gray-700 placeholder:text-sm placeholder:font-medium;
647
+ }
648
+ &__selected {
649
+ @apply text-sm font-medium;
650
+ }
651
+ }
652
+ }
653
+
654
+ .v-select.customselect.vs--multiple {
655
+ .vs__selected-options {
656
+ margin-top: v-bind(selectedMultiple);
657
+ }
658
+ }
659
+
660
+ .v-select.customselect.drop-up.vs--open .vs__dropdown-toggle {
661
+ border-radius: 0 0 4px 4px;
662
+ border-top-color: transparent;
663
+ border-bottom-color: rgba(60, 60, 60, 0.26);
664
+ }
665
+
666
+ .v-select.customselect .vs__dropdown-toggle .vs__actions {
667
+ display: v-bind(dropDownIcon);
668
+ }
669
+
670
+ :root {
671
+ --vs-dropdown-option--active-bg: #7e22ce;
672
+ --vs-dropdown-option--active-color: #eeeeee;
673
+ }
674
+
675
+ .v-select.customselect input::-webkit-input-placeholder {
676
+ width: fit-content;
677
+ background: v-bind(selectRequited);
678
+ -webkit-background-clip: text;
679
+ -webkit-text-fill-color: transparent;
680
+ }
681
+ }
682
+ </style>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div>
3
+ <label for="label" class="mb-4 text-xs font-medium text-gray-400">{{selected?.length < 3}} - {{ selected?.length < 3 }}</label>
4
+ <v-select
5
+ v-model="selected"
6
+ multiple
7
+ placeholder="Choose up to 3 books!"
8
+ label="title"
9
+ :options="dataBooks"
10
+ :selectable="() => selected?.length < 3"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { computed, ref } from "vue";
17
+ import vSelect from "vue-select";
18
+ import "vue-select/dist/vue-select.css";
19
+ const selected = ref([]);
20
+ import books from "../../data/books";
21
+
22
+ const dataBooks = computed(() => books);
23
+ </script>