vectis-ui 0.1.0 → 0.8.0

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 (475) hide show
  1. package/README.md +40 -6
  2. package/dist/components/VAccordion/VAccordion.css +1 -1
  3. package/dist/components/VAccordion/VAccordion.d.ts +9 -16
  4. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  5. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
  6. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/VAccordion/VAccordionItem.css +1 -1
  8. package/dist/components/VAccordion/VAccordionItem.d.ts +33 -19
  9. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  10. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +50 -38
  11. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/VAccordion/context.d.ts +1 -8
  13. package/dist/components/VAccordion/context.js.map +1 -1
  14. package/dist/components/VAvatar/VAvatar.css +1 -1
  15. package/dist/components/VAvatar/VAvatar.d.ts +44 -29
  16. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  17. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +38 -35
  18. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VAvatar/VAvatarGroup.d.ts +5 -16
  20. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  21. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +7 -7
  22. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/VAvatar/context.d.ts +6 -10
  24. package/dist/components/VAvatar/context.js.map +1 -1
  25. package/dist/components/VBadge/VBadge.css +1 -1
  26. package/dist/components/VBadge/VBadge.d.ts +31 -10
  27. package/dist/components/VBadge/VBadge.js.map +1 -1
  28. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +39 -24
  29. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/VBreadcrumb/VBreadcrumb.css +1 -1
  31. package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +4 -17
  32. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  33. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +23 -25
  34. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/VButton/VButton.css +1 -1
  36. package/dist/components/VButton/VButton.d.ts +30 -10
  37. package/dist/components/VButton/VButton.js.map +1 -1
  38. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +39 -30
  39. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/VButton/VButtonGroup.css +1 -1
  41. package/dist/components/VButton/VButtonGroup.d.ts +76 -13
  42. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  43. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +74 -8
  44. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/VButton/context.d.ts +30 -0
  46. package/dist/components/VButton/context.js +6 -0
  47. package/dist/components/VButton/context.js.map +1 -0
  48. package/dist/components/VCalendar/VCalendar.css +1 -1
  49. package/dist/components/VCalendar/VCalendar.d.ts +50 -36
  50. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  51. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +99 -85
  52. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/VCalendar/VCalendarEvent.css +1 -1
  54. package/dist/components/VCalendar/VCalendarEvent.d.ts +5 -11
  55. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  56. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +7 -1
  57. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/VCalendar/VCalendarMonth.css +1 -1
  59. package/dist/components/VCalendar/VCalendarMonth.d.ts +10 -13
  60. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  61. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +183 -244
  62. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
  64. package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +15 -20
  65. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  66. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +385 -448
  67. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/VCalendar/VCalendarYear.css +1 -1
  69. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  70. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +53 -49
  71. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/VCalendar/gesture.d.ts +158 -0
  73. package/dist/components/VCalendar/gesture.js +170 -0
  74. package/dist/components/VCalendar/gesture.js.map +1 -0
  75. package/dist/components/VCalendar/keyboard.d.ts +9 -3
  76. package/dist/components/VCalendar/keyboard.js +2 -6
  77. package/dist/components/VCalendar/keyboard.js.map +1 -1
  78. package/dist/components/VCalendar/layout.d.ts +67 -54
  79. package/dist/components/VCalendar/layout.js +77 -69
  80. package/dist/components/VCalendar/layout.js.map +1 -1
  81. package/dist/components/VCalendar/timeGrid.d.ts +55 -0
  82. package/dist/components/VCalendar/timeGrid.js +71 -0
  83. package/dist/components/VCalendar/timeGrid.js.map +1 -0
  84. package/dist/components/VCalendar/types.d.ts +41 -16
  85. package/dist/components/VCarousel/VCarousel.css +1 -1
  86. package/dist/components/VCarousel/VCarousel.d.ts +21 -41
  87. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  88. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +157 -129
  89. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  90. package/dist/components/VCarousel/VCarouselItem.d.ts +0 -17
  91. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  92. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/VCarousel/context.d.ts +0 -12
  94. package/dist/components/VCarousel/context.js.map +1 -1
  95. package/dist/components/VCheckbox/VCheckbox.css +1 -1
  96. package/dist/components/VCheckbox/VCheckbox.d.ts +31 -16
  97. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  98. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +62 -29
  99. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/VChip/VChip.css +1 -1
  101. package/dist/components/VChip/VChip.d.ts +36 -26
  102. package/dist/components/VChip/VChip.js.map +1 -1
  103. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +57 -48
  104. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/VCombobox/VCombobox.css +1 -1
  106. package/dist/components/VCombobox/VCombobox.d.ts +127 -31
  107. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  108. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +336 -247
  109. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/components/VCombobox/VComboboxGroup.css +1 -1
  111. package/dist/components/VCombobox/VComboboxGroup.d.ts +0 -9
  112. package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
  113. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  114. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/VCombobox/VComboboxOption.css +1 -1
  116. package/dist/components/VCombobox/VComboboxOption.d.ts +0 -15
  117. package/dist/components/VCombobox/VComboboxOption.js.map +1 -1
  118. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +4 -4
  119. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -1
  121. package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
  123. package/dist/components/VDataTable/VDataTable.css +1 -1
  124. package/dist/components/VDataTable/VDataTable.d.ts +50 -28
  125. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  126. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +183 -194
  127. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  128. package/dist/components/VDateInput/VDateInput.css +1 -1
  129. package/dist/components/VDateInput/VDateInput.d.ts +90 -42
  130. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  131. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +159 -191
  132. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/VDatePicker/VDatePicker.css +1 -1
  134. package/dist/components/VDatePicker/VDatePicker.d.ts +61 -30
  135. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  136. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +243 -221
  137. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/components/VDialog/VDialog.css +1 -1
  139. package/dist/components/VDialog/VDialog.d.ts +45 -33
  140. package/dist/components/VDialog/VDialog.js.map +1 -1
  141. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +65 -64
  142. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/VDialog/VDialogAlert.d.ts +24 -20
  144. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  145. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +36 -25
  146. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  147. package/dist/components/VFileInput/VFileInput.css +1 -1
  148. package/dist/components/VFileInput/VFileInput.d.ts +78 -26
  149. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  150. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +144 -132
  151. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  152. package/dist/components/VFilePicker/VFilePicker.css +1 -1
  153. package/dist/components/VFilePicker/VFilePicker.d.ts +47 -30
  154. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  155. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +166 -163
  156. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  157. package/dist/components/VFilePicker/fileKind.d.ts +2 -27
  158. package/dist/components/VFilePicker/fileKind.js +9 -8
  159. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  160. package/dist/components/VHotkeys/VHotkeys.css +1 -1
  161. package/dist/components/VHotkeys/VHotkeys.d.ts +8 -30
  162. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  163. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +4 -4
  164. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/VHotkeys/platform.js.map +1 -1
  166. package/dist/components/VIcon/VIcon.css +1 -1
  167. package/dist/components/VIcon/VIcon.d.ts +15 -6
  168. package/dist/components/VIcon/VIcon.js.map +1 -1
  169. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +45 -37
  170. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  171. package/dist/components/VIcon/iconProps.js.map +1 -1
  172. package/dist/components/VIcon/icons/index.d.ts +1 -1
  173. package/dist/components/VIcon/icons/index.js.map +1 -1
  174. package/dist/components/VIcon/icons/names.d.ts +1 -1
  175. package/dist/components/VIcon/icons/names.js.map +1 -1
  176. package/dist/components/VIcon/resolver.d.ts +3 -3
  177. package/dist/components/VIcon/resolver.js.map +1 -1
  178. package/dist/components/VIcon/types.d.ts +12 -12
  179. package/dist/components/VIconButton/VIconButton.css +1 -1
  180. package/dist/components/VIconButton/VIconButton.d.ts +28 -11
  181. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  182. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +26 -20
  183. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  184. package/dist/components/VInput/VInput.css +1 -1
  185. package/dist/components/VInput/VInput.d.ts +26 -7
  186. package/dist/components/VInput/VInput.js.map +1 -1
  187. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +86 -75
  188. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  189. package/dist/components/VInput/VInputGroup.css +2 -0
  190. package/dist/components/VInput/VInputGroup.d.ts +47 -0
  191. package/dist/components/VInput/VInputGroup.js +9 -0
  192. package/dist/components/VInput/VInputGroup.js.map +1 -0
  193. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +80 -0
  194. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  195. package/dist/components/VInput/context.d.ts +11 -0
  196. package/dist/components/VInput/context.js +6 -0
  197. package/dist/components/VInput/context.js.map +1 -0
  198. package/dist/components/VInputOTP/VInputOTP.css +1 -1
  199. package/dist/components/VInputOTP/VInputOTP.d.ts +37 -22
  200. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  201. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +98 -61
  202. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/components/VMenu/VMenu.d.ts +23 -30
  204. package/dist/components/VMenu/VMenu.js.map +1 -1
  205. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +31 -27
  206. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  207. package/dist/components/VMenu/VMenuGroup.css +1 -1
  208. package/dist/components/VMenu/VMenuGroup.d.ts +12 -8
  209. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  210. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +11 -11
  211. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  212. package/dist/components/VMenu/VMenuItem.css +1 -1
  213. package/dist/components/VMenu/VMenuItem.d.ts +11 -19
  214. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  215. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +65 -57
  216. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  217. package/dist/components/VMenu/VMenuPanel.d.ts +14 -30
  218. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  219. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +43 -44
  220. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  221. package/dist/components/VMenu/context.d.ts +2 -6
  222. package/dist/components/VMenu/context.js.map +1 -1
  223. package/dist/components/VPagination/VPagination.css +1 -1
  224. package/dist/components/VPagination/VPagination.d.ts +60 -22
  225. package/dist/components/VPagination/VPagination.js.map +1 -1
  226. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +113 -161
  227. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  228. package/dist/components/VPopover/VPopover.css +1 -1
  229. package/dist/components/VPopover/VPopover.d.ts +26 -7
  230. package/dist/components/VPopover/VPopover.js.map +1 -1
  231. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +43 -37
  232. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  233. package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
  234. package/dist/components/VProgressCircular/VProgressCircular.d.ts +15 -4
  235. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  236. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +32 -30
  237. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  238. package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
  239. package/dist/components/VProgressLinear/VProgressLinear.d.ts +23 -8
  240. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  241. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +34 -32
  242. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  243. package/dist/components/VRadio/VRadio.css +1 -1
  244. package/dist/components/VRadio/VRadio.d.ts +36 -18
  245. package/dist/components/VRadio/VRadio.js.map +1 -1
  246. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +55 -26
  247. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  248. package/dist/components/VSeparator/VSeparator.d.ts +4 -2
  249. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  250. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  251. package/dist/components/VSideNavigation/VSideNavigation.css +1 -1
  252. package/dist/components/VSideNavigation/VSideNavigation.d.ts +5 -19
  253. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  254. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +5 -5
  255. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  256. package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
  257. package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +9 -17
  258. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  259. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  260. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  261. package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
  262. package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +22 -30
  263. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  264. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +77 -87
  265. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  266. package/dist/components/VSideNavigation/context.d.ts +0 -14
  267. package/dist/components/VSideNavigation/context.js.map +1 -1
  268. package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
  269. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +9 -9
  270. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  271. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  272. package/dist/components/VSlider/VSlider.css +1 -1
  273. package/dist/components/VSlider/VSlider.d.ts +52 -27
  274. package/dist/components/VSlider/VSlider.js.map +1 -1
  275. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +202 -118
  276. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  277. package/dist/components/VSnackbar/VSnackbar.css +1 -1
  278. package/dist/components/VSnackbar/VSnackbar.d.ts +0 -23
  279. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  280. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +38 -38
  281. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  282. package/dist/components/VSnackbar/state.d.ts +0 -27
  283. package/dist/components/VSnackbar/state.js.map +1 -1
  284. package/dist/components/VSpinner/VSpinner.css +1 -1
  285. package/dist/components/VSpinner/VSpinner.d.ts +6 -6
  286. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  287. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +10 -9
  288. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  289. package/dist/components/VSwitch/VSwitch.css +1 -1
  290. package/dist/components/VSwitch/VSwitch.d.ts +35 -13
  291. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  292. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +62 -21
  293. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  294. package/dist/components/VTabs/VTab.css +1 -1
  295. package/dist/components/VTabs/VTab.d.ts +12 -12
  296. package/dist/components/VTabs/VTab.js.map +1 -1
  297. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +36 -24
  298. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  299. package/dist/components/VTabs/VTabPanel.d.ts +2 -10
  300. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  301. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +4 -4
  302. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  303. package/dist/components/VTabs/VTabs.css +1 -1
  304. package/dist/components/VTabs/VTabs.d.ts +27 -18
  305. package/dist/components/VTabs/VTabs.js.map +1 -1
  306. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +92 -81
  307. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  308. package/dist/components/VTabs/context.d.ts +9 -19
  309. package/dist/components/VTabs/context.js +1 -1
  310. package/dist/components/VTabs/context.js.map +1 -1
  311. package/dist/components/VTextarea/VTextarea.css +1 -1
  312. package/dist/components/VTextarea/VTextarea.d.ts +34 -6
  313. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  314. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +91 -74
  315. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  316. package/dist/components/VTimeInput/VTimeInput.css +1 -1
  317. package/dist/components/VTimeInput/VTimeInput.d.ts +123 -33
  318. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  319. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +294 -291
  320. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  321. package/dist/components/VTimeInput/search.d.ts +24 -0
  322. package/dist/components/VTimeInput/search.js +22 -0
  323. package/dist/components/VTimeInput/search.js.map +1 -0
  324. package/dist/components/VTimePicker/VTimePicker.css +1 -1
  325. package/dist/components/VTimePicker/VTimePicker.d.ts +51 -30
  326. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  327. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +216 -151
  328. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  329. package/dist/components/VTimePicker/limits.d.ts +88 -0
  330. package/dist/components/VTimePicker/limits.js +70 -0
  331. package/dist/components/VTimePicker/limits.js.map +1 -0
  332. package/dist/components/VToast/VToast.css +1 -1
  333. package/dist/components/VToast/VToast.d.ts +0 -10
  334. package/dist/components/VToast/VToast.js.map +1 -1
  335. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +10 -10
  336. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  337. package/dist/components/VToast/VToaster.css +1 -1
  338. package/dist/components/VToast/VToaster.d.ts +0 -17
  339. package/dist/components/VToast/VToaster.js.map +1 -1
  340. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +29 -28
  341. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  342. package/dist/components/VToast/state.d.ts +10 -19
  343. package/dist/components/VToast/state.js +1 -1
  344. package/dist/components/VToast/state.js.map +1 -1
  345. package/dist/components/VToggle/VToggle.css +1 -1
  346. package/dist/components/VToggle/VToggle.d.ts +56 -11
  347. package/dist/components/VToggle/VToggle.js.map +1 -1
  348. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +80 -46
  349. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  350. package/dist/components/VToggle/VToggleItem.d.ts +16 -2
  351. package/dist/components/VToggle/VToggleItem.js +0 -2
  352. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  353. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +23 -15
  354. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  355. package/dist/components/VToggle/context.d.ts +4 -24
  356. package/dist/components/VToggle/context.js.map +1 -1
  357. package/dist/components/VTooltip/VTooltip.css +1 -1
  358. package/dist/components/VTooltip/VTooltip.d.ts +9 -33
  359. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  360. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +28 -24
  361. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  362. package/dist/components/VTypography/VTypography.js.map +1 -1
  363. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  364. package/dist/composables/useAriaLabel.d.ts +0 -17
  365. package/dist/composables/useAriaLabel.js.map +1 -1
  366. package/dist/composables/useClearable.d.ts +42 -0
  367. package/dist/composables/useClearable.js +19 -0
  368. package/dist/composables/useClearable.js.map +1 -0
  369. package/dist/composables/useControlShape.d.ts +22 -0
  370. package/dist/composables/useControlShape.js +13 -0
  371. package/dist/composables/useControlShape.js.map +1 -0
  372. package/dist/composables/useDetailsOpen.d.ts +22 -0
  373. package/dist/composables/useDetailsOpen.js +21 -0
  374. package/dist/composables/useDetailsOpen.js.map +1 -0
  375. package/dist/composables/useFieldIds.d.ts +0 -15
  376. package/dist/composables/useFieldIds.js +8 -7
  377. package/dist/composables/useFieldIds.js.map +1 -1
  378. package/dist/composables/useFieldPanel.d.ts +21 -18
  379. package/dist/composables/useFieldPanel.js +43 -23
  380. package/dist/composables/useFieldPanel.js.map +1 -1
  381. package/dist/composables/useFileDrop.d.ts +0 -22
  382. package/dist/composables/useFileDrop.js.map +1 -1
  383. package/dist/composables/useFileField.d.ts +45 -17
  384. package/dist/composables/useFileField.js +40 -20
  385. package/dist/composables/useFileField.js.map +1 -1
  386. package/dist/composables/useFocusoutDismiss.d.ts +0 -15
  387. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  388. package/dist/composables/useIconClickHandlers.d.ts +29 -14
  389. package/dist/composables/useIconClickHandlers.js +15 -5
  390. package/dist/composables/useIconClickHandlers.js.map +1 -1
  391. package/dist/composables/useInertLink.d.ts +20 -0
  392. package/dist/composables/useInertLink.js +23 -0
  393. package/dist/composables/useInertLink.js.map +1 -0
  394. package/dist/composables/useMaskedField.d.ts +33 -10
  395. package/dist/composables/useMaskedField.js +45 -1
  396. package/dist/composables/useMaskedField.js.map +1 -1
  397. package/dist/composables/usePopover.d.ts +15 -1
  398. package/dist/composables/usePopover.js +23 -8
  399. package/dist/composables/usePopover.js.map +1 -1
  400. package/dist/composables/useProgressValue.d.ts +5 -8
  401. package/dist/composables/useProgressValue.js +6 -3
  402. package/dist/composables/useProgressValue.js.map +1 -1
  403. package/dist/composables/useRootAttrs.d.ts +12 -19
  404. package/dist/composables/useRootAttrs.js.map +1 -1
  405. package/dist/composables/useTimer.d.ts +8 -10
  406. package/dist/composables/useTimer.js.map +1 -1
  407. package/dist/i18n/en.d.ts +2 -10
  408. package/dist/i18n/en.js +18 -19
  409. package/dist/i18n/en.js.map +1 -1
  410. package/dist/i18n/fr.d.ts +2 -18
  411. package/dist/i18n/fr.js +18 -19
  412. package/dist/i18n/fr.js.map +1 -1
  413. package/dist/i18n/state.d.ts +44 -47
  414. package/dist/i18n/state.js +20 -17
  415. package/dist/i18n/state.js.map +1 -1
  416. package/dist/i18n/types.d.ts +53 -44
  417. package/dist/icons.d.ts +3 -3
  418. package/dist/index.d.ts +43 -17
  419. package/dist/index.js +45 -44
  420. package/dist/styles.css +1 -1
  421. package/dist/tokens/css.js.map +1 -1
  422. package/dist/tokens/index.d.ts +5 -1
  423. package/dist/tokens/primitives.js.map +1 -1
  424. package/dist/tokens/semantic.d.ts +5 -1
  425. package/dist/tokens/semantic.js +6 -2
  426. package/dist/tokens/semantic.js.map +1 -1
  427. package/dist/tokens/themes/dark.js.map +1 -1
  428. package/dist/tokens/types.d.ts +7 -15
  429. package/dist/tokens/types.js.map +1 -1
  430. package/dist/tokens.json +25 -5
  431. package/dist/types.d.ts +24 -0
  432. package/dist/utils/array.d.ts +3 -6
  433. package/dist/utils/array.js.map +1 -1
  434. package/dist/utils/arrowNav.d.ts +17 -17
  435. package/dist/utils/arrowNav.js +5 -3
  436. package/dist/utils/arrowNav.js.map +1 -1
  437. package/dist/utils/chip.d.ts +11 -15
  438. package/dist/utils/chip.js.map +1 -1
  439. package/dist/utils/css.d.ts +22 -11
  440. package/dist/utils/css.js +5 -2
  441. package/dist/utils/css.js.map +1 -1
  442. package/dist/utils/date.d.ts +42 -19
  443. package/dist/utils/date.js +97 -98
  444. package/dist/utils/date.js.map +1 -1
  445. package/dist/utils/direction.d.ts +6 -12
  446. package/dist/utils/direction.js.map +1 -1
  447. package/dist/utils/env.d.ts +5 -6
  448. package/dist/utils/file.d.ts +46 -58
  449. package/dist/utils/file.js +43 -36
  450. package/dist/utils/file.js.map +1 -1
  451. package/dist/utils/focus.d.ts +8 -17
  452. package/dist/utils/focus.js.map +1 -1
  453. package/dist/utils/hostWarns.d.ts +12 -0
  454. package/dist/utils/hostWarns.js +6 -0
  455. package/dist/utils/hostWarns.js.map +1 -0
  456. package/dist/utils/ids.d.ts +10 -0
  457. package/dist/utils/ids.js +8 -0
  458. package/dist/utils/ids.js.map +1 -0
  459. package/dist/utils/matcher.d.ts +5 -9
  460. package/dist/utils/matcher.js.map +1 -1
  461. package/dist/utils/memo.d.ts +12 -0
  462. package/dist/utils/memo.js +9 -0
  463. package/dist/utils/memo.js.map +1 -0
  464. package/dist/utils/number.d.ts +3 -4
  465. package/dist/utils/number.js.map +1 -1
  466. package/dist/utils/text.d.ts +20 -9
  467. package/dist/utils/text.js +17 -3
  468. package/dist/utils/text.js.map +1 -1
  469. package/dist/utils/time.d.ts +53 -61
  470. package/dist/utils/time.js +49 -45
  471. package/dist/utils/time.js.map +1 -1
  472. package/dist/utils/vnode.d.ts +8 -15
  473. package/dist/utils/vnode.js.map +1 -1
  474. package/package.json +6 -6
  475. package/dist/components/VToggle/VToggleItem.css +0 -2
