edvoyui-component-library-test-flight 0.0.184 → 0.0.186

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 (227) hide show
  1. package/README.md +57 -8
  2. package/dist/EUIButton.vue.d.ts.map +1 -0
  3. package/dist/EUIButtonGroup.vue.d.ts.map +1 -0
  4. package/dist/edvoy-ui.cjs.js +2 -2
  5. package/dist/edvoy-ui.css +1 -1
  6. package/dist/edvoy-ui.es.js +13 -16
  7. package/dist/edvoy-ui.umd.js +5 -5
  8. package/dist/table/EUIDashboardTable.vue.d.ts +1 -1
  9. package/dist/table/EUITable.vue.d.ts +1 -1
  10. package/package.json +18 -17
  11. package/dist/button/EUIButton.vue.d.ts.map +0 -1
  12. package/dist/button/EUIButtonGroup.vue.d.ts.map +0 -1
  13. package/src/App.vue +0 -16
  14. package/src/App.vue.js.map +0 -1
  15. package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
  16. package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
  17. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
  18. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
  19. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
  20. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
  21. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
  22. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
  23. package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
  24. package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
  25. package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
  26. package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
  27. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
  28. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
  29. package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
  30. package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
  31. package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
  32. package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
  33. package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
  34. package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
  35. package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
  36. package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
  37. package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
  38. package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
  39. package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
  40. package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
  41. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
  42. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
  43. package/src/assets/images/search-nodata.png +0 -0
  44. package/src/assets/scss/body.scss +0 -25
  45. package/src/assets/svg/CheckTick.vue +0 -21
  46. package/src/assets/svg/CheckTick.vue.js.map +0 -1
  47. package/src/assets/svg/ChevronBigDown.vue +0 -22
  48. package/src/assets/svg/ChevronBigDown.vue.js.map +0 -1
  49. package/src/assets/svg/ChevronDownSolid.vue +0 -19
  50. package/src/assets/svg/ChevronDownSolid.vue.js.map +0 -1
  51. package/src/assets/svg/ChevronDownStroke.vue +0 -22
  52. package/src/assets/svg/ChevronDownStroke.vue.js.map +0 -1
  53. package/src/assets/svg/ChevronDownStrokeSolid.vue +0 -19
  54. package/src/assets/svg/ChevronDownStrokeSolid.vue.js.map +0 -1
  55. package/src/assets/svg/SearchBigZoomIn.vue +0 -21
  56. package/src/assets/svg/SearchBigZoomIn.vue.js.map +0 -1
  57. package/src/assets/svg/SortArrow.vue +0 -24
  58. package/src/assets/svg/SortArrow.vue.js.map +0 -1
  59. package/src/assets/svg/Student.vue +0 -30
  60. package/src/assets/svg/Student.vue.js.map +0 -1
  61. package/src/assets/svg/partner.vue +0 -33
  62. package/src/assets/svg/partner.vue.js.map +0 -1
  63. package/src/assets/svg/people.vue +0 -25
  64. package/src/assets/svg/people.vue.js.map +0 -1
  65. package/src/assets/vue.svg +0 -1
  66. package/src/components/HelloWorld.vue +0 -1972
  67. package/src/components/HelloWorld.vue.js.map +0 -1
  68. package/src/components/accordion/EUIAccordion.stories.ts +0 -204
  69. package/src/components/accordion/EUIAccordion.vue +0 -152
  70. package/src/components/accordion/EUIAccordion.vue.js.map +0 -1
  71. package/src/components/alerts/EUIAlerts.stories.ts +0 -217
  72. package/src/components/alerts/EUIAlerts.vue +0 -194
  73. package/src/components/alerts/EUIAlerts.vue.js.map +0 -1
  74. package/src/components/avatar/EUIAvatar.stories.ts +0 -157
  75. package/src/components/avatar/EUIAvatar.vue +0 -96
  76. package/src/components/avatar/EUIAvatar.vue.js.map +0 -1
  77. package/src/components/breadcrumb/EUIBreadcrumb.stories.ts +0 -75
  78. package/src/components/breadcrumb/EUIBreadcrumb.vue +0 -59
  79. package/src/components/breadcrumb/EUIBreadcrumb.vue.js.map +0 -1
  80. package/src/components/button/EUIButton.stories.ts +0 -270
  81. package/src/components/button/EUIButton.vue +0 -154
  82. package/src/components/button/EUIButton.vue.js.map +0 -1
  83. package/src/components/button/EUIButtonGroup.vue +0 -287
  84. package/src/components/button/EUIButtonGroup.vue.js.map +0 -1
  85. package/src/components/button/buttonAnimateTab.vue +0 -74
  86. package/src/components/button/buttonAnimateTab.vue.js.map +0 -1
  87. package/src/components/checkbox/EUICheckbox.stories.ts +0 -58
  88. package/src/components/checkbox/EUICheckbox.vue +0 -110
  89. package/src/components/checkbox/EUICheckbox.vue.js.map +0 -1
  90. package/src/components/datepicker/EUIDatepicker.stories.ts +0 -492
  91. package/src/components/datepicker/EUIDatepicker.vue +0 -295
  92. package/src/components/datepicker/EUIDatepicker.vue.js.map +0 -1
  93. package/src/components/delete.vue +0 -262
  94. package/src/components/delete.vue.js.map +0 -1
  95. package/src/components/dragModal/EUIDrag.vue +0 -179
  96. package/src/components/dragModal/EUIDrag.vue.js.map +0 -1
  97. package/src/components/dropdown/EUIMultiDropdown.stories.ts +0 -294
  98. package/src/components/dropdown/EUIMultiDropdown.vue +0 -187
  99. package/src/components/dropdown/EUIMultiDropdown.vue.js.map +0 -1
  100. package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
  101. package/src/components/errorMessage/EUIErrorMessage.stories.ts +0 -41
  102. package/src/components/errorMessage/EUIErrorMessage.vue +0 -25
  103. package/src/components/errorMessage/EUIErrorMessage.vue.js.map +0 -1
  104. package/src/components/index.js.map +0 -1
  105. package/src/components/index.ts +0 -61
  106. package/src/components/input/EUIInput.stories.ts +0 -387
  107. package/src/components/input/EUIInput.vue +0 -223
  108. package/src/components/input/EUIInput.vue.js.map +0 -1
  109. package/src/components/input/EUINumberInput.vue +0 -250
  110. package/src/components/loader/EUICircleLoader.vue +0 -31
  111. package/src/components/loader/EUICircleLoader.vue.js.map +0 -1
  112. package/src/components/loader/EUICubeLoader.vue +0 -237
  113. package/src/components/loader/EUICubeLoader.vue.js.map +0 -1
  114. package/src/components/loader/EUILoader.stories.ts +0 -99
  115. package/src/components/loader/EUILoader.vue +0 -17
  116. package/src/components/loader/EUILoader.vue.js.map +0 -1
  117. package/src/components/loader/EUISquareLoader.vue +0 -47
  118. package/src/components/loader/EUISquareLoader.vue.js.map +0 -1
  119. package/src/components/modal/EUIModal.stories.ts +0 -412
  120. package/src/components/modal/EUIModal.vue +0 -228
  121. package/src/components/modal/EUIModal.vue.js.map +0 -1
  122. package/src/components/pillSelect/EUIPillSelect.stories.ts +0 -74
  123. package/src/components/pillSelect/EUIPillSelect.vue +0 -149
  124. package/src/components/pillSelect/EUIPillSelect.vue.js.map +0 -1
  125. package/src/components/popover/EUIPopover.stories.ts +0 -306
  126. package/src/components/popover/EUIPopover.vue +0 -297
  127. package/src/components/popover/EUIPopover.vue.js.map +0 -1
  128. package/src/components/radio/EUIRadio.stories.ts +0 -54
  129. package/src/components/radio/EUIRadio.vue +0 -75
  130. package/src/components/radio/EUIRadio.vue.js.map +0 -1
  131. package/src/components/searchInput/EUISearch.stories.ts +0 -24
  132. package/src/components/searchInput/EUISearch.vue +0 -223
  133. package/src/components/searchInput/EUISearch.vue.js.map +0 -1
  134. package/src/components/searchTagSelect/EUISearchTagSelect.stories.ts +0 -217
  135. package/src/components/searchTagSelect/EUISearchTagSelect.vue +0 -642
  136. package/src/components/searchTagSelect/EUISearchTagSelect.vue.js.map +0 -1
  137. package/src/components/searchTagSelect/SearchInput.vue +0 -167
  138. package/src/components/searchTagSelect/SearchInput.vue.js.map +0 -1
  139. package/src/components/searchexpand/EUISearchExpand.vue +0 -148
  140. package/src/components/searchexpand/EUISearchExpand.vue.js.map +0 -1
  141. package/src/components/searchexpand/EUISearchToggle.vue +0 -86
  142. package/src/components/searchexpand/EUISearchToggle.vue.js.map +0 -1
  143. package/src/components/select/EUISelect.stories.ts +0 -101
  144. package/src/components/select/EUISelect.vue +0 -1092
  145. package/src/components/select/EUISelect.vue.js.map +0 -1
  146. package/src/components/slideover/EUISlideover.stories.ts +0 -318
  147. package/src/components/slideover/EUISlideover.vue +0 -212
  148. package/src/components/slideover/EUISlideover.vue.js.map +0 -1
  149. package/src/components/stepperTimeline/EUIStepperHorizontal.vue +0 -242
  150. package/src/components/stepperTimeline/EUIStepperHorizontal.vue.js.map +0 -1
  151. package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +0 -54
  152. package/src/components/stepperTimeline/EUIStepperTimeline.vue +0 -16
  153. package/src/components/stepperTimeline/EUIStepperTimeline.vue.js.map +0 -1
  154. package/src/components/stepperTimeline/EUIStepperVertical.vue +0 -112
  155. package/src/components/stepperTimeline/EUIStepperVertical.vue.js.map +0 -1
  156. package/src/components/table/ColumnResizeTable.vue +0 -740
  157. package/src/components/table/ColumnResizeTable.vue.js.map +0 -1
  158. package/src/components/table/EUIDashboardTable.vue +0 -514
  159. package/src/components/table/EUIDashboardTable.vue.js.map +0 -1
  160. package/src/components/table/EUIPageLimit.vue +0 -66
  161. package/src/components/table/EUIPageLimit.vue.js.map +0 -1
  162. package/src/components/table/EUIPagination.vue +0 -175
  163. package/src/components/table/EUIPagination.vue.js.map +0 -1
  164. package/src/components/table/EUIStudentPagination.vue +0 -172
  165. package/src/components/table/EUIStudentPagination.vue.js.map +0 -1
  166. package/src/components/table/EUITable.stories.ts +0 -300
  167. package/src/components/table/EUITable.vue +0 -559
  168. package/src/components/table/EUITable.vue.js.map +0 -1
  169. package/src/components/table/EUITableCheckbox.vue +0 -98
  170. package/src/components/table/EUITableCheckbox.vue.js.map +0 -1
  171. package/src/components/table/GrowthTable.vue +0 -575
  172. package/src/components/table/GrowthTable.vue.js.map +0 -1
  173. package/src/components/table/GrowthTableView.vue +0 -108
  174. package/src/components/table/GrowthTableView.vue.js.map +0 -1
  175. package/src/components/table/ResizeTableview.vue +0 -198
  176. package/src/components/table/ResizeTableview.vue.js.map +0 -1
  177. package/src/components/table/UCheckbox.vue +0 -169
  178. package/src/components/table/UCheckbox.vue.js.map +0 -1
  179. package/src/components/table/UTable.scss +0 -69
  180. package/src/components/table/UTable.vue +0 -611
  181. package/src/components/table/UTable.vue.js.map +0 -1
  182. package/src/components/table/UTableview.vue +0 -189
  183. package/src/components/table/UTableview.vue.js.map +0 -1
  184. package/src/components/tabs/EUITabOutline.vue +0 -263
  185. package/src/components/tabs/EUITabOutline.vue.js.map +0 -1
  186. package/src/components/tabs/EUITabs.vue +0 -262
  187. package/src/components/tabs/EUITabs.vue.js.map +0 -1
  188. package/src/components/tabs/EUItabs.stories.ts +0 -137
  189. package/src/components/tag/EUITag.stories.ts +0 -53
  190. package/src/components/tag/EUITag.vue +0 -88
  191. package/src/components/tag/EUITag.vue.js.map +0 -1
  192. package/src/components/telephone/EUITelephone.stories.ts +0 -358
  193. package/src/components/telephone/EUITelephone.vue +0 -291
  194. package/src/components/telephone/EUITelephone.vue.js.map +0 -1
  195. package/src/components/textArea/EUITextArea.stories.ts +0 -134
  196. package/src/components/textArea/EUITextArea.vue +0 -155
  197. package/src/components/textArea/EUITextArea.vue.js.map +0 -1
  198. package/src/components/timeLine/EUITimeLine.stories.ts +0 -247
  199. package/src/components/timeLine/EUITimeLine.vue +0 -148
  200. package/src/components/timeLine/EUITimeLine.vue.js.map +0 -1
  201. package/src/components/toggle/EUIToggle.stories.ts +0 -63
  202. package/src/components/toggle/EUIToggle.vue +0 -101
  203. package/src/components/toggle/EUIToggle.vue.js.map +0 -1
  204. package/src/components/tooltip/EUITooltip.stories.ts +0 -53
  205. package/src/components/tooltip/EUITooltip.vue +0 -111
  206. package/src/components/tooltip/EUITooltip.vue.js.map +0 -1
  207. package/src/components/uidemo/select-com.vue +0 -120
  208. package/src/components/uidemo/select-com.vue.js.map +0 -1
  209. package/src/data/books.js.map +0 -1
  210. package/src/data/books.ts +0 -163
  211. package/src/data/country.ts +0 -56
  212. package/src/data/tab.js.map +0 -1
  213. package/src/data/tab.ts +0 -40
  214. package/src/data/table.js.map +0 -1
  215. package/src/data/table.ts +0 -5654
  216. package/src/main.js.map +0 -1
  217. package/src/main.ts +0 -5
  218. package/src/style.scss +0 -186
  219. package/src/utils/helpers.js.map +0 -1
  220. package/src/utils/helpers.ts +0 -30
  221. package/src/utils/lodash.js.map +0 -1
  222. package/src/utils/lodash.ts +0 -9
  223. package/src/utils/types.js.map +0 -1
  224. package/src/utils/types.ts +0 -9
  225. package/src/vite-env.d.ts +0 -5
  226. /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
  227. /package/dist/{button/EUIButtonGroup.vue.d.ts → EUIButtonGroup.vue.d.ts} +0 -0
