@volverjs/ui-vue 0.0.10-beta.34 → 0.0.10-beta.36

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 (348) hide show
  1. package/README.md +78 -77
  2. package/bin/icons.cjs +1 -1
  3. package/bin/icons.js +5 -5
  4. package/dist/Volver.d.ts +10 -10
  5. package/dist/components/VvAccordion/VvAccordion.es.js +11 -11
  6. package/dist/components/VvAccordion/VvAccordion.umd.js +1 -1
  7. package/dist/components/VvAccordionGroup/VvAccordionGroup.es.js +17 -17
  8. package/dist/components/VvAccordionGroup/VvAccordionGroup.umd.js +1 -1
  9. package/dist/components/VvAction/VvAction.es.js +6 -6
  10. package/dist/components/VvAction/VvAction.umd.js +1 -1
  11. package/dist/components/VvAlert/VvAlert.es.js +23 -21
  12. package/dist/components/VvAlert/VvAlert.umd.js +1 -1
  13. package/dist/components/VvAlert/index.d.ts +2 -2
  14. package/dist/components/VvAlertGroup/VvAlertGroup.es.js +351 -349
  15. package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
  16. package/dist/components/VvAlertGroup/VvAlertGroup.vue.d.ts +3 -3
  17. package/dist/components/VvAlertGroup/index.d.ts +1 -1
  18. package/dist/components/VvAvatar/VvAvatar.es.js +4 -1
  19. package/dist/components/VvAvatar/VvAvatar.umd.js +1 -1
  20. package/dist/components/VvAvatarGroup/VvAvatarGroup.es.js +11 -3
  21. package/dist/components/VvAvatarGroup/VvAvatarGroup.umd.js +1 -1
  22. package/dist/components/VvBreadcrumb/VvBreadcrumb.es.js +10 -10
  23. package/dist/components/VvBreadcrumb/VvBreadcrumb.umd.js +1 -1
  24. package/dist/components/VvButton/VvButton.es.js +31 -25
  25. package/dist/components/VvButton/VvButton.umd.js +1 -1
  26. package/dist/components/VvButtonGroup/VvButtonGroup.es.js +1 -1
  27. package/dist/components/VvButtonGroup/VvButtonGroup.umd.js +1 -1
  28. package/dist/components/VvCheckbox/VvCheckbox.es.js +208 -202
  29. package/dist/components/VvCheckbox/VvCheckbox.umd.js +1 -1
  30. package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +3 -3
  31. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +21 -15
  32. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  33. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +2 -2
  34. package/dist/components/VvCombobox/VvCombobox.es.js +454 -446
  35. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  36. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +5 -5
  37. package/dist/components/VvCombobox/index.d.ts +5 -10
  38. package/dist/components/VvDialog/VvDialog.es.js +11 -11
  39. package/dist/components/VvDialog/VvDialog.umd.js +1 -1
  40. package/dist/components/VvDropdown/VvDropdown.es.js +29 -25
  41. package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
  42. package/dist/components/VvDropdown/VvDropdown.vue.d.ts +12 -8
  43. package/dist/components/VvDropdownAction/VvDropdownAction.es.js +11 -14
  44. package/dist/components/VvDropdownAction/VvDropdownAction.umd.js +1 -1
  45. package/dist/components/VvIcon/VvIcon.es.js +1 -1
  46. package/dist/components/VvIcon/VvIcon.umd.js +1 -1
  47. package/dist/components/VvInputFile/VvInputFile.es.js +61 -55
  48. package/dist/components/VvInputFile/VvInputFile.umd.js +1 -1
  49. package/dist/components/VvInputFile/VvInputFile.vue.d.ts +2 -2
  50. package/dist/components/VvInputFile/index.d.ts +6 -6
  51. package/dist/components/VvInputText/VvInputText.es.js +287 -286
  52. package/dist/components/VvInputText/VvInputText.umd.js +1 -1
  53. package/dist/components/VvInputText/VvInputText.vue.d.ts +2 -2
  54. package/dist/components/VvInputText/index.d.ts +7 -2
  55. package/dist/components/VvNav/VvNav.es.js +23 -20
  56. package/dist/components/VvNav/VvNav.umd.js +1 -1
  57. package/dist/components/VvNavItem/VvNavItem.es.js +6 -6
  58. package/dist/components/VvNavItem/VvNavItem.umd.js +1 -1
  59. package/dist/components/VvRadio/VvRadio.es.js +208 -202
  60. package/dist/components/VvRadio/VvRadio.umd.js +1 -1
  61. package/dist/components/VvRadio/VvRadio.vue.d.ts +2 -2
  62. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +21 -15
  63. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  64. package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +2 -2
  65. package/dist/components/VvSelect/VvSelect.es.js +22 -20
  66. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  67. package/dist/components/VvSelect/VvSelect.vue.d.ts +2 -2
  68. package/dist/components/VvTab/VvTab.es.js +29 -23
  69. package/dist/components/VvTab/VvTab.umd.js +1 -1
  70. package/dist/components/VvTextarea/VvTextarea.es.js +29 -27
  71. package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
  72. package/dist/components/VvTextarea/VvTextarea.vue.d.ts +2 -2
  73. package/dist/components/VvTooltip/VvTooltip.es.js +4 -1
  74. package/dist/components/VvTooltip/VvTooltip.umd.js +1 -1
  75. package/dist/components/common/HintSlot.d.ts +3 -4
  76. package/dist/components/index.es.js +893 -876
  77. package/dist/components/index.umd.js +1 -1
  78. package/dist/composables/alert/useAlert.d.ts +2 -2
  79. package/dist/composables/index.es.js +10 -10
  80. package/dist/composables/index.umd.js +1 -1
  81. package/dist/composables/useBlurhash.d.ts +1 -1
  82. package/dist/composables/usePersistence.d.ts +2 -1
  83. package/dist/composables/useUniqueId.d.ts +1 -1
  84. package/dist/directives/index.es.js +5 -2
  85. package/dist/directives/index.umd.js +1 -1
  86. package/dist/directives/v-contextmenu.es.js +1 -1
  87. package/dist/directives/v-contextmenu.umd.js +1 -1
  88. package/dist/directives/v-tooltip.es.js +4 -1
  89. package/dist/directives/v-tooltip.umd.js +1 -1
  90. package/dist/icons.es.js +3 -3
  91. package/dist/icons.umd.js +1 -1
  92. package/dist/index.es.js +2 -2
  93. package/dist/stories/Alert/AlertModifiers.stories.d.ts +1 -1
  94. package/dist/stories/Alert/AlertSlots.stories.d.ts +1 -1
  95. package/dist/stories/AlertGroup/AlertGroupPosition.stories.d.ts +1 -1
  96. package/dist/stories/AlertGroup/AlertGroupSlots.stories.d.ts +1 -1
  97. package/dist/stories/AlertGroup/AlertGroupWithComposable.stories.d.ts +1 -1
  98. package/dist/stories/Badge/Badge.test.d.ts +1 -1
  99. package/dist/stories/Combobox/Combobox.settings.d.ts +1 -1
  100. package/dist/test/options.d.ts +1 -1
  101. package/dist/test/sleep.d.ts +1 -1
  102. package/dist/types/alert.d.ts +1 -1
  103. package/dist/utils/ObjectUtilities.d.ts +7 -7
  104. package/package.json +232 -239
  105. package/src/Volver.ts +243 -243
  106. package/src/assets/icons/detailed.json +1 -1
  107. package/src/assets/icons/normal.json +1 -1
  108. package/src/assets/icons/simple.json +1 -1
  109. package/src/components/VvAccordion/VvAccordion.vue +155 -155
  110. package/src/components/VvAccordion/index.ts +62 -62
  111. package/src/components/VvAccordionGroup/VvAccordionGroup.vue +220 -219
  112. package/src/components/VvAccordionGroup/index.ts +41 -41
  113. package/src/components/VvAction/VvAction.vue +144 -142
  114. package/src/components/VvAlert/VvAlert.vue +72 -70
  115. package/src/components/VvAlert/index.ts +147 -150
  116. package/src/components/VvAlertGroup/VvAlertGroup.vue +56 -55
  117. package/src/components/VvAlertGroup/index.ts +99 -103
  118. package/src/components/VvAvatar/VvAvatar.vue +20 -14
  119. package/src/components/VvAvatar/index.ts +5 -5
  120. package/src/components/VvAvatarGroup/VvAvatarGroup.vue +58 -53
  121. package/src/components/VvAvatarGroup/index.ts +21 -21
  122. package/src/components/VvBadge/VvBadge.vue +15 -14
  123. package/src/components/VvBadge/index.ts +2 -2
  124. package/src/components/VvBreadcrumb/VvBreadcrumb.vue +49 -48
  125. package/src/components/VvBreadcrumb/index.ts +2 -2
  126. package/src/components/VvButton/VvButton.vue +163 -162
  127. package/src/components/VvButton/index.ts +102 -102
  128. package/src/components/VvButtonGroup/VvButtonGroup.vue +72 -72
  129. package/src/components/VvButtonGroup/index.ts +22 -22
  130. package/src/components/VvCard/VvCard.vue +30 -30
  131. package/src/components/VvCard/index.ts +2 -2
  132. package/src/components/VvCheckbox/VvCheckbox.vue +185 -180
  133. package/src/components/VvCheckbox/index.ts +44 -44
  134. package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +88 -86
  135. package/src/components/VvCombobox/VvCombobox.vue +633 -623
  136. package/src/components/VvCombobox/index.ts +166 -166
  137. package/src/components/VvDialog/VvDialog.vue +131 -129
  138. package/src/components/VvDialog/index.ts +35 -35
  139. package/src/components/VvDropdown/VvDropdown.vue +464 -452
  140. package/src/components/VvDropdown/VvDropdownAction.vue +37 -39
  141. package/src/components/VvDropdown/VvDropdownItem.vue +29 -28
  142. package/src/components/VvDropdown/VvDropdownOptgroup.vue +13 -12
  143. package/src/components/VvDropdown/VvDropdownOption.vue +47 -47
  144. package/src/components/VvDropdown/index.ts +53 -53
  145. package/src/components/VvIcon/README.md +1 -1
  146. package/src/components/VvIcon/VvIcon.vue +133 -133
  147. package/src/components/VvIcon/index.ts +77 -77
  148. package/src/components/VvInputFile/VvInputFile.vue +367 -363
  149. package/src/components/VvInputFile/index.ts +125 -125
  150. package/src/components/VvInputText/VvInputClearAction.ts +50 -50
  151. package/src/components/VvInputText/VvInputPasswordAction.ts +65 -65
  152. package/src/components/VvInputText/VvInputStepAction.ts +43 -43
  153. package/src/components/VvInputText/VvInputText.vue +636 -637
  154. package/src/components/VvInputText/VvInputTextActions.ts +86 -86
  155. package/src/components/VvInputText/index.ts +198 -198
  156. package/src/components/VvNav/VvNav.vue +40 -33
  157. package/src/components/VvNav/VvNavItem.vue +12 -12
  158. package/src/components/VvNav/VvNavSeparator.vue +6 -6
  159. package/src/components/VvNav/index.ts +2 -2
  160. package/src/components/VvProgress/VvProgress.vue +27 -26
  161. package/src/components/VvProgress/index.ts +28 -28
  162. package/src/components/VvRadio/VvRadio.vue +115 -112
  163. package/src/components/VvRadio/index.ts +27 -27
  164. package/src/components/VvRadioGroup/VvRadioGroup.vue +91 -89
  165. package/src/components/VvSelect/VvSelect.vue +241 -238
  166. package/src/components/VvSelect/index.ts +62 -62
  167. package/src/components/VvTab/VvTab.vue +79 -73
  168. package/src/components/VvTab/index.ts +12 -12
  169. package/src/components/VvTextarea/VvTextarea.vue +218 -216
  170. package/src/components/VvTextarea/index.ts +35 -35
  171. package/src/components/VvTooltip/VvTooltip.vue +22 -16
  172. package/src/components/VvTooltip/index.ts +12 -12
  173. package/src/components/common/HintSlot.ts +149 -150
  174. package/src/composables/alert/useAlert.ts +74 -74
  175. package/src/composables/alert/useInjectAlert.ts +1 -1
  176. package/src/composables/alert/useProvideAlert.ts +10 -10
  177. package/src/composables/dropdown/useInjectDropdown.ts +6 -6
  178. package/src/composables/dropdown/useProvideDropdown.ts +62 -62
  179. package/src/composables/group/useInjectedGroupState.ts +41 -41
  180. package/src/composables/group/useProvideGroupState.ts +1 -2
  181. package/src/composables/useBlurhash.ts +52 -60
  182. package/src/composables/useComponentFocus.ts +9 -9
  183. package/src/composables/useComponentIcon.ts +35 -35
  184. package/src/composables/useDebouncedInput.ts +25 -25
  185. package/src/composables/useDefaults.ts +77 -76
  186. package/src/composables/useModifiers.ts +29 -29
  187. package/src/composables/useOptions.ts +45 -43
  188. package/src/composables/usePersistence.ts +70 -72
  189. package/src/composables/useTextCount.ts +44 -44
  190. package/src/composables/useUniqueId.ts +3 -2
  191. package/src/composables/useVolver.ts +1 -1
  192. package/src/constants.ts +70 -70
  193. package/src/directives/v-contextmenu.ts +34 -34
  194. package/src/directives/v-tooltip.ts +17 -17
  195. package/src/index.ts +3 -3
  196. package/src/props/index.ts +453 -453
  197. package/src/resolvers/unplugin.ts +138 -138
  198. package/src/shims.d.ts +4 -5
  199. package/src/stories/Accordion/Accordion.settings.ts +49 -49
  200. package/src/stories/Accordion/Accordion.stories.ts +21 -21
  201. package/src/stories/Accordion/Accordion.test.ts +56 -54
  202. package/src/stories/Accordion/AccordionSlots.stories.ts +13 -13
  203. package/src/stories/AccordionGroup/AccordionGroup.settings.ts +69 -67
  204. package/src/stories/AccordionGroup/AccordionGroup.stories.ts +37 -37
  205. package/src/stories/AccordionGroup/AccordionGroup.test.ts +49 -47
  206. package/src/stories/AccordionGroup/AccordionGroupSlots.stories.ts +34 -34
  207. package/src/stories/Alert/Alert.settings.ts +115 -115
  208. package/src/stories/Alert/Alert.stories.ts +30 -30
  209. package/src/stories/Alert/Alert.test.ts +78 -78
  210. package/src/stories/Alert/AlertModifiers.stories.ts +45 -45
  211. package/src/stories/Alert/AlertSlots.stories.ts +35 -35
  212. package/src/stories/AlertGroup/AlertGroup.settings.ts +104 -104
  213. package/src/stories/AlertGroup/AlertGroup.stories.ts +25 -25
  214. package/src/stories/AlertGroup/AlertGroup.test.ts +67 -67
  215. package/src/stories/AlertGroup/AlertGroupPosition.stories.ts +68 -68
  216. package/src/stories/AlertGroup/AlertGroupSlots.stories.ts +23 -23
  217. package/src/stories/AlertGroup/AlertGroupWithComposable.stories.ts +57 -57
  218. package/src/stories/Avatar/Avatar.settings.ts +29 -29
  219. package/src/stories/Avatar/Avatar.stories.ts +23 -23
  220. package/src/stories/Avatar/Avatar.test.ts +22 -22
  221. package/src/stories/Avatar/AvatarBadge.stories.ts +15 -15
  222. package/src/stories/Avatar/AvatarModifiers.stories.ts +61 -61
  223. package/src/stories/Avatar/AvatarSlots.stories.ts +18 -18
  224. package/src/stories/AvatarGroup/AvatarGroup.settings.ts +53 -53
  225. package/src/stories/AvatarGroup/AvatarGroup.stories.ts +17 -17
  226. package/src/stories/AvatarGroup/AvatarGroup.test.ts +24 -24
  227. package/src/stories/AvatarGroup/AvatarGroupModifiers.stories.ts +15 -15
  228. package/src/stories/AvatarGroup/AvatarGroupSlotDefault.stories.ts +17 -17
  229. package/src/stories/Badge/Badge.settings.ts +20 -20
  230. package/src/stories/Badge/Badge.stories.ts +23 -23
  231. package/src/stories/Badge/Badge.test.ts +8 -8
  232. package/src/stories/Badge/BadgeSlots.stories.ts +10 -10
  233. package/src/stories/Blurhash/BlurhashComposable.stories.ts +77 -76
  234. package/src/stories/Breadcrumb/Breadcrumb.settings.ts +34 -34
  235. package/src/stories/Breadcrumb/Breadcrumb.stories.ts +22 -22
  236. package/src/stories/Breadcrumb/Breadcrumb.test.ts +44 -43
  237. package/src/stories/Breadcrumb/BreadcrumbSlots.stories.ts +17 -17
  238. package/src/stories/Button/Button.settings.ts +144 -144
  239. package/src/stories/Button/Button.stories.ts +18 -18
  240. package/src/stories/Button/Button.test.ts +41 -40
  241. package/src/stories/Button/ButtonIcon.stories.ts +42 -42
  242. package/src/stories/Button/ButtonLink.stories.ts +24 -24
  243. package/src/stories/Button/ButtonLoading.stories.ts +22 -22
  244. package/src/stories/Button/ButtonModifiers.stories.ts +91 -91
  245. package/src/stories/Button/ButtonSlots.stories.ts +47 -47
  246. package/src/stories/Button/ButtonState.stories.ts +23 -23
  247. package/src/stories/Button/ButtonToggle.stories.ts +30 -30
  248. package/src/stories/ButtonGroup/ButtonGroup.settings.ts +32 -32
  249. package/src/stories/ButtonGroup/ButtonGroup.stories.ts +19 -19
  250. package/src/stories/ButtonGroup/ButtonGroup.test.ts +23 -22
  251. package/src/stories/ButtonGroup/ButtonGroupModifiers.stories.ts +20 -20
  252. package/src/stories/ButtonGroup/ButtonGroupSlots.stories.ts +18 -18
  253. package/src/stories/ButtonGroup/ButtonGroupToggle.stories.ts +22 -22
  254. package/src/stories/Card/Card.settings.ts +48 -48
  255. package/src/stories/Card/Card.stories.ts +22 -22
  256. package/src/stories/Card/Card.test.ts +14 -14
  257. package/src/stories/Card/CardSlots.stories.ts +42 -42
  258. package/src/stories/Checkbox/Checkbox.settings.ts +35 -35
  259. package/src/stories/Checkbox/Checkbox.stories.ts +57 -57
  260. package/src/stories/Checkbox/Checkbox.test.ts +63 -62
  261. package/src/stories/Checkbox/CheckboxBinary.stories.ts +17 -17
  262. package/src/stories/Checkbox/CheckboxSlots.stories.ts +15 -15
  263. package/src/stories/CheckboxGroup/CheckboxGroup.settings.ts +9 -9
  264. package/src/stories/CheckboxGroup/CheckboxGroup.stories.ts +50 -50
  265. package/src/stories/CheckboxGroup/CheckboxGroup.test.ts +63 -63
  266. package/src/stories/CheckboxGroup/CheckboxGroupOptions.stories.ts +34 -34
  267. package/src/stories/CheckboxGroup/CheckboxGroupSlots.stories.ts +23 -23
  268. package/src/stories/Combobox/Combobox.settings.ts +390 -390
  269. package/src/stories/Combobox/Combobox.stories.ts +107 -107
  270. package/src/stories/Combobox/Combobox.test.ts +89 -87
  271. package/src/stories/Combobox/ComboboxIconPosition.stories.ts +24 -24
  272. package/src/stories/Combobox/ComboboxMultiple.stories.ts +22 -22
  273. package/src/stories/Combobox/ComboboxOptions.stories.ts +84 -84
  274. package/src/stories/Combobox/ComboboxSlots.stories.ts +55 -55
  275. package/src/stories/Dialog/Dialog.settings.ts +39 -39
  276. package/src/stories/Dialog/Dialog.stories.ts +28 -28
  277. package/src/stories/Dialog/Dialog.test.ts +49 -49
  278. package/src/stories/Dialog/DialogSlots.stories.ts +20 -20
  279. package/src/stories/Dropdown/Dropdown.settings.ts +62 -62
  280. package/src/stories/Dropdown/Dropdown.stories.ts +59 -59
  281. package/src/stories/Dropdown/Dropdown.test.ts +9 -9
  282. package/src/stories/Dropdown/DropdownContextmenuDirective.stories.ts +16 -16
  283. package/src/stories/Dropdown/DropdownMultilevel.stories.ts +18 -18
  284. package/src/stories/Dropdown/DropdownSlots.stories.ts +49 -49
  285. package/src/stories/Icon/Icon.settings.ts +64 -64
  286. package/src/stories/Icon/Icon.stories.ts +28 -28
  287. package/src/stories/Icon/IconsCollection.stories.ts +22 -22
  288. package/src/stories/InputFile/InputFile.settings.ts +29 -29
  289. package/src/stories/InputFile/InputFile.stories.ts +54 -54
  290. package/src/stories/InputFile/InputFileDropArea.stories.ts +34 -34
  291. package/src/stories/InputFile/InputFileIconPosition.stories.ts +24 -24
  292. package/src/stories/InputFile/InputFileSlots.stories.ts +17 -17
  293. package/src/stories/InputText/InputText.settings.ts +245 -246
  294. package/src/stories/InputText/InputText.stories.ts +67 -67
  295. package/src/stories/InputText/InputText.test.ts +118 -117
  296. package/src/stories/InputText/InputTextIconPosition.stories.ts +24 -24
  297. package/src/stories/InputText/InputTextLength.stories.ts +33 -33
  298. package/src/stories/InputText/InputTextMask.stories.ts +91 -91
  299. package/src/stories/InputText/InputTextMinMax.stories.ts +29 -29
  300. package/src/stories/InputText/InputTextSlots.stories.ts +20 -20
  301. package/src/stories/InputText/InputTextType.stories.ts +70 -70
  302. package/src/stories/Nav/Nav.settings.ts +25 -25
  303. package/src/stories/Nav/Nav.stories.ts +17 -17
  304. package/src/stories/Nav/Nav.test.ts +10 -10
  305. package/src/stories/Nav/NavModifiers.stories.ts +25 -25
  306. package/src/stories/Progress/Progress.settings.ts +23 -23
  307. package/src/stories/Progress/Progress.stories.ts +23 -23
  308. package/src/stories/Progress/Progress.test.ts +4 -4
  309. package/src/stories/Radio/Radio.settings.ts +9 -9
  310. package/src/stories/Radio/Radio.stories.ts +47 -47
  311. package/src/stories/Radio/Radio.test.ts +54 -53
  312. package/src/stories/Radio/RadioSlots.stories.ts +15 -15
  313. package/src/stories/RadioGroup/RadioGroup.settings.ts +9 -9
  314. package/src/stories/RadioGroup/RadioGroup.stories.ts +50 -50
  315. package/src/stories/RadioGroup/RadioGroup.test.ts +63 -63
  316. package/src/stories/RadioGroup/RadioGroupOptions.stories.ts +34 -34
  317. package/src/stories/RadioGroup/RadioGroupSlots.stories.ts +23 -23
  318. package/src/stories/Select/Select.settings.ts +70 -70
  319. package/src/stories/Select/Select.stories.ts +66 -66
  320. package/src/stories/Select/Select.test.ts +65 -64
  321. package/src/stories/Select/SelectIconPosition.stories.ts +24 -24
  322. package/src/stories/Select/SelectOptions.stories.ts +54 -54
  323. package/src/stories/Select/SelectSlots.stories.ts +20 -20
  324. package/src/stories/Tab/Tab.settings.ts +32 -32
  325. package/src/stories/Tab/Tab.stories.ts +17 -17
  326. package/src/stories/Tab/Tab.test.ts +17 -17
  327. package/src/stories/Textarea/Textarea.settings.ts +78 -79
  328. package/src/stories/Textarea/Textarea.stories.ts +63 -63
  329. package/src/stories/Textarea/Textarea.test.ts +70 -69
  330. package/src/stories/Textarea/TextareaLength.stories.ts +33 -33
  331. package/src/stories/Textarea/TextareaSlots.stories.ts +20 -20
  332. package/src/stories/Textarea/TextareatIconPosition.stories.ts +24 -24
  333. package/src/stories/Tooltip/Tooltip.settings.ts +16 -16
  334. package/src/stories/Tooltip/Tooltip.stories.ts +18 -18
  335. package/src/stories/Tooltip/Tooltip.test.ts +53 -52
  336. package/src/stories/Tooltip/TooltipDirective.stories.ts +37 -37
  337. package/src/stories/argTypes.ts +484 -485
  338. package/src/test/expect.ts +71 -74
  339. package/src/test/options.ts +17 -16
  340. package/src/test/sleep.ts +3 -2
  341. package/src/test/types.d.ts +11 -11
  342. package/src/types/alert.ts +18 -18
  343. package/src/types/blurhash.ts +18 -18
  344. package/src/types/generic.ts +1 -2
  345. package/src/types/group.ts +21 -21
  346. package/src/types/input-file.ts +17 -17
  347. package/src/types/nav.ts +13 -13
  348. package/src/utils/ObjectUtilities.ts +192 -177
