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,35 +1,35 @@
1
1
  import { useLocale as e, useMessages as t } from "../../i18n/state.js";
2
2
  import n from "../VTypography/VTypography.js";
3
- import { useRootAttrs as ee } from "../../composables/useRootAttrs.js";
4
- import te from "../VInput/VInput.js";
5
- import ne from "../VChip/VChip.js";
6
- import { chipScaleFor as r } from "../../utils/chip.js";
7
- import { attach_file as i } from "../VIcon/icons/attach_file.js";
8
- import { useFileDrop as re } from "../../composables/useFileDrop.js";
9
- import { formatBytes as ie } from "../../utils/file.js";
10
- import { useFileField as ae } from "../../composables/useFileField.js";
11
- import { truncateMiddle as oe } from "./truncate.js";
12
- import { Fragment as se, computed as a, createBlock as ce, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createSlots as le, createTextVNode as l, createVNode as u, defineComponent as d, mergeModels as f, mergeProps as p, normalizeClass as ue, normalizeStyle as m, openBlock as h, ref as g, renderList as _, renderSlot as v, toDisplayString as y, unref as b, useId as x, useModel as de, withCtx as S } from "vue";
3
+ import { useControlShape as ee } from "../../composables/useControlShape.js";
4
+ import { useRootAttrs as te } from "../../composables/useRootAttrs.js";
5
+ import { joinIds as r } from "../../utils/ids.js";
6
+ import { iconStartListener as i } from "../../composables/useIconClickHandlers.js";
7
+ import { canClear as a } from "../../composables/useClearable.js";
8
+ import { inputGroupKey as ne } from "../VInput/context.js";
9
+ import re from "../VInput/VInput.js";
10
+ import ie from "../VChip/VChip.js";
11
+ import { chipScaleFor as ae } from "../../utils/chip.js";
12
+ import { attach_file as o } from "../VIcon/icons/attach_file.js";
13
+ import { useFileDrop as oe } from "../../composables/useFileDrop.js";
14
+ import { fileKey as se, formatBytes as ce } from "../../utils/file.js";
15
+ import { useFileField as le } from "../../composables/useFileField.js";
16
+ import { truncateMiddle as ue } from "./truncate.js";
17
+ import { Fragment as de, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as f, createTextVNode as p, createVNode as m, defineComponent as h, inject as fe, mergeModels as g, mergeProps as _, normalizeClass as pe, normalizeStyle as me, openBlock as v, ref as y, renderList as he, renderSlot as b, toDisplayString as x, unref as S, useId as C, useModel as ge, withCtx as w } from "vue";
13
18
  //#region src/components/VFileInput/VFileInput.vue?vue&type=script&setup=true&lang.ts
