vectis-ui 0.8.1 → 0.9.1

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 (432) hide show
  1. package/README.md +3 -3
  2. package/dist/components/VAccordion/VAccordionItem.d.ts +4 -6
  3. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  4. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +21 -19
  5. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/VAccordion/context.d.ts +6 -1
  7. package/dist/components/VAccordion/context.js.map +1 -1
  8. package/dist/components/VAvatar/VAvatar.css +1 -1
  9. package/dist/components/VAvatar/VAvatar.d.ts +5 -3
  10. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  11. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +53 -39
  12. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/VAvatar/VAvatarGroup.d.ts +12 -3
  14. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  15. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +27 -20
  16. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/VAvatar/context.d.ts +2 -2
  18. package/dist/components/VAvatar/context.js.map +1 -1
  19. package/dist/components/VBadge/VBadge.css +1 -1
  20. package/dist/components/VBadge/VBadge.d.ts +8 -4
  21. package/dist/components/VBadge/VBadge.js.map +1 -1
  22. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +6 -3
  23. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +5 -4
  25. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  26. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +8 -3
  27. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/VButton/VButton.css +1 -1
  29. package/dist/components/VButton/VButton.d.ts +4 -1
  30. package/dist/components/VButton/VButton.js.map +1 -1
  31. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +8 -7
  32. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  34. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/VCalendar/VCalendar.css +1 -1
  36. package/dist/components/VCalendar/VCalendar.d.ts +15 -6
  37. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  38. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +144 -126
  39. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/VCalendar/VCalendarEvent.css +1 -1
  41. package/dist/components/VCalendar/VCalendarEvent.d.ts +1 -1
  42. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  43. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  44. package/dist/components/VCalendar/VCalendarMonth.css +1 -1
  45. package/dist/components/VCalendar/VCalendarMonth.d.ts +1 -1
  46. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  47. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +99 -90
  48. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
  50. package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +3 -3
  51. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  52. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +256 -246
  53. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  54. package/dist/components/VCalendar/VCalendarYear.css +1 -1
  55. package/dist/components/VCalendar/VCalendarYear.d.ts +8 -1
  56. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  57. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +39 -32
  58. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/VCalendar/color.d.ts +1 -1
  60. package/dist/components/VCalendar/color.js.map +1 -1
  61. package/dist/components/VCalendar/edgeStep.d.ts +3 -3
  62. package/dist/components/VCalendar/edgeStep.js +5 -0
  63. package/dist/components/VCalendar/edgeStep.js.map +1 -1
  64. package/dist/components/VCalendar/gesture.d.ts +10 -9
  65. package/dist/components/VCalendar/gesture.js +60 -45
  66. package/dist/components/VCalendar/gesture.js.map +1 -1
  67. package/dist/components/VCalendar/keyboard.d.ts +22 -5
  68. package/dist/components/VCalendar/keyboard.js +17 -16
  69. package/dist/components/VCalendar/keyboard.js.map +1 -1
  70. package/dist/components/VCalendar/layout.d.ts +47 -37
  71. package/dist/components/VCalendar/layout.js +47 -37
  72. package/dist/components/VCalendar/layout.js.map +1 -1
  73. package/dist/components/VCalendar/timeGrid.d.ts +4 -4
  74. package/dist/components/VCalendar/timeGrid.js +6 -6
  75. package/dist/components/VCalendar/timeGrid.js.map +1 -1
  76. package/dist/components/VCalendar/types.d.ts +5 -5
  77. package/dist/components/VCarousel/VCarousel.css +1 -1
  78. package/dist/components/VCarousel/VCarousel.d.ts +59 -38
  79. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  80. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +161 -132
  81. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  82. package/dist/components/VCarousel/VCarouselItem.d.ts +1 -1
  83. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  84. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/VCarousel/context.d.ts +1 -1
  86. package/dist/components/VCarousel/context.js.map +1 -1
  87. package/dist/components/VCheckbox/VCheckbox.css +1 -1
  88. package/dist/components/VCheckbox/VCheckbox.d.ts +2 -2
  89. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  90. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +10 -8
  91. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  92. package/dist/components/VChip/VChip.css +1 -1
  93. package/dist/components/VChip/VChip.d.ts +7 -2
  94. package/dist/components/VChip/VChip.js.map +1 -1
  95. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +69 -55
  96. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/components/VCombobox/VCombobox.css +1 -1
  98. package/dist/components/VCombobox/VCombobox.d.ts +50 -36
  99. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  100. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +167 -161
  101. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  102. package/dist/components/VCombobox/VComboboxGroup.css +1 -1
  103. package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
  104. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  105. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  106. package/dist/components/VCombobox/infiniteScroll.d.ts +12 -3
  107. package/dist/components/VCombobox/infiniteScroll.js +18 -12
  108. package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
  109. package/dist/components/VDataTable/VDataTable.css +1 -1
  110. package/dist/components/VDataTable/VDataTable.d.ts +55 -24
  111. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  112. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +192 -155
  113. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/VDateInput/VDateInput.css +1 -1
  115. package/dist/components/VDateInput/VDateInput.d.ts +15 -12
  116. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  117. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +180 -160
  118. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  119. package/dist/components/VDateInput/mask.d.ts +95 -0
  120. package/dist/components/VDateInput/mask.js +118 -0
  121. package/dist/components/VDateInput/mask.js.map +1 -0
  122. package/dist/components/VDatePicker/VDatePicker.css +1 -1
  123. package/dist/components/VDatePicker/VDatePicker.d.ts +6 -5
  124. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  125. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +204 -173
  126. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/VDatePicker/keyboard.d.ts +3 -3
  128. package/dist/components/VDatePicker/keyboard.js.map +1 -1
  129. package/dist/components/VDatePicker/names.d.ts +34 -0
  130. package/dist/components/VDatePicker/names.js +42 -0
  131. package/dist/components/VDatePicker/names.js.map +1 -0
  132. package/dist/components/VDialog/VDialog.css +1 -1
  133. package/dist/components/VDialog/VDialog.d.ts +2 -2
  134. package/dist/components/VDialog/VDialog.js.map +1 -1
  135. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +63 -41
  136. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  137. package/dist/components/VFileInput/VFileInput.d.ts +38 -25
  138. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  139. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +74 -71
  140. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/VFileInput/truncate.d.ts +4 -4
  142. package/dist/components/VFileInput/truncate.js.map +1 -1
  143. package/dist/components/VFilePicker/VFilePicker.css +1 -1
  144. package/dist/components/VFilePicker/VFilePicker.d.ts +54 -37
  145. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  146. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +152 -135
  147. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  148. package/dist/components/VFilePicker/fileKind.d.ts +2 -2
  149. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  150. package/dist/components/VHotkeys/VHotkeys.css +1 -1
  151. package/dist/components/VHotkeys/VHotkeys.d.ts +10 -8
  152. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  153. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +22 -20
  154. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/VHotkeys/platform.d.ts +9 -7
  156. package/dist/components/VHotkeys/platform.js +41 -30
  157. package/dist/components/VHotkeys/platform.js.map +1 -1
  158. package/dist/components/VIcon/VIcon.css +1 -1
  159. package/dist/components/VIcon/VIcon.d.ts +6 -6
  160. package/dist/components/VIcon/VIcon.js.map +1 -1
  161. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  162. package/dist/components/VIcon/iconProps.d.ts +4 -4
  163. package/dist/components/VIcon/iconProps.js.map +1 -1
  164. package/dist/components/VIcon/icons/index.d.ts +1 -1
  165. package/dist/components/VIcon/icons/index.js.map +1 -1
  166. package/dist/components/VIcon/icons/names.d.ts +1 -1
  167. package/dist/components/VIcon/icons/names.js.map +1 -1
  168. package/dist/components/VIcon/resolver.d.ts +3 -3
  169. package/dist/components/VIcon/resolver.js +23 -20
  170. package/dist/components/VIcon/resolver.js.map +1 -1
  171. package/dist/components/VIcon/types.d.ts +4 -4
  172. package/dist/components/VIconButton/VIconButton.d.ts +4 -4
  173. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  174. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  175. package/dist/components/VInput/VInput.d.ts +16 -8
  176. package/dist/components/VInput/VInput.js.map +1 -1
  177. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +22 -16
  178. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/components/VInput/VInputGroup.css +1 -1
  180. package/dist/components/VInput/VInputGroup.js.map +1 -1
  181. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +43 -28
  182. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  183. package/dist/components/VInputOTP/VInputOTP.css +1 -1
  184. package/dist/components/VInputOTP/VInputOTP.d.ts +3 -3
  185. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  186. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +152 -85
  187. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  188. package/dist/components/VMenu/VMenu.d.ts +4 -4
  189. package/dist/components/VMenu/VMenu.js.map +1 -1
  190. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/components/VMenu/VMenuGroup.css +1 -1
  192. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  193. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +18 -11
  194. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  195. package/dist/components/VMenu/VMenuItem.css +1 -1
  196. package/dist/components/VMenu/VMenuItem.d.ts +6 -6
  197. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  198. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +83 -69
  199. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  200. package/dist/components/VMenu/VMenuPanel.css +1 -1
  201. package/dist/components/VMenu/VMenuPanel.d.ts +2 -2
  202. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  203. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +56 -55
  204. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  205. package/dist/components/VMenu/context.d.ts +2 -2
  206. package/dist/components/VMenu/context.js.map +1 -1
  207. package/dist/components/VPagination/VPagination.css +1 -1
  208. package/dist/components/VPagination/VPagination.d.ts +31 -9
  209. package/dist/components/VPagination/VPagination.js.map +1 -1
  210. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +82 -52
  211. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  212. package/dist/components/VPopover/VPopover.css +1 -1
  213. package/dist/components/VPopover/VPopover.d.ts +1 -1
  214. package/dist/components/VPopover/VPopover.js.map +1 -1
  215. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  216. package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
  217. package/dist/components/VProgressCircular/VProgressCircular.d.ts +12 -7
  218. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  219. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
  221. package/dist/components/VProgressLinear/VProgressLinear.d.ts +15 -10
  222. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  223. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  224. package/dist/components/VRadio/VRadio.css +1 -1
  225. package/dist/components/VRadio/VRadio.js.map +1 -1
  226. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +3 -3
  227. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  228. package/dist/components/VSeparator/VSeparator.d.ts +1 -1
  229. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  230. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/components/VSideNavigation/VSideNavigation.d.ts +2 -2
  232. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  233. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +1 -1
  234. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  235. package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
  236. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  237. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  238. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  239. package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
  240. package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +12 -13
  241. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  242. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +87 -68
  243. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
  245. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +10 -7
  246. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  247. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +5 -5
  248. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  249. package/dist/components/VSlider/VSlider.css +1 -1
  250. package/dist/components/VSlider/VSlider.d.ts +21 -7
  251. package/dist/components/VSlider/VSlider.js.map +1 -1
  252. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +159 -140
  253. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  254. package/dist/components/VSnackbar/VSnackbar.css +1 -1
  255. package/dist/components/VSnackbar/VSnackbar.d.ts +4 -4
  256. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  257. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +85 -59
  258. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  259. package/dist/components/VSnackbar/state.d.ts +7 -7
  260. package/dist/components/VSnackbar/state.js +13 -11
  261. package/dist/components/VSnackbar/state.js.map +1 -1
  262. package/dist/components/VSpinner/VSpinner.css +1 -1
  263. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  264. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  265. package/dist/components/VSwitch/VSwitch.css +1 -1
  266. package/dist/components/VSwitch/VSwitch.d.ts +1 -1
  267. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  268. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +4 -4
  269. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  270. package/dist/components/VTabs/VTab.css +1 -1
  271. package/dist/components/VTabs/VTab.d.ts +4 -0
  272. package/dist/components/VTabs/VTab.js.map +1 -1
  273. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +9 -8
  274. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  275. package/dist/components/VTabs/VTabs.css +1 -1
  276. package/dist/components/VTabs/VTabs.d.ts +17 -7
  277. package/dist/components/VTabs/VTabs.js.map +1 -1
  278. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +84 -77
  279. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  280. package/dist/components/VTextarea/VTextarea.d.ts +8 -8
  281. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  282. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +71 -69
  283. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  284. package/dist/components/VTimeInput/VTimeInput.css +1 -1
  285. package/dist/components/VTimeInput/VTimeInput.d.ts +21 -12
  286. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  287. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +230 -206
  288. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  289. package/dist/components/VTimeInput/search.d.ts +17 -2
  290. package/dist/components/VTimeInput/search.js +19 -9
  291. package/dist/components/VTimeInput/search.js.map +1 -1
  292. package/dist/components/VTimePicker/VTimePicker.css +1 -1
  293. package/dist/components/VTimePicker/VTimePicker.d.ts +8 -7
  294. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  295. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +128 -106
  296. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  297. package/dist/components/VTimePicker/limits.d.ts +11 -4
  298. package/dist/components/VTimePicker/limits.js +3 -2
  299. package/dist/components/VTimePicker/limits.js.map +1 -1
  300. package/dist/components/VToast/VToast.css +1 -1
  301. package/dist/components/VToast/VToast.js.map +1 -1
  302. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +33 -37
  303. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  304. package/dist/components/VToast/VToaster.js.map +1 -1
  305. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +91 -61
  306. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  307. package/dist/components/VToast/state.d.ts +8 -6
  308. package/dist/components/VToast/state.js +15 -13
  309. package/dist/components/VToast/state.js.map +1 -1
  310. package/dist/components/VToggle/VToggle.css +1 -1
  311. package/dist/components/VToggle/VToggle.d.ts +9 -4
  312. package/dist/components/VToggle/VToggle.js.map +1 -1
  313. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +2 -1
  314. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  315. package/dist/components/VToggle/VToggleItem.d.ts +4 -0
  316. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  317. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +5 -5
  318. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  319. package/dist/components/VTooltip/VTooltip.css +1 -1
  320. package/dist/components/VTooltip/VTooltip.d.ts +17 -10
  321. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  322. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +46 -26
  323. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  324. package/dist/components/VTypography/VTypography.css +1 -1
  325. package/dist/components/VTypography/VTypography.d.ts +6 -4
  326. package/dist/components/VTypography/VTypography.js.map +1 -1
  327. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  328. package/dist/composables/useAriaLabel.js +1 -1
  329. package/dist/composables/useAriaLabel.js.map +1 -1
  330. package/dist/composables/useClearable.d.ts +2 -2
  331. package/dist/composables/useClearable.js.map +1 -1
  332. package/dist/composables/useDetailsOpen.d.ts +3 -3
  333. package/dist/composables/useDetailsOpen.js +14 -12
  334. package/dist/composables/useDetailsOpen.js.map +1 -1
  335. package/dist/composables/useFieldIds.d.ts +2 -1
  336. package/dist/composables/useFieldIds.js +6 -5
  337. package/dist/composables/useFieldIds.js.map +1 -1
  338. package/dist/composables/useFieldPanel.d.ts +2 -2
  339. package/dist/composables/useFieldPanel.js +47 -37
  340. package/dist/composables/useFieldPanel.js.map +1 -1
  341. package/dist/composables/useFileDrop.js +3 -3
  342. package/dist/composables/useFileDrop.js.map +1 -1
  343. package/dist/composables/useFileField.d.ts +1 -1
  344. package/dist/composables/useFileField.js +62 -41
  345. package/dist/composables/useFileField.js.map +1 -1
  346. package/dist/composables/useIconClickHandlers.d.ts +3 -3
  347. package/dist/composables/useIconClickHandlers.js +14 -13
  348. package/dist/composables/useIconClickHandlers.js.map +1 -1
  349. package/dist/composables/useInertLink.js +12 -10
  350. package/dist/composables/useInertLink.js.map +1 -1
  351. package/dist/composables/useLiveAnnouncer.d.ts +5 -0
  352. package/dist/composables/useLiveAnnouncer.js +23 -0
  353. package/dist/composables/useLiveAnnouncer.js.map +1 -0
  354. package/dist/composables/useMaskedField.d.ts +5 -5
  355. package/dist/composables/useMaskedField.js.map +1 -1
  356. package/dist/composables/usePopover.d.ts +3 -3
  357. package/dist/composables/usePopover.js +6 -4
  358. package/dist/composables/usePopover.js.map +1 -1
  359. package/dist/composables/useProgressValue.js +11 -2
  360. package/dist/composables/useProgressValue.js.map +1 -1
  361. package/dist/composables/useRootAttrs.d.ts +1 -1
  362. package/dist/composables/useRootAttrs.js.map +1 -1
  363. package/dist/composables/useSlotNodes.d.ts +18 -0
  364. package/dist/composables/useSlotNodes.js +13 -0
  365. package/dist/composables/useSlotNodes.js.map +1 -0
  366. package/dist/composables/useTextLimit.d.ts +2 -1
  367. package/dist/composables/useTextLimit.js +2 -2
  368. package/dist/composables/useTextLimit.js.map +1 -1
  369. package/dist/composables/useTimer.d.ts +5 -0
  370. package/dist/composables/useTimer.js +22 -11
  371. package/dist/composables/useTimer.js.map +1 -1
  372. package/dist/i18n/en.js +1 -1
  373. package/dist/i18n/en.js.map +1 -1
  374. package/dist/i18n/fr.js +14 -14
  375. package/dist/i18n/fr.js.map +1 -1
  376. package/dist/i18n/state.d.ts +7 -7
  377. package/dist/i18n/state.js +37 -28
  378. package/dist/i18n/state.js.map +1 -1
  379. package/dist/i18n/types.d.ts +12 -12
  380. package/dist/icons.d.ts +2 -2
  381. package/dist/index.d.ts +12 -11
  382. package/dist/styles.css +1 -1
  383. package/dist/tokens/css.d.ts +1 -1
  384. package/dist/tokens/css.js.map +1 -1
  385. package/dist/tokens/index.d.ts +6 -0
  386. package/dist/tokens/semantic.d.ts +6 -0
  387. package/dist/tokens/semantic.js +66 -60
  388. package/dist/tokens/semantic.js.map +1 -1
  389. package/dist/tokens/themes/dark.js +3 -3
  390. package/dist/tokens/themes/dark.js.map +1 -1
  391. package/dist/tokens.json +130 -66
  392. package/dist/types.d.ts +1 -1
  393. package/dist/utils/arrowNav.d.ts +4 -1
  394. package/dist/utils/arrowNav.js +7 -7
  395. package/dist/utils/arrowNav.js.map +1 -1
  396. package/dist/utils/chip.d.ts +1 -1
  397. package/dist/utils/chip.js.map +1 -1
  398. package/dist/utils/clock.d.ts +113 -0
  399. package/dist/utils/clock.js +84 -0
  400. package/dist/utils/clock.js.map +1 -0
  401. package/dist/utils/css.d.ts +6 -4
  402. package/dist/utils/css.js +2 -2
  403. package/dist/utils/css.js.map +1 -1
  404. package/dist/utils/date.d.ts +7 -102
  405. package/dist/utils/date.js +33 -160
  406. package/dist/utils/date.js.map +1 -1
  407. package/dist/utils/direction.d.ts +1 -1
  408. package/dist/utils/direction.js.map +1 -1
  409. package/dist/utils/env.d.ts +12 -3
  410. package/dist/utils/env.js +6 -0
  411. package/dist/utils/env.js.map +1 -0
  412. package/dist/utils/file.d.ts +3 -3
  413. package/dist/utils/file.js +1 -1
  414. package/dist/utils/file.js.map +1 -1
  415. package/dist/utils/focus.d.ts +1 -1
  416. package/dist/utils/focus.js.map +1 -1
  417. package/dist/utils/hostWarns.d.ts +1 -1
  418. package/dist/utils/hostWarns.js.map +1 -1
  419. package/dist/utils/ids.d.ts +1 -1
  420. package/dist/utils/ids.js.map +1 -1
  421. package/dist/utils/matcher.d.ts +2 -2
  422. package/dist/utils/matcher.js.map +1 -1
  423. package/dist/utils/memo.d.ts +1 -1
  424. package/dist/utils/memo.js.map +1 -1
  425. package/dist/utils/text.d.ts +3 -3
  426. package/dist/utils/text.js.map +1 -1
  427. package/dist/utils/time.d.ts +2 -101
  428. package/dist/utils/time.js +22 -98
  429. package/dist/utils/time.js.map +1 -1
  430. package/dist/utils/vnode.d.ts +5 -3
  431. package/dist/utils/vnode.js.map +1 -1
  432. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"date.js","names":[],"sources":["../../src/utils/date.ts"],"sourcesContent":["// @ssr @core — module-wide: every export below is @core unless tagged otherwise.\n/**\n * The date arithmetic behind VDatePicker and VDateInput, as pure functions. One currency\n * throughout: the ISO `YYYY-MM-DD` string, computed in LOCAL time.\n *\n * Two shortcuts are banned as a result. `new Date('YYYY-MM-DD')` parses as UTC and lands a\n * day out depending on the zone, and `toISOString()` formats in UTC for the same reason.\n * `Date` exists here only as an intermediate, built with `new Date(y, m, d)` — local\n * midnight — and turned back into text by concatenation.\n *\n * Month and day names come from `Intl` on REFERENCE dates pinned to `timeZone: 'UTC'`, so a\n * label never depends on the rendering machine's zone and the server agrees with the browser.\n */\n\nimport { memo } from './memo'\nimport { digitsOf, pad2 } from './text'\n\nconst ISO_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\n/**\n * Tells whether a value is a real `YYYY-MM-DD` date. The shape alone is not enough:\n * `2026-02-31` matches the pattern, so the check goes through a parse and a\n * reformat, and only a value that survives the round trip unchanged is accepted.\n */\nexport function isValidISO(iso: unknown): iso is string {\n if (typeof iso !== 'string' || !ISO_RE.test(iso)) return false\n const d = parseISO(iso)\n return d !== null && formatISO(d) === iso\n}\n\n/**\n * Turns an ISO string into a `Date` set at local midnight, or returns `null` when\n * the string is not one. Every caller here has to handle that `null`: the bounds a\n * consumer passes are raw strings and may be anything.\n */\nexport function parseISO(iso: string | null | undefined): Date | null {\n if (typeof iso !== 'string' || !ISO_RE.test(iso)) return null\n const parts = iso.split('-')\n const date = new Date(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]))\n return Number.isNaN(date.getTime()) ? null : date\n}\n\n/**\n * Writes a `Date` as an ISO string, reading its LOCAL components. This manual\n * concatenation is what `toISOString()` cannot do, since that one formats in UTC.\n */\nexport function formatISO(date: Date): string {\n return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`\n}\n\n/**\n * Builds an ISO string from separate values. The month is 0-indexed, as everywhere\n * in the language: 0 is January.\n */\nexport function isoOf(year: number, month0: number, day: number): string {\n return formatISO(new Date(year, month0, day))\n}\n\n/**\n * Moves a date by a number of days, forwards or backwards. Crossing into another\n * month or year is handled by `Date` itself.\n */\nexport function addDays(iso: string, n: number): string {\n const d = parseISO(iso)\n if (!d) return iso\n d.setDate(d.getDate() + n)\n return formatISO(d)\n}\n\n/**\n * Moves a date by a number of months, keeping the day of the month where possible.\n * When the target month is too short the day is brought back to its last one: 31\n * January plus one month gives 28 or 29 February, and never spills over into March\n * the way a naive addition would.\n */\nexport function addMonths(iso: string, n: number): string {\n const d = parseISO(iso)\n if (!d) return iso\n const day = d.getDate()\n d.setDate(1)\n d.setMonth(d.getMonth() + n)\n d.setDate(Math.min(day, daysInMonth(d.getFullYear(), d.getMonth())))\n return formatISO(d)\n}\n\n/**\n * How many days the given month holds, leap years included. Day 0 of the following\n * month is the last day of this one, which is what makes the leap year rule the\n * language's problem rather than ours.\n */\nexport function daysInMonth(year: number, month0: number): number {\n return new Date(year, month0 + 1, 0).getDate()\n}\n\n/**\n * Compares two dates chronologically, returning the usual -1, 0 or 1. Because the\n * `YYYY-MM-DD` format puts its most significant part first, comparing the strings as\n * text already gives the chronological order: no parsing is needed.\n */\nexport function compareISO(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\n/**\n * Whether two dates are the same day, with a null on either side counting as no\n * date at all rather than as a match.\n */\nexport const isSameISO = (a: string | null, b: string | null) => !!a && a === b\n\n/**\n * Brings a date back inside the allowed interval, returning the bound it exceeded.\n * Both bounds are optional, and an absent one means unbounded on that side.\n */\nexport function clampISO(iso: string, min?: string, max?: string): string {\n if (min && compareISO(iso, min) < 0) return min\n if (max && compareISO(iso, max) > 0) return max\n return iso\n}\n\n/** Whether a date falls inside the allowed interval, each bound being optional. */\nexport function isWithin(iso: string, min?: string, max?: string): boolean {\n if (min && compareISO(iso, min) < 0) return false\n if (max && compareISO(iso, max) > 0) return false\n return true\n}\n\n/**\n * Whether a date may be chosen: inside the bounds, and not one the matcher excludes. It is\n * the ONE rule behind both a struck-through day in VDatePicker and a typed date VDateInput\n * refuses, so the two cannot come to disagree about what \"unavailable\" means.\n */\nexport function isDateAllowed(\n iso: string,\n min: string | undefined,\n max: string | undefined,\n excluded: (iso: string) => boolean,\n): boolean {\n return isWithin(iso, min, max) && !excluded(iso)\n}\n\n/** One square of a month grid. */\nexport interface MonthCell {\n /** The day it stands for, as an ISO `YYYY-MM-DD` string. */\n iso: string\n /** The day of the month, carried so a caller does not parse back what was just formatted. */\n day: number\n /**\n * Which side of the displayed month this day belongs to when it is not part of it,\n * and `null` when it is.\n */\n adjacent: 'prev' | 'next' | null\n}\n\n/**\n * Builds the grid of a month: 42 cells, six rows of seven, filled out at both ends\n * with the days of the neighbouring months. The count is fixed on purpose, so that\n * the calendar keeps the same height from one month to the next instead of jumping\n * by a row. `firstDayOfWeek` runs from 0 for Sunday to 6 for Saturday.\n */\nexport function buildMonthGrid(year: number, month0: number, firstDayOfWeek: number): MonthCell[] {\n const first = new Date(year, month0, 1)\n // How many cells the 1st of the month sits after the start of its row, which is\n // exactly how many days of the previous month the grid has to open with.\n const offset = (first.getDay() - firstDayOfWeek + 7) % 7\n const cells: MonthCell[] = []\n for (let i = 0; i < 42; i++) {\n // Built from the 1st rather than stepped from a start date, so the month and year\n // rolling over at either end is `Date`'s arithmetic and not ours.\n const d = new Date(year, month0, 1 - offset + i)\n const adjacent =\n d.getMonth() === month0 && d.getFullYear() === year ? null : d < first ? 'prev' : 'next'\n cells.push({ iso: formatISO(d), day: d.getDate(), adjacent })\n }\n return cells\n}\n\nconst firstDayCache = new Map<string, number>()\n\n// @fallback @ssr\n/**\n * The day the week starts on in a given locale, from 0 for Sunday to 6 for Saturday\n * — Sunday in the United States, Monday in most of Europe, Saturday in much of the\n * Middle East. It comes from `Intl.Locale`, whose own numbering runs from 1 for\n * Monday to 7 for Sunday.\n *\n * That part of `Intl` is not everywhere (some Node builds lack it), so the answer\n * falls back to Monday when it is missing. A component can always override the\n * result with its `firstDayOfWeek` prop.\n */\nexport function firstDayOfWeekFor(locale: string): number {\n return memo(firstDayCache, locale, () => resolveFirstDayOfWeek(locale))\n}\n\nfunction resolveFirstDayOfWeek(locale: string): number {\n try {\n // Implementations disagree on the shape: Chrome and Safari expose `weekInfo` as\n // a getter, others a `getWeekInfo()` method. Both are tried.\n const loc = new Intl.Locale(locale) as Intl.Locale & {\n weekInfo?: { firstDay: number }\n getWeekInfo?: () => { firstDay: number }\n }\n const info = loc.getWeekInfo?.() ?? loc.weekInfo\n if (info?.firstDay) return info.firstDay % 7 // brings Sunday, their 7, back to 0\n } catch {\n /* an invalid locale throws a RangeError: fall through to the fallback */\n }\n return 1 // Monday\n}\n\n// The reference instants the names are formatted from. Any Sunday will do for the\n// weekdays, and any year for the months; combined with `timeZone: 'UTC'` at every\n// call site, they pin the output whatever zone the machine is in.\nconst REF_SUNDAY = Date.UTC(2021, 7, 1) // 1 August 2021 fell on a Sunday\nconst MS_DAY = 86_400_000\n\n/**\n * The names of the seven days, starting from `firstDayOfWeek` so the list can be\n * dropped straight into a calendar header.\n */\nexport function weekdayNames(\n locale: string,\n firstDayOfWeek: number,\n weekday: 'short' | 'long' = 'short',\n): string[] {\n const fmt = new Intl.DateTimeFormat(locale, { weekday, timeZone: 'UTC' })\n return Array.from({ length: 7 }, (_, i) =>\n fmt.format(REF_SUNDAY + ((firstDayOfWeek + i) % 7) * MS_DAY),\n )\n}\n\n/** The full names of the twelve months, in January-to-December order. */\nexport function monthNames(locale: string): string[] {\n const fmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' })\n return Array.from({ length: 12 }, (_, i) => fmt.format(Date.UTC(2021, i, 1)))\n}\n\n/**\n * Month names shortened for the picker's narrow cells: a name of four characters or\n * fewer is kept whole (\"May\", \"June\", \"July\"), a longer one is cut to three\n * characters followed by a dot (\"January\" becomes \"Jan.\"). The name is spread with\n * `[...n]` rather than indexed, so that an accented or non-Latin character counts as\n * one character and is never cut in half.\n */\nexport function monthNamesCompact(locale: string): string[] {\n return monthNames(locale).map((n) => {\n const chars = [...n]\n return chars.length <= 4 ? n : chars.slice(0, 3).join('') + '.'\n })\n}\n\n/**\n * One formatter kept per locale and set of options, for the lifetime of the module —\n * the same `formatterFor` idiom as in `utils/file.ts` and `utils/time.ts`.\n *\n * Building an `Intl.DateTimeFormat` costs one to two orders of magnitude more than\n * using one, and the three functions below are called ONE VALUE AT A TIME: VDateInput\n * formats a multiple selection inside a `.map`, so a fresh formatter would be built\n * for every date. `weekdayNames` and `monthNames` already hoist theirs out of their\n * loop; this cache gives the per-call functions the same property.\n *\n * The options object is part of the cache key. `JSON.stringify` is stable enough\n * here — these objects are literals written by the components, not data coming from\n * a user — and costs a fraction of a construction.\n */\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/** The full name of one month, 0 being January. */\nexport function monthName(locale: string, month0: number): string {\n return formatterFor(locale, { month: 'long', timeZone: 'UTC' }).format(Date.UTC(2021, month0, 1))\n}\n\n/**\n * A date written out for the reader, in the conventions of their locale — this is\n * what VDateInput shows in its field. An unparsable date yields an empty string\n * rather than a broken one.\n */\nexport function formatDateDisplay(\n iso: string,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n): string {\n const d = parseISO(iso)\n return d ? formatterFor(locale, options).format(d) : ''\n}\n\n/**\n * A period written out for the reader. `Intl`'s own `formatRange` is what factors\n * out the parts the two dates share, giving \"19–26 June 2026\" rather than the two\n * full dates side by side. A period of a single day is formatted as that one date.\n */\nexport function formatDisplayRange(\n start: string,\n end: string,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n): string {\n const a = parseISO(start)\n const b = parseISO(end)\n if (!a || !b) return ''\n const fmt = formatterFor(locale, options)\n return compareISO(start, end) === 0 ? fmt.format(a) : fmt.formatRange(a, b)\n}\n\n/*\n * The numeric input mask, used by VDateInput when its field can be typed into.\n *\n * A field being typed into never shows the long display format — \"10 June 2026\" is\n * not something one can type — but a purely numeric mask instead. The order of the\n * three fields and the separator between them are DERIVED from the locale rather\n * than hardcoded, which is what makes the same field work for a reader in Tokyo and\n * one in Chicago.\n */\n\nexport type DateMaskField = 'day' | 'month' | 'year'\n\n/** Everything a locale decides about how a date is typed. */\nexport interface DateMask {\n /**\n * The order the three fields appear in: day, month, year in the United Kingdom,\n * month, day, year in the United States, year, month, day in Japan.\n */\n order: readonly DateMaskField[]\n /** The single character between two fields, stripped of bidi marks and spaces. */\n separator: string\n /** How many digits each field takes, in the same order: 4 for the year, 2 otherwise. */\n lengths: readonly number[]\n /** How many digits the complete mask holds, which is always 8. */\n size: number\n}\n\nconst MASK_FALLBACK: DateMask = {\n order: ['day', 'month', 'year'],\n separator: '/',\n lengths: [2, 2, 4],\n size: 8,\n}\n\n/**\n * The date the mask is read from: 22 November 2021. Its three numbers all differ, so\n * whichever order the locale prints them in, each one can be told apart.\n */\nconst REF_MASK_DATE = Date.UTC(2021, 10, 22)\n\n/** The invisible direction marks some locales insert, such as U+200F before \"/\" in ar-EG. */\nconst BIDI_MARKS = /[‎‏؜]/g\n\nconst maskCache = new Map<string, DateMask>()\n\n/**\n * Works out how a date is typed in a given locale, by formatting a known date and\n * looking at what came out.\n *\n * The calendar and the numbering system are FORCED to Gregorian and Latin digits.\n * Without that, `fa-IR` answers with a Persian year (1400 rather than 2021) and\n * `ar-EG` with Arabic-Indic digits — two things a numeric field could neither\n * display nor read back. An invalid locale throws, and the answer then falls back to\n * day/month/year separated by \"/\".\n */\nexport function dateMaskFor(locale: string): DateMask {\n return memo(maskCache, locale, () => buildDateMask(locale))\n}\n\n/*\n * TRAP — the returned `DateMask` is SHARED between every caller for a locale, so it must be\n * treated as read-only. Nothing mutates it today (it is read field by field in\n * `formatDateMask`, `parseDateMask` and `maskPlaceholder`), and it is the same contract the\n * memoized `Intl` formatters in this file already have.\n */\nfunction buildDateMask(locale: string): DateMask {\n try {\n const parts = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n timeZone: 'UTC',\n calendar: 'gregory',\n numberingSystem: 'latn',\n }).formatToParts(REF_MASK_DATE)\n\n const order = parts\n .map((p) => p.type)\n .filter((t): t is DateMaskField => t === 'day' || t === 'month' || t === 'year')\n\n // The separator is the first literal appearing AFTER the first field, and not\n // simply the first literal: Hungarian and Korean end the whole format with a dot\n // (\"2021. 11. 22.\"), which must not be mistaken for it.\n const firstField = parts.findIndex((p) => p.type !== 'literal')\n const separator = parts\n .slice(firstField)\n .find((p) => p.type === 'literal')\n ?.value.replace(BIDI_MARKS, '')\n .trim()\n\n if (order.length === 3 && separator) {\n const lengths = order.map((f) => (f === 'year' ? 4 : 2))\n return { order, separator, lengths, size: 8 }\n }\n } catch {\n /* an invalid locale throws a RangeError: fall through to the fallback */\n }\n return MASK_FALLBACK\n}\n\n/**\n * Lays a run of digits out as masked text. The separator appears AS SOON AS the field\n * before it is full — typing \"22\" already gives \"22/\" — so the reader sees their\n * progress without ever having to type a separator themselves.\n *\n * This has a consequence the component must honour: pressing Backspace on such a\n * separator has to delete the DIGIT before it. Deleting the separator alone would\n * see the mask write it straight back, and the key would look dead.\n */\nexport function formatDateMask(digits: string, mask: DateMask): string {\n const all = digitsOf(digits).slice(0, mask.size)\n let out = ''\n let i = 0\n for (let f = 0; f < mask.lengths.length; f++) {\n const len = mask.lengths[f] as number\n const chunk = all.slice(i, i + len)\n if (!chunk) break\n out += chunk\n i += len\n if (chunk.length < len) break // this field is still being typed: no separator yet\n if (f < mask.lengths.length - 1) out += mask.separator\n }\n return out\n}\n\n/**\n * Writes an ISO date in the mask of the locale, ready to be put in the field: the\n * same day reads \"10/06/2026\" in London and \"06/10/2026\" in Chicago.\n */\nexport function isoToMask(iso: string, mask: DateMask): string {\n if (!isValidISO(iso)) return ''\n const [year, month, day] = iso.split('-') as [string, string, string]\n const by: Record<DateMaskField, string> = { year, month, day }\n return formatDateMask(mask.order.map((f) => by[f]).join(''), mask)\n}\n\nexport interface ParseMaskOptions {\n /**\n * The century a two-digit year is expanded into: with 2000, \"10/06/26\" is read as\n * 2026. It is only accepted when the year is the LAST field of the mask, since\n * elsewhere the following separator already tells the two apart.\n *\n * Leaving it out refuses any year shorter than four digits, and that is the mode\n * used while the reader types — so that \"26\", passed through on the way to \"2026\",\n * is never committed as a year of its own.\n */\n yearPivot?: number\n}\n\n/**\n * Reads masked text back into an ISO date, or returns `null` when the text is\n * incomplete, holds too many digits, or names a day that does not exist — 31\n * February passes every length check and is caught by the round trip `isValidISO`\n * performs.\n *\n * Whether the resulting date is allowed is a different question: the `min`/`max`\n * bounds and the disabled dates belong to the component, and this function knows\n * nothing about props.\n */\nexport function parseDateMask(\n text: string,\n mask: DateMask,\n options: ParseMaskOptions = {},\n): string | null {\n const digits = digitsOf(text)\n const by: Partial<Record<DateMaskField, string>> = {}\n let i = 0\n for (let k = 0; k < mask.order.length; k++) {\n const field = mask.order[k] as DateMaskField\n const len = mask.lengths[k] as number\n const chunk = digits.slice(i, i + len)\n if (chunk.length === len) i += len\n else if (\n field === 'year' &&\n options.yearPivot !== undefined &&\n k === mask.order.length - 1 &&\n chunk.length === 2\n )\n i += 2\n else return null\n by[field] = chunk\n }\n if (i !== digits.length) return null // digits are left over: the entry is too long\n const year =\n (by.year as string).length === 2\n ? String((options.yearPivot as number) + Number(by.year))\n : (by.year as string)\n const iso = `${year}-${by.month}-${by.day}`\n return isValidISO(iso) ? iso : null\n}\n\n/**\n * Where the caret has to go to sit just after the nth digit. Counting digits is the\n * only landmark that survives a reformat: an absolute position jumps by one the\n * moment a separator appears or disappears, so restoring it would leave the caret in\n * the wrong place on exactly the keystrokes that matter.\n *\n * When a separator is passed and it directly follows that position, the caret steps\n * over it: while typing, it must land in the NEXT field rather than in front of a\n * separator that has just been written. On deletion the argument is omitted, so the\n * caret stays before it and the next Backspace reaches the digit.\n */\nexport function caretAfterDigits(text: string, n: number, separator?: string): number {\n let pos = 0\n if (n > 0) {\n pos = text.length\n let seen = 0\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (code >= 48 && code <= 57 && ++seen === n) {\n pos = i + 1\n break\n }\n }\n }\n if (separator && text.startsWith(separator, pos)) pos += separator.length\n return pos\n}\n\nconst PLACEHOLDER_FALLBACK: Record<DateMaskField, string> = { day: 'd', month: 'm', year: 'y' }\n\n/**\n * Ideographic scripts, which are excluded from the placeholder: a repeated \"日\" does\n * not read as a template the way a repeated letter does.\n */\nconst IDEOGRAPHIC = /[\\p{sc=Han}\\p{sc=Hangul}\\p{sc=Hiragana}\\p{sc=Katakana}]/u\n\n// @fallback\n/**\n * The empty template shown in the field: \"dd/mm/yyyy\" in English, \"jj/mm/aaaa\" in\n * French, \"tt.mm.jjjj\" in German, \"дд/мм/гггг\" in Russian.\n *\n * Each letter is the first letter of the field's own name in that language, taken\n * from `Intl.DisplayNames` — which lands on the attested convention of every\n * alphabetic script without a table to maintain. It falls back to the Latin letters\n * when that part of `Intl` is missing, or when the script is ideographic and the\n * repetition would mean nothing.\n */\nexport function maskPlaceholder(locale: string, mask: DateMask): string {\n const letters = placeholderLetters(locale)\n return mask.order.map((f, k) => letters[f].repeat(mask.lengths[k] as number)).join(mask.separator)\n}\n\nconst placeholderLetterCache = new Map<string, typeof PLACEHOLDER_FALLBACK>()\n\n/**\n * The three letters a locale writes its date fields with, worked out once per locale.\n *\n * The LETTERS are cached, not the finished placeholder: that also depends on the mask handed\n * in, and would be wrong the moment a caller passes one that is not `dateMaskFor(locale)`.\n * All the cost is here anyway — `Intl.DisplayNames` is this file's most expensive\n * constructor by an order of magnitude (~0.22 ms against ~0.07 for `dateMaskFor`).\n */\nfunction placeholderLetters(locale: string): typeof PLACEHOLDER_FALLBACK {\n return memo(placeholderLetterCache, locale, () => buildPlaceholderLetters(locale))\n}\n\nfunction buildPlaceholderLetters(locale: string): typeof PLACEHOLDER_FALLBACK {\n const letters = { ...PLACEHOLDER_FALLBACK }\n try {\n const names = new Intl.DisplayNames(locale, { type: 'dateTimeField' })\n for (const field of ['day', 'month', 'year'] as const) {\n const first = [...(names.of(field) ?? '')][0]\n if (first && /\\p{L}/u.test(first) && !IDEOGRAPHIC.test(first))\n letters[field] = first.toLocaleLowerCase(locale)\n }\n } catch {\n /* Intl.DisplayNames is unavailable here: keep the Latin letters */\n }\n return letters\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"date.js","names":[],"sources":["../../src/utils/date.ts"],"sourcesContent":["// @ssr @core — module-wide: every export below is @core unless tagged otherwise.\n/**\n * The date arithmetic behind VDatePicker and VDateInput, as pure functions. One currency\n * throughout: the ISO `YYYY-MM-DD` string, computed in LOCAL time.\n *\n * Two shortcuts are banned as a result. `new Date('YYYY-MM-DD')` parses as UTC and lands a\n * day out depending on the zone, and `toISOString()` formats in UTC for the same reason.\n * `Date` exists here only as an intermediate, built with `localDate(y, m, d)` — local\n * midnight — and turned back into text by concatenation.\n *\n * Month and day names come from `Intl` on REFERENCE dates pinned to `timeZone: 'UTC'`, so a\n * label never depends on the rendering machine's zone and the server agrees with the browser.\n */\n\nimport { memo } from './memo'\nimport { pad2 } from './text'\n\n/**\n * A local-midnight `Date`, rolling over at either end the way `new Date(y, m, d)` does.\n *\n * TRAP — not `new Date(y, m, d)` itself, which reads a year from 0 to 99 as 1900 to 1999:\n * `0050-01-01` would come back as 1950, and a `min` in the first century would open the\n * years view nineteen centuries late. `setFullYear` takes the year as it is.\n */\nfunction localDate(year: number, month0: number, day: number): Date {\n const date = new Date(year, month0, day)\n if (year >= 0 && year < 100) date.setFullYear(year, month0, day)\n return date\n}\n\nconst ISO_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\n/**\n * Tells whether a value is a real `YYYY-MM-DD` date. The shape alone is not enough:\n * `2026-02-31` matches the pattern, so the check goes through a parse and a\n * reformat, and only a value that survives the round trip unchanged is accepted.\n */\nexport function isValidISO(iso: unknown): iso is string {\n return typeof iso === 'string' && parseISO(iso) !== null\n}\n\n/**\n * Turns an ISO string into a `Date` set at local midnight, or returns `null` when\n * the string is not one. Every caller here has to handle that `null`: the bounds a\n * consumer passes are raw strings and may be anything.\n *\n * TRAP: the shape is not enough. The `Date` constructor rolls an impossible day over\n * rather than refusing it (`2026-02-31` is March 3rd), so the date is written back and\n * compared: a day the month does not have reads as no date at all.\n */\nexport function parseISO(iso: string | null | undefined): Date | null {\n if (typeof iso !== 'string' || !ISO_RE.test(iso)) return null\n const parts = iso.split('-')\n const date = localDate(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]))\n return Number.isNaN(date.getTime()) || formatISO(date) !== iso ? null : date\n}\n\n/**\n * Writes a `Date` as an ISO string, reading its LOCAL components. This manual\n * concatenation is what `toISOString()` cannot do, since that one formats in UTC.\n */\nexport function formatISO(date: Date): string {\n // The year is padded to four digits: `999-01-10` would sort after `2026-…` as text.\n const year = String(date.getFullYear()).padStart(4, '0')\n return `${year}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`\n}\n\n/**\n * Builds an ISO string from separate values. The month is 0-indexed, as everywhere\n * in the language: 0 is January.\n */\nexport function isoOf(year: number, month0: number, day: number): string {\n return formatISO(localDate(year, month0, day))\n}\n\n/**\n * Moves a date by a number of days, forwards or backwards. Crossing into another\n * month or year is handled by `Date` itself.\n */\nexport function addDays(iso: string, n: number): string {\n const d = parseISO(iso)\n if (!d) return iso\n d.setDate(d.getDate() + n)\n return formatISO(d)\n}\n\n/**\n * Moves a date by a number of months, keeping the day of the month where possible.\n * When the target month is too short the day is brought back to its last one: 31\n * January plus one month gives 28 or 29 February, and never spills over into March\n * the way a naive addition would.\n */\nexport function addMonths(iso: string, n: number): string {\n const d = parseISO(iso)\n if (!d) return iso\n const day = d.getDate()\n d.setDate(1)\n d.setMonth(d.getMonth() + n)\n d.setDate(Math.min(day, daysInMonth(d.getFullYear(), d.getMonth())))\n return formatISO(d)\n}\n\n/**\n * How many days the given month holds, leap years included. Day 0 of the following\n * month is the last day of this one, which is what makes the leap year rule the\n * language's problem rather than ours.\n */\nexport function daysInMonth(year: number, month0: number): number {\n return localDate(year, month0 + 1, 0).getDate()\n}\n\n/**\n * Compares two dates chronologically, returning the usual -1, 0 or 1. Because the\n * `YYYY-MM-DD` format puts its most significant part first, comparing the strings as\n * text already gives the chronological order: no parsing is needed.\n */\nexport function compareISO(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\n/**\n * Whether two dates are the same day, with a null on either side counting as no\n * date at all rather than as a match.\n */\nexport const isSameISO = (a: string | null, b: string | null) => !!a && a === b\n\n/**\n * Brings a date back inside the allowed interval, returning the bound it exceeded.\n * Both bounds are optional, and an absent one means unbounded on that side.\n */\nexport function clampISO(iso: string, min?: string, max?: string): string {\n if (min && compareISO(iso, min) < 0) return min\n if (max && compareISO(iso, max) > 0) return max\n return iso\n}\n\n/** Whether a date falls inside the allowed interval, each bound being optional. */\nexport function isWithin(iso: string, min?: string, max?: string): boolean {\n if (min && compareISO(iso, min) < 0) return false\n if (max && compareISO(iso, max) > 0) return false\n return true\n}\n\n/**\n * Whether a date may be chosen: inside the bounds, and not one the matcher excludes. It is\n * the ONE rule behind both a struck-through day in VDatePicker and a typed date VDateInput\n * refuses, so the two cannot come to disagree about what \"unavailable\" means.\n */\nexport function isDateAllowed(\n iso: string,\n min: string | undefined,\n max: string | undefined,\n excluded: (iso: string) => boolean,\n): boolean {\n return isWithin(iso, min, max) && !excluded(iso)\n}\n\n/** One square of a month grid. */\nexport interface MonthCell {\n /** The day it stands for, as an ISO `YYYY-MM-DD` string. */\n iso: string\n /** The day of the month, carried so a caller does not parse back what was just formatted. */\n day: number\n /**\n * Which side of the displayed month this day belongs to when it is not part of it,\n * and `null` when it is.\n */\n adjacent: 'prev' | 'next' | null\n}\n\n/**\n * Builds the grid of a month: 42 cells, six rows of seven, filled out at both ends\n * with the days of the neighbouring months. The count is fixed on purpose, so that\n * the calendar keeps the same height from one month to the next instead of jumping\n * by a row. `firstDayOfWeek` runs from 0 for Sunday to 6 for Saturday.\n */\nexport function buildMonthGrid(year: number, month0: number, firstDayOfWeek: number): MonthCell[] {\n const first = localDate(year, month0, 1)\n // How many cells the 1st of the month sits after the start of its row, which is\n // exactly how many days of the previous month the grid has to open with.\n const offset = (first.getDay() - firstDayOfWeek + 7) % 7\n const cells: MonthCell[] = []\n for (let i = 0; i < 42; i++) {\n // Built from the 1st rather than stepped from a start date, so the month and year\n // rolling over at either end is `Date`'s arithmetic and not ours.\n const d = localDate(year, month0, 1 - offset + i)\n const adjacent =\n d.getMonth() === month0 && d.getFullYear() === year ? null : d < first ? 'prev' : 'next'\n cells.push({ iso: formatISO(d), day: d.getDate(), adjacent })\n }\n return cells\n}\n\nconst firstDayCache = new Map<string, number>()\n\n// @fallback @ssr\n/**\n * The day the week starts on in a given locale, from 0 for Sunday to 6 for Saturday\n *: Sunday in the United States, Monday in most of Europe, Saturday in much of the\n * Middle East. It comes from `Intl.Locale`, whose own numbering runs from 1 for\n * Monday to 7 for Sunday.\n *\n * That part of `Intl` is not everywhere (some Node builds lack it), so the answer\n * falls back to Monday when it is missing. A component can always override the\n * result with its `firstDayOfWeek` prop.\n */\nexport function firstDayOfWeekFor(locale: string): number {\n return memo(firstDayCache, locale, () => resolveFirstDayOfWeek(locale))\n}\n\nfunction resolveFirstDayOfWeek(locale: string): number {\n try {\n // Implementations disagree on the shape: Chrome and Safari expose `weekInfo` as\n // a getter, others a `getWeekInfo()` method. Both are tried.\n const loc = new Intl.Locale(locale) as Intl.Locale & {\n weekInfo?: { firstDay: number }\n getWeekInfo?: () => { firstDay: number }\n }\n const info = loc.getWeekInfo?.() ?? loc.weekInfo\n if (info?.firstDay) return info.firstDay % 7 // brings Sunday, their 7, back to 0\n } catch {\n /* an invalid locale throws a RangeError: fall through to the fallback */\n }\n return 1 // Monday\n}\n\n// The reference instants the names are formatted from. Any Sunday will do for the\n// weekdays, and any year for the months; combined with `timeZone: 'UTC'` at every\n// call site, they pin the output whatever zone the machine is in.\nconst REF_SUNDAY = Date.UTC(2021, 7, 1) // 1 August 2021 fell on a Sunday\nconst MS_DAY = 86_400_000\n\n/**\n * The names of the seven days, starting from `firstDayOfWeek` so the list can be\n * dropped straight into a calendar header.\n */\nexport function weekdayNames(\n locale: string,\n firstDayOfWeek: number,\n weekday: 'short' | 'long' = 'short',\n): string[] {\n const fmt = new Intl.DateTimeFormat(locale, { weekday, timeZone: 'UTC' })\n return Array.from({ length: 7 }, (_, i) =>\n fmt.format(REF_SUNDAY + ((firstDayOfWeek + i) % 7) * MS_DAY),\n )\n}\n\n/**\n * One formatter kept per locale and set of options, for the lifetime of the module —\n * the same `formatterFor` idiom as in `utils/file.ts` and `utils/time.ts`.\n *\n * Building an `Intl.DateTimeFormat` costs one to two orders of magnitude more than\n * using one, and the two functions below are called ONE VALUE AT A TIME: VDateInput\n * formats a multiple selection inside a `.map`, so a fresh formatter would be built\n * for every date. `weekdayNames` already hoists its own out of its loop; this cache\n * gives the per-call functions the same property.\n *\n * The options object is part of the cache key. `JSON.stringify` is stable enough\n * here — these objects are literals written by the components, not data coming from\n * a user — and costs a fraction of a construction.\n */\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/**\n * A date written out for the reader, in the conventions of their locale: this is\n * what VDateInput shows in its field. An unparsable date yields an empty string\n * rather than a broken one.\n */\nexport function formatDateDisplay(\n iso: string,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n): string {\n const d = parseISO(iso)\n return d ? formatterFor(locale, options).format(d) : ''\n}\n\n/**\n * A period written out for the reader. `Intl`'s own `formatRange` is what factors\n * out the parts the two dates share, giving \"19–26 June 2026\" rather than the two\n * full dates side by side. A period of a single day is formatted as that one date.\n */\nexport function formatDisplayRange(\n start: string,\n end: string,\n locale: string,\n options: Intl.DateTimeFormatOptions,\n): string {\n const a = parseISO(start)\n const b = parseISO(end)\n if (!a || !b) return ''\n const fmt = formatterFor(locale, options)\n const order = compareISO(start, end)\n if (order === 0) return fmt.format(a)\n // A range handed over the wrong way round is written in order rather than as \"26 – 19\".\n return order < 0 ? fmt.formatRange(a, b) : fmt.formatRange(b, a)\n}\n"],"mappings":"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"}
@@ -6,7 +6,7 @@
6
6
  * them has to know which way the inline axis runs before "forward" means anything.
7
7
  *
8
8
  * The COMPUTED direction, not the `dir` attribute, which may sit on any ancestor or come
9
- * from a stylesheet. That read forces a style recalculation — ask at event time, never in a
9
+ * from a stylesheet. That read forces a style recalculation. Ask at event time, never in a
10
10
  * render or a loop. A null element answers `false`, the assumption the rest of the code makes.
11
11
  */
12
12
  export declare function isRtl(el: Element | null | undefined): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"direction.js","names":[],"sources":["../../src/utils/direction.ts"],"sourcesContent":["// @core\n/**\n * Whether an element is laid out right to left.\n *\n * Logical properties mirror themselves, so this exists only for what cannot: key names\n * (`ArrowRight`), pointer coordinates and scroll deltas are physical, and the code reading\n * them has to know which way the inline axis runs before \"forward\" means anything.\n *\n * The COMPUTED direction, not the `dir` attribute, which may sit on any ancestor or come\n * from a stylesheet. That read forces a style recalculation — ask at event time, never in a\n * render or a loop. A null element answers `false`, the assumption the rest of the code makes.\n */\nexport function isRtl(el: Element | null | undefined): boolean {\n return el != null && getComputedStyle(el).direction === 'rtl'\n}\n"],"mappings":";AAYA,SAAgB,EAAM,GAAyC;CAC7D,OAAO,KAAM,QAAQ,iBAAiB,CAAE,CAAC,CAAC,cAAc;AAC1D"}