@@ -1,629 +1,639 @@
1
- <script lang="ts">
2
- export default {
3
- name: 'VvCombobox',
4
- components: {
5
- VvDropdown,
6
- VvDropdownOption,
7
- VvDropdownOptgroup,
8
- VvButton,
9
- },
10
- }
1
+ <script setup lang="ts">
2
+ import type { Ref } from 'vue'
3
+ import { toRefs } from 'vue'
4
+ import VvIcon from '../VvIcon/VvIcon.vue'
5
+ import VvDropdown from '../VvDropdown/VvDropdown.vue'
6
+ import VvDropdownOption from '../VvDropdown/VvDropdownOption.vue'
7
+ import VvDropdownOptgroup from '../VvDropdown/VvDropdownOptgroup.vue'
8
+ import VvSelect from '../VvSelect/VvSelect.vue'
9
+ import VvBadge from '../VvBadge/VvBadge.vue'
10
+ import VvButton from '../VvButton/VvButton.vue'
11
+ import HintSlotFactory from '../common/HintSlot'
12
+ import type { Option } from '../../types/generic'
13
+ import { DropdownRole } from '../../constants'
14
+ import { VvComboboxProps, VvComboboxEvents } from '.'
15
+
16
+ // props, emit and slots
17
+ const props = defineProps(VvComboboxProps)
18
+
19
+ const emit = defineEmits(VvComboboxEvents)
20
+
21
+ const slots = useSlots()
22
+
23
+ // props merged with volver defaults (now only for labels)
24
+ const propsDefaults = useDefaults<typeof VvComboboxProps>(
25
+ 'VvCombobox',
26
+ VvComboboxProps,
27
+ props,
28
+ )
29
+
30
+ // Grouped options
31
+ function isGroup(option: string | Option) {
32
+ if (typeof option === 'string') {
33
+ return false
34
+ }
35
+ return option.options && option.options.length > 0
36
+ }
37
+
38
+ // hint slot
39
+ const {
40
+ HintSlot,
41
+ hasHintLabelOrSlot,
42
+ hasInvalidLabelOrSlot,
43
+ hintSlotScope,
44
+ } = HintSlotFactory(propsDefaults, slots)
45
+
46
+ // template ref
47
+ const inputEl: Ref<HTMLElement | null> = ref(null)
48
+ const inputSearchEl: Ref<HTMLElement | null> = ref(null)
49
+ const wrapperEl: Ref<HTMLElement | null> = ref(null)
50
+
51
+ // focus
52
+ const { focused } = useComponentFocus(inputEl, emit)
53
+ const { focused: focusedWithin } = useFocusWithin(wrapperEl)
54
+
55
+ watch(focused, (newValue) => {
56
+ if (!props.autoOpen) {
57
+ return
58
+ }
59
+ if (newValue && !expanded.value) {
60
+ expand()
61
+ return
62
+ }
63
+ if (!newValue && expanded.value && !focusedWithin.value) {
64
+ collapse()
65
+ }
66
+ })
67
+
68
+ watch(focusedWithin, (newValue) => {
69
+ if (!focused.value && !newValue && expanded.value) {
70
+ collapse()
71
+ }
72
+ })
73
+
74
+ // search
75
+ const searchText = ref('')
76
+ const debouncedSearchText = refDebounced(
77
+ searchText,
78
+ computed(() => Number(props.debounceSearch)),
79
+ )
80
+ watch(debouncedSearchText, () => {
81
+ emit('update:search', debouncedSearchText.value)
82
+ /**
83
+ * @deprecated change:search should not be used, use update:search instead
84
+ */
85
+ // eslint-disable-next-line vue/custom-event-name-casing
86
+ emit('change:search', debouncedSearchText.value)
87
+ })
88
+
89
+ // expanded
90
+ const expanded = ref(false)
91
+ function toggleExpanded() {
92
+ if (props.disabled || props.readonly)
93
+ return
94
+ expanded.value = !expanded.value
95
+ }
96
+ function expand() {
97
+ if (props.disabled || props.readonly || expanded.value)
98
+ return
99
+ expanded.value = true
100
+ }
101
+ function collapse() {
102
+ if (props.disabled || props.readonly || !expanded.value)
103
+ return
104
+ expanded.value = false
105
+ }
106
+ function onAfterExpand() {
107
+ if (propsDefaults.value.searchable) {
108
+ if (inputSearchEl.value) {
109
+ inputSearchEl.value.focus({
110
+ preventScroll: true,
111
+ })
112
+ }
113
+ }
114
+ }
115
+ function onAfterCollapse() {
116
+ if (propsDefaults.value.searchable) {
117
+ searchText.value = ''
118
+ }
119
+ }
120
+
121
+ // data
122
+ const {
123
+ id,
124
+ icon,
125
+ iconPosition,
126
+ modifiers,
127
+ disabled,
128
+ readonly,
129
+ loading,
130
+ valid,
131
+ invalid,
132
+ floating,
133
+ } = toRefs(props)
134
+ const hasId = useUniqueId(id)
135
+ const hasHintId = computed(() => `${hasId.value}-hint`)
136
+ const hasDropdownId = computed(() => `${hasId.value}-dropdown`)
137
+ const hasSearchId = computed(() => `${hasId.value}-search`)
138
+ const hasLabelId = computed(() => `${hasId.value}-label`)
139
+
140
+ // loading
141
+ const localLoading = ref(false)
142
+ const isLoading = computed(() => localLoading.value || loading.value)
143
+
144
+ // ref
145
+ const dropdownEl = ref()
146
+
147
+ // icons
148
+ const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition)
149
+
150
+ // dirty
151
+ const isDirty = computed(() => !isEmpty(props.modelValue))
152
+
153
+ // tabindex
154
+ const hasTabindex = computed(() => {
155
+ return disabled.value || readonly.value ? -1 : props.tabindex
156
+ })
157
+
158
+ // styles
159
+ const bemCssClasses = useModifiers(
160
+ 'vv-select',
161
+ modifiers,
162
+ computed(() => ({
163
+ 'disabled': disabled.value,
164
+ 'loading': isLoading.value,
165
+ 'readonly': readonly.value,
166
+ 'icon-before': hasIconBefore.value !== undefined,
167
+ 'icon-after': hasIconAfter.value !== undefined,
168
+ 'valid': valid.value,
169
+ 'invalid': invalid.value,
170
+ 'dirty': isDirty.value,
171
+ 'focus': focused.value || focusedWithin.value || expanded.value,
172
+ 'floating': floating.value,
173
+ 'badges': props.badges,
174
+ })),
175
+ )
176
+
177
+ const {
178
+ getOptionLabel,
179
+ getOptionValue,
180
+ getOptionGrouped,
181
+ isOptionDisabled,
182
+ } = useOptions(props)
183
+
184
+ // options filtered by search text
185
+ const filteredOptions = computedAsync(async () => {
186
+ if (propsDefaults.value.searchFunction) {
187
+ localLoading.value = true
188
+ const toReturn = await Promise.resolve(
189
+ propsDefaults.value.searchFunction(
190
+ debouncedSearchText.value,
191
+ props.options,
192
+ ),
193
+ )
194
+ localLoading.value = false
195
+ return toReturn
196
+ }
197
+ return props.options?.filter((option) => {
198
+ return getOptionLabel(option)
199
+ .toLowerCase()
200
+ .includes(debouncedSearchText.value.toLowerCase().trim())
201
+ })
202
+ })
203
+
204
+ /**
205
+ * Check if an option exist into modelValue array (multiple) or is equal to modelValue (single)
206
+ * @param {string | Option} option
207
+ */
208
+ function isOptionSelected(option: string | Option) {
209
+ if (Array.isArray(props.modelValue)) {
210
+ // check if contain whole option or option value
211
+ return (
212
+ contains(option, props.modelValue)
213
+ || contains(getOptionValue(option), props.modelValue)
214
+ )
215
+ }
216
+ // check if modelValue is equal to option or option value
217
+ return (
218
+ equals(option, props.modelValue)
219
+ || equals(getOptionValue(option), props.modelValue)
220
+ )
221
+ }
222
+
223
+ /**
224
+ * Compute the label to show to the user
225
+ * Check if is multiple mode, object mode or "string" mode
226
+ */
227
+ const selectedOptions = computed(() => {
228
+ const options = props.options.reduce<Array<Option | string>>(
229
+ (acc, value) => {
230
+ if (isGroup(value)) {
231
+ return [...acc, ...getOptionGrouped(value)]
232
+ }
233
+ return [...acc, value]
234
+ },
235
+ [],
236
+ )
237
+ return options.filter((option) => {
238
+ return isOptionSelected(option)
239
+ })
240
+ })
241
+
242
+ const hasValue = computed(() => {
243
+ return selectedOptions.value
244
+ .map((option: string | Option) => getOptionLabel(option))
245
+ .join(props.separator)
246
+ })
247
+
248
+ /**
249
+ * Function triggered on click on input
250
+ */
251
+ function onClickInput() {
252
+ props.autoOpen ? expand() : toggleExpanded()
253
+ }
254
+
255
+ /**
256
+ * Function triggered on input of checkbox or radio (multple or single mode)
257
+ * @param option {string | Option} option value
258
+ */
259
+ function onInput(option: string | Option) {
260
+ if (props.disabled || props.readonly) {
261
+ return
262
+ }
263
+
264
+ // get option value
265
+ const value = getOptionValue(option)
266
+ let toReturn: string | string[] | Option | Option[] | undefined = value
267
+
268
+ // check multiple prop, override value with array and remove or add the value
269
+ if (props.multiple) {
270
+ // check max-values prop and block check new values
271
+ if (Array.isArray(props.modelValue)) {
272
+ const maxValues = Number(props.maxValues)
273
+ if (
274
+ props.maxValues !== undefined
275
+ && maxValues >= 0
276
+ && props.modelValue?.length >= maxValues
277
+ ) {
278
+ if (!contains(value, props.modelValue)) {
279
+ // maxValues reached
280
+ return
281
+ }
282
+ }
283
+ toReturn = contains(value, props.modelValue)
284
+ ? removeFromList(value, props.modelValue)
285
+ : [...props.modelValue, value]
286
+ }
287
+ else {
288
+ toReturn = [value as Option]
289
+ }
290
+ }
291
+ else {
292
+ if (!props.keepOpen) {
293
+ collapse()
294
+ }
295
+ if (Array.isArray(props.modelValue)) {
296
+ if (props.unselectable && props.modelValue.includes(value)) {
297
+ toReturn = []
298
+ }
299
+ else {
300
+ toReturn = [value]
301
+ }
302
+ }
303
+ else if (props.unselectable && value === props.modelValue) {
304
+ toReturn = undefined
305
+ }
306
+ }
307
+ emit('update:modelValue', toReturn)
308
+ }
309
+
310
+ const selectProps = computed(() => ({
311
+ id: hasId.value,
312
+ name: props.name,
313
+ tabindex: hasTabindex.value,
314
+ valid: valid.value,
315
+ validLabel: propsDefaults.value.validLabel,
316
+ invalid: invalid.value,
317
+ invalidLabel: propsDefaults.value.invalidLabel,
318
+ hintLabel: propsDefaults.value.hintLabel,
319
+ loading: isLoading.value,
320
+ loadingLabel: propsDefaults.value.loadingLabel,
321
+ disabled: disabled.value,
322
+ readonly: readonly.value,
323
+ modifiers: propsDefaults.value.modifiers,
324
+ options: propsDefaults.value.options,
325
+ labelKey: propsDefaults.value.labelKey,
326
+ valueKey: propsDefaults.value.valueKey,
327
+ icon: propsDefaults.value.icon,
328
+ iconPosition: propsDefaults.value.iconPosition,
329
+ floating: propsDefaults.value.floating,
330
+ unselectable: propsDefaults.value.unselectable,
331
+ multiple: propsDefaults.value.multiple,
332
+ label: propsDefaults.value.label,
333
+ placeholder: propsDefaults.value.placeholder,
334
+ modelValue: props.modelValue,
335
+ }))
336
+
337
+ const dropdownProps = computed(() => ({
338
+ id: hasDropdownId.value,
339
+ reference: wrapperEl.value,
340
+ placement: propsDefaults.value.placement,
341
+ strategy: propsDefaults.value.strategy,
342
+ transitionName: propsDefaults.value.transitionName,
343
+ offset: propsDefaults.value.offset,
344
+ shift: propsDefaults.value.shift,
345
+ flip: propsDefaults.value.flip,
346
+ autoPlacement: propsDefaults.value.autoPlacement,
347
+ arrow: propsDefaults.value.arrow,
348
+ autofocusFirst: propsDefaults.value.searchable
349
+ ? true
350
+ : propsDefaults.value.autofocusFirst,
351
+ triggerWidth: propsDefaults.value.triggerWidth,
352
+ modifiers: propsDefaults.value.dropdownModifiers,
353
+ }))
354
+
355
+ // slots
356
+ const slotProps = computed(() => ({
357
+ valid: props.valid,
358
+ invalid: props.invalid,
359
+ modelValue: props.modelValue,
360
+ }))
361
+
362
+ // computed
363
+ onKeyStroke(
364
+ [' ', 'Enter'],
365
+ (e) => {
366
+ if (props.autoOpen) {
367
+ return
368
+ }
369
+ if (!expanded.value && focused.value) {
370
+ e.preventDefault()
371
+ e.stopImmediatePropagation()
372
+ toggleExpanded()
373
+ }
374
+ },
375
+ { target: inputEl },
376
+ )
11
377
  </script>