@@ -1,642 +0,0 @@
1
- <template>
2
- <div ref="componentRef" class="relative w-full">
3
- <slot v-if="$slots.label" name="label">
4
- <label
5
- v-if="label"
6
- for="search-input"
7
- class="block text-sm font-medium text-gray-700"
8
- >
9
- {{ label }} <span v-if="required" class="text-red-500">*</span>
10
- </label>
11
- </slot>
12
- <Popper
13
- :class="[`popper-defaultstyle w-full ${popperClasses}`]"
14
- v-bind="$attrs"
15
- :show="showDropDown"
16
- arrow
17
- closeDelay="100"
18
- :offsetSkid="offsetSkid"
19
- :offsetDistance="offsetDistance"
20
- :placement="placement"
21
- :interactive="true"
22
- :auto-hide="true"
23
- @open:popper="handleOpen"
24
- @close:popper="handleClose"
25
- >
26
- <SearchInput
27
- v-if="showDropDown || selectedValues.length === 0"
28
- ref="searchInputRef"
29
- id="search-input"
30
- v-model:model-value="internalSearch"
31
- input-type="defaultInput"
32
- :icon="SearchBigZoomIn"
33
- :placeholder="placeholder"
34
- :disabled="disabled"
35
- @focus="handleSearchFocus"
36
- @click="handleOpen"
37
- />
38
- <button
39
- v-else-if="!showDropDown && selectedValues.length > 0"
40
- type="button"
41
- class="flex items-center justify-between w-full h-10 gap-2 px-4 py-2 text-left bg-white border border-gray-200 border-solid cursor-pointer search-textstyle rounded-3xl"
42
- @click="handleOpen"
43
- >
44
- <component
45
- v-if="searchIcon"
46
- :is="SearchBigZoomIn"
47
- class="flex-shrink-0 w-5 h-5 text-gray-500"
48
- />
49
- <div class="flex-1 min-w-0">
50
- <span
51
- v-if="selectType === 'single'"
52
- class="text-sm font-semibold text-current truncate"
53
- >
54
- {{ startCase(selectedValues[0][itemText] || selectedValues[0]) }}
55
- </span>
56
- <template v-else-if="selectType === 'multiple' && showCount">
57
- <div
58
- class="inline-flex items-center gap-2 py-1 pl-2 pr-1 text-xs font-semibold text-current bg-gray-100 rounded-3xl"
59
- >
60
- Selected Cities
61
- <span class="show-count"> {{ selectedValues.length }}</span>
62
- </div>
63
- </template>
64
- <span v-else class="text-sm font-normal text-gray-400">
65
- {{ placeholder }}
66
- </span>
67
- </div>
68
- <div class="flex items-center flex-shrink-0 gap-2 m-auto">
69
- <XMarkIcon
70
- v-if="selectedValues.length > 0 && clearable"
71
- class="w-4 h-4 text-gray-300 cursor-pointer hover:text-gray-500"
72
- @click.stop="handleClearAll"
73
- />
74
- <ChevronDownStroke
75
- v-else
76
- :class="[
77
- 'w-5 h-5 transform transition duration-200 ease-in-out',
78
- showDropDown
79
- ? 'text-gray-800 rotate-180'
80
- : 'text-gray-400 rotate-0',
81
- ]"
82
- />
83
- </div>
84
- </button>
85
- <template #content>
86
- <div
87
- v-if="showDropDown"
88
- class="w-full p-4 overflow-y-auto text-sm bg-white border-2 border-gray-100 border-solid shadow-lg rounded-3xl max-h-72 scrollbar--hide"
89
- >
90
- <h3
91
- class="sticky z-10 p-2 mb-2 -mx-px -mt-3 font-semibold text-gray-500 bg-white text-sm/4 -top-4"
92
- >
93
- Search Results
94
- </h3>
95
- <ul
96
- ref="options"
97
- tabindex="-1"
98
- role="listbox"
99
- aria-labelledby="listbox-label"
100
- aria-activedescendant="listbox-option-3"
101
- class="space-y-0.5"
102
- >
103
- <li v-if="filteredItems.length === 0 && !hideNoData">
104
- <slot name="no-items">
105
- <div
106
- v-if="internalSearch.length > 0"
107
- class="px-2 py-4 mb-6 text-sm font-medium text-center text-gray-500 min-h-32"
108
- >
109
- No results found for "<strong>{{ internalSearch }}</strong
110
- >"
111
- </div>
112
- </slot>
113
- </li>
114
- <li
115
- v-for="(item, i) in filteredItems"
116
- v-else
117
- :key="`items-${i}`"
118
- role="option"
119
- :class="[
120
- 'transition-all duration-100 ease-in-out',
121
- selectType === 'single' ? 'cursor-pointer' : '',
122
- ]"
123
- @click="
124
- selectType === 'single'
125
- ? selected(item)
126
- ? handleDeselect(item)
127
- : handleSelect(item)
128
- : null
129
- "
130
- @click.stop
131
- >
132
- <!-- Single Select Item -->
133
- <template v-if="selectType === 'single'">
134
- <slot name="item" :item="item">
135
- <div
136
- :class="[
137
- selected(item)
138
- ? 'bg-purple-50 text-purple-600'
139
- : 'text-gray-600 hover:bg-gray-50 hover:text-gray-800',
140
- 'relative py-2 px-4 flex items-center capitalize text-sm transition-colors duration-75 rounded',
141
- ]"
142
- >
143
- <span
144
- :class="[
145
- selected(item) ? 'font-semibold mr-5' : 'font-medium',
146
- 'block tracking-tight',
147
- ]"
148
- >
149
- {{ startCase(item[itemText] || item) }}
150
- </span>
151
- <span
152
- v-if="selected(item)"
153
- class="absolute inset-y-0 right-0 flex items-center pr-4"
154
- >
155
- <CheckTick
156
- class="text-current size-5"
157
- aria-hidden="true"
158
- />
159
- </span>
160
- </div>
161
- </slot>
162
- </template>
163
-
164
- <!-- Multiple Select Item -->
165
- <template v-else-if="selectType === 'multiple'">
166
- <slot name="item" :item="item">
167
- <EUICheckbox
168
- :model-value="selected(item)"
169
- name="checkbox"
170
- :class="[
171
- selected(item)
172
- ? 'text-gray-800 hover:bg-purple-50 hover:text-purple-600'
173
- : 'text-gray-600 hover:bg-gray-50 hover:text-gray-800',
174
- 'relative flex items-center capitalize text-sm transition-colors duration-75 w-full multiple-select rounded-md font-medium [&_label]:w-full [&_label]:p-2.5',
175
- ]"
176
- @update:model-value="
177
- (checked) => handleCheckboxChange(item, checked)
178
- "
179
- >
180
- <template #label>
181
- <span class="ms-2 first-letter:capitalize">{{
182
- startCase(item[itemText] || item)
183
- }}</span>
184
- </template>
185
- </EUICheckbox>
186
- </slot>
187
- </template>
188
- </li>
189
- </ul>
190
- </div>
191
- </template>
192
- </Popper>
193
- <template v-if="errors && errors.length && !showDropDown">
194
- <EUIErrorMessage :errors="errors" :name="name" class="mt-2" />
195
- </template>
196
-
197
- <slot v-if="$slots.labelhint" name="labelhint"></slot>
198
- <div
199
- v-if="selectType === 'multiple' && selectedValues.length > 0 && showTags"
200
- class="px-0.5 my-2 inline-flex gap-x-3 gap-y-2 items-center flex-wrap"
201
- >
202
- <slot
203
- v-for="(item, index) in selectedValues"
204
- name="selection"
205
- :item="item"
206
- :clear="() => handleDeselect(item)"
207
- :key="`selected-values-${index}`"
208
- >
209
- <EUITag
210
- class="capitalize"
211
- :disabled="disabled"
212
- closeIcon
213
- size="md"
214
- color="secondary"
215
- @remove="handleTagRemove(item)"
216
- >
217
- {{ startCase(item[itemText] || item) }}
218
- </EUITag>
219
- </slot>
220
- </div>
221
- <div
222
- class="absolute top-0 px-2 text-xs text-white rounded right-6"
223
- :class="[
224
- { 'bg-gray-400': tagColor === 'None' },
225
- { 'bg-green-400': tagColor === 'Success' },
226
- { 'bg-red-400': tagColor === 'Error' },
227
- ]"
228
- v-if="tag"
229
- >
230
- {{ tag }}
231
- </div>
232
- </div>
233
- </template>
234
-
235
- <script setup lang="ts">
236
- import { computed, ref, watch, nextTick, onMounted, onUnmounted } from "vue";
237
- import { startCase } from "lodash";
238
- import { ErrorObject, ValidationErrors } from "../../utils/types";
239
- import SearchInput from "./SearchInput.vue";
240
- import SearchBigZoomIn from "../../assets/svg/SearchBigZoomIn.vue";
241
- import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
242
- import EUICheckbox from "../checkbox/EUICheckbox.vue";
243
- import EUITag from "../tag/EUITag.vue";
244
- import Popper from "vue3-popper";
245
- import CheckTick from "../../assets/svg/CheckTick.vue";
246
- import { XMarkIcon } from "@heroicons/vue/20/solid";
247
- import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
248
-
249
- // Props
250
- interface Props {
251
- modelValue?: any;
252
- items?: any[];
253
- label?: string;
254
- name?: string;
255
- placement?:
256
- | "auto"
257
- | "auto-start"
258
- | "auto-end"
259
- | "top"
260
- | "top-start"
261
- | "top-end"
262
- | "bottom"
263
- | "bottom-start"
264
- | "bottom-end"
265
- | "right"
266
- | "right-start"
267
- | "right-end"
268
- | "left"
269
- | "left-start"
270
- | "left-end";
271
- itemText?: string;
272
- placeholder?: string;
273
- offsetSkid?: string;
274
- offsetDistance?: string;
275
- errors?: ValidationErrors | ErrorObject[];
276
- selectType?: "single" | "multiple";
277
- filterFunction?: Function;
278
- searchable?: boolean;
279
- backendPagination?: boolean;
280
- hideNoData?: boolean;
281
- disabled?: boolean;
282
- tag?: string;
283
- tagColor?: "None" | "Success" | "Error";
284
- required?: boolean;
285
- classes?: string;
286
- searchIcon?: boolean;
287
- showTags?: boolean;
288
- clearable?: boolean;
289
- ignoreDeselect?: boolean;
290
- popperClasses?: string;
291
- showCount?: boolean;
292
- }
293
- const props = withDefaults(defineProps<Props>(), {
294
- items: () => [],
295
- itemText: "name",
296
- placeholder: "Please Select",
297
- name: "",
298
- offsetDistance: "4",
299
- offsetSkid: "0",
300
- filterFunction: () => {},
301
- selectType: "single",
302
- searchable: true,
303
- backendPagination: false,
304
- hideNoData: false,
305
- disabled: false,
306
- tag: "",
307
- tagColor: "None",
308
- required: false,
309
- classes: "",
310
- searchIcon: false,
311
- showTags: true,
312
- clearable: true,
313
- placement: "bottom-start",
314
- ignoreDeselect: false,
315
- popperClasses: "",
316
- showCount: false,
317
- });
318
-
319
-
320
- // Emits
321
- const emit = defineEmits<{
322
- "update:modelValue": [value: any];
323
- blur: [];
324
- search: [value: string];
325
- create: [value: string];
326
- "on-change": [value: any];
327
- "on-deselect": [value: any];
328
- toggle: [value?: any];
329
- }>();
330
-
331
- // Refs
332
- const internalSearch = ref("");
333
- const showDropDown = ref(false);
334
- const options = ref<HTMLElement>();
335
- const searchInputRef = ref<any>();
336
- const componentRef = ref<HTMLElement>();
337
- const isOpening = ref(false);
338
-
339
- // Computed properties
340
- const selectedValues = computed({
341
- get(): any {
342
- const value: any = props.modelValue;
343
- if (!value) return [];
344
- return [].concat(value);
345
- },
346
- set(value: any) {
347
- emit("update:modelValue", value);
348
- },
349
- });
350
-
351
- const selected = computed(() => {
352
- return (item: any) => {
353
- if (typeof item === "object")
354
- return Boolean(
355
- selectedValues.value.find(
356
- (x: any) => x[props.itemText] === item[props.itemText]
357
- )
358
- );
359
- if (typeof item === "string") return selectedValues.value.includes(item);
360
- };
361
- });
362
-
363
- export type SelectItemKey =
364
- | string
365
- | (string | number)[]
366
- | ((item: object, fallback?: any) => any);
367
-
368
- function getNestedValue(
369
- obj: any,
370
- path: (string | number)[],
371
- fallback?: any
372
- ): any {
373
- const last = path.length - 1;
374
-
375
- if (last < 0) return obj === undefined ? fallback : obj;
376
-
377
- for (let i = 0; i < last; i++) {
378
- if (obj == null) {
379
- return fallback;
380
- }
381
- obj = obj[path[i]];
382
- }
383
-
384
- if (obj == null) return fallback;
385
-
386
- return obj[path[last]] === undefined ? fallback : obj[path[last]];
387
- }
388
-
389
- function getObjectValueByPath(obj: any, path: string, fallback?: any): any {
390
- if (obj == null || !path || typeof path !== "string") return fallback;
391
- if (obj[path] !== undefined) return obj[path];
392
- path = path.replace(/\[(\w+)\]/g, ".$1"); // convert indexes to properties
393
- path = path.replace(/^\./, ""); // strip a leading dot
394
- return getNestedValue(obj, path.split("."), fallback);
395
- }
396
-
397
- function getPropertyFromItem(
398
- item: object,
399
- property: SelectItemKey,
400
- fallback?: any
401
- ): any {
402
- if (property == null) return item === undefined ? fallback : item;
403
-
404
- if (item !== Object(item)) return fallback === undefined ? item : fallback;
405
-
406
- if (typeof property === "string")
407
- return getObjectValueByPath(item, property, fallback);
408
-
409
- if (Array.isArray(property)) return getNestedValue(item, property, fallback);
410
-
411
- if (typeof property !== "function") return fallback;
412
-
413
- const value = property(item, fallback);
414
-
415
- return typeof value === "undefined" ? fallback : value;
416
- }
417
-
418
- const filteredItems = computed(() => {
419
- let items = props.items?.slice();
420
- const search = internalSearch.value.trim().toLowerCase();
421
-
422
- if (internalSearch.value !== "") {
423
- if (search === "") return [];
424
- if (props.backendPagination) return props.items;
425
- items = props.items.filter((option: any) => {
426
- const value = getPropertyFromItem(option, props.itemText);
427
- const text = value != null ? String(value).toLowerCase() : "";
428
- return text.includes(search);
429
- });
430
- }
431
- return items;
432
- });
433
-
434
- const handleDeselect = (item: any) => {
435
- // console.log("called with:", item, selectedValues.value);
436
- if (props.ignoreDeselect) return;
437
- let index = -1;
438
- if (typeof item === "object" && item[props.itemText]) {
439
- index = selectedValues.value.findIndex(
440
- (x: any) => x[props.itemText] === item[props.itemText]
441
- );
442
- } else {
443
- index = selectedValues.value.indexOf(item);
444
- }
445
-
446
- if (index > -1) {
447
- const newValues = [...selectedValues.value];
448
- newValues.splice(index, 1);
449
- emit("update:modelValue", newValues);
450
- nextTick(() => {
451
- if (selectedValues.value.length !== newValues.length) {
452
- selectedValues.value = newValues;
453
- }
454
- });
455
- }
456
-
457
- if (!props.selectType || props.selectType === "single") {
458
- handleClose();
459
- }
460
- emit("on-deselect", item);
461
- emit("toggle");
462
- };
463
-
464
- const handleClearAll = () => {
465
- emit("update:modelValue", []);
466
- emit("toggle");
467
- };
468
-
469
- const handleTagRemove = (item: any) => {
470
- handleDeselect(item);
471
- };
472
-
473
- const handleCheckboxChange = (item: any, checked: boolean) => {
474
- if (checked) {
475
- handleSelect(item);
476
- } else {
477
- handleDeselect(item);
478
- }
479
- };
480
-
481
- const handleUpdate = (items: any) => {
482
- if (typeof items === "object") {
483
- if (Array.isArray(items)) {
484
- if (items.length == 0) {
485
- emit("update:modelValue", "");
486
- } else {
487
- emit("update:modelValue", items);
488
- }
489
- } else {
490
- emit("update:modelValue", items);
491
- }
492
- } else if (items.length > 0) {
493
- emit("update:modelValue", items);
494
- } else {
495
- emit("update:modelValue", "");
496
- }
497
- };
498
-
499
- const handleSelect = (item: any) => {
500
- let newSelection: any;
501
-
502
- if (props.selectType === "multiple" && typeof item === "object") {
503
- const findObj = selectedValues.value.find(
504
- (x: any) => x[props.itemText] === item[props.itemText]
505
- );
506
- if (findObj) {
507
- newSelection = selectedValues.value.filter(
508
- (x: any) => x[props.itemText] !== item[props.itemText]
509
- );
510
- } else {
511
- newSelection = selectedValues.value.concat(item);
512
- }
513
- emit("on-change", [...newSelection]);
514
- } else if (props.selectType === "multiple" && typeof item === "string") {
515
- if (selectedValues.value.includes(item)) {
516
- return handleDeselect(item);
517
- }
518
- newSelection = selectedValues.value.concat(item);
519
- emit("on-change", [...newSelection]);
520
- } else {
521
- // Single select
522
- newSelection = item;
523
- }
524
-
525
- // Only clear search for single select, keep it for multiple select
526
- if (props.selectType === "single") {
527
- internalSearch.value = "";
528
- }
529
-
530
- handleUpdate(newSelection);
531
- if (!props.selectType || props.selectType === "single") {
532
- handleClose();
533
- }
534
- emit("toggle", newSelection);
535
- };
536
-
537
- const handleOpen = () => {
538
- isOpening.value = true;
539
-
540
- // Only clear search for single select, preserve it for multiple select
541
- if (props.selectType === "single") {
542
- internalSearch.value = "";
543
- }
544
- showDropDown.value = true;
545
-
546
- nextTick(() => {
547
- setTimeout(() => {
548
- internalSearch.value = "";
549
- isOpening.value = false;
550
- if (searchInputRef.value?.searchInput) {
551
- searchInputRef.value.searchInput.focus();
552
- } else if (searchInputRef.value?.$el) {
553
- const inputElement = searchInputRef.value.$el.querySelector("input");
554
- if (inputElement) {
555
- inputElement.focus();
556
- }
557
- }
558
- }, 50);
559
- });
560
- };
561
-
562
- const handleClose = () => {
563
- if (showDropDown.value) {
564
- emit("blur");
565
- }
566
- showDropDown.value = false;
567
-
568
- // Only clear search for single select, keep it for multiple select
569
- if (props.selectType === "single") {
570
- internalSearch.value = "";
571
- }
572
- };
573
-
574
- const handleSearchFocus = () => {
575
- internalSearch.value = "";
576
- };
577
-
578
- // Document click handler for outside clicks
579
- const handleDocumentClick = (event: MouseEvent) => {
580
- // Don't close if we're currently opening
581
- if (isOpening.value) return;
582
-
583
- const target = event.target as Node;
584
-
585
- // Check if click is outside the component and popper
586
- if (showDropDown.value && componentRef.value) {
587
- // Check if click is outside the main component
588
- const isOutsideComponent = !componentRef.value.contains(target);
589
-
590
- // Check if click is outside any popper content
591
- const popperElements = document.querySelectorAll(
592
- '[data-popper-placement], .popper-defaultstyle, [role="tooltip"]'
593
- );
594
- const isOutsidePopper = Array.from(popperElements).every(
595
- (popper) => !popper.contains(target)
596
- );
597
-
598
- if (isOutsideComponent && isOutsidePopper) {
599
- handleClose();
600
- }
601
- }
602
- };
603
-
604
- // Lifecycle hooks
605
- onMounted(() => {
606
- document.addEventListener("click", handleDocumentClick);
607
- });
608
-
609
- onUnmounted(() => {
610
- document.removeEventListener("click", handleDocumentClick);
611
- });
612
-
613
- // Watchers
614
- watch(internalSearch, (value: string) => {
615
- emit("search", value);
616
- });
617
-
618
- watch(
619
- () => props.modelValue,
620
- (newValue, oldValue) => {
621
- console.log("changed from:", oldValue, "to:", newValue);
622
- },
623
- { deep: true }
624
- );
625
- </script>
626
-
627
- <style lang="scss">
628
- .popper-defaultstyle {
629
- border: 0px solid transparent !important;
630
- margin: 0px !important;
631
- @apply w-full;
632
-
633
- & > div.popper {
634
- width: 100% !important;
635
- }
636
- }
637
-
638
- .show-count {
639
- min-width: 20px;
640
- @apply h-5 inline-flex items-center justify-center text-xss font-semibold bg-white rounded-xl;
641
- }
642
- </style>