1
+ {"version":3,"file":"direction.js","names":[],"sources":["../../src/utils/direction.ts"],"sourcesContent":["// @core\n/**\n * Whether an element is laid out right to left.\n *\n * Logical properties mirror themselves, so this exists only for what cannot: key names\n * (`ArrowRight`), pointer coordinates and scroll deltas are physical, and the code reading\n * them has to know which way the inline axis runs before \"forward\" means anything.\n *\n * The COMPUTED direction, not the `dir` attribute, which may sit on any ancestor or come\n * from a stylesheet. That read forces a style recalculation. Ask at event time, never in a\n * render or a loop. A null element answers `false`, the assumption the rest of the code makes.\n */\nexport function isRtl(el: Element | null | undefined): boolean {\n return el != null && getComputedStyle(el).direction === 'rtl'\n}\n"],"mappings":";AAYA,SAAgB,EAAM,GAAyC;CAC7D,OAAO,KAAM,QAAQ,iBAAiB,CAAE,CAAC,CAAC,cAAc;AAC1D"}
@@ -2,8 +2,17 @@
2
2
  * Whether the library is running in a development build. Every integrator-facing warning
3
3
  * is gated on it, so none reaches a finished application.
4
4
  *
5
- * Looked up cautiously: the flag comes from the build tool the library is developed with,
6
- * and an application built with another may not provide it — the warnings then stay silent
7
- * rather than failing.
5
+ * TRAP: it is read from `process.env.NODE_ENV`, which the CONSUMER's bundler replaces, and
6
+ * never from `import.meta.env`: Vite folds `import.meta.env.*` to constants when it builds
7
+ * a library, so such a flag would be `false` in the published package and the minifier
8
+ * would delete every guarded warning with it. `process.env.*` is left alone by a library build,
9
+ * exactly so the application can decide. It is the contract Vue's own `esm-bundler` build
10
+ * relies on, so any bundler that can serve Vue already defines it; the library cannot run
11
+ * without a bundler anyway, each component importing its own stylesheet.
12
+ * `scripts/check-dev-warnings.ts` guards it on the artefact.
13
+ *
14
+ * A production build then strips the warnings only where the bundler carries a constant
15
+ * across modules: Rolldown and Rollup (Vite, Nuxt) do, esbuild alone does not, and there
16
+ * the strings ship inert, costing bytes but never a message.
8
17
  */