12
378
 
13
- <script setup lang="ts">
14
- import type { Ref } from 'vue'
15
- import { toRefs } from 'vue'
16
- import { VvComboboxProps, VvComboboxEvents } from '.'
17
- import VvIcon from '../VvIcon/VvIcon.vue'
18
- import VvDropdown from '../VvDropdown/VvDropdown.vue'
19
- import VvDropdownOption from '../VvDropdown/VvDropdownOption.vue'
20
- import VvDropdownOptgroup from '../VvDropdown/VvDropdownOptgroup.vue'
21
- import VvSelect from '../VvSelect/VvSelect.vue'
22
- import VvBadge from '../VvBadge/VvBadge.vue'
23
- import VvButton from '../VvButton/VvButton.vue'
24
- import HintSlotFactory from '../common/HintSlot'
25
- import type { Option } from '../../types/generic'
26
- import { DropdownRole } from '../../constants'
27
-
28
- // props, emit and slots
29
- const props = defineProps(VvComboboxProps)
30
- const emit = defineEmits(VvComboboxEvents)
31
- const slots = useSlots()
32
-
33
- // props merged with volver defaults (now only for labels)
34
- const propsDefaults = useDefaults<typeof VvComboboxProps>(
35
- 'VvCombobox',
36
- VvComboboxProps,
37
- props,
38
- )
39
-
40
- // Grouped options
41
- const isGroup = (option: string | Option) => {
42
- if (typeof option === 'string') {
43
- return false
44
- }
45
- return option.options && option.options.length > 0
46
- }
47
-
48
- // hint slot
49
- const {
50
- HintSlot,
51
- hasHintLabelOrSlot,
52
- hasInvalidLabelOrSlot,
53
- hintSlotScope,
54
- } = HintSlotFactory(propsDefaults, slots)
55
-
56
- // template ref
57
- const inputEl: Ref<HTMLElement | null> = ref(null)
58
- const inputSearchEl: Ref<HTMLElement | null> = ref(null)
59
- const wrapperEl: Ref<HTMLElement | null> = ref(null)
60
-
61
- // focus
62
- const { focused } = useComponentFocus(inputEl, emit)
63
- const { focused: focusedWithin } = useFocusWithin(wrapperEl)
64
-
65
- watch(focused, (newValue) => {
66
- if (!props.autoOpen) {
67
- return
68
- }
69
- if (newValue && !expanded.value) {
70
- expand()
71
- return
72
- }
73
- if (!newValue && expanded.value && !focusedWithin.value) {
74
- collapse()
75
- }
76
- })
77
-
78
- watch(focusedWithin, (newValue) => {
79
- if (!focused.value && !newValue && expanded.value) {
80
- collapse()
81
- }
82
- })
83
-
84
- // search
85
- const searchText = ref('')
86
- const debouncedSearchText = refDebounced(
87
- searchText,
88
- computed(() => Number(props.debounceSearch)),
89
- )
90
- watch(debouncedSearchText, () => {
91
- emit('update:search', debouncedSearchText.value)
92
- /**
93
- * @deprecated change:search should not be used, use update:search instead
94
- */
95
- emit('change:search', debouncedSearchText.value)
96
- })
97
-
98
- // expanded
99
- const expanded = ref(false)
100
- const toggleExpanded = () => {
101
- if (props.disabled || props.readonly) return
102
- expanded.value = !expanded.value
103
- }
104
- const expand = () => {
105
- if (props.disabled || props.readonly || expanded.value) return
106
- expanded.value = true
107
- }
108
- const collapse = () => {
109
- if (props.disabled || props.readonly || !expanded.value) return
110
- expanded.value = false
111
- }
112
- const onAfterExpand = () => {
113
- if (propsDefaults.value.searchable) {
114
- if (inputSearchEl.value) {
115
- inputSearchEl.value.focus({
116
- preventScroll: true,
117
- })
118
- }
119
- }
120
- }
121
- const onAfterCollapse = () => {
122
- if (propsDefaults.value.searchable) {
123
- searchText.value = ''
124
- }
125
- }
126
-
127
- // data
128
- const {
129
- id,
130
- icon,
131
- iconPosition,
132
- modifiers,
133
- disabled,
134
- readonly,
135
- loading,
136
- valid,
137
- invalid,
138
- floating,
139
- } = toRefs(props)
140
- const hasId = useUniqueId(id)
141
- const hasHintId = computed(() => `${hasId.value}-hint`)
142
- const hasDropdownId = computed(() => `${hasId.value}-dropdown`)
143
- const hasSearchId = computed(() => `${hasId.value}-search`)
144
- const hasLabelId = computed(() => `${hasId.value}-label`)
145
-
146
- // loading
147
- const localLoading = ref(false)
148
- const isLoading = computed(() => localLoading.value || loading.value)
149
-
150
- // ref
151
- const dropdownEl = ref()
152
-
153
- // icons
154
- const { hasIconBefore, hasIconAfter } = useComponentIcon(icon, iconPosition)
155
-
156
- // dirty
157
- const isDirty = computed(() => !isEmpty(props.modelValue))
158
-
159
- // tabindex
160
- const hasTabindex = computed(() => {
161
- return disabled.value || readonly.value ? -1 : props.tabindex
162
- })
163
-
164
- // styles
165
- const bemCssClasses = useModifiers(
166
- 'vv-select',
167
- modifiers,
168
- computed(() => ({
169
- disabled: disabled.value,
170
- loading: isLoading.value,
171
- readonly: readonly.value,
172
- 'icon-before': hasIconBefore.value !== undefined,
173
- 'icon-after': hasIconAfter.value !== undefined,
174
- valid: valid.value,
175
- invalid: invalid.value,
176
- dirty: isDirty.value,
177
- focus: focused.value || focusedWithin.value || expanded.value,
178
- floating: floating.value,
179
- badges: props.badges,
180
- })),
181
- )
182
-
183
- const {
184
- getOptionLabel,
185
- getOptionValue,
186
- getOptionGrouped,
187
- isOptionDisabled,
188
- } = useOptions(props)
189
-
190
- // options filtered by search text
191
- const filteredOptions = computedAsync(async () => {
192
- if (propsDefaults.value.searchFunction) {
193
- localLoading.value = true
194
- const toReturn = await Promise.resolve(
195
- propsDefaults.value.searchFunction(
196
- debouncedSearchText.value,
197
- props.options,
198
- ),
199
- )
200
- localLoading.value = false
201
- return toReturn
202
- }
203
- return props.options?.filter((option) => {
204
- return getOptionLabel(option)
205
- .toLowerCase()
206
- .includes(debouncedSearchText.value.toLowerCase().trim())
207
- })
208
- })
209
-
210
- /**
211
- * Check if an option exist into modelValue array (multiple) or is equal to modelValue (single)
212
- * @param {String | Option} option
213
- */
214
- function isOptionSelected(option: string | Option) {
215
- if (Array.isArray(props.modelValue)) {
216
- // check if contain whole option or option value
217
- return (
218
- contains(option, props.modelValue) ||
219
- contains(getOptionValue(option), props.modelValue)
220
- )
221
- }
222
- // check if modelValue is equal to option or option value
223
- return (
224
- equals(option, props.modelValue) ||
225
- equals(getOptionValue(option), props.modelValue)
226
- )
227
- }
228
-
229
- /**
230
- * Compute the label to show to the user
231
- * Check if is multiple mode, object mode or "string" mode
232
- */
233
- const selectedOptions = computed(() => {
234
- const options = props.options.reduce<Array<Option | string>>(
235
- (acc, value) => {
236
- if (isGroup(value)) {
237
- return [...acc, ...getOptionGrouped(value)]
238
- }
239
- return [...acc, value]
240
- },
241
- [],
242
- )
243
- return options.filter((option) => {
244
- return isOptionSelected(option)
245
- })
246
- })
247
-
248
- const hasValue = computed(() => {
249
- return selectedOptions.value
250
- .map((option: string | Option) => getOptionLabel(option))
251
- .join(props.separator)
252
- })
253
-
254
- /**
255
- * Function triggered on click on input
256
- */
257
- const onClickInput = () => {
258
- props.autoOpen ? expand() : toggleExpanded()
259
- }
260
-
261
- /**
262
- * Function triggered on input of checkbox or radio (multple or single mode)
263
- * @param event on input event (checkbox or radio input)
264
- */
265
- const onInput = (option: string | Option) => {
266
- if (props.disabled || props.readonly) {
267
- return
268
- }
269
-
270
- // get option value
271
- const value = getOptionValue(option)
272
- let toReturn: string | string[] | Option | Option[] | undefined = value
273
-
274
- // check multiple prop, override value with array and remove or add the value
275
- if (props.multiple) {
276
- // check max-values prop and block check new values
277
- if (Array.isArray(props.modelValue)) {
278
- const maxValues = Number(props.maxValues)
279
- if (
280
- props.maxValues !== undefined &&
281
- maxValues >= 0 &&
282
- props.modelValue?.length >= maxValues
283
- ) {
284
- if (!contains(value, props.modelValue)) {
285
- // maxValues reached
286
- return
287
- }
288
- }
289
- toReturn = contains(value, props.modelValue)
290
- ? removeFromList(value, props.modelValue)
291
- : [...props.modelValue, value]
292
- } else {
293
- toReturn = [value as Option]
294
- }
295
- } else {
296
- if (!props.keepOpen) {
297
- collapse()
298
- }
299
- if (Array.isArray(props.modelValue)) {
300
- if (props.unselectable && props.modelValue.includes(value)) {
301
- toReturn = []
302
- } else {
303
- toReturn = [value]
304
- }
305
- } else if (props.unselectable && value === props.modelValue) {
306
- toReturn = undefined
307
- }
308
- }
309
- emit('update:modelValue', toReturn)
310
- }
311
-
312
- const selectProps = computed(() => ({
313
- id: hasId.value,
314
- name: props.name,
315
- tabindex: hasTabindex.value,
316
- valid: valid.value,
317
- validLabel: propsDefaults.value.validLabel,
318
- invalid: invalid.value,
319
- invalidLabel: propsDefaults.value.invalidLabel,
320
- hintLabel: propsDefaults.value.hintLabel,
321
- loading: isLoading.value,
322
- loadingLabel: propsDefaults.value.loadingLabel,
323
- disabled: disabled.value,
324
- readonly: readonly.value,
325
- modifiers: propsDefaults.value.modifiers,
326
- options: propsDefaults.value.options,
327
- labelKey: propsDefaults.value.labelKey,
328
- valueKey: propsDefaults.value.valueKey,
329
- icon: propsDefaults.value.icon,
330
- iconPosition: propsDefaults.value.iconPosition,
331
- floating: propsDefaults.value.floating,
332
- unselectable: propsDefaults.value.unselectable,
333
- multiple: propsDefaults.value.multiple,
334
- label: propsDefaults.value.label,
335
- placeholder: propsDefaults.value.placeholder,
336
- modelValue: props.modelValue,
337
- }))
338
-
339
- const dropdownProps = computed(() => ({
340
- id: hasDropdownId.value,
341
- reference: wrapperEl.value,
342
- placement: propsDefaults.value.placement,
343
- strategy: propsDefaults.value.strategy,
344
- transitionName: propsDefaults.value.transitionName,
345
- offset: propsDefaults.value.offset,
346
- shift: propsDefaults.value.shift,
347
- flip: propsDefaults.value.flip,
348
- autoPlacement: propsDefaults.value.autoPlacement,
349
- arrow: propsDefaults.value.arrow,
350
- autofocusFirst: propsDefaults.value.searchable
351
- ? true
352
- : propsDefaults.value.autofocusFirst,
353
- triggerWidth: propsDefaults.value.triggerWidth,
354
- modifiers: propsDefaults.value.dropdownModifiers,
355
- }))
356
-
357
- // slots
358
- const slotProps = computed(() => ({
359
- valid: props.valid,
360
- invalid: props.invalid,
361
- modelValue: props.modelValue,
362
- }))
363
-
364
- // computed
365
- onKeyStroke(
366
- [' ', 'Enter'],
367
- (e) => {
368
- if (props.autoOpen) {
369
- return
370
- }
371
- if (!expanded.value && focused.value) {
372
- e.preventDefault()
373
- e.stopImmediatePropagation()
374
- toggleExpanded()
375
- }
376
- },
377
- { target: inputEl },
378
- )
379
+ <script lang="ts">
380
+ export default {
381
+ name: 'VvCombobox',
382
+ components: {
383
+ VvDropdown,
384
+ VvDropdownOption,
385
+ VvDropdownOptgroup,
386
+ VvButton,
387
+ },
388
+ }
379
389
  </script>