14
- var fe = [
19
+ var _e = [
15
20
  "data-size",
16
21
  "data-compact",
17
22
  "data-display",
18
23
  "data-disabled",
19
24
  "data-readonly",
20
- "data-dragging",
21
- "data-can-clear"
22
- ], pe = [
23
- "accept",
24
- "multiple",
25
- "disabled"
26
- ], me = {
25
+ "data-dragging"
26
+ ], ve = {
27
27
  key: 0,
28
- class: "v-file-input-meta"
29
- }, he = ["id"], C = /*@__PURE__*/ d({
28
+ class: "v-file-input-meta v-field-meta"
29
+ }, ye = ["id"], T = /*@__PURE__*/ h({
30
30
  inheritAttrs: !1,
31
31
  __name: "VFileInput",
32
- props: /*@__PURE__*/ f({
32
+ props: /*@__PURE__*/ g({
33
33
  multiple: {
34
34
  type: Boolean,
35
35
  default: !1
@@ -43,10 +43,10 @@ var fe = [
43
43
  type: Boolean,
44
44
  default: !1
45
45
  },
46
- attachIcon: { default: () => i },
47
- droppable: {
46
+ pickerIcon: { default: () => o },
47
+ noDrop: {
48
48
  type: Boolean,
49
- default: !0
49
+ default: !1
50
50
  },
51
51
  size: { default: "md" },
52
52
  compact: {
@@ -68,128 +68,130 @@ var fe = [
68
68
  label: { default: void 0 },
69
69
  hint: { default: void 0 },
70
70
  placeholder: { default: void 0 },
71
+ iconStart: { default: void 0 },
72
+ iconStartLabel: { default: void 0 },
73
+ pickerIconLabel: { default: void 0 },
74
+ loading: {
75
+ type: Boolean,
76
+ default: !1
77
+ },
78
+ loadingLabel: { default: void 0 },
71
79
  clearable: {
72
80
  type: Boolean,
73
- default: !0
74
- }
81
+ default: !1
82
+ },
83
+ clearLabel: { default: void 0 }
75
84
  }, {
76
85
  modelValue: { default: () => [] },
77
86
  modelModifiers: {}
78
87
  }),
79
- emits: /*@__PURE__*/ f([
88
+ emits: /*@__PURE__*/ g([
80
89
  "change",
81
90
  "reject",
82
- "clear"
91
+ "remove",
92
+ "clear",
93
+ "click:icon-start"
83
94
  ], ["update:modelValue"]),
84
- setup(i, { expose: d, emit: f }) {
85
- let C = i, w = f, T = de(i, "modelValue"), { attrs: E, rootClass: D, rootStyle: O, forwardedAttrs: k } = ee(), A = t(), j = e(), { fileEl: M, nativeAttrs: N, controlAttrs: P, acceptFiles: F, onNativeChange: I, openPicker: L, resetNative: R } = ae({
86
- model: T,
87
- forwardedAttrs: k,
88
- enabled: () => !C.disabled && !C.readonly,
89
- multiple: () => C.multiple,
90
- limits: () => ({
91
- accept: C.accept,
92
- maxSize: C.maxSize,
93
- maxFiles: C.maxFiles,
94
- maxTotalSize: C.maxTotalSize
95
- }),
96
- onReject: (e) => w("reject", e),
97
- onChange: (e) => w("change", e),
98
- excludeFromControl: ["aria-describedby"]
99
- }), z = g(null), B = a(() => C.multiple ? C.display : "text"), ge = a(() => B.value === "chip" ? "" : T.value.map((e) => e.name).join(", ")), _e = a(() => T.value.length > 0 ? void 0 : C.placeholder ?? A.value.fileInput.placeholder), V = a(() => C.clearable && !C.disabled && !C.readonly && T.value.length > 0), ve = a(() => C.readonly ? void 0 : C.attachIcon), H = a(() => T.value.reduce((e, t) => e + t.size, 0)), U = a(() => {
100
- let e = A.value.fileInput.files(T.value.length);
101
- return T.value.length === 0 ? e : `${e} (${ie(H.value, j.value)})`;
102
- }), W = x(), G = x(), K = a(() => [
103
- E["aria-describedby"],
104
- C.hint ? W : void 0,
105
- C.counter ? G : void 0
106
- ].filter(Boolean).join(" ") || void 0), q = a(() => r(C.size, C.compact)), J = (e) => oe(e.name);
107
- function ye(e) {
108
- e.target.closest("button") || L();
95
+ setup(o, { expose: h, emit: g }) {
96
+ let T = o, E = g, D = ge(o, "modelValue"), { attrs: O, rootClass: k, rootStyle: A, forwardedAttrs: j } = te(), M = i((e) => E("click:icon-start", e)), N = t(), P = e(), { size: F, compact: I, disabled: L } = ee(T, fe(ne, null)), { fileEl: be, enabled: R, nativeInputAttrs: xe, controlAttrs: Se, acceptFiles: Ce, openPicker: z, removeAt: we, clear: Te } = le({
97
+ model: D,
98
+ props: T,
99
+ emit: E,
100
+ forwardedAttrs: j,
101
+ disabled: L,
102
+ excludeFromControl: ["aria-describedby"],
103
+ onClear: () => E("clear"),
104
+ warnings: void 0
105
+ }), Ee = s(() => ({
106
+ ...Se.value,
107
+ ...M
108
+ })), B = y(null), V = y(null), H = s(() => T.multiple ? T.display : "text"), De = s(() => H.value === "chip" ? "" : D.value.map((e) => e.name).join(", ")), Oe = s(() => D.value.length > 0 ? void 0 : T.placeholder ?? N.value.fileInput.placeholder), ke = s(() => a(T, L.value, D.value.length > 0)), Ae = s(() => T.readonly ? void 0 : T.pickerIcon), je = s(() => T.pickerIconLabel ?? N.value.fileInput.openPicker), Me = s(() => T.clearLabel ?? N.value.fileInput.clear), U = s(() => D.value.reduce((e, t) => e + t.size, 0)), W = s(() => {
109
+ let e = N.value.fileInput.files(D.value.length);
110
+ return D.value.length === 0 ? e : `${e} (${ce(U.value, P.value)})`;
111
+ }), G = C(), K = C(), Ne = s(() => r(O["aria-describedby"], !!T.hint && G, T.counter && K)), q = s(() => ae(F.value, I.value)), J = s(() => D.value.map((e) => ue(e.name)));
112
+ function Pe(e) {
113
+ e.target.closest("button") || z();
109
114
  }
110
- function be(e) {
111
- e.key !== "Enter" && e.key !== " " || (e.preventDefault(), L());
115
+ function Fe(e) {
116
+ e.key !== "Enter" && e.key !== " " || (e.preventDefault(), z());
112
117
  }
113
118
  function Y(e) {
114
- T.value = T.value.filter((t, n) => n !== e), R(), w("change", T.value), z.value?.focus();
115
- }
116
- function xe() {
117
- T.value = [], R(), w("clear"), w("change", T.value);
119
+ we(e) && B.value?.focus();
118
120
  }
119
- let { dragging: Se, onDragEnter: X, onDragOver: Z, onDragLeave: Q, onDrop: $ } = re(() => C.droppable && !C.disabled && !C.readonly, F);
120
- return d({
121
- focus: (e) => z.value?.focus(e),
122
- open: L
123
- }), (e, t) => (h(), s("div", {
124
- class: ue(["v-file-input", b(D)]),
125
- style: m([{ "--chip-height": q.value.height }, b(O)]),
126
- "data-size": i.size,
127
- "data-compact": i.compact ? "" : void 0,
128
- "data-display": B.value,
129
- "data-disabled": i.disabled ? "" : void 0,
130
- "data-readonly": i.readonly ? "" : void 0,
131
- "data-dragging": b(Se) ? "" : void 0,
132
- "data-can-clear": V.value ? "" : void 0,
133
- onDragenter: t[1] ||= (...e) => b(X) && b(X)(...e),
134
- onDragover: t[2] ||= (...e) => b(Z) && b(Z)(...e),
135
- onDragleave: t[3] ||= (...e) => b(Q) && b(Q)(...e),
136
- onDrop: t[4] ||= (...e) => b($) && b($)(...e)
121
+ let { dragging: Ie, onDragEnter: X, onDragOver: Z, onDragLeave: Q, onDrop: $ } = oe(() => !T.noDrop && R.value, Ce);
122
+ return h({
123
+ focus: (e) => B.value?.focus(e),
124
+ open: z,
125
+ el: V
126
+ }), (e, t) => (v(), u("div", {
127
+ ref_key: "rootEl",
128
+ ref: V,
129
+ class: pe(["v-file-input", S(k)]),
130
+ style: me([{ "--chip-height": q.value.height }, S(A)]),
131
+ "data-size": S(F),
132
+ "data-compact": S(I) ? "" : void 0,
133
+ "data-display": H.value,
134
+ "data-disabled": S(L) ? "" : void 0,
135
+ "data-readonly": o.readonly ? "" : void 0,
136
+ "data-dragging": S(Ie) ? "" : void 0,
137
+ onDragenter: t[0] ||= (...e) => S(X) && S(X)(...e),
138
+ onDragover: t[1] ||= (...e) => S(Z) && S(Z)(...e),
139
+ onDragleave: t[2] ||= (...e) => S(Q) && S(Q)(...e),
140
+ onDrop: t[3] ||= (...e) => S($) && S($)(...e)
137
141
  }, [
138
- c("input", p(b(N), {
142
+ d("input", _(S(xe), {
139
143
  ref_key: "fileEl",
140
- ref: M,
141
- type: "file",
142
- class: "v-file-input-native",
143
- tabindex: "-1",
144
- "aria-hidden": "true",
145
- accept: i.accept,
146
- multiple: i.multiple || void 0,
147
- disabled: i.disabled || void 0,
148
- onChange: t[0] ||= (...e) => b(I) && b(I)(...e)
149
- }), null, 16, pe),
150
- c("div", {
144
+ ref: be,
145
+ class: "v-file-input-native v-hidden-input"
146
+ }), null, 16),
147
+ d("div", {
151
148
  class: "v-file-input-control",
152
- onClick: ye
153
- }, [u(te, p(b(P), {
149
+ onClick: Pe
150
+ }, [m(re, _(Ee.value, {
154
151
  ref_key: "inputRef",
155
- ref: z,
156
- "model-value": ge.value,
152
+ ref: B,
153
+ class: { "v-input-end-pinned v-input-chips": H.value === "chip" },
154
+ "model-value": De.value,
157
155
  readonly: "",
158
- label: i.label,
159
- placeholder: _e.value,
160
- size: i.size,
161
- compact: i.compact,
162
- disabled: i.disabled,
163
- invalid: i.invalid,
164
- clearable: i.clearable,
165
- "clear-visible": V.value,
166
- "clear-label": b(A).fileInput.clear,
167
- "icon-end": ve.value,
168
- "icon-end-label": b(A).fileInput.attach,
169
- "aria-describedby": K.value,
170
- "onClick:iconEnd": b(L),
171
- onClear: xe,
172
- onKeydown: be
173
- }), le({ _: 2 }, [B.value === "chip" ? {
156
+ label: o.label,
157
+ placeholder: Oe.value,
158
+ size: S(F),
159
+ compact: S(I),
160
+ disabled: S(L),
161
+ invalid: o.invalid,
162
+ clearable: o.clearable,
163
+ "clear-visible": ke.value,
164
+ "clear-label": Me.value,
165
+ "icon-start": o.iconStart,
166
+ "icon-start-label": o.iconStartLabel,
167
+ loading: o.loading,
168
+ "loading-label": o.loadingLabel,
169
+ "icon-end": Ae.value,
170
+ "icon-end-label": je.value,
171
+ "aria-describedby": Ne.value,
172
+ "onClick:iconEnd": S(z),
173
+ onClear: S(Te),
174
+ onKeydown: Fe
175
+ }), f({ _: 2 }, [H.value === "chip" || e.$slots.start ? {
174
176
  name: "start",
175
- fn: S(() => [(h(!0), s(se, null, _(T.value, (t, n) => v(e.$slots, "chip", {
177
+ fn: w(() => [(v(!0), u(de, null, he(H.value === "chip" ? D.value : [], (t, n) => b(e.$slots, "chip", {
176
178
  file: t,
177
179
  index: n,
178
- label: J(t),
180
+ label: J.value[n],
179
181
  remove: () => Y(n),
180
182
  size: q.value.size,
181
183
  compact: q.value.compact
182
- }, () => [u(ne, {
184
+ }, () => [m(ie, {
183
185
  tone: "accent",
184
186
  size: q.value.size,
185
187
  compact: q.value.compact,
186
- dismissible: !i.readonly && !i.disabled,
187
- "dismiss-label": b(A).fileInput.remove(t.name),
188
- disabled: i.disabled,
189
- title: J(t) === t.name ? void 0 : t.name,
188
+ dismissible: S(R),
189
+ "dismiss-label": S(N).common.remove(t.name),
190
+ disabled: S(L),
191
+ title: J.value[n] === t.name ? void 0 : t.name,
190
192
  onDismiss: (e) => Y(n)
191
193
  }, {
192
- default: S(() => [l(y(J(t)), 1)]),
194
+ default: w(() => [p(x(J.value[n]), 1)]),
193
195
  _: 2
194
196
  }, 1032, [
195
197
  "size",
@@ -199,9 +201,14 @@ var fe = [
199
201
  "disabled",
200
202
  "title",
201
203
  "onDismiss"
202
- ])], void 0, `${n}-${t.name}`)), 128))]),
204
+ ])], void 0, S(se)(t))), 128)), b(e.$slots, "start")]),
203
205
  key: "0"
206
+ } : void 0, e.$slots["value-end"] ? {
207
+ name: "value-end",
208
+ fn: w(() => [b(e.$slots, "value-end")]),
209
+ key: "1"
204
210
  } : void 0]), 1040, [
211
+ "class",
205
212
  "model-value",
206
213
  "label",
207
214
  "placeholder",
@@ -212,33 +219,38 @@ var fe = [
212
219
  "clearable",
213
220
  "clear-visible",
214
221
  "clear-label",
222
+ "icon-start",
223
+ "icon-start-label",
224
+ "loading",
225
+ "loading-label",
215
226
  "icon-end",
216
227
  "icon-end-label",
217
228
  "aria-describedby",
218
- "onClick:iconEnd"
229
+ "onClick:iconEnd",
230
+ "onClear"
219
231
  ])]),
220
- i.hint || i.counter ? (h(), s("div", me, [i.hint ? (h(), ce(n, {
232
+ o.hint || o.counter ? (v(), u("div", ve, [o.hint ? (v(), c(n, {
221
233
  key: 0,
222
- id: b(W),
234
+ id: S(G),
223
235
  variant: "caption",
224
236
  tone: "muted",
225
237
  class: "v-file-input-hint"
226
238
  }, {
227
- default: S(() => [l(y(i.hint), 1)]),
239
+ default: w(() => [p(x(o.hint), 1)]),
228
240
  _: 1
229
- }, 8, ["id"])) : o("", !0), i.counter ? (h(), s("span", {
241
+ }, 8, ["id"])) : l("", !0), o.counter ? (v(), u("span", {
230
242
  key: 1,
231
- id: b(G),
232
- class: "v-file-input-counter"
233
- }, [v(e.$slots, "counter", {
234
- count: T.value.length,
235
- size: H.value,
236
- text: U.value
237
- }, () => [l(y(U.value), 1)])], 8, he)) : o("", !0)])) : o("", !0)
238
- ], 46, fe));
243
+ id: S(K),
244
+ class: "v-file-input-counter v-field-counter"
245
+ }, [b(e.$slots, "counter", {
246
+ count: D.value.length,
247
+ bytes: U.value,
248
+ text: W.value
249
+ }, () => [p(x(W.value), 1)])], 8, ye)) : l("", !0)])) : l("", !0)
250
+ ], 46, _e));
239
251
  }
240
252
  });
241
253
  //#endregion
242
- export { C as default };
254
+ export { T as default };
243
255
 
244
256
  //# sourceMappingURL=VFileInput.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VFileInput.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VFileInput/VFileInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Choosing files, presented as an ordinary form field: a read-only text field showing\n * what was picked, with the real file input hidden behind it. It is the shape of a\n * read-only date picker, without the panel.\n *\n * What was chosen is reported as a plain list of files, which is what lets a consumer\n * build whatever preview they like from it.\n *\n * The JavaScript here is imposed by the platform rather than chosen. A file dialog opens\n * ONLY from a real click on a real file input, and the list of files it holds cannot be\n * written from a template — so the visible field can never BE the native control, and\n * that control can only ever be a SOURCE of files, never a mirror of the value.\n *\n * Everything else follows from those two facts: the clicks and keys relayed to the\n * hidden input, the reset of that input after every change — without which the same file\n * cannot be picked twice in a row — and the screening of incoming files in code, since\n * the `accept` attribute has no say whatsoever over a drop.\n */\nimport { computed, ref, useId, watchEffect } from 'vue'\n\nimport VChip from '../VChip/VChip.vue'\nimport { attach_file as attachFileIcon } from '../VIcon/icons/attach_file'\nimport type { IconSource } from '../VIcon/types'\nimport VInput from '../VInput/VInput.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useFileDrop } from '../../composables/useFileDrop'\nimport { useFileField } from '../../composables/useFileField'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useLocale, useMessages } from '../../i18n/state'\nimport { chipScaleFor } from '../../utils/chip'\nimport { isDev } from '../../utils/env'\nimport { formatBytes } from '../../utils/file'\nimport { truncateMiddle } from './truncate'\n\n/** How the chosen files are shown inside the field when several are allowed. */\nexport type FileInputDisplay = 'text' | 'chip'\n\n/** Why a file was turned away: its kind, its size, how many there already are, or the total. */\nexport type FileInputRejectReason = 'type' | 'size' | 'count' | 'total-size'\n\n/** One file that was turned away, and the reason it was. */\nexport interface FileInputRejection {\n /** The file itself, so a message can name it. */\n file: File\n /** What it fell foul of. */\n reason: FileInputRejectReason\n}\n\ninterface FileInputProps {\n /** Allows several files to be chosen. With one only, every extra file is turned away. */\n multiple?: boolean\n /**\n * Which kinds of file are accepted, in the browser's own syntax (`image/*,.pdf`).\n *\n * It is applied TWICE, and it has to be: as an attribute, which is what filters the\n * system's file dialog, and again in code, which is the only thing that can filter a\n * file DROPPED on the component — the attribute has no say over a drop.\n */\n accept?: string\n /**\n * How the chosen files are shown: their names joined by commas, or one dismissible\n * chip each. It only means something when several files are allowed; a single name is\n * always text.\n */\n display?: FileInputDisplay\n /** The largest ONE file may be, in bytes. */\n maxSize?: number\n /** The largest the whole selection may be, in bytes. */\n maxTotalSize?: number\n /** How many files may be chosen at most. */\n maxFiles?: number\n /** Shows how much has been chosen under the field: \"3 files (1.2 MB)\". */\n counter?: boolean\n /** The icon at the end of the field, which opens the file dialog. */\n attachIcon?: IconSource\n /** Accepts files dropped onto the component, as well as chosen through the dialog. */\n droppable?: boolean\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: 'sm' | 'md' | 'lg'\n /** Takes 4px off the height, leaving the padding, the text and the icons as they are. */\n compact?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows what was chosen without allowing it to change: no dialog, no drop, no removal.\n */\n readonly?: boolean\n /**\n * Marks the field as invalid — for a rule of your own, since nothing here is checked\n * by the browser.\n */\n invalid?: boolean\n /** The label above the field, tied to it so that clicking it focuses the field. */\n label?: string\n /**\n * A line of help under the field, to the left of the counter. It is tied to the field\n * for assistive technology.\n */\n hint?: string\n /**\n * What the field says while nothing is chosen. It falls back to the design system\n * dictionary.\n */\n placeholder?: string\n /** Offers a cross that empties the selection. */\n clearable?: boolean\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FileInputProps>(), {\n multiple: false,\n accept: undefined,\n display: 'text',\n maxSize: undefined,\n maxTotalSize: undefined,\n maxFiles: undefined,\n counter: false,\n attachIcon: () => attachFileIcon,\n droppable: true,\n size: 'md',\n compact: false,\n disabled: false,\n readonly: false,\n invalid: false,\n label: undefined,\n hint: undefined,\n placeholder: undefined,\n // On by default, unlike an ordinary field: what is in a picker cannot be erased by\n // typing, so without the cross there would be no way to empty it — the same reasoning\n // as in a read-only date picker.\n clearable: true,\n})\n\nconst emit = defineEmits<{\n /** The reader changed the selection — added something, removed something, cleared it. */\n change: [files: File[]]\n /**\n * A file was turned away and never joined the selection. It is emitted once PER file,\n * so a batch drop can be reported precisely.\n */\n reject: [rejection: FileInputRejection]\n /** The clear cross emptied the selection. */\n clear: []\n}>()\n\ndefineSlots<{\n /**\n * Replaces the chip standing for one file.\n *\n * Three of the values it receives are what make it usable without regressions:\n * `label` is the name already shortened in the MIDDLE so that its extension survives,\n * `remove` is what takes the file out — without it the file could no longer be removed\n * at all — and the size and density are the ones worked out to sit inside the field,\n * which cannot be guessed from outside.\n */\n chip?(props: {\n file: File\n index: number\n label: string\n remove: () => void\n size: 'xs' | 'sm'\n compact: boolean\n }): unknown\n /**\n * Replaces the counter under the field. `text` is the sentence already built and\n * translated; the count and the total size are there for a wording of your own.\n */\n counter?(props: { count: number; size: number; text: string }): unknown\n}>()\n\n/**\n * Always a LIST of files, whether or not several are allowed — never a file on its own.\n * The shape of the value does not depend on a prop, so a consumer never has to narrow a\n * union TypeScript has no way of discriminating. With a single file it is simply a list\n * of at most one.\n */\nconst model = defineModel<File[]>({ default: () => [] })\n\nconst { attrs, rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst m = useMessages()\nconst locale = useLocale()\n\n/*\n * The hidden input, the sorting of the consumer's attributes and the single entry point\n * into the value all live in `useFileField`, shared with VFilePicker.\n *\n * Here, the bucket meant for \"the control the user deals with\" goes to the visible\n * field: that is what they see, focus and click, so a consumer's own `<label for>` has\n * to point at it. The description attribute is pulled out of that bucket, because this\n * component re-assembles it further down.\n */\nconst {\n fileEl,\n nativeAttrs,\n controlAttrs: fieldAttrs,\n acceptFiles,\n onNativeChange,\n openPicker,\n resetNative,\n} = useFileField({\n model,\n forwardedAttrs,\n enabled: () => !props.disabled && !props.readonly,\n multiple: () => props.multiple,\n limits: () => ({\n accept: props.accept,\n maxSize: props.maxSize,\n maxFiles: props.maxFiles,\n maxTotalSize: props.maxTotalSize,\n }),\n onReject: (rejection) => emit('reject', rejection),\n onChange: (files) => emit('change', files),\n excludeFromControl: ['aria-describedby'],\n})\n\nconst inputRef = ref<InstanceType<typeof VInput> | null>(null)\n\n// Chips only mean something for a list: a single file always shows as plain text.\nconst resolvedDisplay = computed<FileInputDisplay>(() => (props.multiple ? props.display : 'text'))\n\nconst displayText = computed(() =>\n resolvedDisplay.value === 'chip' ? '' : model.value.map((file) => file.name).join(', '),\n)\n\nconst placeholderText = computed(() =>\n model.value.length > 0 ? undefined : (props.placeholder ?? m.value.fileInput.placeholder),\n)\n\n/*\n * Whether the clear cross is shown has to be answered EXPLICITLY here. The visible field\n * is read-only, and a read-only field hides its cross by default — rightly so, since its\n * text cannot be edited. Here the value comes from the file dialog rather than from\n * typing, so there is something to clear all the same.\n */\nconst canClear = computed(\n () => props.clearable && !props.disabled && !props.readonly && model.value.length > 0,\n)\n\n// @a11y @devwarn\n/*\n * The icon disappears along with what it offers: a read-only field opens no dialog, so\n * an icon inviting one would be a lie — the same rule VDateInput follows for its\n * calendar.\n *\n * TRAP — its LABEL stays defined at all times, even when no icon is rendered. The helper\n * that detects a click handler on an icon warns AT SETUP if one is attached without a\n * label, and it has no way of knowing whether an icon exists.\n */\nconst endIcon = computed<IconSource | undefined>(() =>\n props.readonly ? undefined : props.attachIcon,\n)\n\nconst totalSize = computed(() => model.value.reduce((sum, file) => sum + file.size, 0))\n\n/*\n * The counter is assembled from three sources: the WORD comes from the dictionary, since\n * it is language; the SIZE is formatted by the platform, which knows the local\n * conventions; and the parentheses come from neither, being punctuation every language\n * shares — the same boundary VBadge's \"99+\" falls on.\n *\n * With nothing chosen it states the count alone: \"0 files ()\" would be noise.\n */\nconst counterText = computed(() => {\n const word = m.value.fileInput.files(model.value.length)\n return model.value.length === 0 ? word : `${word} (${formatBytes(totalSize.value, locale.value)})`\n})\n\nconst hintId = useId()\nconst counterId = useId()\n\n// @a11y\n/*\n * What describes the field for a screen reader is a LIST of references, assembled here\n * rather than by VInput: the hint belongs to OUR row under the field, VInput having no\n * such row — its own counter sits inside the field.\n *\n * The counter is deliberately part of that list, unlike in VTextarea. When the files are\n * shown as chips the field's own text is EMPTY, and the counter is then the only spoken\n * summary of what has been chosen.\n */\nconst describedBy = computed(\n () =>\n [\n attrs['aria-describedby'] as string | undefined,\n props.hint ? hintId : undefined,\n props.counter ? counterId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined,\n)\n\n// The size, the density and the HEIGHT of the chips sitting inside the field, worked out\n// once in `utils/chip.ts` and shared with VCombobox. The height is set inline rather than\n// restated as a table of CSS rules: it belongs to the chips' own subtree, out of the\n// field's reach, and the field has to force its input to that same height or it grows\n// when focused.\nconst chipScale = computed(() => chipScaleFor(props.size, props.compact))\n\n/**\n * What a chip shows for a file. The name is shortened in the MIDDLE rather than cut off\n * at the end, for two reasons.\n *\n * The chips WRAP, so there is no line for a long name to overflow: left whole it would\n * simply push the field onto two or three rows. And cutting the middle preserves the\n * extension, which is what tells the reader what kind of file it is — an ellipsis at the\n * end drops it first.\n *\n * The full name is never lost: the removal button is named with it, and the chip carries\n * it as a tooltip whenever the label was actually shortened.\n */\nconst chipLabel = (file: File) => truncateMiddle(file.name)\n\nfunction onControlClick(event: MouseEvent) {\n // The field's own buttons already handle their clicks, and the click also reaches the\n // field itself. Without this guard the attach icon would open the dialog TWICE, and\n // the clear cross would reopen it immediately after emptying the selection.\n if ((event.target as HTMLElement).closest('button')) return\n openPicker()\n}\n\nfunction onFieldKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter' && event.key !== ' ') return\n // Cancelling the default on Enter also stops the form from being submitted: a\n // read-only text field is still a field, and Enter in one submits the form around it.\n event.preventDefault()\n openPicker()\n}\n\nfunction removeAt(index: number) {\n model.value = model.value.filter((_, i) => i !== index)\n resetNative()\n emit('change', model.value)\n // The removal button disappears along with its chip, so the focus would fall back to\n // the page body. Unlike the date and time pickers, nothing here opens on focus, so\n // this needs no guard against re-entering.\n inputRef.value?.focus()\n}\n\n/**\n * Empties the selection, and the hidden input with it — without that reset the same file\n * could not be chosen again straight afterwards.\n */\nfunction clearValue() {\n model.value = []\n resetNative()\n emit('clear')\n emit('change', model.value)\n}\n\n/* Files may be dropped on the component itself; there is no separate drop area here —\n that is what VFilePicker is for. */\nconst { dragging, onDragEnter, onDragOver, onDragLeave, onDrop } = useFileDrop(\n () => props.droppable && !props.disabled && !props.readonly,\n acceptFiles,\n)\n\n// @devwarn\nif (isDev) {\n watchEffect(() => {\n if (props.display === 'chip' && !props.multiple)\n console.warn(\n '[VFileInput] display=\"chip\" ignored without `multiple`: a single file shows as text.',\n )\n if (props.maxFiles !== undefined && !props.multiple)\n console.warn(\n '[VFileInput] `maxFiles` ignored without `multiple`: single mode already caps at one file.',\n )\n if (attrs.required !== undefined)\n console.warn(\n '[VFileInput] `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 })\n}\n\ndefineExpose({\n /** Moves the focus to the visible field. */\n focus: (options?: FocusOptions) => inputRef.value?.focus(options),\n /**\n * Opens the file dialog. It only works when called from something the reader did — a\n * click, a key press: browsers refuse to open a file dialog by themselves.\n */\n open: openPicker,\n})\n</script>\n\n<template>\n <div\n class=\"v-file-input\"\n :class=\"rootClass\"\n :style=\"[{ '--chip-height': chipScale.height }, rootStyle]\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-display=\"resolvedDisplay\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n :data-can-clear=\"canClear ? '' : undefined\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <input\n v-bind=\"nativeAttrs\"\n ref=\"fileEl\"\n type=\"file\"\n class=\"v-file-input-native\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :accept=\"accept\"\n :multiple=\"multiple || undefined\"\n :disabled=\"disabled || undefined\"\n @change=\"onNativeChange\"\n />\n\n <div class=\"v-file-input-control\" @click=\"onControlClick\">\n <VInput\n v-bind=\"fieldAttrs\"\n ref=\"inputRef\"\n :model-value=\"displayText\"\n readonly\n :label=\"label\"\n :placeholder=\"placeholderText\"\n :size=\"size\"\n :compact=\"compact\"\n :disabled=\"disabled\"\n :invalid=\"invalid\"\n :clearable=\"clearable\"\n :clear-visible=\"canClear\"\n :clear-label=\"m.fileInput.clear\"\n :icon-end=\"endIcon\"\n :icon-end-label=\"m.fileInput.attach\"\n :aria-describedby=\"describedBy\"\n @click:icon-end=\"openPicker\"\n @clear=\"clearValue\"\n @keydown=\"onFieldKeydown\"\n >\n <template v-if=\"resolvedDisplay === 'chip'\" #start>\n <template v-for=\"(file, index) in model\" :key=\"`${index}-${file.name}`\">\n <slot\n name=\"chip\"\n :file=\"file\"\n :index=\"index\"\n :label=\"chipLabel(file)\"\n :remove=\"() => removeAt(index)\"\n :size=\"chipScale.size\"\n :compact=\"chipScale.compact\"\n >\n <VChip\n tone=\"accent\"\n :size=\"chipScale.size\"\n :compact=\"chipScale.compact\"\n :dismissible=\"!readonly && !disabled\"\n :dismiss-label=\"m.fileInput.remove(file.name)\"\n :disabled=\"disabled\"\n :title=\"chipLabel(file) === file.name ? undefined : file.name\"\n @dismiss=\"removeAt(index)\"\n >{{ chipLabel(file) }}</VChip\n >\n </slot>\n </template>\n </template>\n </VInput>\n </div>\n\n <div v-if=\"hint || counter\" class=\"v-file-input-meta\">\n <VTypography\n v-if=\"hint\"\n :id=\"hintId\"\n variant=\"caption\"\n tone=\"muted\"\n class=\"v-file-input-hint\"\n >\n {{ hint }}\n </VTypography>\n <span v-if=\"counter\" :id=\"counterId\" class=\"v-file-input-counter\">\n <slot name=\"counter\" :count=\"model.length\" :size=\"totalSize\" :text=\"counterText\">\n {{ counterText }}\n </slot>\n </span>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /* Positioned so the hidden file input, which has no size at all, has something to be\n placed against. */\n .v-file-input {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n /* The real file input is a SOURCE of files and not a control anyone deals with. It is\n hidden with `opacity` and never with `display: none`, the design system's rule for a\n hidden form control, which has to stay submittable; it is given no size and made\n deaf to the pointer, so it can never swallow a click meant for the field. Taking it\n out of the tab order and hiding it from screen readers, in the template, is what\n leaves the visible field as the single stop and the single announcement. */\n .v-file-input-native {\n position: absolute;\n inline-size: 0;\n block-size: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n .v-file-input:not([data-disabled]):not([data-readonly]) .v-file-input-control,\n .v-file-input:not([data-disabled]):not([data-readonly])[data-display='text'] .v-input-control {\n cursor: pointer;\n }\n\n /* An ellipsis DOES work on an input, and a read-only one never scrolls by itself, so a\n long list of names is simply cut short. No tooltip is added for the rest: it would be\n announced as a description repeating the value the field already shows, and the\n complete list is what the model is for. */\n .v-file-input[data-display='text'] .v-input-control {\n text-overflow: ellipsis;\n }\n\n /* While a file is being dragged over it, the field is highlighted by redefining the\n very variable VInput uses for its own border colour — so the two can never disagree.\n The selector is one step more specific than VInput's, which is what makes it win\n whatever order the two sheets end up in. */\n .v-file-input[data-dragging] .v-input-field {\n --field-border-color: var(--vectis-color-accent);\n\n background: var(--vectis-color-accent-surface);\n }\n\n /* Shown as chips, the field holds them and lets them WRAP onto several rows, so it\n grows instead of scrolling.\n\n Two things have to be forced for that to hold together. The input inside is given\n the chips' own height rather than the full height it inherits, or its natural height\n would stretch every row it shares. And the padding at the end reserves exactly the\n room the icons take, since those are lifted out of the wrapping flow just below.\n\n That reservation is written as what the flow itself produces when the files are\n shown as text and nothing is lifted out: one glyph's width per action from the\n field's padding, one gap between two of them. It reads from the same two variables\n as the insets further down, so the room reserved and the glyphs it protects cannot\n drift apart. */\n .v-file-input[data-display='chip'] .v-input-field {\n position: relative;\n flex-wrap: wrap;\n height: auto;\n min-height: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline-end: calc(\n var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap)\n );\n }\n\n .v-file-input[data-display='chip'][data-can-clear] .v-input-field {\n padding-inline-end: calc(\n var(--control-padding-inline-field) + 2 * var(--vectis-icon-size) + 2 * var(--control-gap)\n );\n }\n\n .v-file-input[data-display='chip'] .v-input-control {\n height: var(--chip-height);\n }\n\n /* The two icons are lifted out of the wrapping flow — the same recipe VCombobox uses —\n so that they stay pinned to the end of the field and vertically centred whatever the\n chips do. VInput renders the clear cross FIRST and the end icon after it, which is\n why the icon has to be addressed by excluding the cross. */\n .v-file-input[data-display='chip'] .v-input-clear,\n .v-file-input[data-display='chip'] .v-input-action:not(.v-input-clear) {\n position: absolute;\n top: 50%;\n translate: 0 -50%;\n }\n\n .v-file-input[data-display='chip'] .v-input-action:not(.v-input-clear) {\n inset-inline-end: var(--control-padding-inline-field);\n }\n\n /* This is the ONE place where the spacing between the two icons has to be written by\n hand. Everywhere else the field's own flow produces it for free, and the two must\n agree, or the same component would show two different gaps depending on how the\n files are displayed.\n\n So it is written as exactly what that flow produces: the end icon occupies one\n glyph's width from the field's padding, then one gap separates the two.\n\n TRAP — this reads in GLYPHS and not in buttons. VInput gives its inner buttons a\n negative margin equal to half the difference between the two, which makes an inset\n land on the glyph's edge rather than on the button's. Measuring in button widths\n instead pushes the cross a whole gap too far, with nothing anywhere to signal it. */\n .v-file-input[data-display='chip'] .v-input-clear {\n inset-inline-end: calc(\n var(--control-padding-inline-field) + var(--vectis-icon-size) + var(--control-gap)\n );\n }\n\n .v-file-input-meta {\n display: flex;\n align-items: baseline;\n gap: var(--vectis-space-2);\n }\n\n /* The counter stays styled locally: tabular-nums is not a typographic role.\n No overflow state — an over-limit file never enters the model, so the\n counter cannot overflow. */\n .v-file-input-counter {\n margin-inline-start: auto;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n font-variant-numeric: tabular-nums;\n }\n\n .v-file-input[data-disabled] .v-file-input-hint,\n .v-file-input[data-disabled] .v-file-input-counter {\n color: var(--vectis-color-text-subtle);\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VFileInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VFileInput/VFileInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * File selection presented as an ordinary form field: a read-only VInput showing what was\n * picked, with the real file input hidden behind it — VDateInput's `readonly` shape, minus\n * the panel. The v-model is always a `File[]`, `multiple` or not, so a consumer never has to\n * narrow a union TypeScript cannot discriminate.\n *\n * The JS is imposed by the platform, not chosen. A dialog opens ONLY from a real click on a\n * file input, and a `FileList` cannot be written from a template — so the visible field can\n * never BE the native control, and that control is only ever a SOURCE of files.\n *\n * The rest follows: the relayed click, the reset after every change (without which the same\n * file cannot be picked twice running), and screening in code, `accept` having no say over\n * a drop.\n */\nimport { computed, inject, ref, useId } from 'vue'\n\nimport VChip from '../VChip/VChip.vue'\nimport type { ChipSize } from '../VChip/VChip.vue'\nimport { attach_file as attachFileIcon } from '../VIcon/icons/attach_file'\nimport type { IconSource } from '../VIcon/types'\nimport VInput from '../VInput/VInput.vue'\nimport { inputGroupKey } from '../VInput/context'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { canClear } from '../../composables/useClearable'\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useFileDrop } from '../../composables/useFileDrop'\nimport { useFileField } from '../../composables/useFileField'\nimport { iconStartListener } from '../../composables/useIconClickHandlers'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useLocale, useMessages } from '../../i18n/state'\nimport { chipScaleFor } from '../../utils/chip'\nimport { isDev } from '../../utils/env'\nimport { fileKey, formatBytes, type FileRejection } from '../../utils/file'\nimport { joinIds } from '../../utils/ids'\nimport { truncateMiddle } from './truncate'\n\n/** How the chosen files are shown inside the field when several are allowed. */\nexport type FileInputDisplay = 'text' | 'chip'\n\n/** The height of the field: 32, 40 or 48 pixels. */\nexport type FileInputSize = 'sm' | 'md' | 'lg'\n\ninterface FileInputProps {\n /** Allows several files to be chosen. With one only, every extra file is turned away. */\n multiple?: boolean\n /**\n * Which kinds of file are accepted, in the browser's own syntax (`image/*,.pdf`).\n *\n * It is applied TWICE, and it has to be: as an attribute, which is what filters the\n * system's file dialog, and again in code, which is the only thing that can filter a\n * file DROPPED on the component — the attribute has no say over a drop.\n */\n accept?: string\n /**\n * How the chosen files are shown: their names joined by commas, or one dismissible\n * chip each. It only means something when several files are allowed; a single name is\n * always text.\n */\n display?: FileInputDisplay\n /** The largest ONE file may be, in bytes. */\n maxSize?: number\n /** The largest the whole selection may be, in bytes. */\n maxTotalSize?: number\n /** How many files may be chosen at most. */\n maxFiles?: number\n /** Shows how much has been chosen under the field: \"3 files (1.2 MB)\". */\n counter?: boolean\n /** The icon at the end of the field, which opens the file dialog. */\n pickerIcon?: IconSource\n /** Refuses files dropped onto the component: only the dialog then adds any. */\n noDrop?: boolean\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: FileInputSize\n /** Takes 4px off the height, leaving the padding, the text and the icons as they are. */\n compact?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows what was chosen without allowing it to change: no dialog, no drop, no removal.\n */\n readonly?: boolean\n /**\n * Marks the field as invalid — for a rule of your own, since nothing here is checked\n * by the browser.\n */\n invalid?: boolean\n /** The label above the field, tied to it so that clicking it focuses the field. */\n label?: string\n /**\n * A line of help under the field, to the left of the counter. It is tied to the field\n * for assistive technology.\n */\n hint?: string\n /**\n * What the field says while nothing is chosen. It falls back to the design system\n * dictionary.\n */\n placeholder?: string\n /**\n * An icon inside the field, at the start. It is rendered before the chips rather than\n * in their place, so it survives a chip display. Decorative by default, it becomes a\n * real button as soon as a `@click:icon-start` listener is attached, in which case it\n * needs `iconStartLabel`.\n */\n iconStart?: IconSource\n /** What the start icon does, in words, once it is clickable. */\n iconStartLabel?: string\n /**\n * What the button at the end of the field does, in words. It names the button\n * `pickerIcon` renders, and falls back to the design system dictionary.\n */\n pickerIconLabel?: string\n /**\n * Shows a spinner at the end of the field, in place of the attach icon — while an\n * upload is under way, typically. It says that something is happening and changes\n * nothing else: files can still be dropped and the dialog still opens.\n */\n loading?: boolean\n /**\n * What screen readers announce while the spinner turns. It falls back to the design\n * system dictionary.\n */\n loadingLabel?: string\n /**\n * Offers a cross that empties the selection. Worth turning on here more than on an\n * ordinary field: what a picker holds cannot be erased by typing, so the cross is the\n * only way back out of a wrong choice.\n */\n clearable?: boolean\n /** What that cross does, in words. It falls back to the design system dictionary. */\n clearLabel?: string\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FileInputProps>(), {\n multiple: false,\n accept: undefined,\n display: 'text',\n maxSize: undefined,\n maxTotalSize: undefined,\n maxFiles: undefined,\n counter: false,\n pickerIcon: () => attachFileIcon,\n noDrop: false,\n size: 'md',\n compact: false,\n disabled: false,\n readonly: false,\n invalid: false,\n label: undefined,\n hint: undefined,\n placeholder: undefined,\n iconStart: undefined,\n iconStartLabel: undefined,\n pickerIconLabel: undefined,\n loading: false,\n loadingLabel: undefined,\n clearable: false,\n clearLabel: undefined,\n})\n\nconst emit = defineEmits<{\n /** The reader changed the selection — added something, removed something, cleared it. */\n change: [files: File[]]\n /**\n * A file was turned away and never joined the selection. It is emitted once PER file,\n * so a batch drop can be reported precisely.\n */\n reject: [rejection: FileRejection]\n /**\n * ONE file was taken out through its chip, with the file and the position it held.\n * `change` follows it with the whole list, as it does after every other change.\n */\n remove: [file: File, index: number]\n /** The clear cross emptied the selection. */\n clear: []\n /** The start icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-start': [event: MouseEvent]\n}>()\n\ndefineSlots<{\n /**\n * Content at the start of the field, rendered after the chips standing for the chosen\n * files rather than in their place.\n */\n start?(): unknown\n /**\n * Controls of your own inside the field, placed before the ones the field owns — the\n * clear cross and the icon that opens the file dialog. Those two are this component's\n * own affordance, which is why there is no `#end` here: it would replace them.\n */\n 'value-end'?(): unknown\n /**\n * Replaces the chip standing for one file.\n *\n * Three of the values it receives are what make it usable without regressions:\n * `label` is the name already shortened in the MIDDLE so that its extension survives,\n * `remove` is what takes the file out — without it the file could no longer be removed\n * at all — and the size and density are the ones worked out to sit inside the field,\n * which cannot be guessed from outside.\n */\n chip?(props: {\n file: File\n index: number\n label: string\n remove: () => void\n size: ChipSize\n compact: boolean\n }): unknown\n /**\n * Replaces the counter under the field. `text` is the sentence already built and\n * translated; the count and the total size in `bytes` are there for a wording of your own.\n */\n counter?(props: { count: number; bytes: number; text: string }): unknown\n}>()\n\n/**\n * Always a LIST of files, whether or not several are allowed — never a file on its own.\n * The shape of the value does not depend on a prop, so a consumer never has to narrow a\n * union TypeScript has no way of discriminating. With a single file it is simply a list\n * of at most one.\n */\nconst model = defineModel<File[]>({ default: () => [] })\n\nconst { attrs, rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// Declared as this component's own event, `click:icon-start` is out of `$attrs`, so the\n// listener is relayed to the field by hand — and only when the consumer wrote one.\nconst iconStartClick = iconStartListener((event) => emit('click:icon-start', event))\n\nconst m = useMessages()\nconst locale = useLocale()\n\n// A VInputGroup joins several controls into one object, so the shape of this field is the\n// row's decision rather than its own (VInput/context.ts). The chips read the resolved pair\n// too, or they would come out one step off the field they sit in.\nconst group = inject(inputGroupKey, null)\nconst {\n size: resolvedSize,\n compact: resolvedCompact,\n disabled: resolvedDisabled,\n} = useControlShape(props, group)\n\n/*\n * The hidden input, the sorting of the consumer's attributes, the single entry point into\n * the value, the removal of a file and the emptying of all of them live in `useFileField`,\n * shared with VFilePicker.\n *\n * Here, the bucket meant for \"the control the user deals with\" goes to the visible\n * field: that is what they see, focus and click, so a consumer's own `<label for>` has\n * to point at it. The description attribute is pulled out of that bucket, because this\n * component re-assembles it further down.\n */\nconst {\n fileEl,\n enabled,\n nativeInputAttrs,\n controlAttrs,\n acceptFiles,\n openPicker,\n removeAt,\n clear,\n} = useFileField({\n model,\n props,\n emit,\n forwardedAttrs,\n disabled: resolvedDisabled,\n excludeFromControl: ['aria-describedby'],\n onClear: () => emit('clear'),\n // Behind `isDev`, which a production build folds to false, so the message is dropped.\n warnings: isDev\n ? () => [\n props.display === 'chip' &&\n !props.multiple &&\n 'display=\"chip\" ignored without `multiple`: a single file shows as text.',\n ]\n : undefined,\n})\n\n/** What reaches the visible field: the consumer's own attributes, plus that listener. */\nconst fieldAttrs = computed(() => ({ ...controlAttrs.value, ...iconStartClick }))\n\nconst inputRef = ref<InstanceType<typeof VInput> | null>(null)\nconst rootEl = ref<HTMLElement | null>(null)\n\n// Chips only mean something for a list: a single file always shows as plain text.\nconst resolvedDisplay = computed<FileInputDisplay>(() => (props.multiple ? props.display : 'text'))\n\nconst displayText = computed(() =>\n resolvedDisplay.value === 'chip' ? '' : model.value.map((file) => file.name).join(', '),\n)\n\nconst placeholderText = computed(() =>\n model.value.length > 0 ? undefined : (props.placeholder ?? m.value.fileInput.placeholder),\n)\n\n/*\n * Whether the clear cross is shown has to be answered EXPLICITLY here. The visible field\n * is read-only, and a read-only field hides its cross by default — rightly so, since its\n * text cannot be edited. Here the value comes from the file dialog rather than from\n * typing, so there is something to clear all the same.\n */\nconst clearVisible = computed(() => canClear(props, resolvedDisabled.value, model.value.length > 0))\n\n// @a11y @devwarn\n/*\n * The icon disappears along with what it offers: a read-only field opens no dialog, so\n * an icon inviting one would be a lie — the same rule VDateInput follows for its\n * calendar.\n *\n * TRAP — its LABEL stays defined at all times, even when no icon is rendered. The helper\n * that detects a click handler on an icon warns AT SETUP if one is attached without a\n * label, and it has no way of knowing whether an icon exists.\n */\nconst endIcon = computed<IconSource | undefined>(() =>\n props.readonly ? undefined : props.pickerIcon,\n)\nconst endIconLabel = computed(() => props.pickerIconLabel ?? m.value.fileInput.openPicker)\nconst resolvedClearLabel = computed(() => props.clearLabel ?? m.value.fileInput.clear)\n\nconst totalSize = computed(() => model.value.reduce((sum, file) => sum + file.size, 0))\n\n/*\n * The counter is assembled from three sources: the WORD comes from the dictionary, since\n * it is language; the SIZE is formatted by the platform, which knows the local\n * conventions; and the parentheses come from neither, being punctuation every language\n * shares — the same boundary VBadge's \"99+\" falls on.\n *\n * With nothing chosen it states the count alone: \"0 files ()\" would be noise.\n */\nconst counterText = computed(() => {\n const word = m.value.fileInput.files(model.value.length)\n return model.value.length === 0 ? word : `${word} (${formatBytes(totalSize.value, locale.value)})`\n})\n\nconst hintId = useId()\nconst counterId = useId()\n\n// @a11y\n/*\n * What describes the field for a screen reader is a LIST of references, assembled here\n * rather than by VInput: the hint belongs to OUR row under the field, VInput having no\n * such row — its own counter sits inside the field.\n *\n * The counter is deliberately part of that list, unlike in VTextarea. When the files are\n * shown as chips the field's own text is EMPTY, and the counter is then the only spoken\n * summary of what has been chosen.\n */\nconst describedBy = computed(() =>\n joinIds(\n attrs['aria-describedby'] as string | undefined,\n !!props.hint && hintId,\n props.counter && counterId,\n ),\n)\n\n// The size, the density and the HEIGHT of the chips sitting inside the field, worked out\n// once in `utils/chip.ts` and shared with VCombobox. The height is set inline rather than\n// restated as a table of CSS rules: it belongs to the chips' own subtree, out of the\n// field's reach, and the field has to force its input to that same height or it grows\n// when focused.\nconst chipScale = computed(() => chipScaleFor(resolvedSize.value, resolvedCompact.value))\n\n/**\n * What each chip shows for its file, worked out once per change of the selection rather\n * than on every render, which reads it three times per chip. The name is shortened in the\n * MIDDLE rather than cut off at the end, for two reasons.\n *\n * The chips WRAP, so there is no line for a long name to overflow: left whole it would\n * simply push the field onto two or three rows. And cutting the middle preserves the\n * extension, which is what tells the reader what kind of file it is — an ellipsis at the\n * end drops it first.\n *\n * The full name is never lost: the removal button is named with it, and the chip carries\n * it as a tooltip whenever the label was actually shortened.\n */\n// Computed lazily, so a text display, which never reads it, never pays for it.\nconst chipLabels = computed(() => model.value.map((file) => truncateMiddle(file.name)))\n\nfunction onControlClick(event: MouseEvent) {\n // The field's own buttons already handle their clicks, and the click also reaches the\n // field itself. Without this guard the attach icon would open the dialog TWICE, and\n // the clear cross would reopen it immediately after emptying the selection.\n if ((event.target as HTMLElement).closest('button')) return\n openPicker()\n}\n\nfunction onFieldKeydown(event: KeyboardEvent) {\n if (event.key !== 'Enter' && event.key !== ' ') return\n // Cancelling the default on Enter also stops the form from being submitted: a\n // read-only text field is still a field, and Enter in one submits the form around it.\n event.preventDefault()\n openPicker()\n}\n\nfunction removeFile(index: number) {\n // The removal button disappears along with its chip, so the focus would fall back to\n // the page body. Unlike the date and time pickers, nothing here opens on focus, so\n // this needs no guard against re-entering.\n if (removeAt(index)) inputRef.value?.focus()\n}\n\n/* Files may be dropped on the component itself; there is no separate drop area here —\n that is what VFilePicker is for. */\nconst { dragging, onDragEnter, onDragOver, onDragLeave, onDrop } = useFileDrop(\n () => !props.noDrop && enabled.value,\n acceptFiles,\n)\n\ndefineExpose({\n /** Moves the focus to the visible field. */\n focus: (options?: FocusOptions) => inputRef.value?.focus(options),\n /**\n * Opens the file dialog. It only works when called from something the reader did — a\n * click, a key press: browsers refuse to open a file dialog by themselves.\n */\n open: openPicker,\n /**\n * The component's own box, for what neither of the two above covers. It is the wrapper\n * and not the hidden file input: that one is the FORM's element, this is the reader's.\n */\n el: rootEl,\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-file-input\"\n :class=\"rootClass\"\n :style=\"[{ '--chip-height': chipScale.height }, rootStyle]\"\n :data-size=\"resolvedSize\"\n :data-compact=\"resolvedCompact ? '' : undefined\"\n :data-display=\"resolvedDisplay\"\n :data-disabled=\"resolvedDisabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <input v-bind=\"nativeInputAttrs\" ref=\"fileEl\" class=\"v-file-input-native v-hidden-input\" />\n\n <div class=\"v-file-input-control\" @click=\"onControlClick\">\n <!-- Shown as chips, the field takes VInput's two arrangements for chips: its end\n controls lifted out of the flow, and the chips wrapping onto several rows. -->\n <VInput\n v-bind=\"fieldAttrs\"\n ref=\"inputRef\"\n :class=\"{ 'v-input-end-pinned v-input-chips': resolvedDisplay === 'chip' }\"\n :model-value=\"displayText\"\n readonly\n :label=\"label\"\n :placeholder=\"placeholderText\"\n :size=\"resolvedSize\"\n :compact=\"resolvedCompact\"\n :disabled=\"resolvedDisabled\"\n :invalid=\"invalid\"\n :clearable=\"clearable\"\n :clear-visible=\"clearVisible\"\n :clear-label=\"resolvedClearLabel\"\n :icon-start=\"iconStart\"\n :icon-start-label=\"iconStartLabel\"\n :loading=\"loading\"\n :loading-label=\"loadingLabel\"\n :icon-end=\"endIcon\"\n :icon-end-label=\"endIconLabel\"\n :aria-describedby=\"describedBy\"\n @click:icon-end=\"openPicker\"\n @clear=\"clear\"\n @keydown=\"onFieldKeydown\"\n >\n <template v-if=\"resolvedDisplay === 'chip' || $slots.start\" #start>\n <template\n v-for=\"(file, index) in resolvedDisplay === 'chip' ? model : []\"\n :key=\"fileKey(file)\"\n >\n <slot\n name=\"chip\"\n :file=\"file\"\n :index=\"index\"\n :label=\"chipLabels[index]!\"\n :remove=\"() => removeFile(index)\"\n :size=\"chipScale.size\"\n :compact=\"chipScale.compact\"\n >\n <VChip\n tone=\"accent\"\n :size=\"chipScale.size\"\n :compact=\"chipScale.compact\"\n :dismissible=\"enabled\"\n :dismiss-label=\"m.common.remove(file.name)\"\n :disabled=\"resolvedDisabled\"\n :title=\"chipLabels[index] === file.name ? undefined : file.name\"\n @dismiss=\"removeFile(index)\"\n >{{ chipLabels[index] }}</VChip\n >\n </slot>\n </template>\n <slot name=\"start\" />\n </template>\n\n <template v-if=\"$slots['value-end']\" #value-end><slot name=\"value-end\" /></template>\n </VInput>\n </div>\n\n <div v-if=\"hint || counter\" class=\"v-file-input-meta v-field-meta\">\n <VTypography\n v-if=\"hint\"\n :id=\"hintId\"\n variant=\"caption\"\n tone=\"muted\"\n class=\"v-file-input-hint\"\n >\n {{ hint }}\n </VTypography>\n <span v-if=\"counter\" :id=\"counterId\" class=\"v-file-input-counter v-field-counter\">\n <slot name=\"counter\" :count=\"model.length\" :bytes=\"totalSize\" :text=\"counterText\">\n {{ counterText }}\n </slot>\n </span>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /* Positioned so the hidden file input, which has no size at all, has something to be\n placed against. */\n .v-file-input {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-1);\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n /* The real file input is a SOURCE of files and not a control anyone deals with: it\n wears `.v-hidden-input`, and taking it out of the tab order and hiding it from screen\n readers, in `useFileField`, is what leaves the visible field as the single stop and the\n single announcement. */\n .v-file-input:not([data-disabled]):not([data-readonly]) .v-file-input-control,\n .v-file-input:not([data-disabled]):not([data-readonly])[data-display='text'] .v-input-control {\n cursor: pointer;\n }\n\n /* An ellipsis DOES work on an input, and a read-only one never scrolls by itself, so a\n long list of names is simply cut short. No tooltip is added for the rest: it would be\n announced as a description repeating the value the field already shows, and the\n complete list is what the model is for. */\n .v-file-input[data-display='text'] .v-input-control {\n text-overflow: ellipsis;\n }\n\n /* While a file is being dragged over it, the field is highlighted by redefining the\n very variable VInput uses for its own border colour — so the two can never disagree.\n\n TRAP — the selector weighs (0,4,0), one step above VInput's states, and it has to. The\n field inside is ALWAYS read-only, and VInput's read-only background weighs (0,3,0): at\n that weight the winner would be whichever of the two sheets a bundler put last. */\n .v-file-input[data-dragging] .v-input .v-input-field {\n --field-border-color: var(--vectis-color-accent);\n\n background: var(--vectis-color-accent-surface);\n }\n\n .v-file-input[data-disabled] .v-file-input-hint,\n .v-file-input[data-disabled] .v-file-input-counter {\n color: var(--vectis-color-text-subtle);\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  @layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
2
- @layer vectis.components{.v-file-picker{--file-picker-border-color:var(--vectis-color-border-strong);--file-picker-bg:var(--vectis-color-surface-sunken);--file-picker-text:var(--vectis-color-text);--file-picker-text-muted:var(--vectis-color-text-muted);--file-picker-row-bg:var(--vectis-color-surface-raised);--file-picker-thumb-bg:var(--vectis-color-surface-muted);inline-size:100%;font-family:var(--vectis-text-family);display:block;position:relative}.v-file-picker-native{opacity:0;pointer-events:none;block-size:0;inline-size:0;position:absolute}.v-file-picker-body{gap:var(--vectis-space-4);flex-direction:column;display:flex}.v-file-picker-zone{justify-content:center;align-items:center;gap:var(--vectis-space-2);inline-size:100%;min-block-size:var(--vectis-control-size-file-picker-min-block);padding:var(--vectis-space-6) var(--vectis-space-4);appearance:none;border:1px dashed var(--file-picker-border-color);border-radius:var(--vectis-radius-surface);background:var(--file-picker-bg);color:var(--file-picker-text);font:inherit;text-align:center;transition:border-color var(--vectis-duration-fast) var(--vectis-ease-default), background-color var(--vectis-duration-fast) var(--vectis-ease-default);flex-direction:column;margin:0;display:flex}.v-file-picker:not([data-disabled]):not([data-readonly]) .v-file-picker-zone{cursor:pointer}.v-file-picker:not([data-disabled]):not([data-readonly]) .v-file-picker-zone:hover{--file-picker-border-color:var(--vectis-color-accent)}.v-file-picker-zone:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:var(--vectis-focus-ring-offset)}.v-file-picker[data-dragging]{--file-picker-border-color:var(--vectis-color-accent);--file-picker-bg:var(--vectis-color-accent-surface)}.v-file-picker-icon{--vectis-icon-size:var(--vectis-control-size-file-picker-icon);color:var(--file-picker-text-muted);display:inline-flex}.v-file-picker-subtitle{--typography-color:var(--file-picker-text-muted)}.v-file-picker-separator{align-items:center;gap:var(--vectis-space-3);inline-size:100%;color:var(--file-picker-text-muted);font-size:var(--vectis-text-caption-size);margin-block-start:var(--vectis-space-2);display:flex}.v-file-picker-separator:before,.v-file-picker-separator:after{content:"";border-block-start:1px solid var(--vectis-color-border);flex:1 1 0}.v-file-picker-list{gap:var(--vectis-space-2);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.v-file-picker-item{align-items:center;gap:var(--vectis-space-3);padding:var(--vectis-space-2);border:1px solid var(--vectis-color-border);border-radius:var(--vectis-radius-interactive);background:var(--file-picker-row-bg);display:flex}.v-file-picker-thumb{inline-size:var(--vectis-control-size-file-picker-thumb);block-size:var(--vectis-control-size-file-picker-thumb);border-radius:var(--vectis-radius-interactive);background:var(--file-picker-thumb-bg);color:var(--file-picker-text-muted);flex:none;justify-content:center;align-items:center;display:inline-flex;overflow:hidden}.v-file-picker-image{object-fit:cover;block-size:100%;inline-size:100%;display:block}.v-file-picker-info{min-inline-size:0;color:var(--file-picker-text);flex-direction:column;flex:auto;display:flex}.v-file-picker-name{font-size:var(--vectis-text-body-sm-size);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.v-file-picker-size{color:var(--file-picker-text-muted);font-size:var(--vectis-text-caption-size);font-variant-numeric:tabular-nums}.v-file-picker[data-preview=end]{container:v-file-picker/inline-size}.v-file-picker[data-preview=end] .v-file-picker-body{flex-direction:row;align-items:flex-start}.v-file-picker[data-preview=end] .v-file-picker-zone,.v-file-picker[data-preview=end] .v-file-picker-list{flex:1 1 0;min-inline-size:0}@container v-file-picker (width<=34rem){.v-file-picker[data-preview=end] .v-file-picker-body{flex-direction:column}}.v-file-picker[data-disabled]{--file-picker-border-color:var(--vectis-color-border);--file-picker-bg:var(--vectis-color-surface-muted);--file-picker-text:var(--vectis-color-text-muted);--file-picker-text-muted:var(--vectis-color-text-muted);--file-picker-row-bg:var(--vectis-color-surface-muted)}.v-file-picker[data-readonly]{--file-picker-border-color:var(--vectis-color-border)}@media (prefers-reduced-motion:reduce){.v-file-picker-zone{transition:none}}@media (forced-colors:active){.v-file-picker[data-dragging] .v-file-picker-zone{border-style:solid}.v-file-picker-thumb{border:1px solid}}}
2
+ @layer vectis.components{.v-file-picker{--file-picker-border-color:var(--vectis-color-border-strong);--file-picker-bg:var(--vectis-color-surface-sunken);--file-picker-text:var(--vectis-color-text);--file-picker-text-muted:var(--vectis-color-text-muted);--file-picker-row-bg:var(--vectis-color-surface-raised);--file-picker-thumb-bg:var(--vectis-color-surface-muted);inline-size:100%;font-family:var(--vectis-text-family);display:block;position:relative}.v-file-picker-body{gap:var(--vectis-space-4);flex-direction:column;display:flex}.v-file-picker-zone{justify-content:center;align-items:center;gap:var(--vectis-space-2);inline-size:100%;min-block-size:var(--vectis-control-size-file-picker-min-block);padding:var(--vectis-space-6) var(--vectis-space-4);appearance:none;border:1px dashed var(--file-picker-border-color);border-radius:var(--vectis-radius-surface);background:var(--file-picker-bg);color:var(--file-picker-text);font:inherit;text-align:center;transition:border-color var(--vectis-duration-fast) var(--vectis-ease-default), background-color var(--vectis-duration-fast) var(--vectis-ease-default);flex-direction:column;margin:0;display:flex}.v-file-picker:not([data-disabled]):not([data-readonly]) .v-file-picker-zone{cursor:pointer}.v-file-picker:not([data-disabled]):not([data-readonly]) .v-file-picker-zone:hover{--file-picker-border-color:var(--vectis-color-accent)}.v-file-picker[data-invalid] .v-file-picker-zone{--file-picker-border-color:var(--vectis-color-danger)}.v-file-picker-zone:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:var(--vectis-focus-ring-offset)}.v-file-picker[data-dragging]{--file-picker-border-color:var(--vectis-color-accent);--file-picker-bg:var(--vectis-color-accent-surface)}.v-file-picker-icon{--vectis-icon-size:var(--vectis-control-size-file-picker-icon);min-inline-size:var(--vectis-control-size-file-picker-icon);min-block-size:var(--vectis-control-size-file-picker-icon);color:var(--file-picker-text-muted);justify-content:center;align-items:center;display:inline-flex}.v-file-picker-icon>.v-spinner{font-size:var(--vectis-icon-size)}.v-file-picker-subtitle{--typography-color:var(--file-picker-text-muted)}.v-file-picker-separator{align-items:center;gap:var(--vectis-space-3);inline-size:100%;color:var(--file-picker-text-muted);font-size:var(--vectis-text-caption-size);margin-block-start:var(--vectis-space-2);display:flex}.v-file-picker-separator:before,.v-file-picker-separator:after{content:"";border-block-start:1px solid var(--vectis-color-border);flex:1 1 0}.v-file-picker-list{gap:var(--vectis-space-2);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.v-file-picker-item{align-items:center;gap:var(--vectis-space-3);padding:var(--vectis-space-2);border:1px solid var(--vectis-color-border);border-radius:var(--vectis-radius-interactive);background:var(--file-picker-row-bg);display:flex}.v-file-picker-thumb{inline-size:var(--vectis-control-size-file-picker-thumb);block-size:var(--vectis-control-size-file-picker-thumb);border-radius:var(--vectis-radius-interactive);background:var(--file-picker-thumb-bg);color:var(--file-picker-text-muted);flex:none;justify-content:center;align-items:center;display:inline-flex;overflow:hidden}.v-file-picker-image{object-fit:cover;block-size:100%;inline-size:100%;display:block}.v-file-picker-info{min-inline-size:0;color:var(--file-picker-text);flex-direction:column;flex:auto;display:flex}.v-file-picker-name{font-size:var(--vectis-text-body-sm-size);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.v-file-picker-size{color:var(--file-picker-text-muted);font-size:var(--vectis-text-caption-size);font-variant-numeric:tabular-nums}.v-file-picker[data-preview=end]{container:v-file-picker/inline-size}.v-file-picker[data-preview=end] .v-file-picker-body{flex-direction:row;align-items:flex-start}.v-file-picker[data-preview=end] .v-file-picker-zone,.v-file-picker[data-preview=end] .v-file-picker-list{flex:1 1 0;min-inline-size:0}@container v-file-picker (width<=34rem){.v-file-picker[data-preview=end] .v-file-picker-body{flex-direction:column}}.v-file-picker[data-disabled]{--file-picker-border-color:var(--vectis-color-border);--file-picker-bg:var(--vectis-color-surface-muted);--file-picker-text:var(--vectis-color-text-muted);--file-picker-text-muted:var(--vectis-color-text-muted);--file-picker-row-bg:var(--vectis-color-surface-muted)}.v-file-picker[data-readonly]{--file-picker-border-color:var(--vectis-color-border)}@media (prefers-reduced-motion:reduce){.v-file-picker-zone{transition:none}}@media (forced-colors:active){.v-file-picker[data-dragging] .v-file-picker-zone{border-style:solid}.v-file-picker-thumb{border:1px solid}}}