9
18
  export declare const isDev: boolean;
@@ -0,0 +1,6 @@
1
+ //#region src/utils/env.ts
2
+ var e = process.env.NODE_ENV !== "production";
3
+ //#endregion
4
+ export { e as isDev };
5
+
6
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","names":[],"sources":["../../src/utils/env.ts"],"sourcesContent":["/*\n * Typed here rather than through `@types/node`: the library's build compiles with no ambient\n * types, and a `declare global` would leak into the consumer's compilation. Declared in a\n * module, it shadows nothing outside this file.\n */\ndeclare const process: { env: { NODE_ENV?: string } }\n\n// @devwarn\n/**\n * Whether the library is running in a development build. Every integrator-facing warning\n * is gated on it, so none reaches a finished application.\n *\n * TRAP: it is read from `process.env.NODE_ENV`, which the CONSUMER's bundler replaces, and\n * never from `import.meta.env`: Vite folds `import.meta.env.*` to constants when it builds\n * a library, so such a flag would be `false` in the published package and the minifier\n * would delete every guarded warning with it. `process.env.*` is left alone by a library build,\n * exactly so the application can decide. It is the contract Vue's own `esm-bundler` build\n * relies on, so any bundler that can serve Vue already defines it; the library cannot run\n * without a bundler anyway, each component importing its own stylesheet.\n * `scripts/check-dev-warnings.ts` guards it on the artefact.\n *\n * A production build then strips the warnings only where the bundler carries a constant\n * across modules: Rolldown and Rollup (Vite, Nuxt) do, esbuild alone does not, and there\n * the strings ship inert, costing bytes but never a message.\n */\nexport const isDev = process.env.NODE_ENV !== 'production'\n"],"mappings":";AAyBA,IAAa,IAAA,QAAA,IAAA,aAAiC"}
@@ -20,7 +20,7 @@ export declare function parseAccept(accept?: string): string[];
20
20
  * The list may be handed over already read by `parseAccept`, which is what a batch does:
21
21
  * screening a hundred dropped files would otherwise split the same string a hundred times.
22
22
  *
23
- * TRAP — `file.type` is the browser's GUESS and is often empty (an unknown extension, some
23
+ * TRAP: `file.type` is the browser's GUESS and is often empty (an unknown extension, some
24
24
  * Linux setups). A list written only in MIME types then turns away a perfectly good file,
25
25
  * which is why the docs ask for extensions alongside: `image/*,.heic`, not `image/*` alone.
26
26
  */
@@ -28,7 +28,7 @@ export declare function matchesAccept(file: FileCandidate, accept?: string | rea
28
28
  export declare function fileKey(file: File): number;
29
29
  /**
30
30
  * A file size as a reader expects it: 1 200 000 gives "1.2 MB" in English, "1,2 Mo" in
31
- * French. Nothing here is translatable — `Intl` knows the unit names and the decimal mark.
31
+ * French. Nothing here is translatable: `Intl` knows the unit names and the decimal mark.
32
32
  *
33
33
  * SI base 1000, which is what the unit names `Intl` prints actually mean. The computing
34
34
  * convention of 1024 would show a 1024-byte file as "1.02 kB", a discrepancy no reader can
@@ -43,7 +43,7 @@ export declare function formatBytes(bytes: number, locale: string): string;
43
43
  * VFileInput and VFilePicker screen a batch through the same `screenFiles` below, so the
44
44
  * two report the same thing and the type is declared ONCE, here, rather than copied into
45
45
  * each of them under a name of its own. It is the `TimePickerAllowed` arrangement: the type
46
- * lives beside the rule that produces it, and `index.ts` is what makes it public — the
46
+ * lives beside the rule that produces it, and `index.ts` is what makes it public. The
47
47
  * MODULE stays internal, and a handler written for one of the two components can be
48
48
  * handed to the other.
49
49
  */
@@ -25,7 +25,7 @@ function l(t, n) {
25
25
  return e(s, `${t}|${n}`, () => new Intl.NumberFormat(t, {
26
26
  style: "unit",
27
27
  unit: o[n],
28
- unitDisplay: "short",
28
+ unitDisplay: n === 0 ? "long" : "short",
29
29
  maximumFractionDigits: c(n)
30
30
  }));
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","names":[],"sources":["../../src/utils/file.ts"],"sourcesContent":["// @core — module-wide: pure domain logic, no a11y, no DOM, no environment guard.\n/**\n * The FILE domain: whether a file is of an accepted kind, how its size is written out, and\n * which of a batch may come in. Grouped by subject rather than by shared code, like `text.ts`.\n *\n * Nothing here knows about components, which is what shapes the screening: it RETURNS its\n * refusals instead of emitting them. One body then serves VFileInput, which reports them one\n * at a time, and a test that reads them all as a list without a mount.\n */\nimport { memo } from './memo'\n\n/** All the matching needs of a file, so that a test does not have to counterfeit one. */\nexport interface FileCandidate {\n name: string\n type: string\n}\n\n/**\n * An `accept` list read into its tokens: split on commas, trimmed, lowercased, the empty ones\n * dropped. An empty result accepts everything.\n */\nexport function parseAccept(accept?: string): string[] {\n if (!accept) return []\n return accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean)\n}\n\n/**\n * Whether a file matches an `accept` list, written exactly as the HTML attribute is:\n * `.pdf` (case-insensitive), `image/*`, or one precise MIME type. An empty list accepts\n * everything.\n *\n * The rule is applied in JS because the ATTRIBUTE only governs the dialog the browser\n * opens: a DROPPED file bypasses it entirely. Without this second reading, dropping\n * smuggles anything past a restriction the consumer believes is enforced.\n *\n * The list may be handed over already read by `parseAccept`, which is what a batch does:\n * screening a hundred dropped files would otherwise split the same string a hundred times.\n *\n * TRAP — `file.type` is the browser's GUESS and is often empty (an unknown extension, some\n * Linux setups). A list written only in MIME types then turns away a perfectly good file,\n * which is why the docs ask for extensions alongside: `image/*,.heic`, not `image/*` alone.\n */\nexport function matchesAccept(file: FileCandidate, accept?: string | readonly string[]): boolean {\n const tokens = typeof accept === 'string' || accept === undefined ? parseAccept(accept) : accept\n if (tokens.length === 0) return true\n\n const name = file.name.toLowerCase()\n const type = file.type.toLowerCase()\n\n return tokens.some((token) => {\n if (token === '*' || token === '*/*') return true\n if (token.startsWith('.')) return name.endsWith(token)\n if (token.endsWith('/*')) return type !== '' && type.startsWith(token.slice(0, -1))\n return type === token\n })\n}\n\n/**\n * A stable key per FILE OBJECT, for the `v-for` of a file list.\n *\n * An index-based key re-keys every row after a removal, which remounts them — a thumbnail's\n * `<img>` included — and a name is not unique across folders. A File travels through a\n * v-model unproxied (reactivity only wraps plain objects and collections), so its identity is\n * a key that survives both. The map is weak, so a file that leaves every list is not held.\n */\nconst fileIds = new WeakMap<File, number>()\nlet nextFileId = 0\n\nexport function fileKey(file: File): number {\n let id = fileIds.get(file)\n if (id === undefined) {\n id = nextFileId++\n fileIds.set(file, id)\n }\n return id\n}\n\n/** The units a size can be written in, smallest first — the rungs of the ladder. */\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte'] as const\n\n/**\n * Building a number formatter costs one to two orders of magnitude more than using one,\n * and a running total is rewritten every time a file is added — so one is built per\n * language and rung, and kept for as long as the page lives.\n */\nconst formatters = new Map<string, Intl.NumberFormat>()\n\n/** Bytes are counted whole; above that, one decimal is what reads as a size. */\nconst digitsFor = (step: number) => (step === 0 ? 0 : 1)\n\nfunction formatterFor(locale: string, step: number): Intl.NumberFormat {\n return memo(\n formatters,\n `${locale}|${step}`,\n () =>\n new Intl.NumberFormat(locale, {\n style: 'unit',\n unit: UNITS[step]!,\n unitDisplay: 'short',\n maximumFractionDigits: digitsFor(step),\n }),\n )\n}\n\n/**\n * A file size as a reader expects it: 1 200 000 gives \"1.2 MB\" in English, \"1,2 Mo\" in\n * French. Nothing here is translatable — `Intl` knows the unit names and the decimal mark.\n *\n * SI base 1000, which is what the unit names `Intl` prints actually mean. The computing\n * convention of 1024 would show a 1024-byte file as \"1.02 kB\", a discrepancy no reader can\n * explain to themselves. A negative or non-finite size reads as 0: the number comes straight\n * off the file, and a size beside a name must never be the thing that breaks.\n */\nexport function formatBytes(bytes: number, locale: string): string {\n const n = Number.isFinite(bytes) && bytes > 0 ? bytes : 0\n\n let step = n === 0 ? 0 : Math.min(UNITS.length - 1, Math.max(0, Math.floor(Math.log10(n) / 3)))\n let value = n / 1000 ** step\n\n /*\n * The carry. 999 999 bytes belongs on the kB rung and ROUNDS to 1000 at one decimal, so\n * rung and rounding have to agree or the reader is shown \"1,000 kB\" for \"1 MB\". Round\n * first, then step up: the other order lets the same discrepancy through one rung higher.\n */\n const rounded = Math.round(value * 10 ** digitsFor(step)) / 10 ** digitsFor(step)\n if (rounded >= 1000 && step < UNITS.length - 1) {\n step += 1\n value = n / 1000 ** step\n }\n\n return formatterFor(locale, step).format(value)\n}\n\n/**\n * Why a file was turned away: its kind, its size, how many there already are, or the\n * total.\n *\n * VFileInput and VFilePicker screen a batch through the same `screenFiles` below, so the\n * two report the same thing and the type is declared ONCE, here, rather than copied into\n * each of them under a name of its own. It is the `TimePickerAllowed` arrangement: the type\n * lives beside the rule that produces it, and `index.ts` is what makes it public — the\n * MODULE stays internal, and a handler written for one of the two components can be\n * handed to the other.\n */\nexport type FileRejectReason = 'type' | 'size' | 'count' | 'total-size'\n\n/** One file that was turned away, and the reason it was. */\nexport interface FileRejection {\n /** The file itself, so a message can name it. */\n file: File\n /** What it fell foul of. */\n reason: FileRejectReason\n}\n\nexport interface FileLimits {\n accept?: string\n /** How large ONE file may be, in bytes. */\n maxSize?: number\n /** Already settled by the caller: a field that takes a single file passes one. */\n maxFiles?: number\n maxTotalSize?: number\n}\n\n/**\n * Screens an arriving batch against what is already chosen, returning the accepted files\n * and one rejection per refusal.\n *\n * The order `type → size → count → total-size` is a contract both `.mdx` pages state, and\n * it is the order a reader can act on: a file of the wrong KIND is reported as such even\n * when it is also too big, since being told to shrink a file that would never be accepted\n * is worse than useless.\n *\n * Duplicates are deliberately NOT a reason: two files in different folders may share a\n * name, and there is no reliable way to tell one from another. What is already chosen\n * counts towards both the count and the running total, so a second drop obeys the same\n * limits as the first instead of starting over.\n */\nexport function screenFiles(\n incoming: readonly File[],\n current: readonly File[],\n limits: FileLimits,\n): { accepted: File[]; rejected: FileRejection[] } {\n const accepted: File[] = []\n const rejected: FileRejection[] = []\n let total = current.reduce((sum, file) => sum + file.size, 0)\n const accept = parseAccept(limits.accept)\n\n for (const file of incoming) {\n if (!matchesAccept(file, accept)) {\n rejected.push({ file, reason: 'type' })\n continue\n }\n if (limits.maxSize !== undefined && file.size > limits.maxSize) {\n rejected.push({ file, reason: 'size' })\n continue\n }\n if (limits.maxFiles !== undefined && current.length + accepted.length >= limits.maxFiles) {\n rejected.push({ file, reason: 'count' })\n continue\n }\n if (limits.maxTotalSize !== undefined && total + file.size > limits.maxTotalSize) {\n rejected.push({ file, reason: 'total-size' })\n continue\n }\n accepted.push(file)\n total += file.size\n }\n\n return { accepted, rejected }\n}\n"],"mappings":";;AAqBA,SAAgB,EAAY,GAA2B;CAErD,OADK,IACE,EACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAU,EAAM,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAC1C,OAAO,OAAO,IAJG,CAAC;AAKvB;AAkBA,SAAgB,EAAc,GAAqB,GAA8C;CAC/F,IAAM,IAAS,OAAO,KAAW,YAAY,MAAW,KAAA,IAAY,EAAY,CAAM,IAAI;CAC1F,IAAI,EAAO,WAAW,GAAG,OAAO;CAEhC,IAAM,IAAO,EAAK,KAAK,YAAY,GAC7B,IAAO,EAAK,KAAK,YAAY;CAEnC,OAAO,EAAO,MAAM,MACd,MAAU,OAAO,MAAU,QAAc,KACzC,EAAM,WAAW,GAAG,IAAU,EAAK,SAAS,CAAK,IACjD,EAAM,SAAS,IAAI,IAAU,MAAS,MAAM,EAAK,WAAW,EAAM,MAAM,GAAG,EAAE,CAAC,IAC3E,MAAS,CACjB;AACH;AAUA,IAAM,oBAAU,IAAI,QAAsB,GACtC,IAAa;AAEjB,SAAgB,EAAQ,GAAoB;CAC1C,IAAI,IAAK,EAAQ,IAAI,CAAI;CAKzB,OAJI,MAAO,KAAA,MACT,IAAK,KACL,EAAQ,IAAI,GAAM,CAAE,IAEf;AACT;AAGA,IAAM,IAAQ;CAAC;CAAQ;CAAY;CAAY;CAAY;AAAU,GAO/D,oBAAa,IAAI,IAA+B,GAGhD,KAAa,MAAkB,MAAS,IAAI,IAAI;AAEtD,SAAS,EAAa,GAAgB,GAAiC;CACrE,OAAO,EACL,GACA,GAAG,EAAO,GAAG,WAEX,IAAI,KAAK,aAAa,GAAQ;EAC5B,OAAO;EACP,MAAM,EAAM;EACZ,aAAa;EACb,uBAAuB,EAAU,CAAI;CACvC,CAAC,CACL;AACF;AAWA,SAAgB,EAAY,GAAe,GAAwB;CACjE,IAAM,IAAI,OAAO,SAAS,CAAK,KAAK,IAAQ,IAAI,IAAQ,GAEpD,IAAO,MAAM,IAAI,IAAI,KAAK,IAAI,EAAM,SAAS,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAC1F,IAAQ,IAAI,OAAQ;CAaxB,OANgB,KAAK,MAAM,IAAQ,MAAM,EAAU,CAAI,CAAC,IAAI,MAAM,EAAU,CAAI,KACjE,OAAQ,IAAO,EAAM,SAAS,MAC3C,KAAQ,GACR,IAAQ,IAAI,OAAQ,IAGf,EAAa,GAAQ,CAAI,CAAC,CAAC,OAAO,CAAK;AAChD;AA8CA,SAAgB,EACd,GACA,GACA,GACiD;CACjD,IAAM,IAAmB,CAAC,GACpB,IAA4B,CAAC,GAC/B,IAAQ,EAAQ,QAAQ,GAAK,MAAS,IAAM,EAAK,MAAM,CAAC,GACtD,IAAS,EAAY,EAAO,MAAM;CAExC,KAAK,IAAM,KAAQ,GAAU;EAC3B,IAAI,CAAC,EAAc,GAAM,CAAM,GAAG;GAChC,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAO,CAAC;GACtC;EACF;EACA,IAAI,EAAO,YAAY,KAAA,KAAa,EAAK,OAAO,EAAO,SAAS;GAC9D,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAO,CAAC;GACtC;EACF;EACA,IAAI,EAAO,aAAa,KAAA,KAAa,EAAQ,SAAS,EAAS,UAAU,EAAO,UAAU;GACxF,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAQ,CAAC;GACvC;EACF;EACA,IAAI,EAAO,iBAAiB,KAAA,KAAa,IAAQ,EAAK,OAAO,EAAO,cAAc;GAChF,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAa,CAAC;GAC5C;EACF;EAEA,AADA,EAAS,KAAK,CAAI,GAClB,KAAS,EAAK;CAChB;CAEA,OAAO;EAAE;EAAU;CAAS;AAC9B"}
1
+ {"version":3,"file":"file.js","names":[],"sources":["../../src/utils/file.ts"],"sourcesContent":["// @core — module-wide: pure domain logic, no a11y, no DOM, no environment guard.\n/**\n * The FILE domain: whether a file is of an accepted kind, how its size is written out, and\n * which of a batch may come in. Grouped by subject rather than by shared code, like `text.ts`.\n *\n * Nothing here knows about components, which is what shapes the screening: it RETURNS its\n * refusals instead of emitting them. One body then serves VFileInput, which reports them one\n * at a time, and a test that reads them all as a list without a mount.\n */\nimport { memo } from './memo'\n\n/** All the matching needs of a file, so that a test does not have to counterfeit one. */\nexport interface FileCandidate {\n name: string\n type: string\n}\n\n/**\n * An `accept` list read into its tokens: split on commas, trimmed, lowercased, the empty ones\n * dropped. An empty result accepts everything.\n */\nexport function parseAccept(accept?: string): string[] {\n if (!accept) return []\n return accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean)\n}\n\n/**\n * Whether a file matches an `accept` list, written exactly as the HTML attribute is:\n * `.pdf` (case-insensitive), `image/*`, or one precise MIME type. An empty list accepts\n * everything.\n *\n * The rule is applied in JS because the ATTRIBUTE only governs the dialog the browser\n * opens: a DROPPED file bypasses it entirely. Without this second reading, dropping\n * smuggles anything past a restriction the consumer believes is enforced.\n *\n * The list may be handed over already read by `parseAccept`, which is what a batch does:\n * screening a hundred dropped files would otherwise split the same string a hundred times.\n *\n * TRAP: `file.type` is the browser's GUESS and is often empty (an unknown extension, some\n * Linux setups). A list written only in MIME types then turns away a perfectly good file,\n * which is why the docs ask for extensions alongside: `image/*,.heic`, not `image/*` alone.\n */\nexport function matchesAccept(file: FileCandidate, accept?: string | readonly string[]): boolean {\n const tokens = typeof accept === 'string' || accept === undefined ? parseAccept(accept) : accept\n if (tokens.length === 0) return true\n\n const name = file.name.toLowerCase()\n const type = file.type.toLowerCase()\n\n return tokens.some((token) => {\n if (token === '*' || token === '*/*') return true\n if (token.startsWith('.')) return name.endsWith(token)\n if (token.endsWith('/*')) return type !== '' && type.startsWith(token.slice(0, -1))\n return type === token\n })\n}\n\n/**\n * A stable key per FILE OBJECT, for the `v-for` of a file list.\n *\n * An index-based key re-keys every row after a removal, which remounts them — a thumbnail's\n * `<img>` included — and a name is not unique across folders. A File travels through a\n * v-model unproxied (reactivity only wraps plain objects and collections), so its identity is\n * a key that survives both. The map is weak, so a file that leaves every list is not held.\n */\nconst fileIds = new WeakMap<File, number>()\nlet nextFileId = 0\n\nexport function fileKey(file: File): number {\n let id = fileIds.get(file)\n if (id === undefined) {\n id = nextFileId++\n fileIds.set(file, id)\n }\n return id\n}\n\n/** The units a size can be written in, smallest first — the rungs of the ladder. */\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte'] as const\n\n/**\n * Building a number formatter costs one to two orders of magnitude more than using one,\n * and a running total is rewritten every time a file is added — so one is built per\n * language and rung, and kept for as long as the page lives.\n */\nconst formatters = new Map<string, Intl.NumberFormat>()\n\n/** Bytes are counted whole; above that, one decimal is what reads as a size. */\nconst digitsFor = (step: number) => (step === 0 ? 0 : 1)\n\nfunction formatterFor(locale: string, step: number): Intl.NumberFormat {\n return memo(\n formatters,\n `${locale}|${step}`,\n () =>\n new Intl.NumberFormat(locale, {\n style: 'unit',\n unit: UNITS[step]!,\n // The byte rung is spelled out, plural included: CLDR's short English name for a\n // byte is the word \"byte\" itself, which printed \"999 byte\".\n unitDisplay: step === 0 ? 'long' : 'short',\n maximumFractionDigits: digitsFor(step),\n }),\n )\n}\n\n/**\n * A file size as a reader expects it: 1 200 000 gives \"1.2 MB\" in English, \"1,2 Mo\" in\n * French. Nothing here is translatable: `Intl` knows the unit names and the decimal mark.\n *\n * SI base 1000, which is what the unit names `Intl` prints actually mean. The computing\n * convention of 1024 would show a 1024-byte file as \"1.02 kB\", a discrepancy no reader can\n * explain to themselves. A negative or non-finite size reads as 0: the number comes straight\n * off the file, and a size beside a name must never be the thing that breaks.\n */\nexport function formatBytes(bytes: number, locale: string): string {\n const n = Number.isFinite(bytes) && bytes > 0 ? bytes : 0\n\n let step = n === 0 ? 0 : Math.min(UNITS.length - 1, Math.max(0, Math.floor(Math.log10(n) / 3)))\n let value = n / 1000 ** step\n\n /*\n * The carry. 999 999 bytes belongs on the kB rung and ROUNDS to 1000 at one decimal, so\n * rung and rounding have to agree or the reader is shown \"1,000 kB\" for \"1 MB\". Round\n * first, then step up: the other order lets the same discrepancy through one rung higher.\n */\n const rounded = Math.round(value * 10 ** digitsFor(step)) / 10 ** digitsFor(step)\n if (rounded >= 1000 && step < UNITS.length - 1) {\n step += 1\n value = n / 1000 ** step\n }\n\n return formatterFor(locale, step).format(value)\n}\n\n/**\n * Why a file was turned away: its kind, its size, how many there already are, or the\n * total.\n *\n * VFileInput and VFilePicker screen a batch through the same `screenFiles` below, so the\n * two report the same thing and the type is declared ONCE, here, rather than copied into\n * each of them under a name of its own. It is the `TimePickerAllowed` arrangement: the type\n * lives beside the rule that produces it, and `index.ts` is what makes it public. The\n * MODULE stays internal, and a handler written for one of the two components can be\n * handed to the other.\n */\nexport type FileRejectReason = 'type' | 'size' | 'count' | 'total-size'\n\n/** One file that was turned away, and the reason it was. */\nexport interface FileRejection {\n /** The file itself, so a message can name it. */\n file: File\n /** What it fell foul of. */\n reason: FileRejectReason\n}\n\nexport interface FileLimits {\n accept?: string\n /** How large ONE file may be, in bytes. */\n maxSize?: number\n /** Already settled by the caller: a field that takes a single file passes one. */\n maxFiles?: number\n maxTotalSize?: number\n}\n\n/**\n * Screens an arriving batch against what is already chosen, returning the accepted files\n * and one rejection per refusal.\n *\n * The order `type → size → count → total-size` is a contract both `.mdx` pages state, and\n * it is the order a reader can act on: a file of the wrong KIND is reported as such even\n * when it is also too big, since being told to shrink a file that would never be accepted\n * is worse than useless.\n *\n * Duplicates are deliberately NOT a reason: two files in different folders may share a\n * name, and there is no reliable way to tell one from another. What is already chosen\n * counts towards both the count and the running total, so a second drop obeys the same\n * limits as the first instead of starting over.\n */\nexport function screenFiles(\n incoming: readonly File[],\n current: readonly File[],\n limits: FileLimits,\n): { accepted: File[]; rejected: FileRejection[] } {\n const accepted: File[] = []\n const rejected: FileRejection[] = []\n let total = current.reduce((sum, file) => sum + file.size, 0)\n const accept = parseAccept(limits.accept)\n\n for (const file of incoming) {\n if (!matchesAccept(file, accept)) {\n rejected.push({ file, reason: 'type' })\n continue\n }\n if (limits.maxSize !== undefined && file.size > limits.maxSize) {\n rejected.push({ file, reason: 'size' })\n continue\n }\n if (limits.maxFiles !== undefined && current.length + accepted.length >= limits.maxFiles) {\n rejected.push({ file, reason: 'count' })\n continue\n }\n if (limits.maxTotalSize !== undefined && total + file.size > limits.maxTotalSize) {\n rejected.push({ file, reason: 'total-size' })\n continue\n }\n accepted.push(file)\n total += file.size\n }\n\n return { accepted, rejected }\n}\n"],"mappings":";;AAqBA,SAAgB,EAAY,GAA2B;CAErD,OADK,IACE,EACJ,MAAM,GAAG,CAAC,CACV,KAAK,MAAU,EAAM,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAC1C,OAAO,OAAO,IAJG,CAAC;AAKvB;AAkBA,SAAgB,EAAc,GAAqB,GAA8C;CAC/F,IAAM,IAAS,OAAO,KAAW,YAAY,MAAW,KAAA,IAAY,EAAY,CAAM,IAAI;CAC1F,IAAI,EAAO,WAAW,GAAG,OAAO;CAEhC,IAAM,IAAO,EAAK,KAAK,YAAY,GAC7B,IAAO,EAAK,KAAK,YAAY;CAEnC,OAAO,EAAO,MAAM,MACd,MAAU,OAAO,MAAU,QAAc,KACzC,EAAM,WAAW,GAAG,IAAU,EAAK,SAAS,CAAK,IACjD,EAAM,SAAS,IAAI,IAAU,MAAS,MAAM,EAAK,WAAW,EAAM,MAAM,GAAG,EAAE,CAAC,IAC3E,MAAS,CACjB;AACH;AAUA,IAAM,oBAAU,IAAI,QAAsB,GACtC,IAAa;AAEjB,SAAgB,EAAQ,GAAoB;CAC1C,IAAI,IAAK,EAAQ,IAAI,CAAI;CAKzB,OAJI,MAAO,KAAA,MACT,IAAK,KACL,EAAQ,IAAI,GAAM,CAAE,IAEf;AACT;AAGA,IAAM,IAAQ;CAAC;CAAQ;CAAY;CAAY;CAAY;AAAU,GAO/D,oBAAa,IAAI,IAA+B,GAGhD,KAAa,MAAkB,MAAS,IAAI,IAAI;AAEtD,SAAS,EAAa,GAAgB,GAAiC;CACrE,OAAO,EACL,GACA,GAAG,EAAO,GAAG,WAEX,IAAI,KAAK,aAAa,GAAQ;EAC5B,OAAO;EACP,MAAM,EAAM;EAGZ,aAAa,MAAS,IAAI,SAAS;EACnC,uBAAuB,EAAU,CAAI;CACvC,CAAC,CACL;AACF;AAWA,SAAgB,EAAY,GAAe,GAAwB;CACjE,IAAM,IAAI,OAAO,SAAS,CAAK,KAAK,IAAQ,IAAI,IAAQ,GAEpD,IAAO,MAAM,IAAI,IAAI,KAAK,IAAI,EAAM,SAAS,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAC1F,IAAQ,IAAI,OAAQ;CAaxB,OANgB,KAAK,MAAM,IAAQ,MAAM,EAAU,CAAI,CAAC,IAAI,MAAM,EAAU,CAAI,KACjE,OAAQ,IAAO,EAAM,SAAS,MAC3C,KAAQ,GACR,IAAQ,IAAI,OAAQ,IAGf,EAAa,GAAQ,CAAI,CAAC,CAAC,OAAO,CAAK;AAChD;AA8CA,SAAgB,EACd,GACA,GACA,GACiD;CACjD,IAAM,IAAmB,CAAC,GACpB,IAA4B,CAAC,GAC/B,IAAQ,EAAQ,QAAQ,GAAK,MAAS,IAAM,EAAK,MAAM,CAAC,GACtD,IAAS,EAAY,EAAO,MAAM;CAExC,KAAK,IAAM,KAAQ,GAAU;EAC3B,IAAI,CAAC,EAAc,GAAM,CAAM,GAAG;GAChC,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAO,CAAC;GACtC;EACF;EACA,IAAI,EAAO,YAAY,KAAA,KAAa,EAAK,OAAO,EAAO,SAAS;GAC9D,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAO,CAAC;GACtC;EACF;EACA,IAAI,EAAO,aAAa,KAAA,KAAa,EAAQ,SAAS,EAAS,UAAU,EAAO,UAAU;GACxF,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAQ,CAAC;GACvC;EACF;EACA,IAAI,EAAO,iBAAiB,KAAA,KAAa,IAAQ,EAAK,OAAO,EAAO,cAAc;GAChF,EAAS,KAAK;IAAE;IAAM,QAAQ;GAAa,CAAC;GAC5C;EACF;EAEA,AADA,EAAS,KAAK,CAAI,GAClB,KAAS,EAAK;CAChB;CAEA,OAAO;EAAE;EAAU;CAAS;AAC9B"}
@@ -7,7 +7,7 @@
7
7
  * engine that throws on a pseudo-class it cannot parse; the keyboard is the careful answer
8
8
  * there, being the one that keeps a component reachable.
9
9
  *
10
- * TRAP for the tests — jsdom is NOT that environment. It parses `:focus-visible` happily and
10
+ * TRAP for the tests: jsdom is NOT that environment. It parses `:focus-visible` happily and
11
11
  * answers `false` for everything, a genuinely focused element included, so the `catch` never
12
12
  * runs and every test silently takes the pointer branch. Stub `matches` on the element being
13
13
  * asked; what that locks is that the component ASKS and branches, never jsdom's answer.
@@ -1 +1 @@
1
- {"version":3,"file":"focus.js","names":[],"sources":["../../src/utils/focus.ts"],"sourcesContent":["// @a11y @fallback\n/**\n * Whether this element is focused the way a keyboard user focuses things.\n *\n * A `focus` event does not carry the distinction: a mouse click and a Tab leave an element in\n * the same state. The browser already makes the judgement for its own focus rings and\n * publishes it as `:focus-visible`, so that is what gets asked. The `try` covers a selector\n * engine that throws on a pseudo-class it cannot parse; the keyboard is the careful answer\n * there, being the one that keeps a component reachable.\n *\n * TRAP for the tests — jsdom is NOT that environment. It parses `:focus-visible` happily and\n * answers `false` for everything, a genuinely focused element included, so the `catch` never\n * runs and every test silently takes the pointer branch. Stub `matches` on the element being\n * asked; what that locks is that the component ASKS and branches, never jsdom's answer.\n */\nexport function isKeyboardFocus(target: EventTarget | null): boolean {\n if (!(target instanceof Element)) return false\n try {\n return target.matches(':focus-visible')\n } catch {\n return true\n }\n}\n"],"mappings":";AAeA,SAAgB,EAAgB,GAAqC;CACnE,IAAI,EAAE,aAAkB,UAAU,OAAO;CACzC,IAAI;EACF,OAAO,EAAO,QAAQ,gBAAgB;CACxC,QAAQ;EACN,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"focus.js","names":[],"sources":["../../src/utils/focus.ts"],"sourcesContent":["// @a11y @fallback\n/**\n * Whether this element is focused the way a keyboard user focuses things.\n *\n * A `focus` event does not carry the distinction: a mouse click and a Tab leave an element in\n * the same state. The browser already makes the judgement for its own focus rings and\n * publishes it as `:focus-visible`, so that is what gets asked. The `try` covers a selector\n * engine that throws on a pseudo-class it cannot parse; the keyboard is the careful answer\n * there, being the one that keeps a component reachable.\n *\n * TRAP for the tests: jsdom is NOT that environment. It parses `:focus-visible` happily and\n * answers `false` for everything, a genuinely focused element included, so the `catch` never\n * runs and every test silently takes the pointer branch. Stub `matches` on the element being\n * asked; what that locks is that the component ASKS and branches, never jsdom's answer.\n */\nexport function isKeyboardFocus(target: EventTarget | null): boolean {\n if (!(target instanceof Element)) return false\n try {\n return target.matches(':focus-visible')\n } catch {\n return true\n }\n}\n"],"mappings":";AAeA,SAAgB,EAAgB,GAAqC;CACnE,IAAI,EAAE,aAAkB,UAAU,OAAO;CACzC,IAAI;EACF,OAAO,EAAO,QAAQ,gBAAgB;CACxC,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -3,7 +3,7 @@ import { InjectionKey } from 'vue';
3
3
  * Provided by a component that renders another with props it has ALREADY checked and
4
4
  * reported on: VDateInput for VDatePicker's bounds, VTimeInput for VTimePicker's step and
5
5
  * restrictions, both forwarded as they stand. The component inside then keeps those warnings
6
- * to itself — the consumer wrote the host, and a second copy of the same sentence under a
6
+ * to itself. The consumer wrote the host, and a second copy of the same sentence under a
7
7
  * name they never typed is noise.
8
8
  *
9
9
  * A module of its own and not a line in `env.ts`: that one is in nearly every closure, where a
@@ -1 +1 @@
1
- {"version":3,"file":"hostWarns.js","names":[],"sources":["../../src/utils/hostWarns.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\n\n/**\n * Provided by a component that renders another with props it has ALREADY checked and\n * reported on: VDateInput for VDatePicker's bounds, VTimeInput for VTimePicker's step and\n * restrictions, both forwarded as they stand. The component inside then keeps those warnings\n * to itself — the consumer wrote the host, and a second copy of the same sentence under a\n * name they never typed is noise.\n *\n * A module of its own and not a line in `env.ts`: that one is in nearly every closure, where a\n * key only four components read added bytes to all of them.\n */\nexport const hostWarnsKey: InjectionKey<true> = Symbol('vectisHostWarns')\n"],"mappings":";AAYA,IAAa,IAAmC,OAAO,iBAAiB"}
1
+ {"version":3,"file":"hostWarns.js","names":[],"sources":["../../src/utils/hostWarns.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\n\n/**\n * Provided by a component that renders another with props it has ALREADY checked and\n * reported on: VDateInput for VDatePicker's bounds, VTimeInput for VTimePicker's step and\n * restrictions, both forwarded as they stand. The component inside then keeps those warnings\n * to itself. The consumer wrote the host, and a second copy of the same sentence under a\n * name they never typed is noise.\n *\n * A module of its own and not a line in `env.ts`: that one is in nearly every closure, where a\n * key only four components read added bytes to all of them.\n */\nexport const hostWarnsKey: InjectionKey<true> = Symbol('vectisHostWarns')\n"],"mappings":";AAYA,IAAa,IAAmC,OAAO,iBAAiB"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * An IDREF list — the value of `aria-describedby` or `aria-labelledby` — assembled from
2
+ * An IDREF list: the value of `aria-describedby` or `aria-labelledby`: assembled from
3
3
  * references that may each be absent. The empty ones are dropped by TRUTHINESS, so an empty
4
4
  * string contributes nothing, and a list left with no reference at all is `undefined`, which
5
5
  * removes the attribute instead of writing an empty one.
@@ -1 +1 @@
1
- {"version":3,"file":"ids.js","names":[],"sources":["../../src/utils/ids.ts"],"sourcesContent":["// @a11y\n/**\n * An IDREF list — the value of `aria-describedby` or `aria-labelledby` — assembled from\n * references that may each be absent. The empty ones are dropped by TRUTHINESS, so an empty\n * string contributes nothing, and a list left with no reference at all is `undefined`, which\n * removes the attribute instead of writing an empty one.\n *\n * A module of its own rather than a line in `text.ts`: every field loads it, and none of them\n * should pay for the text helpers to get it.\n */\nexport function joinIds(...ids: (string | false | null | undefined)[]): string | undefined {\n return ids.filter(Boolean).join(' ') || undefined\n}\n"],"mappings":";AAUA,SAAgB,EAAQ,GAAG,GAAgE;CACzF,OAAO,EAAI,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;AAC1C"}
1
+ {"version":3,"file":"ids.js","names":[],"sources":["../../src/utils/ids.ts"],"sourcesContent":["// @a11y\n/**\n * An IDREF list: the value of `aria-describedby` or `aria-labelledby`: assembled from\n * references that may each be absent. The empty ones are dropped by TRUTHINESS, so an empty\n * string contributes nothing, and a list left with no reference at all is `undefined`, which\n * removes the attribute instead of writing an empty one.\n *\n * A module of its own rather than a line in `text.ts`: every field loads it, and none of them\n * should pay for the text helpers to get it.\n */\nexport function joinIds(...ids: (string | false | null | undefined)[]): string | undefined {\n return ids.filter(Boolean).join(' ') || undefined\n}\n"],"mappings":";AAUA,SAAgB,EAAQ,GAAG,GAAgE;CACzF,OAAO,EAAI,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;AAC1C"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Turns the design system's "which entries are unavailable" props — `disabledDates`,
3
- * `disabledPages` and their kind, each accepting a list OR a predicate — into one
2
+ * Turns the design system's "which entries are unavailable" props: `disabledDates`,
3
+ * `disabledPages` and their kind, each accepting a list OR a predicate, into one
4
4
  * function to ask, so components need not care which they were handed.
5
5
  *
6
6
  * Resolve it ONCE inside a `computed`, never per value: the list becomes a `Set` here, so
@@ -1 +1 @@
1
- {"version":3,"file":"matcher.js","names":[],"sources":["../../src/utils/matcher.ts"],"sourcesContent":["// @core\n/**\n * Turns the design system's \"which entries are unavailable\" props — `disabledDates`,\n * `disabledPages` and their kind, each accepting a list OR a predicate — into one\n * function to ask, so components need not care which they were handed.\n *\n * Resolve it ONCE inside a `computed`, never per value: the list becomes a `Set` here, so\n * each lookup is immediate where an `includes` would rescan it for every cell on screen.\n */\nexport function resolveMatcher<T>(\n matcher: readonly T[] | ((value: T) => boolean) | undefined,\n): (value: T) => boolean {\n if (!matcher) return () => false\n if (typeof matcher === 'function') return matcher\n const set = new Set(matcher)\n return (value: T) => set.has(value)\n}\n"],"mappings":";AASA,SAAgB,EACd,GACuB;CACvB,IAAI,CAAC,GAAS,aAAa;CAC3B,IAAI,OAAO,KAAY,YAAY,OAAO;CAC1C,IAAM,IAAM,IAAI,IAAI,CAAO;CAC3B,QAAQ,MAAa,EAAI,IAAI,CAAK;AACpC"}
1
+ {"version":3,"file":"matcher.js","names":[],"sources":["../../src/utils/matcher.ts"],"sourcesContent":["// @core\n/**\n * Turns the design system's \"which entries are unavailable\" props: `disabledDates`,\n * `disabledPages` and their kind, each accepting a list OR a predicate, into one\n * function to ask, so components need not care which they were handed.\n *\n * Resolve it ONCE inside a `computed`, never per value: the list becomes a `Set` here, so\n * each lookup is immediate where an `includes` would rescan it for every cell on screen.\n */\nexport function resolveMatcher<T>(\n matcher: readonly T[] | ((value: T) => boolean) | undefined,\n): (value: T) => boolean {\n if (!matcher) return () => false\n if (typeof matcher === 'function') return matcher\n const set = new Set(matcher)\n return (value: T) => set.has(value)\n}\n"],"mappings":";AASA,SAAgB,EACd,GACuB;CACvB,IAAI,CAAC,GAAS,aAAa;CAC3B,IAAI,OAAO,KAAY,YAAY,OAAO;CAC1C,IAAM,IAAM,IAAI,IAAI,CAAO;CAC3B,QAAQ,MAAa,EAAI,IAAI,CAAK;AACpC"}
@@ -6,7 +6,7 @@
6
6
  * called one value at a time. What each cache holds is the helper's own business; the
7
7
  * get-or-build around it is the same everywhere, and written here once.
8
8
  *
9
- * `undefined` is the miss marker, so a builder must never return it — none does, every entry
9
+ * `undefined` is the miss marker, so a builder must never return it. None does, every entry
10
10
  * being an object, a string or a number.
11
11
  */
12
12
  export declare function memo<K, V>(cache: Map<K, V>, key: K, build: () => V): V;
@@ -1 +1 @@
1
- {"version":3,"file":"memo.js","names":[],"sources":["../../src/utils/memo.ts"],"sourcesContent":["// @core\n/**\n * Reads a module-level cache, building the entry on its first miss.\n *\n * The `Intl` helpers in `date.ts`, `time.ts` and `file.ts` all keep one: an `Intl` object\n * costs one to two orders of magnitude more to build than to use, and those helpers are\n * called one value at a time. What each cache holds is the helper's own business; the\n * get-or-build around it is the same everywhere, and written here once.\n *\n * `undefined` is the miss marker, so a builder must never return it — none does, every entry\n * being an object, a string or a number.\n */\nexport function memo<K, V>(cache: Map<K, V>, key: K, build: () => V): V {\n let value = cache.get(key)\n if (value === undefined) {\n value = build()\n cache.set(key, value)\n }\n return value\n}\n"],"mappings":";AAYA,SAAgB,EAAW,GAAkB,GAAQ,GAAmB;CACtE,IAAI,IAAQ,EAAM,IAAI,CAAG;CAKzB,OAJI,MAAU,KAAA,MACZ,IAAQ,EAAM,GACd,EAAM,IAAI,GAAK,CAAK,IAEf;AACT"}
1
+ {"version":3,"file":"memo.js","names":[],"sources":["../../src/utils/memo.ts"],"sourcesContent":["// @core\n/**\n * Reads a module-level cache, building the entry on its first miss.\n *\n * The `Intl` helpers in `date.ts`, `time.ts` and `file.ts` all keep one: an `Intl` object\n * costs one to two orders of magnitude more to build than to use, and those helpers are\n * called one value at a time. What each cache holds is the helper's own business; the\n * get-or-build around it is the same everywhere, and written here once.\n *\n * `undefined` is the miss marker, so a builder must never return it. None does, every entry\n * being an object, a string or a number.\n */\nexport function memo<K, V>(cache: Map<K, V>, key: K, build: () => V): V {\n let value = cache.get(key)\n if (value === undefined) {\n value = build()\n cache.set(key, value)\n }\n return value\n}\n"],"mappings":";AAYA,SAAgB,EAAW,GAAkB,GAAQ,GAAmB;CACtE,IAAI,IAAQ,EAAM,IAAI,CAAG;CAKzB,OAJI,MAAU,KAAA,MACZ,IAAQ,EAAM,GACd,EAAM,IAAI,GAAK,CAAK,IAEf;AACT"}
@@ -7,8 +7,8 @@
7
7
  */
8
8
  export declare function normalizeText(s: string): string;
9
9
  /**
10
- * A memory of `normalizeText` results, filed under the object a text belongs to — a table row,
11
- * a combobox option — and under a field name when one object holds several texts.
10
+ * A memory of `normalizeText` results, filed under the object a text belongs to: a table row,
11
+ * a combobox option, and under a field name when one object holds several texts.
12
12
  *
13
13
  * A filter normalizes the whole list again on every keystroke, and normalizing decomposes,
14
14
  * strips and lowercases each string: this is what makes the second keystroke cost a lookup.
@@ -19,7 +19,7 @@ export declare function normalizeText(s: string): string;
19
19
  * the list lets the old entries be collected with no invalidation written anywhere.
20
20
  */
21
21
  export declare function createNormalizedCache<K extends object>(): (owner: K, raw: string, field?: string) => string;
22
- /** A whole number written on two digits, so that 7 becomes "07" — as dates and times are. */
22
+ /** A whole number written on two digits, so that 7 becomes "07": as dates and times are. */
23
23
  export declare function pad2(n: number): string;
24
24
  /**
25
25
  * Just the digits of a string, everything else dropped.
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":[],"sources":["../../src/utils/text.ts"],"sourcesContent":["// @core\n/**\n * The form of a text used for COMPARING it: case and accents no longer count.\n *\n * NFD splits each letter into the plain letter and its mark, and the marks are dropped.\n * Used wherever the library matches a list against what someone typed: searching \"e\" has\n * to find \"é\", nobody reaching for the right accent to find a name.\n */\nexport function normalizeText(s: string): string {\n return s\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n}\n\n// @core\n/**\n * A memory of `normalizeText` results, filed under the object a text belongs to — a table row,\n * a combobox option — and under a field name when one object holds several texts.\n *\n * A filter normalizes the whole list again on every keystroke, and normalizing decomposes,\n * strips and lowercases each string: this is what makes the second keystroke cost a lookup.\n *\n * The raw text is passed on EVERY call and compared with the one remembered, rather than the\n * list being derived once: that is what notices a label edited in place, which a value keyed\n * on the list alone would not. And the memory is a `WeakMap` keyed by the owner, so replacing\n * the list lets the old entries be collected with no invalidation written anywhere.\n */\nexport function createNormalizedCache<K extends object>() {\n const cache = new WeakMap<K, Map<string, { raw: string; normalized: string }>>()\n return (owner: K, raw: string, field = ''): string => {\n let texts = cache.get(owner)\n if (!texts) {\n texts = new Map()\n cache.set(owner, texts)\n }\n const hit = texts.get(field)\n if (hit && hit.raw === raw) return hit.normalized\n const normalized = normalizeText(raw)\n texts.set(field, { raw, normalized })\n return normalized\n }\n}\n\n// @core\n/** A whole number written on two digits, so that 7 becomes \"07\" — as dates and times are. */\nexport function pad2(n: number): string {\n return String(n).padStart(2, '0')\n}\n\n// @core\n/**\n * Just the digits of a string, everything else dropped.\n *\n * It knows nothing of dates or times, which is why it lives here rather than with either:\n * the masked fields only ever handle the run of digits and place the separators themselves.\n */\nexport const digitsOf = (text: string): string => text.replace(/\\D/g, '')\n"],"mappings":";AAQA,SAAgB,EAAc,GAAmB;CAC/C,OAAO,EACJ,UAAU,KAAK,CAAC,CAChB,QAAQ,oBAAoB,EAAE,CAAC,CAC/B,YAAY;AACjB;AAeA,SAAgB,IAA0C;CACxD,IAAM,oBAAQ,IAAI,QAA6D;CAC/E,QAAQ,GAAU,GAAa,IAAQ,OAAe;EACpD,IAAI,IAAQ,EAAM,IAAI,CAAK;EAC3B,AAAK,MACH,oBAAQ,IAAI,IAAI,GAChB,EAAM,IAAI,GAAO,CAAK;EAExB,IAAM,IAAM,EAAM,IAAI,CAAK;EAC3B,IAAI,KAAO,EAAI,QAAQ,GAAK,OAAO,EAAI;EACvC,IAAM,IAAa,EAAc,CAAG;EAEpC,OADA,EAAM,IAAI,GAAO;GAAE;GAAK;EAAW,CAAC,GAC7B;CACT;AACF;AAIA,SAAgB,EAAK,GAAmB;CACtC,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;AAClC;AASA,IAAa,KAAY,MAAyB,EAAK,QAAQ,OAAO,EAAE"}
1
+ {"version":3,"file":"text.js","names":[],"sources":["../../src/utils/text.ts"],"sourcesContent":["// @core\n/**\n * The form of a text used for COMPARING it: case and accents no longer count.\n *\n * NFD splits each letter into the plain letter and its mark, and the marks are dropped.\n * Used wherever the library matches a list against what someone typed: searching \"e\" has\n * to find \"é\", nobody reaching for the right accent to find a name.\n */\nexport function normalizeText(s: string): string {\n return s\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n}\n\n// @core\n/**\n * A memory of `normalizeText` results, filed under the object a text belongs to: a table row,\n * a combobox option, and under a field name when one object holds several texts.\n *\n * A filter normalizes the whole list again on every keystroke, and normalizing decomposes,\n * strips and lowercases each string: this is what makes the second keystroke cost a lookup.\n *\n * The raw text is passed on EVERY call and compared with the one remembered, rather than the\n * list being derived once: that is what notices a label edited in place, which a value keyed\n * on the list alone would not. And the memory is a `WeakMap` keyed by the owner, so replacing\n * the list lets the old entries be collected with no invalidation written anywhere.\n */\nexport function createNormalizedCache<K extends object>() {\n const cache = new WeakMap<K, Map<string, { raw: string; normalized: string }>>()\n return (owner: K, raw: string, field = ''): string => {\n let texts = cache.get(owner)\n if (!texts) {\n texts = new Map()\n cache.set(owner, texts)\n }\n const hit = texts.get(field)\n if (hit && hit.raw === raw) return hit.normalized\n const normalized = normalizeText(raw)\n texts.set(field, { raw, normalized })\n return normalized\n }\n}\n\n// @core\n/** A whole number written on two digits, so that 7 becomes \"07\": as dates and times are. */\nexport function pad2(n: number): string {\n return String(n).padStart(2, '0')\n}\n\n// @core\n/**\n * Just the digits of a string, everything else dropped.\n *\n * It knows nothing of dates or times, which is why it lives here rather than with either:\n * the masked fields only ever handle the run of digits and place the separators themselves.\n */\nexport const digitsOf = (text: string): string => text.replace(/\\D/g, '')\n"],"mappings":";AAQA,SAAgB,EAAc,GAAmB;CAC/C,OAAO,EACJ,UAAU,KAAK,CAAC,CAChB,QAAQ,oBAAoB,EAAE,CAAC,CAC/B,YAAY;AACjB;AAeA,SAAgB,IAA0C;CACxD,IAAM,oBAAQ,IAAI,QAA6D;CAC/E,QAAQ,GAAU,GAAa,IAAQ,OAAe;EACpD,IAAI,IAAQ,EAAM,IAAI,CAAK;EAC3B,AAAK,MACH,oBAAQ,IAAI,IAAI,GAChB,EAAM,IAAI,GAAO,CAAK;EAExB,IAAM,IAAM,EAAM,IAAI,CAAK;EAC3B,IAAI,KAAO,EAAI,QAAQ,GAAK,OAAO,EAAI;EACvC,IAAM,IAAa,EAAc,CAAG;EAEpC,OADA,EAAM,IAAI,GAAO;GAAE;GAAK;EAAW,CAAC,GAC7B;CACT;AACF;AAIA,SAAgB,EAAK,GAAmB;CACtC,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;AAClC;AASA,IAAa,KAAY,MAAyB,EAAK,QAAQ,OAAO,EAAE"}
@@ -5,36 +5,12 @@ export interface TimeParts {
5
5
  hour: number;
6
6
  minute: number;
7
7
  }
8
- /** Whether something is a time in the canonical form — two digits, a colon, two digits. */
8
+ /** Whether something is a time in the canonical form: two digits, a colon, two digits. */
9
9
  export declare function isValidTime(value: unknown): value is string;
10
10
  /** Reads a canonical time into its two numbers, or nothing at all if it is not one. */
11
11
  export declare function parseTime(value: string | null | undefined): TimeParts | null;
12
12
  /** Writes an hour and a minute back into the canonical form, both on two digits. */
13
13
  export declare function formatTime(hour: number, minute: number): string;
14
- /**
15
- * Turns an hour of the 24-hour clock into the hour a 12-hour clock face shows, together
16
- * with which half of the day it belongs to: midnight is 12 AM, noon is 12 PM, and eleven
17
- * at night is 11 PM.
18
- */
19
- export declare function to12h(hour24: number): {
20
- hour: number;
21
- meridiem: Meridiem;
22
- };
23
- /**
24
- * The way back: an hour read off a 12-hour clock face, plus the half of the day it is in,
25
- * gives the hour on the 24-hour clock — 12 in the morning is 0, 12 in the afternoon is 12.
26
- */
27
- export declare function to24h(hour12: number, meridiem: Meridiem): number;
28
- /**
29
- * The same hour moved into the other half of the day, or left where it is: 9 with PM gives
30
- * 21, and 21 with PM stays 21. It is what an AM/PM control does to the hour it qualifies.
31
- */
32
- export declare function hourWithMeridiem(hour24: number, meridiem: Meridiem): number;
33
- /**
34
- * A canonical time moved into a half of the day, its minutes untouched, or `null` when it is
35
- * not a time at all: `'09:30'` with PM gives `'21:30'`.
36
- */
37
- export declare function withMeridiem(time: string | null | undefined, meridiem: Meridiem): string | null;
38
14
  /**
39
15
  * Whether a language counts the hours to twelve, with a morning and an afternoon, or
40
16
  * straight to twenty-four. It is the browser that knows, and it is asked.
@@ -51,80 +27,5 @@ export declare function hourCycleFor(locale: string): HourFormat;
51
27
  * must get theirs.
52
28
  */
53
29
  export declare function formatTimeDisplay(time: string, locale: string, format: HourFormat): string;
54
- /**
55
- * Snaps a minute to the nearest allowed step and wraps it back inside the hour.
56
- *
57
- * Both ends need the wrap: 58 snapped to five-minute steps lands on 60, which is 0, and
58
- * stepping back from 0 with the keyboard passes through -1, which is 59.
59
- */
60
- export declare function snapMinute(minute: number, step: number): number;
61
- /**
62
- * Which mark a pointer offset from the dial's centre is aiming at. Marks are numbered
63
- * clockwise from twelve o'clock and the nearest wins. `dy` is negated because screen
64
- * coordinates grow DOWNWARD and the angle is measured from the top.
65
- */
66
- export declare function angleToIndex(dx: number, dy: number, segments: number): number;
67
- /** How far from the centre a finger landed, as a fraction: nothing at the centre, one at the edge. */
68
- export declare function distanceFraction(dx: number, dy: number, radius: number): number;
69
- /**
70
- * How close to the centre a pointer must land to be aiming at the INNER ring, the one
71
- * holding the small hours of a 24-hour dial: the halfway mark between the two rings.
72
- *
73
- * TRAP — the number is DERIVED from the dial tokens. A 256px dial with 48px numerals puts
74
- * the rings' centres at 104px and 56px from the middle, whose midpoint is 0.625 of the
75
- * radius. Change either token without changing this and the threshold no longer separates
76
- * the two rings: a tap near the boundary quietly sets the wrong hour.
77
- */
78
- export declare const DIAL_INNER_THRESHOLD = 0.625;
79
- /**
80
- * Which hour a mark stands for on the two-ring dial: outer carries 12 then 1-11, inner
81
- * carries 00 then 13-23. Index 0 of each is the mark at twelve o'clock.
82
- */
83
- export declare function dialIndexToHour24(index: number, ring: 'outer' | 'inner'): number;
84
- /** The way back, which is what tells the hand where to point. */
85
- export declare function hour24ToDial(hour: number): {
86
- index: number;
87
- ring: 'outer' | 'inner';
88
- };
89
- export interface TimeOption {
90
- /** The canonical time, which is what the component's value will be set to. */
91
- value: string;
92
- /** The same time written out for the reader: "07:30", or "7:30 AM". */
93
- label: string;
94
- }
95
- /** A time as minutes since midnight, `null` if it is not one — its position in a list. */
30
+ /** A time as minutes since midnight, `null` if it is not one: its position in a list. */
96
31
  export declare function minutesOf(time: string | null | undefined): number | null;
97
- /**
98
- * Every time of the day at a given interval, midnight to the last one before the next.
99
- *
100
- * There is deliberately no earliest or latest, VTimePicker having none: do not invent one.
101
- * A nonsensical step — zero, a fraction, more than an hour — falls back to hourly, so the
102
- * list stays FINITE even when the component's warning about it was ignored.
103
- */
104
- export declare function timeList(step: number, locale: string, format: HourFormat): TimeOption[];
105
- /**
106
- * Lays a run of typed digits out as a time. The colon appears AS SOON AS the hour is
107
- * complete — typing "09" already gives "09:" — exactly as a date's separators do.
108
- */
109
- export declare function formatTimeMask(digits: string): string;
110
- /**
111
- * Where the caret belongs to sit just after `n` digits. A closed formula rather than
112
- * `date.ts`'s scan, the colon always being in the same place.
113
- *
114
- * `skipSeparator` means something was INSERTED, and the caret then steps over the colon
115
- * into the minutes. On a DELETION it stays in front of it, or the next Backspace steps
116
- * over the colon instead of erasing a digit and the key appears to do nothing.
117
- */
118
- export declare function timeCaret(n: number, skipSeparator?: boolean): number;
119
- /**
120
- * A canonical time written into the field in whichever form is SHOWN. On a 12-hour clock the
121
- * hour comes back into 1-12: the meridiem belongs to the toggle beside the field, never to
122
- * the text.
123
- */
124
- export declare function timeToMask(time: string | null | undefined, format: HourFormat): string;
125
- /**
126
- * What was typed read back into a canonical time, or `null` when it is incomplete, too long
127
- * or not a real time. On a 12-hour clock this is the ONE place the typed digits and the
128
- * meridiem toggle meet.
129
- */
130
- export declare function parseTimeMask(text: string, format: HourFormat, meridiem?: Meridiem): string | null;