380
390
 
381
391
  <template>
382
- <div v-if="!native" :id="hasId" :class="bemCssClasses">
383
- <label
384
- v-if="label"
385
- :id="hasLabelId"
386
- :for="propsDefaults.searchable ? hasSearchId : undefined"
387
- >
388
- {{ label }}
389
- </label>
390
- <div ref="wrapperEl" class="vv-select__wrapper">
391
- <VvDropdown
392
- ref="dropdownEl"
393
- v-model="expanded"
394
- v-bind="dropdownProps"
395
- :role="DropdownRole.listbox"
396
- @after-expand="onAfterExpand"
397
- @after-collapse="onAfterCollapse"
398
- >
399
- <template
400
- v-if="
401
- propsDefaults.searchable || $slots['dropdown::before']
402
- "
403
- #before
404
- >
405
- <!-- @slot Slot before dropdown items -->
406
- <slot name="dropdown::before" />
407
- <input
408
- v-if="propsDefaults.searchable && !disabled"
409
- :id="hasSearchId"
410
- ref="inputSearchEl"
411
- v-model="searchText"
412
- aria-autocomplete="list"
413
- :aria-controls="hasDropdownId"
414
- autocomplete="off"
415
- spellcheck="false"
416
- type="search"
417
- class="vv-dropdown__search"
418
- :placeholder="propsDefaults.searchPlaceholder"
419
- />
420
- </template>
421
- <template #default="{ aria }">
422
- <div v-if="$slots.before" class="vv-select__input-before">
423
- <!-- @slot Slot before input -->
424
- <slot name="before" v-bind="slotProps" />
425
- </div>
426
- <div class="vv-select__inner">
427
- <VvIcon
428
- v-if="hasIconBefore"
429
- v-bind="hasIconBefore"
430
- class="vv-select__icon"
431
- />
432
- <div
433
- ref="inputEl"
434
- v-bind="aria"
435
- class="vv-select__input"
436
- role="combobox"
437
- :aria-controls="hasDropdownId"
438
- :aria-expanded="expanded"
439
- :aria-labelledby="hasLabelId"
440
- :aria-describedby="
441
- hasHintLabelOrSlot ? hasHintId : undefined
442
- "
443
- :aria-errormessage="
444
- hasInvalidLabelOrSlot ? hasHintId : undefined
445
- "
446
- :tabindex="hasTabindex"
447
- @click.passive="onClickInput"
448
- >
449
- <!-- @slot Slot for value customization -->
450
- <slot
451
- name="value"
452
- v-bind="{ selectedOptions, onInput }"
453
- >
454
- <template v-if="hasValue">
455
- <div
456
- v-if="!badges"
457
- class="vv-select__value"
458
- >
459
- {{ hasValue }}
460
- </div>
461
- <VvBadge
462
- v-for="(
463
- option, index
464
- ) in selectedOptions"
465
- v-else
466
- :key="index"
467
- :modifiers="badgeModifiers"
468
- class="vv-select__badge"
469
- >
470
- {{ getOptionLabel(option) }}
471
- <button
472
- v-if="
473
- unselectable &&
474
- !readonly &&
475
- !disabled
476
- "
477
- :aria-label="
478
- propsDefaults.deselectActionLabel
479
- "
480
- type="button"
481
- @click.stop="onInput(option)"
482
- >
483
- <VvIcon name="close" />
484
- </button>
485
- </VvBadge>
486
- </template>
487
- <template v-else>
488
- {{ placeholder }}
489
- </template>
490
- </slot>
491
- </div>
492
- <VvIcon
493
- v-if="hasIconAfter"
494
- v-bind="hasIconAfter"
495
- class="vv-select__icon vv-select__icon-after"
496
- />
497
- </div>
498
- <div v-if="$slots.after" class="vv-select__input-after">
499
- <!-- @slot Slot after input -->
500
- <slot name="after" v-bind="slotProps" />
501
- </div>
502
- </template>
503
- <template #items>
504
- <template v-if="!disabled && filteredOptions?.length">
505
- <template
506
- v-for="(option, index) in filteredOptions"
507
- :key="index"
508
- >
509
- <template v-if="isGroup(option)">
510
- <VvDropdownOptgroup
511
- :label="getOptionLabel(option)"
512
- />
513
- <VvDropdownOption
514
- v-for="(item, i) in getOptionGrouped(
515
- option,
516
- )"
517
- v-bind="{
518
- selected: isOptionSelected(item),
519
- disabled: isOptionDisabled(item),
520
- unselectable,
521
- deselectHintLabel:
522
- propsDefaults.deselectHintLabel,
523
- selectHintLabel:
524
- propsDefaults.selectHintLabel,
525
- selectedHintLabel:
526
- propsDefaults.selectedHintLabel,
527
- }"
528
- :key="i"
529
- class="vv-dropdown-option"
530
- focus-on-hover
531
- @click.passive="onInput(item)"
532
- >
533
- <!-- @slot Slot for option customization -->
534
- <slot
535
- name="option"
536
- v-bind="{
537
- option,
538
- selectedOptions,
539
- selected: isOptionSelected(item),
540
- disabled: isOptionDisabled(item),
541
- }"
542
- >
543
- {{ getOptionLabel(item) }}
544
- </slot>
545
- </VvDropdownOption>
546
- </template>
547
- <VvDropdownOption
548
- v-else
549
- v-bind="{
550
- selected: isOptionSelected(option),
551
- disabled: isOptionDisabled(option),
552
- unselectable,
553
- deselectHintLabel:
554
- propsDefaults.deselectHintLabel,
555
- selectHintLabel:
556
- propsDefaults.selectHintLabel,
557
- selectedHintLabel:
558
- propsDefaults.selectedHintLabel,
559
- }"
560
- class="vv-dropdown-option"
561
- focus-on-hover
562
- @click.passive="onInput(option)"
563
- >
564
- <!-- @slot Slot for option customization -->
565
- <slot
566
- name="option"
567
- v-bind="{
568
- option,
569
- selectedOptions,
570
- selected: isOptionSelected(option),
571
- disabled: isOptionDisabled(option),
572
- }"
573
- >
574
- {{ getOptionLabel(option) }}
575
- </slot>
576
- </VvDropdownOption>
577
- </template>
578
- </template>
579
- <VvDropdownOption
580
- v-else-if="!options.length"
581
- modifiers="inert"
582
- >
583
- <!-- @slot Slot for no options available -->
584
- <slot name="no-options">
585
- {{ propsDefaults.noOptionsLabel }}
586
- </slot>
587
- </VvDropdownOption>
588
- <VvDropdownOption v-else-if="!disabled" modifiers="inert">
589
- <!-- @slot Slot for no results available -->
590
- <slot name="no-results">
591
- {{ propsDefaults.noResultsLabel }}
592
- </slot>
593
- </VvDropdownOption>
594
- </template>
595
- <template #after>
596
- <!-- @slot Slot after dropdown items -->
597
- <slot name="dropdown::after">
598
- <!-- Close button if dropdown custom position is enabled and floating-ui disabled -->
599
- <VvButton
600
- v-if="dropdownEl?.customPosition"
601
- :label="propsDefaults.closeLabel"
602
- modifiers="secondary"
603
- @click="dropdownEl.hide()"
604
- />
605
- </slot>
606
- </template>
607
- </VvDropdown>
608
- </div>
609
- <HintSlot :id="hasHintId" class="vv-select__hint">
610
- <template v-if="$slots.hint" #hint>
611
- <slot name="hint" v-bind="hintSlotScope" />
612
- </template>
613
- <template v-if="$slots.loading" #loading>
614
- <slot name="loading" v-bind="hintSlotScope" />
615
- </template>
616
- <template v-if="$slots.valid" #valid>
617
- <slot name="valid" v-bind="hintSlotScope" />
618
- </template>
619
- <template v-if="$slots.invalid" #invalid>
620
- <slot name="invalid" v-bind="hintSlotScope" />
621
- </template>
622
- </HintSlot>
623
- </div>
624
- <VvSelect
625
- v-else
626
- v-bind="selectProps"
627
- @update:model-value="emit('update:modelValue', $event)"
628
- />
392
+ <div v-if="!native" :id="hasId" :class="bemCssClasses">
393
+ <label
394
+ v-if="label"
395
+ :id="hasLabelId"
396
+ :for="propsDefaults.searchable ? hasSearchId : undefined"
397
+ >
398
+ {{ label }}
399
+ </label>
400
+ <div ref="wrapperEl" class="vv-select__wrapper">
401
+ <VvDropdown
402
+ ref="dropdownEl"
403
+ v-model="expanded"
404
+ v-bind="dropdownProps"
405
+ :role="DropdownRole.listbox"
406
+ @after-expand="onAfterExpand"
407
+ @after-collapse="onAfterCollapse"
408
+ >
409
+ <template
410
+ v-if="
411
+ propsDefaults.searchable || $slots['dropdown::before']
412
+ "
413
+ #before
414
+ >
415
+ <!-- @slot Slot before dropdown items -->
416
+ <slot name="dropdown::before" />
417
+ <input
418
+ v-if="propsDefaults.searchable && !disabled"
419
+ :id="hasSearchId"
420
+ ref="inputSearchEl"
421
+ v-model="searchText"
422
+ aria-autocomplete="list"
423
+ :aria-controls="hasDropdownId"
424
+ autocomplete="off"
425
+ spellcheck="false"
426
+ type="search"
427
+ class="vv-dropdown__search"
428
+ :placeholder="propsDefaults.searchPlaceholder"
429
+ >
430
+ </template>
431
+ <template #default="{ aria }">
432
+ <div v-if="$slots.before" class="vv-select__input-before">
433
+ <!-- @slot Slot before input -->
434
+ <slot name="before" v-bind="slotProps" />
435
+ </div>
436
+ <div class="vv-select__inner">
437
+ <VvIcon
438
+ v-if="hasIconBefore"
439
+ v-bind="hasIconBefore"
440
+ class="vv-select__icon"
441
+ />
442
+ <div
443
+ ref="inputEl"
444
+ v-bind="aria"
445
+ class="vv-select__input"
446
+ role="combobox"
447
+ :aria-controls="hasDropdownId"
448
+ :aria-expanded="expanded"
449
+ :aria-labelledby="hasLabelId"
450
+ :aria-describedby="
451
+ hasHintLabelOrSlot ? hasHintId : undefined
452
+ "
453
+ :aria-errormessage="
454
+ hasInvalidLabelOrSlot ? hasHintId : undefined
455
+ "
456
+ :tabindex="hasTabindex"
457
+ @click.passive="onClickInput"
458
+ >
459
+ <!-- @slot Slot for value customization -->
460
+ <slot
461
+ name="value"
462
+ v-bind="{ selectedOptions, onInput }"
463
+ >
464
+ <template v-if="hasValue">
465
+ <div
466
+ v-if="!badges"
467
+ class="vv-select__value"
468
+ >
469
+ {{ hasValue }}
470
+ </div>
471
+ <VvBadge
472
+ v-for="(
473
+ option, index
474
+ ) in selectedOptions"
475
+ v-else
476
+ :key="index"
477
+ :modifiers="badgeModifiers"
478
+ class="vv-select__badge"
479
+ >
480
+ {{ getOptionLabel(option) }}
481
+ <button
482
+ v-if="
483
+ unselectable
484
+ && !readonly
485
+ && !disabled
486
+ "
487
+ :aria-label="
488
+ propsDefaults.deselectActionLabel
489
+ "
490
+ type="button"
491
+ @click.stop="onInput(option)"
492
+ >
493
+ <VvIcon name="close" />
494
+ </button>
495
+ </VvBadge>
496
+ </template>
497
+ <template v-else>
498
+ {{ placeholder }}
499
+ </template>
500
+ </slot>
501
+ </div>
502
+ <VvIcon
503
+ v-if="hasIconAfter"
504
+ v-bind="hasIconAfter"
505
+ class="vv-select__icon vv-select__icon-after"
506
+ />
507
+ </div>
508
+ <div v-if="$slots.after" class="vv-select__input-after">
509
+ <!-- @slot Slot after input -->
510
+ <slot name="after" v-bind="slotProps" />
511
+ </div>
512
+ </template>
513
+ <template #items>
514
+ <template v-if="!disabled && filteredOptions?.length">
515
+ <template
516
+ v-for="(option, index) in filteredOptions"
517
+ :key="index"
518
+ >
519
+ <template v-if="isGroup(option)">
520
+ <VvDropdownOptgroup
521
+ :label="getOptionLabel(option)"
522
+ />
523
+ <VvDropdownOption
524
+ v-for="(item, i) in getOptionGrouped(
525
+ option,
526
+ )"
527
+ v-bind="{
528
+ selected: isOptionSelected(item),
529
+ disabled: isOptionDisabled(item),
530
+ unselectable,
531
+ deselectHintLabel:
532
+ propsDefaults.deselectHintLabel,
533
+ selectHintLabel:
534
+ propsDefaults.selectHintLabel,
535
+ selectedHintLabel:
536
+ propsDefaults.selectedHintLabel,
537
+ }"
538
+ :key="i"
539
+ class="vv-dropdown-option"
540
+ focus-on-hover
541
+ @click.passive="onInput(item)"
542
+ >
543
+ <!-- @slot Slot for option customization -->
544
+ <slot
545
+ name="option"
546
+ v-bind="{
547
+ option,
548
+ selectedOptions,
549
+ selected: isOptionSelected(item),
550
+ disabled: isOptionDisabled(item),
551
+ }"
552
+ >
553
+ {{ getOptionLabel(item) }}
554
+ </slot>
555
+ </VvDropdownOption>
556
+ </template>
557
+ <VvDropdownOption
558
+ v-else
559
+ v-bind="{
560
+ selected: isOptionSelected(option),
561
+ disabled: isOptionDisabled(option),
562
+ unselectable,
563
+ deselectHintLabel:
564
+ propsDefaults.deselectHintLabel,
565
+ selectHintLabel:
566
+ propsDefaults.selectHintLabel,
567
+ selectedHintLabel:
568
+ propsDefaults.selectedHintLabel,
569
+ }"
570
+ class="vv-dropdown-option"
571
+ focus-on-hover
572
+ @click.passive="onInput(option)"
573
+ >
574
+ <!-- @slot Slot for option customization -->
575
+ <slot
576
+ name="option"
577
+ v-bind="{
578
+ option,
579
+ selectedOptions,
580
+ selected: isOptionSelected(option),
581
+ disabled: isOptionDisabled(option),
582
+ }"
583
+ >
584
+ {{ getOptionLabel(option) }}
585
+ </slot>
586
+ </VvDropdownOption>
587
+ </template>
588
+ </template>
589
+ <VvDropdownOption
590
+ v-else-if="!options.length"
591
+ modifiers="inert"
592
+ >
593
+ <!-- @slot Slot for no options available -->
594
+ <slot name="no-options">
595
+ {{ propsDefaults.noOptionsLabel }}
596
+ </slot>
597
+ </VvDropdownOption>
598
+ <VvDropdownOption v-else-if="!disabled" modifiers="inert">
599
+ <!-- @slot Slot for no results available -->
600
+ <slot name="no-results">
601
+ {{ propsDefaults.noResultsLabel }}
602
+ </slot>
603
+ </VvDropdownOption>
604
+ </template>
605
+ <template #after>
606
+ <!-- @slot Slot after dropdown items -->
607
+ <slot name="dropdown::after">
608
+ <!-- Close button if dropdown custom position is enabled and floating-ui disabled -->
609
+ <VvButton
610
+ v-if="dropdownEl?.customPosition"
611
+ :label="propsDefaults.closeLabel"
612
+ modifiers="secondary"
613
+ @click="dropdownEl.hide()"
614
+ />
615
+ </slot>
616
+ </template>
617
+ </VvDropdown>
618
+ </div>
619
+ <HintSlot :id="hasHintId" class="vv-select__hint">
620
+ <template v-if="$slots.hint" #hint>
621
+ <slot name="hint" v-bind="hintSlotScope" />
622
+ </template>
623
+ <template v-if="$slots.loading" #loading>
624
+ <slot name="loading" v-bind="hintSlotScope" />
625
+ </template>
626
+ <template v-if="$slots.valid" #valid>
627
+ <slot name="valid" v-bind="hintSlotScope" />
628
+ </template>
629
+ <template v-if="$slots.invalid" #invalid>
630
+ <slot name="invalid" v-bind="hintSlotScope" />
631
+ </template>
632
+ </HintSlot>
633
+ </div>
634
+ <VvSelect
635
+ v-else
636
+ v-bind="selectProps"
637
+ @update:model-value="emit('update:modelValue', $event)"
638
+ />
629
639
  </template>