@@ -1,39 +1,59 @@
1
- import { useFocusoutDismiss as e } from "./useFocusoutDismiss.js";
2
- import { ref as t } from "vue";
1
+ import { NO_BUTTON_GROUP as e, buttonGroupKey as t } from "../components/VButton/context.js";
2
+ import { useFocusoutDismiss as n } from "./useFocusoutDismiss.js";
3
+ import { provide as r, ref as i, useId as a } from "vue";
3
4
  //#region src/composables/useFieldPanel.ts
4
- function n(n) {
5
- let r = t(!1);
6
- function i(e = n.focusOnOpen?.() ?? !0) {
7
- n.disabled() || r.value || (n.onOpen?.(), n.panelRef.value?.show(), e && requestAnimationFrame(() => n.focusInPanel()));
5
+ function o(o) {
6
+ let s = i(!1), c = () => o.openOnFocus?.() ?? !1, l = a();
7
+ r(t, e);
8
+ function u(e = !c()) {
9
+ o.disabled() || s.value || (o.onOpen?.(), o.panelRef.value?.show(), e && requestAnimationFrame(() => o.focusInPanel()));
8
10
  }
9
- function a(e = !1) {
10
- r.value && (n.panelRef.value?.hide(), n.onClose?.(), e && n.fieldEl.value?.focus());
11
+ function d() {
12
+ s.value && (o.panelRef.value?.close(), o.onClose?.());
11
13
  }
12
- function o(e) {
13
- e.target.closest(".v-input-action") || n.disabled() || i();
14
+ let f = !1;
15
+ function p() {
16
+ f = !0, o.field.value?.focus(), f = !1;
14
17
  }
15
- let s = e(n.rootEl, () => a(!1));
16
- function c(e) {
18
+ function m() {
19
+ s.value && (d(), p());
20
+ }
21
+ function h() {
22
+ f || !c() || u(!1);
23
+ }
24
+ function g() {
25
+ s.value ? m() : u(!0);
26
+ }
27
+ function _(e) {
28
+ e.target.closest(".v-input-action") || u();
29
+ }
30
+ let v = n(o.rootEl, d);
31
+ function y(e) {
17
32
  e.target?.closest("button, a, input, select, textarea, [tabindex]") || e.preventDefault();
18
33
  }
19
- function l(e) {
34
+ function b(e) {
20
35
  if (e.key === "Escape") {
21
- r.value && (e.preventDefault(), a(!0));
36
+ s.value && (e.preventDefault(), m());
22
37
  return;
23
38
  }
24
- (e.key === "ArrowDown" || e.key === "Enter") && !r.value && !e.defaultPrevented && (e.preventDefault(), i(!0));
39
+ (e.key === "ArrowDown" || e.key === "Enter") && !s.value && !e.defaultPrevented && (e.preventDefault(), u(!0));
25
40
  }
26
41
  return {
27
- open: r,
28
- openPanel: i,
29
- closePanel: a,
30
- onControlClick: o,
31
- onFocusout: s,
32
- onKeydown: l,
33
- onPanelMousedown: c
42
+ open: s,
43
+ panelId: l,
44
+ openPanel: u,
45
+ closePanel: d,
46
+ closeAndFocus: m,
47
+ focusField: p,
48
+ onFieldFocus: h,
49
+ toggleFromIcon: g,
50
+ onControlClick: _,
51
+ onFocusout: v,
52
+ onKeydown: b,
53
+ onPanelMousedown: y
34
54
  };
35
55
  }
36
56
  //#endregion
37
- export { n as useFieldPanel };
57
+ export { o as useFieldPanel };
38
58
 
39
59
  //# sourceMappingURL=useFieldPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFieldPanel.js","names":[],"sources":["../../src/composables/useFieldPanel.ts"],"sourcesContent":["import { ref } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { useFocusoutDismiss } from './useFocusoutDismiss'\n\n/** The least this needs of the field: something it can put the focus back on. */\ninterface FocusableField {\n focus: () => void\n}\n\n/** The least this needs of the panel: something it can open and close. */\ninterface PanelControl {\n show: () => void\n hide: () => void\n}\n\nexport interface UseFieldPanelOptions {\n /** The component's root, against which \"the focus has left\" is judged. */\n rootEl: Ref<HTMLElement | null>\n /** The panel to open and close. */\n panelRef: Ref<PanelControl | null>\n /** The field the focus returns to. */\n fieldEl: Ref<FocusableField | null>\n /**\n * Whether opening is refused. It is the SINGLE cut-off point: every route in passes\n * through it, so a component never has to repeat the condition per handler.\n */\n disabled: () => boolean\n /** Moves the focus INTO the open panel — where in it is the component's business. */\n focusInPanel: () => void\n /** What the component needs to do as the panel opens: prepare a draft, reset a step. */\n onOpen?: () => void\n /** What it needs to do as the panel closes: clear an announcement, for instance. */\n onClose?: () => void\n /**\n * Whether the focus should enter the panel when it opens. It does by default.\n *\n * A field one TYPES into says no: its panel opens without taking the caret, so typing\n * carries on and the down arrow remains the one explicit way in.\n */\n focusOnOpen?: () => boolean\n}\n\n// @a11y @keyboard @core\n/**\n * The shell shared by the date and the time picker: a field, and a panel below it that\n * nothing dismisses by itself. Neither component owns this — it belongs to both.\n *\n * A panel of that kind does NOTHING on its own: it does not close on a click outside, does\n * not take the focus, and does not hand it back. What follows is exactly that minimum,\n * and nothing more; whatever is particular to one component arrives through the three\n * callbacks above.\n *\n * TRAP — the panel is WRITTEN to directly and READ back through a model. The state here is\n * meant to be bound to the panel, which feeds it from its own events, but the opening\n * itself must stay synchronous: the frame scheduled to move the focus assumes the panel is\n * already open by the time it runs, and going through the model would put a tick in\n * between.\n */\nexport function useFieldPanel(options: UseFieldPanelOptions) {\n const open = ref(false)\n\n function openPanel(moveFocus = options.focusOnOpen?.() ?? true) {\n if (options.disabled() || open.value) return\n options.onOpen?.()\n options.panelRef.value?.show()\n // @a11y\n // The focus has to be moved by hand — the platform moves it into no panel of this\n // kind. It waits a frame because the panel has not been painted by the time it is\n // asked to open, and nothing invisible can take the focus.\n if (moveFocus) requestAnimationFrame(() => options.focusInPanel())\n }\n\n function closePanel(refocus = false) {\n if (!open.value) return\n options.panelRef.value?.hide()\n options.onClose?.()\n if (refocus) options.fieldEl.value?.focus()\n }\n\n function onControlClick(event: MouseEvent) {\n // A click on one of the field's own buttons — the clear cross, an icon — is left to\n // that button's handler: reacting here as well would open the panel the cross has\n // just given a reason to close.\n if ((event.target as HTMLElement).closest('.v-input-action')) return\n if (options.disabled()) return\n openPanel()\n }\n\n // @a11y\n /**\n * Closes as soon as the focus leaves the component — the panel included, which is a\n * descendant of it even while floating above the page.\n */\n const onFocusout = useFocusoutDismiss(options.rootEl, () => closePanel(false))\n\n // @a11y\n /*\n * TRAP — clicking a part of the panel that cannot take focus (its padding, the gutter\n * between two cells, the empty space in a navigation bar) makes the browser take the\n * focus off whatever had it and hand it back to the page body. The handler above then\n * sees the focus leave with nowhere to go, reads it as an exit — rightly — and closes a\n * panel the reader has just clicked on.\n *\n * So the focus is held in place, but ONLY outside things that can take it. An\n * unconditional cancellation, as VCombobox uses — where the focus never leaves the field\n * anyway — would here rob the days and the navigation arrows of the focus, and leave the\n * calendar's keyboard pointing at nothing.\n *\n * None of this is visible in the unit tests, where clicking moves no focus; browser tests\n * cover it.\n */\n function onPanelMousedown(event: MouseEvent) {\n const target = event.target as HTMLElement | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n }\n\n // @keyboard @a11y\n function onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n if (open.value) {\n event.preventDefault()\n closePanel(true)\n }\n return\n }\n // TRAP — a key already consumed INSIDE the panel is ignored here. An Enter that\n // selected a day or confirmed the dial has just CLOSED the panel, and without this\n // guard it would reopen it immediately as it travels up to the root.\n if (\n (event.key === 'ArrowDown' || event.key === 'Enter') &&\n !open.value &&\n !event.defaultPrevented\n ) {\n event.preventDefault()\n // Opened from the KEYBOARD, the panel always takes the focus, whatever the component\n // asked for: otherwise the down arrow would open a panel the keyboard could not\n // reach.\n openPanel(true)\n }\n }\n\n return {\n open,\n openPanel,\n closePanel,\n onControlClick,\n onFocusout,\n onKeydown,\n onPanelMousedown,\n }\n}\n"],"mappings":";;;AA2DA,SAAgB,EAAc,GAA+B;CAC3D,IAAM,IAAO,EAAI,EAAK;CAEtB,SAAS,EAAU,IAAY,EAAQ,cAAc,KAAK,IAAM;EAC1D,EAAQ,SAAS,KAAK,EAAK,UAC/B,EAAQ,SAAS,GACjB,EAAQ,SAAS,OAAO,KAAK,GAKzB,KAAW,4BAA4B,EAAQ,aAAa,CAAC;CACnE;CAEA,SAAS,EAAW,IAAU,IAAO;EAC9B,EAAK,UACV,EAAQ,SAAS,OAAO,KAAK,GAC7B,EAAQ,UAAU,GACd,KAAS,EAAQ,QAAQ,OAAO,MAAM;CAC5C;CAEA,SAAS,EAAe,GAAmB;EAIpC,EAAM,OAAuB,QAAQ,iBAAiB,KACvD,EAAQ,SAAS,KACrB,EAAU;CACZ;CAOA,IAAM,IAAa,EAAmB,EAAQ,cAAc,EAAW,EAAK,CAAC;CAkB7E,SAAS,EAAiB,GAAmB;EAE3C,AADe,EAAM,QACR,QAAQ,gDAAgD,KAAG,EAAM,eAAe;CAC/F;CAGA,SAAS,EAAU,GAAsB;EACvC,IAAI,EAAM,QAAQ,UAAU;GAC1B,AAAI,EAAK,UACP,EAAM,eAAe,GACrB,EAAW,EAAI;GAEjB;EACF;EAIA,CACG,EAAM,QAAQ,eAAe,EAAM,QAAQ,YAC5C,CAAC,EAAK,SACN,CAAC,EAAM,qBAEP,EAAM,eAAe,GAIrB,EAAU,EAAI;CAElB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"useFieldPanel.js","names":[],"sources":["../../src/composables/useFieldPanel.ts"],"sourcesContent":["import { provide, ref, useId } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { NO_BUTTON_GROUP, buttonGroupKey } from '../components/VButton/context'\nimport { useFocusoutDismiss } from './useFocusoutDismiss'\n\n/** The least this needs of the field: something it can put the focus back on. */\ninterface FocusableField {\n focus: () => void\n}\n\n/** The least this needs of the panel: something it can open and close. */\ninterface PanelControl {\n show: () => void\n close: () => void\n}\n\nexport interface UseFieldPanelOptions {\n /** The component's root, against which \"the focus has left\" is judged. */\n rootEl: Ref<HTMLElement | null>\n /** The panel to open and close. */\n panelRef: Ref<PanelControl | null>\n /** The field the focus returns to. */\n field: Ref<FocusableField | null>\n /**\n * Whether opening is refused. It is the SINGLE cut-off point: every route in passes\n * through it, so a component never has to repeat the condition per handler.\n */\n disabled: () => boolean\n /** Moves the focus INTO the open panel — where in it is the component's business. */\n focusInPanel: () => void\n /** What the component needs to do as the panel opens: prepare a draft, reset a step. */\n onOpen?: () => void\n /** What it needs to do as the panel closes: clear an announcement, for instance. */\n onClose?: () => void\n /**\n * Whether focusing the field opens the panel. It does not by default.\n *\n * A field one TYPES into says yes, and its panel then opens WITHOUT taking the caret, so\n * typing carries on and the down arrow remains the one explicit way in. A click on such a\n * field leaves the focus where it is for the same reason.\n */\n openOnFocus?: () => boolean\n}\n\n// @a11y @keyboard @core\n/**\n * The \"field + `VPopover` in `mode=\"manual\"`\" shell of VDateInput and VTimeInput.\n *\n * A `manual` popover does nothing on its own: no light dismiss, no focus move, no focus\n * return. This is exactly that minimum; what is particular to either component arrives\n * through `onOpen`/`onClose`.\n *\n * TRAP — the panel is WRITTEN imperatively and READ back by model. Bind `open` as\n * `v-model:open` so the DOM feeds it, but the write must stay synchronous: the `rAF` that\n * moves focus assumes the panel is already open when it is armed, and the model would put\n * a tick in between.\n */\nexport function useFieldPanel(options: UseFieldPanelOptions) {\n const open = ref(false)\n const openOnFocus = () => options.openOnFocus?.() ?? false\n\n /** The id the panel carries, for the field's `aria-controls`. */\n const panelId = useId()\n\n // @core\n // TRAP — this stops a VButtonGroup's or a VInputGroup's row context at the field's\n // boundary. The picker in the panel sizes its own buttons — VDatePicker writes `size=\"sm\"`\n // on its navigation, VTimePicker `size=\"lg\"` on its hour and minute cells — and a group\n // WINS over a button's prop: without this line a VInputGroup would resize them to its own\n // height, which only shows once the panel is open and nothing in the sheet or the template\n // would say why. It is the JS counterpart of the `.v-overlay` guard every VButtonGroup\n // selector carries — a floating panel is not a segment of the row that opened it.\n provide(buttonGroupKey, NO_BUTTON_GROUP)\n\n function openPanel(moveFocus = !openOnFocus()) {\n if (options.disabled() || open.value) return\n options.onOpen?.()\n options.panelRef.value?.show()\n // @a11y\n // A `manual` popover moves focus nowhere, so it is moved by hand — a frame later,\n // the panel not being painted yet, and nothing invisible can take focus.\n if (moveFocus) requestAnimationFrame(() => options.focusInPanel())\n }\n\n /** Closes the panel and leaves the focus where it is: the focus has already gone elsewhere. */\n function closePanel() {\n if (!open.value) return\n options.panelRef.value?.close()\n options.onClose?.()\n }\n\n // @a11y\n /*\n * TRAP — handing the focus back to the field is what makes a field that opens ON FOCUS\n * reopen the panel that was just closed: the two would chase each other and the panel\n * would never close. The lock covers the focus call, which is synchronous.\n *\n * EVERY focus this shell or a component gives the field must go through `focusField`,\n * `closeAndFocus` included. Focusing the field directly brings the loop straight back.\n */\n let refocusing = false\n\n /**\n * Puts the focus on the field without opening the panel.\n *\n * A component emptying its value calls it BEFORE the field focuses itself, and that order\n * is the point: focusing an element that already has the focus emits no event at all, so\n * the field's own call that follows is inert and the panel stays shut.\n */\n function focusField() {\n refocusing = true\n options.field.value?.focus()\n refocusing = false\n }\n\n /** Closes the panel and hands the focus back to the field, under the lock above. */\n function closeAndFocus() {\n if (!open.value) return\n closePanel()\n focusField()\n }\n\n /** The field's focus handler: opens the panel on a field that asks for it. */\n function onFieldFocus() {\n if (refocusing || !openOnFocus()) return\n openPanel(false)\n }\n\n /**\n * The icon at the end of the field. Clicking it is an explicit request for the panel, and\n * the focus has already left the field for the button — so carrying it into the panel is\n * right whatever `openOnFocus` says.\n */\n function toggleFromIcon() {\n if (open.value) closeAndFocus()\n else openPanel(true)\n }\n\n function onControlClick(event: MouseEvent) {\n // A click on one of the field's own buttons is that button's business: reacting here\n // too would open the panel the clear cross has just given a reason to close.\n if ((event.target as HTMLElement).closest('.v-input-action')) return\n openPanel()\n }\n\n // @a11y\n const onFocusout = useFocusoutDismiss(options.rootEl, closePanel)\n\n // @a11y\n /*\n * TRAP — clicking a non-focusable pixel of the panel (padding, the gutter between cells)\n * hands focus back to `<body>`. `onFocusout` above then fires with a null `relatedTarget`,\n * reads it as an exit — rightly — and closes a panel the reader has just clicked.\n *\n * The filter is essential: VCombobox's unconditional `preventDefault` is safe there\n * because focus never leaves its field, but here it would rob the days and the navigation\n * arrows of focus and desynchronize VDatePicker's roving.\n *\n * Invisible in jsdom, where clicking moves no focus — the `ClicDansLeVide` play functions\n * of both components cover it.\n */\n function onPanelMousedown(event: MouseEvent) {\n const target = event.target as HTMLElement | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n }\n\n // @keyboard @a11y\n function onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n if (open.value) {\n event.preventDefault()\n closeAndFocus()\n }\n return\n }\n // TRAP — a key already consumed INSIDE the panel is ignored. An Enter that selected a\n // day has just CLOSED the panel, and without the guard would reopen it as it bubbles.\n if (\n (event.key === 'ArrowDown' || event.key === 'Enter') &&\n !open.value &&\n !event.defaultPrevented\n ) {\n event.preventDefault()\n // Opened from the KEYBOARD the panel always takes focus, whatever `openOnFocus` says:\n // otherwise ArrowDown opens a panel the keyboard cannot reach.\n openPanel(true)\n }\n }\n\n return {\n open,\n panelId,\n openPanel,\n closePanel,\n closeAndFocus,\n focusField,\n onFieldFocus,\n toggleFromIcon,\n onControlClick,\n onFocusout,\n onKeydown,\n onPanelMousedown,\n }\n}\n"],"mappings":";;;;AA0DA,SAAgB,EAAc,GAA+B;CAC3D,IAAM,IAAO,EAAI,EAAK,GAChB,UAAoB,EAAQ,cAAc,KAAK,IAG/C,IAAU,EAAM;CAUtB,EAAQ,GAAgB,CAAe;CAEvC,SAAS,EAAU,IAAY,CAAC,EAAY,GAAG;EACzC,EAAQ,SAAS,KAAK,EAAK,UAC/B,EAAQ,SAAS,GACjB,EAAQ,SAAS,OAAO,KAAK,GAIzB,KAAW,4BAA4B,EAAQ,aAAa,CAAC;CACnE;CAGA,SAAS,IAAa;EACf,EAAK,UACV,EAAQ,SAAS,OAAO,MAAM,GAC9B,EAAQ,UAAU;CACpB;CAWA,IAAI,IAAa;CASjB,SAAS,IAAa;EAGpB,AAFA,IAAa,IACb,EAAQ,MAAM,OAAO,MAAM,GAC3B,IAAa;CACf;CAGA,SAAS,IAAgB;EAClB,EAAK,UACV,EAAW,GACX,EAAW;CACb;CAGA,SAAS,IAAe;EAClB,KAAc,CAAC,EAAY,KAC/B,EAAU,EAAK;CACjB;CAOA,SAAS,IAAiB;EACxB,AAAI,EAAK,QAAO,EAAc,IACzB,EAAU,EAAI;CACrB;CAEA,SAAS,EAAe,GAAmB;EAGpC,EAAM,OAAuB,QAAQ,iBAAiB,KAC3D,EAAU;CACZ;CAGA,IAAM,IAAa,EAAmB,EAAQ,QAAQ,CAAU;CAehE,SAAS,EAAiB,GAAmB;EAE3C,AADe,EAAM,QACR,QAAQ,gDAAgD,KAAG,EAAM,eAAe;CAC/F;CAGA,SAAS,EAAU,GAAsB;EACvC,IAAI,EAAM,QAAQ,UAAU;GAC1B,AAAI,EAAK,UACP,EAAM,eAAe,GACrB,EAAc;GAEhB;EACF;EAGA,CACG,EAAM,QAAQ,eAAe,EAAM,QAAQ,YAC5C,CAAC,EAAK,SACN,CAAC,EAAM,qBAEP,EAAM,eAAe,GAGrB,EAAU,EAAI;CAElB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -1,26 +1,4 @@
1
1
  import { ComputedRef } from 'vue';
2
- /**
3
- * Everything an area needs in order to accept files dropped onto it, and to show that it
4
- * is ready to receive them. Both the file field and the drop zone are built on it.
5
- *
6
- * Two traps live here, which is the whole reason this exists once rather than twice.
7
- *
8
- * The browser must be told explicitly, while the file is being dragged over the area,
9
- * that a drop is welcome. Left unsaid, it refuses the drop and then NAVIGATES to the
10
- * file, replacing the page the reader was on.
11
- *
12
- * And what is counted is a DEPTH, not a yes-or-no. The browser reports the pointer
13
- * LEAVING every time it crosses into a child element — a field, a chip, a button inside
14
- * the area — so a simple flag would switch off under the cursor and the highlight would
15
- * flicker. A drop forces the count back to zero, because a drag that leaves the window
16
- * altogether never reports the departure that would have balanced it; asking instead
17
- * whether the pointer went to a descendant, the other well-known fix, is no use since
18
- * there is precisely nothing to ask about in that case.
19
- *
20
- * Whether the area accepts anything is read at the moment of the event rather than
21
- * captured once, so a component turned off in the middle of a drag stops accepting
22
- * without anything being re-attached.
23
- */
24
2
  export declare function useFileDrop(enabled: () => boolean, onFiles: (files: File[]) => void): {
25
3
  dragging: ComputedRef<boolean>;
26
4
  onDragEnter: (event: DragEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useFileDrop.js","names":[],"sources":["../../src/composables/useFileDrop.ts"],"sourcesContent":["import { computed, ref, type ComputedRef } from 'vue'\n\n// @core\n/**\n * Everything an area needs in order to accept files dropped onto it, and to show that it\n * is ready to receive them. Both the file field and the drop zone are built on it.\n *\n * Two traps live here, which is the whole reason this exists once rather than twice.\n *\n * The browser must be told explicitly, while the file is being dragged over the area,\n * that a drop is welcome. Left unsaid, it refuses the drop and then NAVIGATES to the\n * file, replacing the page the reader was on.\n *\n * And what is counted is a DEPTH, not a yes-or-no. The browser reports the pointer\n * LEAVING every time it crosses into a child element — a field, a chip, a button inside\n * the area — so a simple flag would switch off under the cursor and the highlight would\n * flicker. A drop forces the count back to zero, because a drag that leaves the window\n * altogether never reports the departure that would have balanced it; asking instead\n * whether the pointer went to a descendant, the other well-known fix, is no use since\n * there is precisely nothing to ask about in that case.\n *\n * Whether the area accepts anything is read at the moment of the event rather than\n * captured once, so a component turned off in the middle of a drag stops accepting\n * without anything being re-attached.\n */\nexport function useFileDrop(\n enabled: () => boolean,\n onFiles: (files: File[]) => void,\n): {\n dragging: ComputedRef<boolean>\n onDragEnter: (event: DragEvent) => void\n onDragOver: (event: DragEvent) => void\n onDragLeave: () => void\n onDrop: (event: DragEvent) => void\n} {\n const depth = ref(0)\n\n function onDragEnter(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value += 1\n }\n\n function onDragOver(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy'\n }\n\n function onDragLeave() {\n if (!enabled()) return\n depth.value = Math.max(0, depth.value - 1)\n }\n\n function onDrop(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value = 0\n onFiles([...(event.dataTransfer?.files ?? [])])\n }\n\n return {\n dragging: computed(() => depth.value > 0),\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n }\n}\n"],"mappings":";;AAyBA,SAAgB,EACd,GACA,GAOA;CACA,IAAM,IAAQ,EAAI,CAAC;CAEnB,SAAS,EAAY,GAAkB;EAChC,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,SAAS;CACjB;CAEA,SAAS,EAAW,GAAkB;EAC/B,EAAQ,MACb,EAAM,eAAe,GACjB,EAAM,iBAAc,EAAM,aAAa,aAAa;CAC1D;CAEA,SAAS,IAAc;EAChB,EAAQ,MACb,EAAM,QAAQ,KAAK,IAAI,GAAG,EAAM,QAAQ,CAAC;CAC3C;CAEA,SAAS,EAAO,GAAkB;EAC3B,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,QAAQ,GACd,EAAQ,CAAC,GAAI,EAAM,cAAc,SAAS,CAAC,CAAE,CAAC;CAChD;CAEA,OAAO;EACL,UAAU,QAAe,EAAM,QAAQ,CAAC;EACxC;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"useFileDrop.js","names":[],"sources":["../../src/composables/useFileDrop.ts"],"sourcesContent":["// @core\n/**\n * The drop-target plumbing of VFileInput and VFilePicker. It exists once rather than twice\n * because of the two traps it carries.\n *\n * `dragover` MUST `preventDefault`, or the browser refuses the drop and then NAVIGATES to\n * the file, replacing the page.\n *\n * And the state is a depth COUNTER, never a boolean: `dragleave` fires every time the\n * pointer crosses into a child, so a flag would flicker off under the cursor. `drop` forces\n * the depth back to 0 — a drag leaving the window never sends the matching `dragleave`, and\n * `currentTarget.contains(relatedTarget)`, the other classic fix, is useless there since\n * `relatedTarget` is null in exactly that case.\n *\n * `enabled` is a getter, read at event time, so a component disabled mid-drag stops\n * accepting with nothing re-bound.\n */\n\nimport { computed, ref, type ComputedRef } from 'vue'\n\nexport function useFileDrop(\n enabled: () => boolean,\n onFiles: (files: File[]) => void,\n): {\n dragging: ComputedRef<boolean>\n onDragEnter: (event: DragEvent) => void\n onDragOver: (event: DragEvent) => void\n onDragLeave: () => void\n onDrop: (event: DragEvent) => void\n} {\n const depth = ref(0)\n\n function onDragEnter(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value += 1\n }\n\n function onDragOver(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy'\n }\n\n function onDragLeave() {\n if (!enabled()) return\n depth.value = Math.max(0, depth.value - 1)\n }\n\n function onDrop(event: DragEvent) {\n if (!enabled()) return\n event.preventDefault()\n depth.value = 0\n onFiles([...(event.dataTransfer?.files ?? [])])\n }\n\n return {\n dragging: computed(() => depth.value > 0),\n onDragEnter,\n onDragOver,\n onDragLeave,\n onDrop,\n }\n}\n"],"mappings":";;AAoBA,SAAgB,EACd,GACA,GAOA;CACA,IAAM,IAAQ,EAAI,CAAC;CAEnB,SAAS,EAAY,GAAkB;EAChC,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,SAAS;CACjB;CAEA,SAAS,EAAW,GAAkB;EAC/B,EAAQ,MACb,EAAM,eAAe,GACjB,EAAM,iBAAc,EAAM,aAAa,aAAa;CAC1D;CAEA,SAAS,IAAc;EAChB,EAAQ,MACb,EAAM,QAAQ,KAAK,IAAI,GAAG,EAAM,QAAQ,CAAC;CAC3C;CAEA,SAAS,EAAO,GAAkB;EAC3B,EAAQ,MACb,EAAM,eAAe,GACrB,EAAM,QAAQ,GACd,EAAQ,CAAC,GAAI,EAAM,cAAc,SAAS,CAAC,CAAE,CAAC;CAChD;CAEA,OAAO;EACL,UAAU,QAAe,EAAM,QAAQ,CAAC;EACxC;EACA;EACA;EACA;CACF;AACF"}
@@ -1,36 +1,64 @@
1
1
  import { ComputedRef, Ref } from 'vue';
2
- import { FileLimits, FileRejection } from '../utils/file.js';
2
+ import { FileRejection } from '../utils/file.js';
3
+ /** The props both components declare under the same names, read at the moment they matter. */
4
+ export interface FileFieldProps {
5
+ multiple: boolean;
6
+ accept?: string;
7
+ maxSize?: number;
8
+ maxFiles?: number;
9
+ maxTotalSize?: number;
10
+ disabled: boolean;
11
+ readonly: boolean;
12
+ }
13
+ /** The events both components declare under the same names and with the same payloads. */
14
+ export interface FileFieldEmit {
15
+ (event: 'change', files: File[]): void;
16
+ (event: 'reject', rejection: FileRejection): void;
17
+ (event: 'remove', file: File, index: number): void;
18
+ }
3
19
  export interface FileFieldOptions {
4
20
  /** The component's value — always a list of files, whether one or several are allowed. */
5
21
  model: Ref<File[]>;
22
+ props: FileFieldProps;
23
+ emit: FileFieldEmit;
6
24
  /** The attributes the consumer wrote, minus styling, still to be split in two. */
7
25
  forwardedAttrs: ComputedRef<Record<string, unknown>>;
8
- /** Read at the moment of the event, so a component turned off mid-way stops accepting. */
9
- enabled: () => boolean;
10
- multiple: () => boolean;
11
- /** The limits as the consumer set them: capping a single-file field at one happens here. */
12
- limits: () => FileLimits;
13
- onReject: (rejection: FileRejection) => void;
14
- onChange: (files: File[]) => void;
15
26
  /**
16
- * Attributes to withhold from the visible control as well.
17
- *
18
- * The file field withholds the link to its descriptive text because it puts that list
19
- * together itself, and a binding written after the spread would silently replace the
20
- * consumer's rather than being merged with it.
27
+ * Whether the component is disabled, the row it sits in taken into account. Left out, the
28
+ * `disabled` prop answers alone.
29
+ */
30
+ disabled?: Ref<boolean>;
31
+ /**
32
+ * Attributes to withhold from the visible control too. VFileInput withholds
33
+ * `aria-describedby`, which it re-aggregates itself: a binding written after the spread
34
+ * would replace the consumer's rather than merge with it.
21
35
  */
22
36
  excludeFromControl?: readonly string[];
37
+ /** Called once the selection has been emptied by `clear`, before `change` is emitted. */
38
+ onClear?: () => void;
39
+ /**
40
+ * The component's own development warnings, one message per condition that holds. They
41
+ * follow the same rule as the shared ones: each is given once per instance.
42
+ */
43
+ warnings?: () => (string | false)[];
23
44
  }
24
45
  export declare function useFileField(options: FileFieldOptions): {
25
46
  fileEl: Ref<HTMLInputElement | null, HTMLInputElement | null>;
26
- nativeAttrs: ComputedRef<{
27
- [k: string]: unknown;
47
+ enabled: ComputedRef<boolean>;
48
+ nativeInputAttrs: ComputedRef<{
49
+ type: string;
50
+ tabindex: number;
51
+ 'aria-hidden': "true";
52
+ accept: string | undefined;
53
+ multiple: true | undefined;
54
+ disabled: true | undefined;
55
+ onChange: (event: Event) => void;
28
56
  }>;
29
57
  controlAttrs: ComputedRef<{
30
58
  [k: string]: unknown;
31
59
  }>;
32
60
  acceptFiles: (incoming: File[]) => void;
33
- onNativeChange: (event: Event) => void;
34
61
  openPicker: () => void;
35
- resetNative: () => void;
62
+ removeAt: (index: number) => File | undefined;
63
+ clear: () => void;
36
64
  };
@@ -8,35 +8,55 @@ var r = [
8
8
  "capture"
9
9
  ];
10
10
  function i(i) {
11
- let a = n(null), o = t(() => Object.fromEntries(Object.entries(i.forwardedAttrs.value).filter(([e]) => r.includes(e)))), s = t(() => {
11
+ let { model: a, props: o, emit: s } = i, c = n(null), l = () => i.disabled?.value ?? o.disabled, u = t(() => !l() && !o.readonly), d = t(() => {
12
12
  let e = i.excludeFromControl ?? [];
13
13
  return Object.fromEntries(Object.entries(i.forwardedAttrs.value).filter(([t]) => !r.includes(t) && !e.includes(t)));
14
14
  });
15
- function c() {
16
- a.value && (a.value.value = "");
15
+ function f() {
16
+ c.value && (c.value.value = "");
17
17
  }
18
- function l(t) {
19
- let n = i.multiple(), r = n ? i.model.value : [], a = i.limits(), { accepted: o, rejected: s } = e(t, r, {
20
- ...a,
21
- maxFiles: n ? a.maxFiles : 1
18
+ function p(t) {
19
+ let n = o.multiple ? a.value : [], { accepted: r, rejected: i } = e(t, n, {
20
+ accept: o.accept,
21
+ maxSize: o.maxSize,
22
+ maxFiles: o.multiple ? o.maxFiles : 1,
23
+ maxTotalSize: o.maxTotalSize
22
24
  });
23
- for (let e of s) i.onReject(e);
24
- c(), o.length !== 0 && (i.model.value = [...r, ...o], i.onChange(i.model.value));
25
+ for (let e of i) s("reject", e);
26
+ f(), r.length !== 0 && (a.value = [...n, ...r], s("change", a.value));
25
27
  }
26
- function u(e) {
27
- l([...e.target.files ?? []]);
28
+ function m(e) {
29
+ p([...e.target.files ?? []]);
28
30
  }
29
- function d() {
30
- i.enabled() && a.value?.click();
31
+ let h = t(() => ({
32
+ ...Object.fromEntries(Object.entries(i.forwardedAttrs.value).filter(([e]) => r.includes(e))),
33
+ type: "file",
34
+ tabindex: -1,
35
+ "aria-hidden": "true",
36
+ accept: o.accept,
37
+ multiple: o.multiple || void 0,
38
+ disabled: l() || void 0,
39
+ onChange: m
40
+ }));
41
+ function g() {
42
+ u.value && c.value?.click();
43
+ }
44
+ function _(e) {
45
+ let t = a.value[e];
46
+ if (!(!t || !u.value)) return a.value = a.value.filter((t, n) => n !== e), f(), s("remove", t, e), s("change", a.value), t;
47
+ }
48
+ function v() {
49
+ a.value = [], f(), i.onClear?.(), s("change", a.value);
31
50
  }
32
51
  return {
33
- fileEl: a,
34
- nativeAttrs: o,
35
- controlAttrs: s,
36
- acceptFiles: l,
37
- onNativeChange: u,
38
- openPicker: d,
39
- resetNative: c
52
+ fileEl: c,
53
+ enabled: u,
54
+ nativeInputAttrs: h,
55
+ controlAttrs: d,
56
+ acceptFiles: p,
57
+ openPicker: g,
58
+ removeAt: _,
59
+ clear: v
40
60
  };
41
61
  }
42
62
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"useFileField.js","names":[],"sources":["../../src/composables/useFileField.ts"],"sourcesContent":["// @core\n/**\n * The hidden file control both file components are built around — the one that actually\n * opens the operating system's file dialog.\n *\n * The code here is imposed by the browser rather than chosen. A file dialog opens ONLY\n * from a genuine click on a file control, and the list of chosen files cannot be handed\n * to that control from a template the way any other value would be. So the thing the\n * reader sees and clicks can never BE the file control, and the file control can only\n * ever be a SOURCE of files. That is exactly the shape of what follows.\n *\n * The rules deciding which files are acceptable live apart from this, on their own; what\n * was left duplicated between the two components was the wiring around them.\n */\nimport { computed, ref, type ComputedRef, type Ref } from 'vue'\n\nimport { screenFiles, type FileLimits, type FileRejection } from '../utils/file'\n\n// @a11y\n/**\n * The attributes that belong on the hidden file control rather than on the visible one.\n *\n * The usual split assumes a single element that does the work, and there are two here, so\n * the attributes go into three piles instead of two: styling stays on the outermost\n * element, these four go to the hidden control because they are what the FORM reads —\n * the field's name, whether it is mandatory, which form it belongs to, and whether the\n * camera should open — and everything else goes to the element the READER focuses.\n *\n * The three piles never overlap, and that matters: an identifier applied twice would\n * break a label the consumer wrote for the field, and a name applied twice would have it\n * announced twice.\n */\nconst NATIVE_ONLY = ['name', 'required', 'form', 'capture']\n\nexport interface FileFieldOptions {\n /** The component's value — always a list of files, whether one or several are allowed. */\n model: Ref<File[]>\n /** The attributes the consumer wrote, minus styling, still to be split in two. */\n forwardedAttrs: ComputedRef<Record<string, unknown>>\n /** Read at the moment of the event, so a component turned off mid-way stops accepting. */\n enabled: () => boolean\n multiple: () => boolean\n /** The limits as the consumer set them: capping a single-file field at one happens here. */\n limits: () => FileLimits\n onReject: (rejection: FileRejection) => void\n onChange: (files: File[]) => void\n /**\n * Attributes to withhold from the visible control as well.\n *\n * The file field withholds the link to its descriptive text because it puts that list\n * together itself, and a binding written after the spread would silently replace the\n * consumer's rather than being merged with it.\n */\n excludeFromControl?: readonly string[]\n}\n\nexport function useFileField(options: FileFieldOptions) {\n const fileEl = ref<HTMLInputElement | null>(null)\n\n const nativeAttrs = computed(() =>\n Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(([key]) => NATIVE_ONLY.includes(key)),\n ),\n )\n\n const controlAttrs = computed(() => {\n const excluded = options.excludeFromControl ?? []\n return Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(\n ([key]) => !NATIVE_ONLY.includes(key) && !excluded.includes(key),\n ),\n )\n })\n\n /**\n * TRAP — choosing the SAME file again, after clearing the field or removing that file\n * from the list, reports nothing at all: as far as the hidden control is concerned its\n * value never changed. The file then becomes impossible to pick, with nothing to show\n * for it. Emptying the control on every path out is what keeps it selectable.\n */\n function resetNative() {\n if (fileEl.value) fileEl.value.value = ''\n }\n\n /**\n * The one way files get into the value: the operating system's dialog and a drop onto\n * the component both arrive here.\n *\n * A file the limits refuse is REFUSED outright — it never enters the value at all — and\n * every refusal is reported so the component can say why. The screening itself is a\n * plain function elsewhere, which is what makes the ORDER of the reasons testable\n * without putting a component on screen.\n */\n function acceptFiles(incoming: File[]) {\n const multiple = options.multiple()\n const current = multiple ? options.model.value : []\n const limits = options.limits()\n const { accepted, rejected } = screenFiles(incoming, current, {\n ...limits,\n // A single-file field is a list capped at one, so extra files are refused for the\n // same reason as anywhere else: too many.\n maxFiles: multiple ? limits.maxFiles : 1,\n })\n\n for (const rejection of rejected) options.onReject(rejection)\n\n resetNative()\n if (accepted.length === 0) return\n\n options.model.value = [...current, ...accepted]\n options.onChange(options.model.value)\n }\n\n function onNativeChange(event: Event) {\n acceptFiles([...((event.target as HTMLInputElement).files ?? [])])\n }\n\n // @fallback\n /**\n * The one call to the browser neither component can do without: opening the dialog.\n *\n * It clicks the hidden control rather than using the newer, more explicit request to\n * open a picker. Both require the reader to have just done something, but the explicit\n * one THROWS when they have not — and in an embedded page from another site — where a\n * click simply does nothing. On a file control there is nothing to gain in exchange.\n */\n function openPicker() {\n if (!options.enabled()) return\n fileEl.value?.click()\n }\n\n return { fileEl, nativeAttrs, controlAttrs, acceptFiles, onNativeChange, openPicker, resetNative }\n}\n"],"mappings":";;;AAgCA,IAAM,IAAc;CAAC;CAAQ;CAAY;CAAQ;AAAS;AAwB1D,SAAgB,EAAa,GAA2B;CACtD,IAAM,IAAS,EAA6B,IAAI,GAE1C,IAAc,QAClB,OAAO,YACL,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAS,EAAY,SAAS,CAAG,CAAC,CAC1F,CACF,GAEM,IAAe,QAAe;EAClC,IAAM,IAAW,EAAQ,sBAAsB,CAAC;EAChD,OAAO,OAAO,YACZ,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAC1C,CAAC,OAAS,CAAC,EAAY,SAAS,CAAG,KAAK,CAAC,EAAS,SAAS,CAAG,CACjE,CACF;CACF,CAAC;CAQD,SAAS,IAAc;EACrB,AAAI,EAAO,UAAO,EAAO,MAAM,QAAQ;CACzC;CAWA,SAAS,EAAY,GAAkB;EACrC,IAAM,IAAW,EAAQ,SAAS,GAC5B,IAAU,IAAW,EAAQ,MAAM,QAAQ,CAAC,GAC5C,IAAS,EAAQ,OAAO,GACxB,EAAE,aAAU,gBAAa,EAAY,GAAU,GAAS;GAC5D,GAAG;GAGH,UAAU,IAAW,EAAO,WAAW;EACzC,CAAC;EAED,KAAK,IAAM,KAAa,GAAU,EAAQ,SAAS,CAAS;EAE5D,EAAY,GACR,EAAS,WAAW,MAExB,EAAQ,MAAM,QAAQ,CAAC,GAAG,GAAS,GAAG,CAAQ,GAC9C,EAAQ,SAAS,EAAQ,MAAM,KAAK;CACtC;CAEA,SAAS,EAAe,GAAc;EACpC,EAAY,CAAC,GAAK,EAAM,OAA4B,SAAS,CAAC,CAAE,CAAC;CACnE;CAWA,SAAS,IAAa;EACf,EAAQ,QAAQ,KACrB,EAAO,OAAO,MAAM;CACtB;CAEA,OAAO;EAAE;EAAQ;EAAa;EAAc;EAAa;EAAgB;EAAY;CAAY;AACnG"}
1
+ {"version":3,"file":"useFileField.js","names":[],"sources":["../../src/composables/useFileField.ts"],"sourcesContent":["// @core\n/**\n * The hidden `<input type=\"file\">` gate of VFileInput and VFilePicker.\n *\n * The JS here is imposed by the platform, not chosen: a dialog opens ONLY from a real click\n * on a file input, and a `FileList` cannot be written from a template. So what the reader\n * clicks can never BE the file input, and the file input can only ever be a SOURCE of files.\n *\n * Hence `.click()` and not `showPicker()` — both need a transient user activation, but\n * `showPicker()` THROWS without one where `.click()` is merely inert — and hence\n * `resetNative()` on every path: without it, re-picking the SAME file after a clear fires no\n * `change` at all and that file becomes unreachable.\n *\n * Everything the two components did identically lives here, so the two cannot drift: the\n * attributes of the hidden input, the screening of what comes in, the removal of one file and\n * the emptying of all of them, and the development warnings both of them owe the integrator.\n */\nimport { computed, getCurrentInstance, ref, watchEffect, type ComputedRef, type Ref } from 'vue'\n\nimport { isDev } from '../utils/env'\nimport { screenFiles, type FileRejection } from '../utils/file'\n\n// @a11y\n/**\n * The attributes belonging on the hidden file input rather than on the visible control.\n *\n * The wrapper-root pattern assumes ONE functional element and there are two here, so the\n * attrs split in three: `class`/`style` on the root, these four on the input because they\n * are what the FORM reads, everything else on the element the READER focuses. The buckets\n * must not overlap — a duplicated `id` breaks a consumer's `<label for>`, a duplicated\n * `name` gets the field announced twice.\n */\nconst NATIVE_ONLY = ['name', 'required', 'form', 'capture']\n\n/** The props both components declare under the same names, read at the moment they matter. */\nexport interface FileFieldProps {\n multiple: boolean\n accept?: string\n maxSize?: number\n maxFiles?: number\n maxTotalSize?: number\n disabled: boolean\n readonly: boolean\n}\n\n/** The events both components declare under the same names and with the same payloads. */\nexport interface FileFieldEmit {\n (event: 'change', files: File[]): void\n (event: 'reject', rejection: FileRejection): void\n (event: 'remove', file: File, index: number): void\n}\n\nexport interface FileFieldOptions {\n /** The component's value — always a list of files, whether one or several are allowed. */\n model: Ref<File[]>\n props: FileFieldProps\n emit: FileFieldEmit\n /** The attributes the consumer wrote, minus styling, still to be split in two. */\n forwardedAttrs: ComputedRef<Record<string, unknown>>\n /**\n * Whether the component is disabled, the row it sits in taken into account. Left out, the\n * `disabled` prop answers alone.\n */\n disabled?: Ref<boolean>\n /**\n * Attributes to withhold from the visible control too. VFileInput withholds\n * `aria-describedby`, which it re-aggregates itself: a binding written after the spread\n * would replace the consumer's rather than merge with it.\n */\n excludeFromControl?: readonly string[]\n /** Called once the selection has been emptied by `clear`, before `change` is emitted. */\n onClear?: () => void\n /**\n * The component's own development warnings, one message per condition that holds. They\n * follow the same rule as the shared ones: each is given once per instance.\n */\n warnings?: () => (string | false)[]\n}\n\nexport function useFileField(options: FileFieldOptions) {\n const { model, props, emit } = options\n\n const fileEl = ref<HTMLInputElement | null>(null)\n\n const disabled = () => options.disabled?.value ?? props.disabled\n\n /** Whether files may come in or go out — no dialog, no drop and no removal otherwise. */\n const enabled = computed(() => !disabled() && !props.readonly)\n\n const controlAttrs = computed(() => {\n const excluded = options.excludeFromControl ?? []\n return Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(\n ([key]) => !NATIVE_ONLY.includes(key) && !excluded.includes(key),\n ),\n )\n })\n\n /**\n * TRAP — picking the SAME file again after a clear or a removal fires no `change` at all:\n * as far as the input is concerned its value never changed, and that file becomes\n * unreachable with nothing to show for it. Emptying it on every path is what keeps it\n * selectable.\n */\n function resetNative() {\n if (fileEl.value) fileEl.value.value = ''\n }\n\n /**\n * The single entry into the model: the dialog and a drop both arrive here.\n *\n * A refused file never enters the model at all, and every refusal is reported so the\n * component can say why. The screening is a pure function in `utils/file`, which is what\n * makes the ORDER of the reasons testable without a mount.\n */\n function acceptFiles(incoming: File[]) {\n const current = props.multiple ? model.value : []\n const { accepted, rejected } = screenFiles(incoming, current, {\n accept: props.accept,\n maxSize: props.maxSize,\n // A single-file field is a list capped at one, so extra files are refused for the\n // same reason as anywhere else: too many.\n maxFiles: props.multiple ? props.maxFiles : 1,\n maxTotalSize: props.maxTotalSize,\n })\n\n for (const rejection of rejected) emit('reject', rejection)\n\n resetNative()\n if (accepted.length === 0) return\n\n model.value = [...current, ...accepted]\n emit('change', model.value)\n }\n\n function onNativeChange(event: Event) {\n acceptFiles([...((event.target as HTMLInputElement).files ?? [])])\n }\n\n /**\n * Everything the hidden input is bound with, the consumer's form attributes included. It\n * is taken out of the tab order and hidden from screen readers, which leaves the visible\n * control as the single stop and the single announcement; it stays disabled only when the\n * component is — a read-only one still submits what it holds.\n */\n const nativeInputAttrs = computed(() => ({\n ...Object.fromEntries(\n Object.entries(options.forwardedAttrs.value).filter(([key]) => NATIVE_ONLY.includes(key)),\n ),\n type: 'file',\n tabindex: -1,\n 'aria-hidden': 'true' as const,\n accept: props.accept,\n multiple: props.multiple || undefined,\n disabled: disabled() || undefined,\n onChange: onNativeChange,\n }))\n\n // @fallback\n /**\n * `.click()` and not `showPicker()`. Both need a transient user activation, but\n * `showPicker()` THROWS without one — and inside a cross-origin iframe — where a click is\n * simply inert. On a file input there is nothing to gain in exchange.\n */\n function openPicker() {\n if (!enabled.value) return\n fileEl.value?.click()\n }\n\n /**\n * Takes ONE file out of the selection, and says which: `remove` with the file and the\n * position it held, then `change` with what is left. It returns the file removed, or\n * `undefined` when nothing was — so the component knows whether it has a focus to catch.\n */\n function removeAt(index: number): File | undefined {\n const file = model.value[index]\n if (!file || !enabled.value) return undefined\n\n model.value = model.value.filter((_, i) => i !== index)\n resetNative()\n emit('remove', file, index)\n emit('change', model.value)\n return file\n }\n\n /** Empties the selection, and the hidden input with it. */\n function clear() {\n model.value = []\n resetNative()\n options.onClear?.()\n emit('change', model.value)\n }\n\n // @devwarn\n /*\n * Both shared guards describe something that fails SILENTLY at runtime. Each message is given\n * once per instance: they sit in an effect, which re-runs on every change of what it reads,\n * and the same sentence repeated at every keystroke is how a warning stops being read.\n */\n if (isDev) {\n // The prefix is the component's own name, read off the instance rather than passed in:\n // this whole block is dropped from a production build, and the name with it.\n const name = getCurrentInstance()?.type.__name\n const warned = new Set<string>()\n const warn = (message: string) => {\n if (warned.has(message)) return\n warned.add(message)\n console.warn(`[${name}] ${message}`)\n }\n watchEffect(() => {\n if (props.maxFiles !== undefined && !props.multiple)\n warn('`maxFiles` ignored without `multiple`: single mode already caps at one file.')\n if (options.forwardedAttrs.value.required !== undefined)\n warn(\n '`required` lands on the hidden file input, which is not focusable: the browser blocks submission with no visible message. Validate the v-model yourself and use the `invalid` prop.',\n )\n for (const message of options.warnings?.() ?? []) if (message) warn(message)\n })\n }\n\n return {\n fileEl,\n enabled,\n nativeInputAttrs,\n controlAttrs,\n acceptFiles,\n openPicker,\n removeAt,\n clear,\n }\n}\n"],"mappings":";;;AAgCA,IAAM,IAAc;CAAC;CAAQ;CAAY;CAAQ;AAAS;AA+C1D,SAAgB,EAAa,GAA2B;CACtD,IAAM,EAAE,UAAO,UAAO,YAAS,GAEzB,IAAS,EAA6B,IAAI,GAE1C,UAAiB,EAAQ,UAAU,SAAS,EAAM,UAGlD,IAAU,QAAe,CAAC,EAAS,KAAK,CAAC,EAAM,QAAQ,GAEvD,IAAe,QAAe;EAClC,IAAM,IAAW,EAAQ,sBAAsB,CAAC;EAChD,OAAO,OAAO,YACZ,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAC1C,CAAC,OAAS,CAAC,EAAY,SAAS,CAAG,KAAK,CAAC,EAAS,SAAS,CAAG,CACjE,CACF;CACF,CAAC;CAQD,SAAS,IAAc;EACrB,AAAI,EAAO,UAAO,EAAO,MAAM,QAAQ;CACzC;CASA,SAAS,EAAY,GAAkB;EACrC,IAAM,IAAU,EAAM,WAAW,EAAM,QAAQ,CAAC,GAC1C,EAAE,aAAU,gBAAa,EAAY,GAAU,GAAS;GAC5D,QAAQ,EAAM;GACd,SAAS,EAAM;GAGf,UAAU,EAAM,WAAW,EAAM,WAAW;GAC5C,cAAc,EAAM;EACtB,CAAC;EAED,KAAK,IAAM,KAAa,GAAU,EAAK,UAAU,CAAS;EAE1D,EAAY,GACR,EAAS,WAAW,MAExB,EAAM,QAAQ,CAAC,GAAG,GAAS,GAAG,CAAQ,GACtC,EAAK,UAAU,EAAM,KAAK;CAC5B;CAEA,SAAS,EAAe,GAAc;EACpC,EAAY,CAAC,GAAK,EAAM,OAA4B,SAAS,CAAC,CAAE,CAAC;CACnE;CAQA,IAAM,IAAmB,SAAgB;EACvC,GAAG,OAAO,YACR,OAAO,QAAQ,EAAQ,eAAe,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAS,EAAY,SAAS,CAAG,CAAC,CAC1F;EACA,MAAM;EACN,UAAU;EACV,eAAe;EACf,QAAQ,EAAM;EACd,UAAU,EAAM,YAAY,KAAA;EAC5B,UAAU,EAAS,KAAK,KAAA;EACxB,UAAU;CACZ,EAAE;CAQF,SAAS,IAAa;EACf,EAAQ,SACb,EAAO,OAAO,MAAM;CACtB;CAOA,SAAS,EAAS,GAAiC;EACjD,IAAM,IAAO,EAAM,MAAM;EACrB,OAAC,KAAQ,CAAC,EAAQ,QAMtB,OAJA,EAAM,QAAQ,EAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAK,GACtD,EAAY,GACZ,EAAK,UAAU,GAAM,CAAK,GAC1B,EAAK,UAAU,EAAM,KAAK,GACnB;CACT;CAGA,SAAS,IAAQ;EAIf,AAHA,EAAM,QAAQ,CAAC,GACf,EAAY,GACZ,EAAQ,UAAU,GAClB,EAAK,UAAU,EAAM,KAAK;CAC5B;CA6BA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -1,17 +1,2 @@
1
1
  import { Ref } from 'vue';
2
- /**
3
- * Closes something as soon as the focus leaves the component — its floating panel
4
- * included.
5
- *
6
- * That last part is what makes this so short. A panel painted above the whole page is
7
- * still, in the document, a descendant of the component that owns it, so asking whether
8
- * the focus went somewhere inside the component is enough; nothing has to be watched at
9
- * the level of the page.
10
- *
11
- * The focus going nowhere in particular — out of the window, or back to the page body —
12
- * counts as leaving too, and closes.
13
- *
14
- * This exists because a panel the browser does not dismiss on its own has to be closed
15
- * by hand. The self-dismissing kind, the menu's, needs none of it.
16
- */
17
2
  export declare function useFocusoutDismiss(root: Ref<HTMLElement | null>, close: () => void): (event: FocusEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useFocusoutDismiss.js","names":[],"sources":["../../src/composables/useFocusoutDismiss.ts"],"sourcesContent":["import type { Ref } from 'vue'\n\n// @a11y\n/**\n * Closes something as soon as the focus leaves the component — its floating panel\n * included.\n *\n * That last part is what makes this so short. A panel painted above the whole page is\n * still, in the document, a descendant of the component that owns it, so asking whether\n * the focus went somewhere inside the component is enough; nothing has to be watched at\n * the level of the page.\n *\n * The focus going nowhere in particular — out of the window, or back to the page body —\n * counts as leaving too, and closes.\n *\n * This exists because a panel the browser does not dismiss on its own has to be closed\n * by hand. The self-dismissing kind, the menu's, needs none of it.\n */\nexport function useFocusoutDismiss(\n root: Ref<HTMLElement | null>,\n close: () => void,\n): (event: FocusEvent) => void {\n return (event: FocusEvent) => {\n const next = event.relatedTarget as Node | null\n if (!next || !root.value?.contains(next)) close()\n }\n}\n"],"mappings":";AAkBA,SAAgB,EACd,GACA,GAC6B;CAC7B,QAAQ,MAAsB;EAC5B,IAAM,IAAO,EAAM;EACnB,CAAI,CAAC,KAAQ,CAAC,EAAK,OAAO,SAAS,CAAI,MAAG,EAAM;CAClD;AACF"}
1
+ {"version":3,"file":"useFocusoutDismiss.js","names":[],"sources":["../../src/composables/useFocusoutDismiss.ts"],"sourcesContent":["// @a11y\n/**\n * A `@focusout` handler closing the component when focus leaves it, panel included.\n *\n * A popover stays a DOM descendant of its owner even while painted in the top layer, so\n * `contains` is the whole test and nothing has to be watched at document level. A null\n * `relatedTarget` — focus gone to the body, or out of the window — counts as leaving.\n *\n * Only `manual` popovers need this. VMenu's `auto` panel is dismissed by the browser.\n */\n\nimport type { Ref } from 'vue'\n\nexport function useFocusoutDismiss(\n root: Ref<HTMLElement | null>,\n close: () => void,\n): (event: FocusEvent) => void {\n return (event: FocusEvent) => {\n const next = event.relatedTarget as Node | null\n if (!next || !root.value?.contains(next)) close()\n }\n}\n"],"mappings":";AAaA,SAAgB,EACd,GACA,GAC6B;CAC7B,QAAQ,MAAsB;EAC5B,IAAM,IAAO,EAAM;EACnB,CAAI,CAAC,KAAQ,CAAC,EAAK,OAAO,SAAS,CAAI,MAAG,EAAM;CAClD;AACF"}
@@ -1,22 +1,37 @@
1
1
  /**
2
- * Tells a field whether the consumer wants its icons to be CLICKABLE.
2
+ * Whether VInput/VTextarea's icons should render as real buttons: an icon is decoration
3
+ * until someone listens for `@click:icon-*`, at which point it needs a tab stop and a name.
3
4
  *
4
- * An icon inside a field is decoration until someone listens for a click on it, at which
5
- * point it becomes a real button — one that can be reached with the keyboard and has a
6
- * name of its own. This is what answers the question.
5
+ * Declared emits are removed from `$attrs`, so the only place left to look is
6
+ * `vnode.props` — in BOTH spellings, a template writing them with dashes and a render
7
+ * function in camel case. Read ONCE and never revised: a listener attached later is not
8
+ * picked up, which is marginal enough to accept.
7
9
  *
8
- * Because those two events are declared by the component, Vue takes them out of the
9
- * attributes it hands down, so the only place left to look is the element description
10
- * Vue was given — and in BOTH spellings, since a template writes them with dashes and a
11
- * render function in camel case.
12
- *
13
- * The answer is read ONCE and never revised: a listener attached later is not picked up.
14
- * That case is marginal and the cost is accepted.
10
+ * The missing-name warning lives here rather than in each field: a button nothing can
11
+ * announce is a flaw of the arrangement, not of the component using it.
12
+ */
13
+ /**
14
+ * Whether the component being set up was handed a `@click:icon-start` / `@click:icon-end`
15
+ * listener, in either spelling.
16
+ */
17
+ export declare function iconClickHandlers(): {
18
+ start: boolean;
19
+ end: boolean;
20
+ };
21
+ /**
22
+ * The start-icon listener a field COMPOSED on top of VInput — VCombobox, VDateInput,
23
+ * VTimeInput, VFileInput — binds onto that inner VInput, ready to spread beside the
24
+ * consumer's attributes. Call it during setup: it reads the component's own vnode.
15
25
  *
16
- * The warning about a missing name belongs here rather than in each field. A button
17
- * nothing can announce is a flaw of the arrangement itself, not of the component that
18
- * happens to use it.
26
+ * Each of those fields declares `click:icon-start` as its own event, which puts it in the API
27
+ * tables and takes it out of `$attrs`, hence out of what is forwarded: the listener has to be
28
+ * bound by hand. And it has to follow what the consumer actually wrote — bound unconditionally,
29
+ * VInput would read a handler on every instance and turn a decorative icon into a focusable
30
+ * button nobody asked for. So it is `undefined` when there is nothing to relay.
19
31
  */
32
+ export declare function iconStartListener(relay: (event: MouseEvent) => void): {
33
+ 'onClick:icon-start': (event: MouseEvent) => void;
34
+ } | undefined;
20
35
  export declare function useIconClickHandlers(options: {
21
36
  name: string;
22
37
  iconStartLabel?: string;
@@ -1,13 +1,23 @@
1
1
  import { getCurrentInstance as e } from "vue";
2
2
  //#region src/composables/useIconClickHandlers.ts
3
- function t(t) {
4
- let n = e()?.vnode.props ?? {};
3
+ function t() {
4
+ let t = e()?.vnode.props ?? {};
5
5
  return {
6
- hasIconStartHandler: "onClick:iconStart" in n || "onClick:icon-start" in n,
7
- hasIconEndHandler: "onClick:iconEnd" in n || "onClick:icon-end" in n
6
+ start: "onClick:iconStart" in t || "onClick:icon-start" in t,
7
+ end: "onClick:iconEnd" in t || "onClick:icon-end" in t
8
+ };
9
+ }
10
+ function n(e) {
11
+ return t().start ? { "onClick:icon-start": e } : void 0;
12
+ }
13
+ function r(e) {
14
+ let { start: n, end: r } = t();
15
+ return {
16
+ hasIconStartHandler: n,
17
+ hasIconEndHandler: r
8
18
  };
9
19
  }
10
20
  //#endregion
11
- export { t as useIconClickHandlers };
21
+ export { t as iconClickHandlers, n as iconStartListener, r as useIconClickHandlers };
12
22
 
13
23
  //# sourceMappingURL=useIconClickHandlers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useIconClickHandlers.js","names":[],"sources":["../../src/composables/useIconClickHandlers.ts"],"sourcesContent":["import { getCurrentInstance } from 'vue'\n\nimport { isDev } from '../utils/env'\n\n// @core\n/**\n * Tells a field whether the consumer wants its icons to be CLICKABLE.\n *\n * An icon inside a field is decoration until someone listens for a click on it, at which\n * point it becomes a real button — one that can be reached with the keyboard and has a\n * name of its own. This is what answers the question.\n *\n * Because those two events are declared by the component, Vue takes them out of the\n * attributes it hands down, so the only place left to look is the element description\n * Vue was given — and in BOTH spellings, since a template writes them with dashes and a\n * render function in camel case.\n *\n * The answer is read ONCE and never revised: a listener attached later is not picked up.\n * That case is marginal and the cost is accepted.\n *\n * The warning about a missing name belongs here rather than in each field. A button\n * nothing can announce is a flaw of the arrangement itself, not of the component that\n * happens to use it.\n */\nexport function useIconClickHandlers(options: {\n name: string\n iconStartLabel?: string\n iconEndLabel?: string\n}): { hasIconStartHandler: boolean; hasIconEndHandler: boolean } {\n const vnodeProps = getCurrentInstance()?.vnode.props ?? {}\n const hasIconStartHandler =\n 'onClick:iconStart' in vnodeProps || 'onClick:icon-start' in vnodeProps\n const hasIconEndHandler = 'onClick:iconEnd' in vnodeProps || 'onClick:icon-end' in vnodeProps\n\n // @a11y @devwarn\n if (isDev) {\n if (hasIconStartHandler && !options.iconStartLabel)\n console.warn(\n `[${options.name}] clickable start icon without iconStartLabel — provide an accessible label.`,\n )\n if (hasIconEndHandler && !options.iconEndLabel)\n console.warn(\n `[${options.name}] clickable end icon without iconEndLabel — provide an accessible label.`,\n )\n }\n\n return { hasIconStartHandler, hasIconEndHandler }\n}\n"],"mappings":";;AAwBA,SAAgB,EAAqB,GAI4B;CAC/D,IAAM,IAAa,EAAmB,CAAC,EAAE,MAAM,SAAS,CAAC;CAiBzD,OAAO;EAAE,qBAfP,uBAAuB,KAAc,wBAAwB;EAejC,mBAdJ,qBAAqB,KAAc,sBAAsB;CAcnC;AAClD"}
1
+ {"version":3,"file":"useIconClickHandlers.js","names":[],"sources":["../../src/composables/useIconClickHandlers.ts"],"sourcesContent":["// @core\n/**\n * Whether VInput/VTextarea's icons should render as real buttons: an icon is decoration\n * until someone listens for `@click:icon-*`, at which point it needs a tab stop and a name.\n *\n * Declared emits are removed from `$attrs`, so the only place left to look is\n * `vnode.props` — in BOTH spellings, a template writing them with dashes and a render\n * function in camel case. Read ONCE and never revised: a listener attached later is not\n * picked up, which is marginal enough to accept.\n *\n * The missing-name warning lives here rather than in each field: a button nothing can\n * announce is a flaw of the arrangement, not of the component using it.\n */\n\nimport { getCurrentInstance } from 'vue'\n\nimport { isDev } from '../utils/env'\n\n/**\n * Whether the component being set up was handed a `@click:icon-start` / `@click:icon-end`\n * listener, in either spelling.\n */\nexport function iconClickHandlers(): { start: boolean; end: boolean } {\n const vnodeProps = getCurrentInstance()?.vnode.props ?? {}\n return {\n start: 'onClick:iconStart' in vnodeProps || 'onClick:icon-start' in vnodeProps,\n end: 'onClick:iconEnd' in vnodeProps || 'onClick:icon-end' in vnodeProps,\n }\n}\n\n/**\n * The start-icon listener a field COMPOSED on top of VInput — VCombobox, VDateInput,\n * VTimeInput, VFileInput — binds onto that inner VInput, ready to spread beside the\n * consumer's attributes. Call it during setup: it reads the component's own vnode.\n *\n * Each of those fields declares `click:icon-start` as its own event, which puts it in the API\n * tables and takes it out of `$attrs`, hence out of what is forwarded: the listener has to be\n * bound by hand. And it has to follow what the consumer actually wrote — bound unconditionally,\n * VInput would read a handler on every instance and turn a decorative icon into a focusable\n * button nobody asked for. So it is `undefined` when there is nothing to relay.\n */\nexport function iconStartListener(\n relay: (event: MouseEvent) => void,\n): { 'onClick:icon-start': (event: MouseEvent) => void } | undefined {\n return iconClickHandlers().start ? { 'onClick:icon-start': relay } : undefined\n}\n\nexport function useIconClickHandlers(options: {\n name: string\n iconStartLabel?: string\n iconEndLabel?: string\n}): { hasIconStartHandler: boolean; hasIconEndHandler: boolean } {\n const { start: hasIconStartHandler, end: hasIconEndHandler } = iconClickHandlers()\n\n // @a11y @devwarn\n if (isDev) {\n if (hasIconStartHandler && !options.iconStartLabel)\n console.warn(\n `[${options.name}] clickable start icon without iconStartLabel — provide an accessible label.`,\n )\n if (hasIconEndHandler && !options.iconEndLabel)\n console.warn(\n `[${options.name}] clickable end icon without iconEndLabel — provide an accessible label.`,\n )\n }\n\n return { hasIconStartHandler, hasIconEndHandler }\n}\n"],"mappings":";;AAsBA,SAAgB,IAAsD;CACpE,IAAM,IAAa,EAAmB,CAAC,EAAE,MAAM,SAAS,CAAC;CACzD,OAAO;EACL,OAAO,uBAAuB,KAAc,wBAAwB;EACpE,KAAK,qBAAqB,KAAc,sBAAsB;CAChE;AACF;AAaA,SAAgB,EACd,GACmE;CACnE,OAAO,EAAkB,CAAC,CAAC,QAAQ,EAAE,sBAAsB,EAAM,IAAI,KAAA;AACvE;AAEA,SAAgB,EAAqB,GAI4B;CAC/D,IAAM,EAAE,OAAO,GAAqB,KAAK,MAAsB,EAAkB;CAcjF,OAAO;EAAE;EAAqB;CAAkB;AAClD"}
@@ -0,0 +1,20 @@
1
+ import { ComputedRef } from 'vue';
2
+ export interface InertLinkOptions {
3
+ /** The address the component would link to, or `undefined` when it is not a link. */
4
+ href: () => string | undefined;
5
+ /** Whether the component is unusable right now. */
6
+ inert: () => boolean;
7
+ /** The attributes the component forwards to the element that acts. */
8
+ attrs: () => Record<string, unknown>;
9
+ }
10
+ export interface InertLink {
11
+ /** Whether the component renders an `<a>`. */
12
+ isLink: ComputedRef<boolean>;
13
+ /** Whether that `<a>` is inert, which is what `aria-disabled` is bound to. */
14
+ isInertLink: ComputedRef<boolean>;
15
+ /** The `href` to bind: the address, or nothing on an inert link. */
16
+ linkHref: ComputedRef<string | undefined>;
17
+ /** The attributes to bind, without the click handler on an inert link. */
18
+ attrs: ComputedRef<Record<string, unknown>>;
19
+ }
20
+ export declare function useInertLink(options: InertLinkOptions): InertLink;
@@ -0,0 +1,23 @@
1
+ import { computed as e } from "vue";
2
+ //#region src/composables/useInertLink.ts
3
+ function t(t) {
4
+ let n = e(() => t.href() !== void 0), r = e(() => n.value && t.inert());
5
+ return {
6
+ isLink: n,
7
+ isInertLink: r,
8
+ linkHref: e(() => r.value ? void 0 : t.href()),
9
+ attrs: e(() => {
10
+ let e = t.attrs();
11
+ if (!r.value) return e;
12
+ let n = {
13
+ role: "link",
14
+ ...e
15
+ };
16
+ return delete n.onClick, n;
17
+ })
18
+ };
19
+ }
20
+ //#endregion
21
+ export { t as useInertLink };
22
+
23
+ //# sourceMappingURL=useInertLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInertLink.js","names":[],"sources":["../../src/composables/useInertLink.ts"],"sourcesContent":["// @a11y\n/**\n * The inert link of every component that may render as an `<a>`: VButton, VChip and VAvatar.\n *\n * A link has no `disabled` attribute, so the complete inertness a `<button disabled>` gets for\n * free is rebuilt by hand, in parts that only work together. The address is dropped, so the\n * link can be neither focused nor followed; `aria-disabled` tells assistive technology why; and\n * the consumer's `onClick` is filtered out of the attributes, since an `<a>` without an `href`\n * still dispatches clicks and a handler would otherwise run on a control announced as disabled.\n *\n * TRAP — the attributes also gain `role=\"link\"`. An `<a>` without `href` is no longer a link\n * but a generic element, on which an `aria-label` is PROHIBITED (axe `aria-prohibited-attr`)\n * and `aria-disabled` describes nothing: an icon-only VIconButton turned inert would lose its\n * name. The role is spread BEFORE the consumer's attributes, so a role of their own still wins —\n * which is also why it travels in the attributes and is never bound after them, where an\n * `undefined` would erase the `role=\"tab\"` a VTab hands its button.\n *\n * Each of the three decides for itself WHEN it is a link and WHEN it is inert (VChip gives\n * `selectable` precedence over `href`, VButton counts `loading` as inert), which is why both\n * arrive as getters; the consequences are the same everywhere and live here.\n */\nimport { computed } from 'vue'\nimport type { ComputedRef } from 'vue'\n\nexport interface InertLinkOptions {\n /** The address the component would link to, or `undefined` when it is not a link. */\n href: () => string | undefined\n /** Whether the component is unusable right now. */\n inert: () => boolean\n /** The attributes the component forwards to the element that acts. */\n attrs: () => Record<string, unknown>\n}\n\nexport interface InertLink {\n /** Whether the component renders an `<a>`. */\n isLink: ComputedRef<boolean>\n /** Whether that `<a>` is inert, which is what `aria-disabled` is bound to. */\n isInertLink: ComputedRef<boolean>\n /** The `href` to bind: the address, or nothing on an inert link. */\n linkHref: ComputedRef<string | undefined>\n /** The attributes to bind, without the click handler on an inert link. */\n attrs: ComputedRef<Record<string, unknown>>\n}\n\nexport function useInertLink(options: InertLinkOptions): InertLink {\n const isLink = computed(() => options.href() !== undefined)\n const isInertLink = computed(() => isLink.value && options.inert())\n return {\n isLink,\n isInertLink,\n linkHref: computed(() => (isInertLink.value ? undefined : options.href())),\n attrs: computed(() => {\n const attrs = options.attrs()\n if (!isInertLink.value) return attrs\n const rest: Record<string, unknown> = { role: 'link', ...attrs }\n delete rest.onClick\n return rest\n }),\n }\n}\n"],"mappings":";;AA4CA,SAAgB,EAAa,GAAsC;CACjE,IAAM,IAAS,QAAe,EAAQ,KAAK,MAAM,KAAA,CAAS,GACpD,IAAc,QAAe,EAAO,SAAS,EAAQ,MAAM,CAAC;CAClE,OAAO;EACL;EACA;EACA,UAAU,QAAgB,EAAY,QAAQ,KAAA,IAAY,EAAQ,KAAK,CAAE;EACzE,OAAO,QAAe;GACpB,IAAM,IAAQ,EAAQ,MAAM;GAC5B,IAAI,CAAC,EAAY,OAAO,OAAO;GAC/B,IAAM,IAAgC;IAAE,MAAM;IAAQ,GAAG;GAAM;GAE/D,OADA,OAAO,EAAK,SACL;EACT,CAAC;CACH;AACF"}