vectis-ui 0.1.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/README.md +40 -6
  2. package/dist/components/VAccordion/VAccordion.css +1 -1
  3. package/dist/components/VAccordion/VAccordion.d.ts +9 -16
  4. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  5. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
  6. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/VAccordion/VAccordionItem.css +1 -1
  8. package/dist/components/VAccordion/VAccordionItem.d.ts +33 -19
  9. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  10. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +50 -38
  11. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/VAccordion/context.d.ts +1 -8
  13. package/dist/components/VAccordion/context.js.map +1 -1
  14. package/dist/components/VAvatar/VAvatar.css +1 -1
  15. package/dist/components/VAvatar/VAvatar.d.ts +44 -29
  16. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  17. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +38 -35
  18. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VAvatar/VAvatarGroup.d.ts +5 -16
  20. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  21. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +7 -7
  22. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/VAvatar/context.d.ts +6 -10
  24. package/dist/components/VAvatar/context.js.map +1 -1
  25. package/dist/components/VBadge/VBadge.css +1 -1
  26. package/dist/components/VBadge/VBadge.d.ts +31 -10
  27. package/dist/components/VBadge/VBadge.js.map +1 -1
  28. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +39 -24
  29. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/VBreadcrumb/VBreadcrumb.css +1 -1
  31. package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +4 -17
  32. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  33. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +23 -25
  34. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/VButton/VButton.css +1 -1
  36. package/dist/components/VButton/VButton.d.ts +30 -10
  37. package/dist/components/VButton/VButton.js.map +1 -1
  38. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +39 -30
  39. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/VButton/VButtonGroup.css +1 -1
  41. package/dist/components/VButton/VButtonGroup.d.ts +76 -13
  42. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  43. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +74 -8
  44. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/VButton/context.d.ts +30 -0
  46. package/dist/components/VButton/context.js +6 -0
  47. package/dist/components/VButton/context.js.map +1 -0
  48. package/dist/components/VCalendar/VCalendar.css +1 -1
  49. package/dist/components/VCalendar/VCalendar.d.ts +50 -36
  50. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  51. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +99 -85
  52. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/VCalendar/VCalendarEvent.css +1 -1
  54. package/dist/components/VCalendar/VCalendarEvent.d.ts +5 -11
  55. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  56. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +7 -1
  57. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/VCalendar/VCalendarMonth.css +1 -1
  59. package/dist/components/VCalendar/VCalendarMonth.d.ts +10 -13
  60. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  61. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +183 -244
  62. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
  64. package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +15 -20
  65. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  66. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +385 -448
  67. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/VCalendar/VCalendarYear.css +1 -1
  69. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  70. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +53 -49
  71. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/VCalendar/gesture.d.ts +158 -0
  73. package/dist/components/VCalendar/gesture.js +170 -0
  74. package/dist/components/VCalendar/gesture.js.map +1 -0
  75. package/dist/components/VCalendar/keyboard.d.ts +9 -3
  76. package/dist/components/VCalendar/keyboard.js +2 -6
  77. package/dist/components/VCalendar/keyboard.js.map +1 -1
  78. package/dist/components/VCalendar/layout.d.ts +67 -54
  79. package/dist/components/VCalendar/layout.js +77 -69
  80. package/dist/components/VCalendar/layout.js.map +1 -1
  81. package/dist/components/VCalendar/timeGrid.d.ts +55 -0
  82. package/dist/components/VCalendar/timeGrid.js +71 -0
  83. package/dist/components/VCalendar/timeGrid.js.map +1 -0
  84. package/dist/components/VCalendar/types.d.ts +41 -16
  85. package/dist/components/VCarousel/VCarousel.css +1 -1
  86. package/dist/components/VCarousel/VCarousel.d.ts +21 -41
  87. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  88. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +157 -129
  89. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  90. package/dist/components/VCarousel/VCarouselItem.d.ts +0 -17
  91. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  92. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/VCarousel/context.d.ts +0 -12
  94. package/dist/components/VCarousel/context.js.map +1 -1
  95. package/dist/components/VCheckbox/VCheckbox.css +1 -1
  96. package/dist/components/VCheckbox/VCheckbox.d.ts +31 -16
  97. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  98. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +62 -29
  99. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/VChip/VChip.css +1 -1
  101. package/dist/components/VChip/VChip.d.ts +36 -26
  102. package/dist/components/VChip/VChip.js.map +1 -1
  103. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +57 -48
  104. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/VCombobox/VCombobox.css +1 -1
  106. package/dist/components/VCombobox/VCombobox.d.ts +127 -31
  107. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  108. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +336 -247
  109. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/components/VCombobox/VComboboxGroup.css +1 -1
  111. package/dist/components/VCombobox/VComboboxGroup.d.ts +0 -9
  112. package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
  113. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  114. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/VCombobox/VComboboxOption.css +1 -1
  116. package/dist/components/VCombobox/VComboboxOption.d.ts +0 -15
  117. package/dist/components/VCombobox/VComboboxOption.js.map +1 -1
  118. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +4 -4
  119. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -1
  121. package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
  123. package/dist/components/VDataTable/VDataTable.css +1 -1
  124. package/dist/components/VDataTable/VDataTable.d.ts +50 -28
  125. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  126. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +183 -194
  127. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  128. package/dist/components/VDateInput/VDateInput.css +1 -1
  129. package/dist/components/VDateInput/VDateInput.d.ts +90 -42
  130. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  131. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +159 -191
  132. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/VDatePicker/VDatePicker.css +1 -1
  134. package/dist/components/VDatePicker/VDatePicker.d.ts +61 -30
  135. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  136. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +243 -221
  137. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/components/VDialog/VDialog.css +1 -1
  139. package/dist/components/VDialog/VDialog.d.ts +45 -33
  140. package/dist/components/VDialog/VDialog.js.map +1 -1
  141. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +65 -64
  142. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/VDialog/VDialogAlert.d.ts +24 -20
  144. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  145. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +36 -25
  146. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  147. package/dist/components/VFileInput/VFileInput.css +1 -1
  148. package/dist/components/VFileInput/VFileInput.d.ts +78 -26
  149. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  150. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +144 -132
  151. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  152. package/dist/components/VFilePicker/VFilePicker.css +1 -1
  153. package/dist/components/VFilePicker/VFilePicker.d.ts +47 -30
  154. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  155. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +166 -163
  156. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  157. package/dist/components/VFilePicker/fileKind.d.ts +2 -27
  158. package/dist/components/VFilePicker/fileKind.js +9 -8
  159. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  160. package/dist/components/VHotkeys/VHotkeys.css +1 -1
  161. package/dist/components/VHotkeys/VHotkeys.d.ts +8 -30
  162. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  163. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +4 -4
  164. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/VHotkeys/platform.js.map +1 -1
  166. package/dist/components/VIcon/VIcon.css +1 -1
  167. package/dist/components/VIcon/VIcon.d.ts +15 -6
  168. package/dist/components/VIcon/VIcon.js.map +1 -1
  169. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +45 -37
  170. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  171. package/dist/components/VIcon/iconProps.js.map +1 -1
  172. package/dist/components/VIcon/icons/index.d.ts +1 -1
  173. package/dist/components/VIcon/icons/index.js.map +1 -1
  174. package/dist/components/VIcon/icons/names.d.ts +1 -1
  175. package/dist/components/VIcon/icons/names.js.map +1 -1
  176. package/dist/components/VIcon/resolver.d.ts +3 -3
  177. package/dist/components/VIcon/resolver.js.map +1 -1
  178. package/dist/components/VIcon/types.d.ts +12 -12
  179. package/dist/components/VIconButton/VIconButton.css +1 -1
  180. package/dist/components/VIconButton/VIconButton.d.ts +28 -11
  181. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  182. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +26 -20
  183. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  184. package/dist/components/VInput/VInput.css +1 -1
  185. package/dist/components/VInput/VInput.d.ts +26 -7
  186. package/dist/components/VInput/VInput.js.map +1 -1
  187. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +86 -75
  188. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  189. package/dist/components/VInput/VInputGroup.css +2 -0
  190. package/dist/components/VInput/VInputGroup.d.ts +47 -0
  191. package/dist/components/VInput/VInputGroup.js +9 -0
  192. package/dist/components/VInput/VInputGroup.js.map +1 -0
  193. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +80 -0
  194. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  195. package/dist/components/VInput/context.d.ts +11 -0
  196. package/dist/components/VInput/context.js +6 -0
  197. package/dist/components/VInput/context.js.map +1 -0
  198. package/dist/components/VInputOTP/VInputOTP.css +1 -1
  199. package/dist/components/VInputOTP/VInputOTP.d.ts +37 -22
  200. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  201. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +98 -61
  202. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/components/VMenu/VMenu.d.ts +23 -30
  204. package/dist/components/VMenu/VMenu.js.map +1 -1
  205. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +31 -27
  206. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  207. package/dist/components/VMenu/VMenuGroup.css +1 -1
  208. package/dist/components/VMenu/VMenuGroup.d.ts +12 -8
  209. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  210. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +11 -11
  211. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  212. package/dist/components/VMenu/VMenuItem.css +1 -1
  213. package/dist/components/VMenu/VMenuItem.d.ts +11 -19
  214. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  215. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +65 -57
  216. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  217. package/dist/components/VMenu/VMenuPanel.d.ts +14 -30
  218. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  219. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +43 -44
  220. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  221. package/dist/components/VMenu/context.d.ts +2 -6
  222. package/dist/components/VMenu/context.js.map +1 -1
  223. package/dist/components/VPagination/VPagination.css +1 -1
  224. package/dist/components/VPagination/VPagination.d.ts +60 -22
  225. package/dist/components/VPagination/VPagination.js.map +1 -1
  226. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +113 -161
  227. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  228. package/dist/components/VPopover/VPopover.css +1 -1
  229. package/dist/components/VPopover/VPopover.d.ts +26 -7
  230. package/dist/components/VPopover/VPopover.js.map +1 -1
  231. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +43 -37
  232. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  233. package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
  234. package/dist/components/VProgressCircular/VProgressCircular.d.ts +15 -4
  235. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  236. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +32 -30
  237. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  238. package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
  239. package/dist/components/VProgressLinear/VProgressLinear.d.ts +23 -8
  240. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  241. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +34 -32
  242. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  243. package/dist/components/VRadio/VRadio.css +1 -1
  244. package/dist/components/VRadio/VRadio.d.ts +36 -18
  245. package/dist/components/VRadio/VRadio.js.map +1 -1
  246. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +55 -26
  247. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  248. package/dist/components/VSeparator/VSeparator.d.ts +4 -2
  249. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  250. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  251. package/dist/components/VSideNavigation/VSideNavigation.css +1 -1
  252. package/dist/components/VSideNavigation/VSideNavigation.d.ts +5 -19
  253. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  254. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +5 -5
  255. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  256. package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
  257. package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +9 -17
  258. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  259. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  260. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  261. package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
  262. package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +22 -30
  263. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  264. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +77 -87
  265. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  266. package/dist/components/VSideNavigation/context.d.ts +0 -14
  267. package/dist/components/VSideNavigation/context.js.map +1 -1
  268. package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
  269. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +9 -9
  270. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  271. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  272. package/dist/components/VSlider/VSlider.css +1 -1
  273. package/dist/components/VSlider/VSlider.d.ts +52 -27
  274. package/dist/components/VSlider/VSlider.js.map +1 -1
  275. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +202 -118
  276. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  277. package/dist/components/VSnackbar/VSnackbar.css +1 -1
  278. package/dist/components/VSnackbar/VSnackbar.d.ts +0 -23
  279. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  280. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +38 -38
  281. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  282. package/dist/components/VSnackbar/state.d.ts +0 -27
  283. package/dist/components/VSnackbar/state.js.map +1 -1
  284. package/dist/components/VSpinner/VSpinner.css +1 -1
  285. package/dist/components/VSpinner/VSpinner.d.ts +6 -6
  286. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  287. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +10 -9
  288. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  289. package/dist/components/VSwitch/VSwitch.css +1 -1
  290. package/dist/components/VSwitch/VSwitch.d.ts +35 -13
  291. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  292. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +62 -21
  293. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  294. package/dist/components/VTabs/VTab.css +1 -1
  295. package/dist/components/VTabs/VTab.d.ts +12 -12
  296. package/dist/components/VTabs/VTab.js.map +1 -1
  297. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +36 -24
  298. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  299. package/dist/components/VTabs/VTabPanel.d.ts +2 -10
  300. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  301. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +4 -4
  302. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  303. package/dist/components/VTabs/VTabs.css +1 -1
  304. package/dist/components/VTabs/VTabs.d.ts +27 -18
  305. package/dist/components/VTabs/VTabs.js.map +1 -1
  306. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +92 -81
  307. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  308. package/dist/components/VTabs/context.d.ts +9 -19
  309. package/dist/components/VTabs/context.js +1 -1
  310. package/dist/components/VTabs/context.js.map +1 -1
  311. package/dist/components/VTextarea/VTextarea.css +1 -1
  312. package/dist/components/VTextarea/VTextarea.d.ts +34 -6
  313. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  314. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +91 -74
  315. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  316. package/dist/components/VTimeInput/VTimeInput.css +1 -1
  317. package/dist/components/VTimeInput/VTimeInput.d.ts +123 -33
  318. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  319. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +294 -291
  320. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  321. package/dist/components/VTimeInput/search.d.ts +24 -0
  322. package/dist/components/VTimeInput/search.js +22 -0
  323. package/dist/components/VTimeInput/search.js.map +1 -0
  324. package/dist/components/VTimePicker/VTimePicker.css +1 -1
  325. package/dist/components/VTimePicker/VTimePicker.d.ts +51 -30
  326. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  327. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +216 -151
  328. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  329. package/dist/components/VTimePicker/limits.d.ts +88 -0
  330. package/dist/components/VTimePicker/limits.js +70 -0
  331. package/dist/components/VTimePicker/limits.js.map +1 -0
  332. package/dist/components/VToast/VToast.css +1 -1
  333. package/dist/components/VToast/VToast.d.ts +0 -10
  334. package/dist/components/VToast/VToast.js.map +1 -1
  335. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +10 -10
  336. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  337. package/dist/components/VToast/VToaster.css +1 -1
  338. package/dist/components/VToast/VToaster.d.ts +0 -17
  339. package/dist/components/VToast/VToaster.js.map +1 -1
  340. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +29 -28
  341. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  342. package/dist/components/VToast/state.d.ts +10 -19
  343. package/dist/components/VToast/state.js +1 -1
  344. package/dist/components/VToast/state.js.map +1 -1
  345. package/dist/components/VToggle/VToggle.css +1 -1
  346. package/dist/components/VToggle/VToggle.d.ts +56 -11
  347. package/dist/components/VToggle/VToggle.js.map +1 -1
  348. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +80 -46
  349. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  350. package/dist/components/VToggle/VToggleItem.d.ts +16 -2
  351. package/dist/components/VToggle/VToggleItem.js +0 -2
  352. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  353. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +23 -15
  354. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  355. package/dist/components/VToggle/context.d.ts +4 -24
  356. package/dist/components/VToggle/context.js.map +1 -1
  357. package/dist/components/VTooltip/VTooltip.css +1 -1
  358. package/dist/components/VTooltip/VTooltip.d.ts +9 -33
  359. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  360. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +28 -24
  361. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  362. package/dist/components/VTypography/VTypography.js.map +1 -1
  363. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  364. package/dist/composables/useAriaLabel.d.ts +0 -17
  365. package/dist/composables/useAriaLabel.js.map +1 -1
  366. package/dist/composables/useClearable.d.ts +42 -0
  367. package/dist/composables/useClearable.js +19 -0
  368. package/dist/composables/useClearable.js.map +1 -0
  369. package/dist/composables/useControlShape.d.ts +22 -0
  370. package/dist/composables/useControlShape.js +13 -0
  371. package/dist/composables/useControlShape.js.map +1 -0
  372. package/dist/composables/useDetailsOpen.d.ts +22 -0
  373. package/dist/composables/useDetailsOpen.js +21 -0
  374. package/dist/composables/useDetailsOpen.js.map +1 -0
  375. package/dist/composables/useFieldIds.d.ts +0 -15
  376. package/dist/composables/useFieldIds.js +8 -7
  377. package/dist/composables/useFieldIds.js.map +1 -1
  378. package/dist/composables/useFieldPanel.d.ts +21 -18
  379. package/dist/composables/useFieldPanel.js +43 -23
  380. package/dist/composables/useFieldPanel.js.map +1 -1
  381. package/dist/composables/useFileDrop.d.ts +0 -22
  382. package/dist/composables/useFileDrop.js.map +1 -1
  383. package/dist/composables/useFileField.d.ts +45 -17
  384. package/dist/composables/useFileField.js +40 -20
  385. package/dist/composables/useFileField.js.map +1 -1
  386. package/dist/composables/useFocusoutDismiss.d.ts +0 -15
  387. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  388. package/dist/composables/useIconClickHandlers.d.ts +29 -14
  389. package/dist/composables/useIconClickHandlers.js +15 -5
  390. package/dist/composables/useIconClickHandlers.js.map +1 -1
  391. package/dist/composables/useInertLink.d.ts +20 -0
  392. package/dist/composables/useInertLink.js +23 -0
  393. package/dist/composables/useInertLink.js.map +1 -0
  394. package/dist/composables/useMaskedField.d.ts +33 -10
  395. package/dist/composables/useMaskedField.js +45 -1
  396. package/dist/composables/useMaskedField.js.map +1 -1
  397. package/dist/composables/usePopover.d.ts +15 -1
  398. package/dist/composables/usePopover.js +23 -8
  399. package/dist/composables/usePopover.js.map +1 -1
  400. package/dist/composables/useProgressValue.d.ts +5 -8
  401. package/dist/composables/useProgressValue.js +6 -3
  402. package/dist/composables/useProgressValue.js.map +1 -1
  403. package/dist/composables/useRootAttrs.d.ts +12 -19
  404. package/dist/composables/useRootAttrs.js.map +1 -1
  405. package/dist/composables/useTimer.d.ts +8 -10
  406. package/dist/composables/useTimer.js.map +1 -1
  407. package/dist/i18n/en.d.ts +2 -10
  408. package/dist/i18n/en.js +18 -19
  409. package/dist/i18n/en.js.map +1 -1
  410. package/dist/i18n/fr.d.ts +2 -18
  411. package/dist/i18n/fr.js +18 -19
  412. package/dist/i18n/fr.js.map +1 -1
  413. package/dist/i18n/state.d.ts +44 -47
  414. package/dist/i18n/state.js +20 -17
  415. package/dist/i18n/state.js.map +1 -1
  416. package/dist/i18n/types.d.ts +53 -44
  417. package/dist/icons.d.ts +3 -3
  418. package/dist/index.d.ts +43 -17
  419. package/dist/index.js +45 -44
  420. package/dist/styles.css +1 -1
  421. package/dist/tokens/css.js.map +1 -1
  422. package/dist/tokens/index.d.ts +5 -1
  423. package/dist/tokens/primitives.js.map +1 -1
  424. package/dist/tokens/semantic.d.ts +5 -1
  425. package/dist/tokens/semantic.js +6 -2
  426. package/dist/tokens/semantic.js.map +1 -1
  427. package/dist/tokens/themes/dark.js.map +1 -1
  428. package/dist/tokens/types.d.ts +7 -15
  429. package/dist/tokens/types.js.map +1 -1
  430. package/dist/tokens.json +25 -5
  431. package/dist/types.d.ts +24 -0
  432. package/dist/utils/array.d.ts +3 -6
  433. package/dist/utils/array.js.map +1 -1
  434. package/dist/utils/arrowNav.d.ts +17 -17
  435. package/dist/utils/arrowNav.js +5 -3
  436. package/dist/utils/arrowNav.js.map +1 -1
  437. package/dist/utils/chip.d.ts +11 -15
  438. package/dist/utils/chip.js.map +1 -1
  439. package/dist/utils/css.d.ts +22 -11
  440. package/dist/utils/css.js +5 -2
  441. package/dist/utils/css.js.map +1 -1
  442. package/dist/utils/date.d.ts +42 -19
  443. package/dist/utils/date.js +97 -98
  444. package/dist/utils/date.js.map +1 -1
  445. package/dist/utils/direction.d.ts +6 -12
  446. package/dist/utils/direction.js.map +1 -1
  447. package/dist/utils/env.d.ts +5 -6
  448. package/dist/utils/file.d.ts +46 -58
  449. package/dist/utils/file.js +43 -36
  450. package/dist/utils/file.js.map +1 -1
  451. package/dist/utils/focus.d.ts +8 -17
  452. package/dist/utils/focus.js.map +1 -1
  453. package/dist/utils/hostWarns.d.ts +12 -0
  454. package/dist/utils/hostWarns.js +6 -0
  455. package/dist/utils/hostWarns.js.map +1 -0
  456. package/dist/utils/ids.d.ts +10 -0
  457. package/dist/utils/ids.js +8 -0
  458. package/dist/utils/ids.js.map +1 -0
  459. package/dist/utils/matcher.d.ts +5 -9
  460. package/dist/utils/matcher.js.map +1 -1
  461. package/dist/utils/memo.d.ts +12 -0
  462. package/dist/utils/memo.js +9 -0
  463. package/dist/utils/memo.js.map +1 -0
  464. package/dist/utils/number.d.ts +3 -4
  465. package/dist/utils/number.js.map +1 -1
  466. package/dist/utils/text.d.ts +20 -9
  467. package/dist/utils/text.js +17 -3
  468. package/dist/utils/text.js.map +1 -1
  469. package/dist/utils/time.d.ts +53 -61
  470. package/dist/utils/time.js +49 -45
  471. package/dist/utils/time.js.map +1 -1
  472. package/dist/utils/vnode.d.ts +8 -15
  473. package/dist/utils/vnode.js.map +1 -1
  474. package/package.json +6 -6
  475. package/dist/components/VToggle/VToggleItem.css +0 -2
@@ -1,18 +1,11 @@
1
- import { addDays as e, formatDisplay as t, parseISO as n } from "../../utils/date.js";
2
- import { coversDay as r, monthWeeks as i } from "./layout.js";
3
- import { Fragment as a, computed as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, defineComponent as d, openBlock as f, renderList as p, toDisplayString as m } from "vue";
1
+ import { addDays as e, addMonths as t, compareISO as n, formatDateDisplay as r, parseISO as i } from "../../utils/date.js";
2
+ import { monthWeeks as a } from "./layout.js";
3
+ import { Fragment as o, computed as s, createCommentVNode as c, createElementBlock as l, createElementVNode as u, createTextVNode as d, defineComponent as f, normalizeClass as p, normalizeStyle as m, openBlock as h, renderList as g, toDisplayString as _ } from "vue";
4
4
  //#region src/components/VCalendar/VCalendarYear.vue?vue&type=script&setup=true&lang.ts
5
- var h = ["aria-label"], g = ["onClick"], _ = {
5
+ var v = ["aria-label"], y = ["onClick"], b = {
6
6
  key: 0,
7
7
  class: "v-calendar-year-count"
8
- }, v = {
9
- class: "v-calendar-year-grid",
10
- "aria-hidden": "true"
11
- }, y = [
12
- "data-adjacent",
13
- "data-today",
14
- "data-busy"
15
- ], b = /*@__PURE__*/ d({
8
+ }, x = ["data-adjacent", "data-busy"], S = /*@__PURE__*/ f({
16
9
  __name: "VCalendarYear",
17
10
  props: {
18
11
  months: {},
@@ -23,54 +16,65 @@ var h = ["aria-label"], g = ["onClick"], _ = {
23
16
  label: {}
24
17
  },
25
18
  emits: ["month-activate"],
26
- setup(d, { emit: b }) {
27
- let x = d, S = b, C = (e) => t(e, x.locale, { month: "long" }), w = o(() => {
28
- let t = /* @__PURE__ */ new Set();
29
- for (let i of x.events) {
30
- let a = n(i.start), o = n(i.end);
31
- if (!a || !o) continue;
32
- let s = i.start;
33
- for (let n = 0; n < 366 && r(i, s); n++) t.add(s), s = e(s, 1);
19
+ setup(f, { emit: S }) {
20
+ let C = f, w = S, T = s(() => {
21
+ let r = /* @__PURE__ */ new Set(), a = C.months[0], o = C.months.at(-1);
22
+ if (!a || !o) return r;
23
+ let s = e(t(o, 1), -1);
24
+ for (let t of C.events) {
25
+ if (!i(t.start) || !i(t.end)) continue;
26
+ let o = n(t.start, a) > 0 ? t.start : a, c = n(t.end, s) < 0 ? t.end : s;
27
+ for (let t = o; n(t, c) <= 0; t = e(t, 1)) r.add(t);
34
28
  }
35
- return t;
36
- }), T = o(() => {
29
+ return r;
30
+ }), E = s(() => C.months.map((e) => a(e, C.weekdays))), D = s(() => {
37
31
  let e = /* @__PURE__ */ new Map();
38
- for (let t of x.months) e.set(t, i(t, x.weekdays));
32
+ for (let t of E.value) for (let n of t) for (let t of n) e.has(t.iso) || e.set(t.iso, r(t.iso, C.locale, { day: "numeric" }));
39
33
  return e;
40
- }), E = (e) => T.value.get(e) ?? [], D = o(() => {
41
- let e = /* @__PURE__ */ new Map();
42
- for (let n of T.value.values()) for (let r of n) for (let n of r) e.has(n.iso) || e.set(n.iso, t(n.iso, x.locale, { day: "numeric" }));
43
- return e;
44
- }), O = (e) => D.value.get(e) ?? t(e, x.locale, { day: "numeric" }), k = o(() => {
45
- let e = /* @__PURE__ */ new Map();
46
- for (let [t, n] of T.value) {
47
- let r = 0;
48
- for (let e of n) for (let t of e) t.adjacent === null && w.value.has(t.iso) && r++;
49
- e.set(t, r);
50
- }
51
- return e;
52
- }), A = (e) => k.value.get(e) ?? 0, j = (e) => e.adjacent === null && w.value.has(e.iso);
53
- return (e, t) => (f(), c("div", {
34
+ }), O = s(() => {
35
+ let e = T.value, t = D.value;
36
+ return C.months.map((n, i) => {
37
+ let a = 0, o = (E.value[i] ?? []).map((n) => n.map((n) => {
38
+ let r = n.adjacent === null && e.has(n.iso);
39
+ return r && a++, {
40
+ iso: n.iso,
41
+ adjacent: n.adjacent,
42
+ number: t.get(n.iso) ?? "",
43
+ busy: r
44
+ };
45
+ }));
46
+ return {
47
+ month: n,
48
+ name: r(n, C.locale, { month: "long" }),
49
+ weeks: o,
50
+ busyCount: a
51
+ };
52
+ });
53
+ });
54
+ return (e, t) => (h(), l("div", {
54
55
  class: "v-calendar-year",
55
56
  role: "group",
56
- "aria-label": d.label
57
- }, [(f(!0), c(a, null, p(d.months, (e) => (f(), c("section", {
58
- key: e,
57
+ "aria-label": f.label
58
+ }, [(h(!0), l(o, null, g(O.value, (e) => (h(), l("section", {
59
+ key: e.month,
59
60
  class: "v-calendar-year-month"
60
- }, [l("button", {
61
+ }, [u("button", {
61
62
  type: "button",
62
- class: "v-calendar-year-title",
63
- onClick: (t) => S("month-activate", e)
64
- }, [u(m(C(e)) + " ", 1), A(e) > 0 ? (f(), c("span", _, m(A(e)), 1)) : s("", !0)], 8, g), l("div", v, [(f(!0), c(a, null, p(E(e), (e, t) => (f(), c(a, { key: t }, [(f(!0), c(a, null, p(e, (e) => (f(), c("span", {
63
+ class: "v-calendar-button v-calendar-year-title",
64
+ onClick: (t) => w("month-activate", e.month)
65
+ }, [d(_(e.name) + " ", 1), e.busyCount > 0 ? (h(), l("span", b, _(e.busyCount), 1)) : c("", !0)], 8, y), u("div", {
66
+ class: "v-calendar-year-grid",
67
+ "aria-hidden": "true",
68
+ style: m({ "--calendar-columns": String(f.weekdays.length) })
69
+ }, [(h(!0), l(o, null, g(e.weeks, (e, t) => (h(), l(o, { key: t }, [(h(!0), l(o, null, g(e, (e) => (h(), l("span", {
65
70
  key: e.iso,
66
- class: "v-calendar-year-day",
71
+ class: p(["v-calendar-year-day", { "v-calendar-today": e.iso === f.today }]),
67
72
  "data-adjacent": e.adjacent ?? void 0,
68
- "data-today": e.iso === d.today ? "" : void 0,
69
- "data-busy": j(e) ? "" : void 0
70
- }, m(O(e.iso)), 9, y))), 128))], 64))), 128))])]))), 128))], 8, h));
73
+ "data-busy": e.busy ? "" : void 0
74
+ }, _(e.number), 11, x))), 128))], 64))), 128))], 4)]))), 128))], 8, v));
71
75
  }
72
76
  });
73
77
  //#endregion
74
- export { b as default };
78
+ export { S as default };
75
79
 
76
80
  //# sourceMappingURL=VCalendarYear.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VCalendarYear.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarYear.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * The year view: twelve small months, each marking the days that have something on them.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it.\n *\n * WHY THE DAYS HERE ARE NOT BUTTONS, unlike every other view. A year is three hundred and\n * sixty-five days, and making each one focusable would put that many stops in the tab\n * order for a view whose whole purpose is to be glanced at. Twelve roving grids would fix\n * the count but leave the arrows unable to cross from one month to the next, which is\n * exactly the movement a year view invites.\n *\n * So this view is a SUMMARY and says so: the days are text, with the busy ones ringed, and\n * the thing you can reach and act on is the month, whose name carries how many of its days\n * carry something. Choosing a day is what the month and day views are for, and the heading\n * is the way through to them.\n */\nimport { computed } from 'vue'\n\nimport { addDays, formatDisplay as formatDate, parseISO } from '../../utils/date'\n\nimport { coversDay, monthWeeks, type MonthCell } from './layout'\nimport type { CalendarEvent } from './types'\n\nexport interface CalendarYearProps<T> {\n /** The first day of each month of the year on show. */\n months: string[]\n events: T[]\n locale: string\n /** Which weekdays are on show, so a mini-month drops the same columns as the others. */\n weekdays: number[]\n today: string | null\n label: string\n}\n\nconst props = defineProps<CalendarYearProps<E>>()\n\nconst emit = defineEmits<{\n /** A month was chosen, and is where the calendar should go next. */\n 'month-activate': [iso: string]\n}>()\n\nconst monthName = (iso: string) => formatDate(iso, props.locale, { month: 'long' })\n\n/** The days of the year that have something on them, worked out once for all twelve. */\nconst busyDays = computed(() => {\n const days = new Set<string>()\n for (const event of props.events) {\n const start = parseISO(event.start)\n const end = parseISO(event.end)\n if (!start || !end) continue\n /*\n * Walked day by day rather than tested against every square: a year holds far more\n * squares than a schedule holds days, so filling a set from the events and asking it\n * one question per square is the cheaper way round. The walk is bounded to a year so a\n * malformed range cannot spin.\n */\n let iso = event.start\n for (let guard = 0; guard < 366 && coversDay(event, iso); guard++) {\n days.add(iso)\n iso = addDays(iso, 1)\n }\n }\n return days\n})\n\n/*\n * The twelve grids and their day numbers, built ONCE per render.\n *\n * `weeksOf` used to be a plain function, and the template reached it three times per month\n * — once in the `v-for`, and twice through `busyCount`, which appears in both the `v-if` and\n * the text beside it. Twelve months therefore rebuilt 36 grids, some 1500 `MonthCell`\n * objects, on every render; the 504 day numbers were formatted alongside them. None of that\n * depends on anything but the anchor, the weekdays and the locale.\n *\n * `busyCount` is a map for the same reason: reading it twice must not cost twice.\n */\nconst grids = computed(() => {\n const map = new Map<string, MonthCell[][]>()\n for (const month of props.months) map.set(month, monthWeeks(month, props.weekdays))\n return map\n})\n\nconst weeksOf = (month: string) => grids.value.get(month) ?? []\n\nconst dayNumbers = computed(() => {\n const map = new Map<string, string>()\n for (const weeks of grids.value.values()) {\n for (const week of weeks) {\n for (const cell of week) {\n if (!map.has(cell.iso))\n map.set(cell.iso, formatDate(cell.iso, props.locale, { day: 'numeric' }))\n }\n }\n }\n return map\n})\n\nconst dayNumber = (iso: string) =>\n dayNumbers.value.get(iso) ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/** How many of a month's own days carry something, which is what its name announces. */\nconst busyCounts = computed(() => {\n const map = new Map<string, number>()\n for (const [month, weeks] of grids.value) {\n let count = 0\n for (const week of weeks) {\n for (const cell of week) if (cell.adjacent === null && busyDays.value.has(cell.iso)) count++\n }\n map.set(month, count)\n }\n return map\n})\n\nconst busyCount = (month: string) => busyCounts.value.get(month) ?? 0\n\nconst isBusy = (cell: MonthCell) => cell.adjacent === null && busyDays.value.has(cell.iso)\n</script>\n\n<template>\n <div class=\"v-calendar-year\" role=\"group\" :aria-label=\"label\">\n <section v-for=\"month in months\" :key=\"month\" class=\"v-calendar-year-month\">\n <button type=\"button\" class=\"v-calendar-year-title\" @click=\"emit('month-activate', month)\">\n {{ monthName(month) }}\n <!-- The count is part of the button's own text, so a month that has something on it\n says so in its accessible name — which is what makes the days below safe to hide\n from the accessibility tree. -->\n <span v-if=\"busyCount(month) > 0\" class=\"v-calendar-year-count\">\n {{ busyCount(month) }}\n </span>\n </button>\n\n <div class=\"v-calendar-year-grid\" aria-hidden=\"true\">\n <template v-for=\"(week, row) in weeksOf(month)\" :key=\"row\">\n <span\n v-for=\"cell in week\"\n :key=\"cell.iso\"\n class=\"v-calendar-year-day\"\n :data-adjacent=\"cell.adjacent ?? undefined\"\n :data-today=\"cell.iso === today ? '' : undefined\"\n :data-busy=\"isBusy(cell) ? '' : undefined\"\n >\n {{ dayNumber(cell.iso) }}\n </span>\n </template>\n </div>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-year {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));\n gap: var(--vectis-space-4);\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n padding: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-calendar-year-month {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-2);\n }\n\n .v-calendar-year-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--vectis-space-2);\n padding: var(--vectis-space-1) var(--vectis-space-2);\n border: none;\n border-radius: var(--vectis-radius-interactive);\n background: none;\n color: var(--vectis-color-text);\n font-family: inherit;\n font-size: var(--vectis-text-heading-4-size);\n font-weight: var(--vectis-text-heading-4-weight);\n text-align: start;\n text-transform: capitalize;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-year-title:hover {\n background: var(--vectis-color-surface-muted);\n }\n\n .v-calendar-year-title:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-calendar-year-count {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-font-weight-medium);\n }\n\n .v-calendar-year-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 1px;\n }\n\n .v-calendar-year-day {\n display: flex;\n align-items: center;\n justify-content: center;\n aspect-ratio: 1;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-caption-size);\n }\n\n .v-calendar-year-day[data-adjacent] {\n color: var(--vectis-color-text-subtle);\n }\n\n /* A busy day is RINGED rather than dotted: at this size a dot would be about one pixel,\n and it would be drawn as a background, which Windows forced-colors flattens away —\n where a border keeps a colour of its own. The tint is a second, redundant signal for\n anyone the ring alone is too fine for. */\n .v-calendar-year-day[data-busy] {\n border: 1px solid var(--vectis-color-accent-border);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-calendar-year-day[data-today] {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-year-title {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;EAqCA,IAAM,IAAQ,GAER,IAAO,GAKP,KAAa,MAAgB,EAAW,GAAK,EAAM,QAAQ,EAAE,OAAO,OAAO,CAAC,GAG5E,IAAW,QAAe;GAC9B,IAAM,oBAAO,IAAI,IAAY;GAC7B,KAAK,IAAM,KAAS,EAAM,QAAQ;IAChC,IAAM,IAAQ,EAAS,EAAM,KAAK,GAC5B,IAAM,EAAS,EAAM,GAAG;IAC9B,IAAI,CAAC,KAAS,CAAC,GAAK;IAOpB,IAAI,IAAM,EAAM;IAChB,KAAK,IAAI,IAAQ,GAAG,IAAQ,OAAO,EAAU,GAAO,CAAG,GAAG,KAExD,AADA,EAAK,IAAI,CAAG,GACZ,IAAM,EAAQ,GAAK,CAAC;GAExB;GACA,OAAO;EACT,CAAC,GAaK,IAAQ,QAAe;GAC3B,IAAM,oBAAM,IAAI,IAA2B;GAC3C,KAAK,IAAM,KAAS,EAAM,QAAQ,EAAI,IAAI,GAAO,EAAW,GAAO,EAAM,QAAQ,CAAC;GAClF,OAAO;EACT,CAAC,GAEK,KAAW,MAAkB,EAAM,MAAM,IAAI,CAAK,KAAK,CAAC,GAExD,IAAa,QAAe;GAChC,IAAM,oBAAM,IAAI,IAAoB;GACpC,KAAK,IAAM,KAAS,EAAM,MAAM,OAAO,GACrC,KAAK,IAAM,KAAQ,GACjB,KAAK,IAAM,KAAQ,GACjB,AAAK,EAAI,IAAI,EAAK,GAAG,KACnB,EAAI,IAAI,EAAK,KAAK,EAAW,EAAK,KAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC,CAAC;GAIhF,OAAO;EACT,CAAC,GAEK,KAAa,MACjB,EAAW,MAAM,IAAI,CAAG,KAAK,EAAW,GAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC,GAGzE,IAAa,QAAe;GAChC,IAAM,oBAAM,IAAI,IAAoB;GACpC,KAAK,IAAM,CAAC,GAAO,MAAU,EAAM,OAAO;IACxC,IAAI,IAAQ;IACZ,KAAK,IAAM,KAAQ,GACjB,KAAK,IAAM,KAAQ,GAAM,AAAI,EAAK,aAAa,QAAQ,EAAS,MAAM,IAAI,EAAK,GAAG,KAAG;IAEvF,EAAI,IAAI,GAAO,CAAK;GACtB;GACA,OAAO;EACT,CAAC,GAEK,KAAa,MAAkB,EAAW,MAAM,IAAI,CAAK,KAAK,GAE9D,KAAU,MAAoB,EAAK,aAAa,QAAQ,EAAS,MAAM,IAAI,EAAK,GAAG;yBAIvF,EA2BM,OAAA;GA3BD,OAAM;GAAkB,MAAK;GAAS,cAAY,EAAA;cACrD,EAyBU,GAAA,MAAA,EAzBe,EAAA,SAAT,YAAhB,EAyBU,WAAA;GAzBwB,KAAK;GAAO,OAAM;MAClD,EAQS,UAAA;GARD,MAAK;GAAS,OAAM;GAAyB,UAAK,MAAE,EAAI,kBAAmB,CAAK;UACnF,EAAU,CAAK,CAAA,IAAI,KAItB,CAAA,GAAY,EAAU,CAAK,IAAA,KAAA,EAAA,GAA3B,EAEO,QAFP,GAEO,EADF,EAAU,CAAK,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,GAAA,CAAA,GAItB,EAaM,OAbN,GAaM,EAAA,EAAA,EAAA,GAZJ,EAWW,GAAA,MAAA,EAXqB,EAAQ,CAAK,IAA3B,GAAM,wBAA8B,EAAG,GAAA,EAAA,EAAA,EAAA,GACvD,EASO,GAAA,MAAA,EARU,IAAR,YADT,EASO,QAAA;GAPJ,KAAK,EAAK;GACX,OAAM;GACL,iBAAe,EAAK,YAAY,KAAA;GAChC,cAAY,EAAK,QAAQ,EAAA,QAAK,KAAQ,KAAA;GACtC,aAAW,EAAO,CAAI,IAAA,KAAS,KAAA;OAE7B,EAAU,EAAK,GAAG,CAAA,GAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"VCalendarYear.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarYear.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * The year view: twelve small months, each marking the days that have something on them.\n * Internal to VCalendar, whose documentation covers it.\n *\n * WHY THE DAYS ARE NOT BUTTONS, unlike every other view. A year is 365 days, and making each\n * focusable would put that many stops in the tab order for a view meant to be glanced at.\n * Twelve roving grids would fix the count but leave the arrows unable to cross from one\n * month to the next, which is exactly the movement a year view invites.\n *\n * So it is a SUMMARY and says so: the days are text with the busy ones ringed, and what can\n * be reached and acted on is the MONTH, whose name carries how many of its days are busy.\n * Choosing a day is what the month and day views are for, and the heading is the way through.\n */\nimport { computed } from 'vue'\n\nimport { addDays, addMonths, compareISO, formatDateDisplay, parseISO } from '../../utils/date'\n\nimport { monthWeeks, type MonthCell } from './layout'\nimport type { CalendarEvent } from './types'\n\nexport interface CalendarYearProps<T> {\n /** The first day of each month of the year on show. */\n months: string[]\n events: T[]\n locale: string\n /** Which weekdays are on show, so a mini-month drops the same columns as the others. */\n weekdays: number[]\n today: string | null\n label: string\n}\n\nconst props = defineProps<CalendarYearProps<E>>()\n\nconst emit = defineEmits<{\n /** A month was chosen, and is where the calendar should go next. */\n 'month-activate': [iso: string]\n}>()\n\n/**\n * The days of the year on show that have something on them, worked out once for all twelve.\n *\n * Walked day by day rather than tested against every square: a year holds far more squares\n * than a schedule holds days, so filling a set from the events and asking it one question per\n * square is the cheaper way round. Each walk is CLAMPED to the year on show, the only days a\n * mini-month marks — so an event from another year costs one comparison, and a range running\n * across several years walks only the part of it this year holds.\n */\nconst busyDays = computed(() => {\n const days = new Set<string>()\n const first = props.months[0]\n const lastMonth = props.months.at(-1)\n if (!first || !lastMonth) return days\n const last = addDays(addMonths(lastMonth, 1), -1)\n\n for (const event of props.events) {\n if (!parseISO(event.start) || !parseISO(event.end)) continue\n const from = compareISO(event.start, first) > 0 ? event.start : first\n const to = compareISO(event.end, last) < 0 ? event.end : last\n for (let iso = from; compareISO(iso, to) <= 0; iso = addDays(iso, 1)) days.add(iso)\n }\n return days\n})\n\n/*\n * The twelve grids, built ONCE per change of anchor or weekdays, and their day numbers once per\n * locale: the adjacent days repeat across neighbouring months, and none of it depends on the\n * events. The busy marks are laid over both in `yearMonths` below.\n */\nconst grids = computed(() => props.months.map((month) => monthWeeks(month, props.weekdays)))\n\nconst dayNumbers = computed(() => {\n const map = new Map<string, string>()\n for (const weeks of grids.value) {\n for (const week of weeks) {\n for (const cell of week) {\n if (!map.has(cell.iso))\n map.set(cell.iso, formatDateDisplay(cell.iso, props.locale, { day: 'numeric' }))\n }\n }\n }\n return map\n})\n\n/** One square of a mini-month, with everything the template writes on it already settled. */\ninterface YearDay {\n iso: string\n adjacent: MonthCell['adjacent']\n number: string\n /** Only a day of the month itself is marked: a neighbour's day belongs to its own month. */\n busy: boolean\n}\n\n/**\n * What the template draws, each month with its name, its squares and how many of them are busy.\n *\n * The template reaches a month's count twice, in the `v-if` and in the text beside it, and each\n * square asks whether it is busy: reading them here means the busy set is walked once per\n * render rather than once per square, and the count is never computed twice.\n */\nconst yearMonths = computed(() => {\n const busy = busyDays.value\n const numbers = dayNumbers.value\n return props.months.map((month, index) => {\n let busyCount = 0\n const weeks: YearDay[][] = (grids.value[index] ?? []).map((week) =>\n week.map((cell) => {\n const isBusy = cell.adjacent === null && busy.has(cell.iso)\n if (isBusy) busyCount++\n return {\n iso: cell.iso,\n adjacent: cell.adjacent,\n number: numbers.get(cell.iso) ?? '',\n busy: isBusy,\n }\n }),\n )\n return {\n month,\n name: formatDateDisplay(month, props.locale, { month: 'long' }),\n weeks,\n busyCount,\n }\n })\n})\n</script>\n\n<template>\n <div class=\"v-calendar-year\" role=\"group\" :aria-label=\"label\">\n <section v-for=\"entry in yearMonths\" :key=\"entry.month\" class=\"v-calendar-year-month\">\n <button\n type=\"button\"\n class=\"v-calendar-button v-calendar-year-title\"\n @click=\"emit('month-activate', entry.month)\"\n >\n {{ entry.name }}\n <!-- The count is part of the button's own text, so a month that has something on it\n says so in its accessible name — which is what makes the days below safe to hide\n from the accessibility tree. -->\n <span v-if=\"entry.busyCount > 0\" class=\"v-calendar-year-count\">\n {{ entry.busyCount }}\n </span>\n </button>\n\n <div\n class=\"v-calendar-year-grid\"\n aria-hidden=\"true\"\n :style=\"{ '--calendar-columns': String(weekdays.length) }\"\n >\n <template v-for=\"(week, row) in entry.weeks\" :key=\"row\">\n <span\n v-for=\"day in week\"\n :key=\"day.iso\"\n class=\"v-calendar-year-day\"\n :class=\"{ 'v-calendar-today': day.iso === today }\"\n :data-adjacent=\"day.adjacent ?? undefined\"\n :data-busy=\"day.busy ? '' : undefined\"\n >\n {{ day.number }}\n </span>\n </template>\n </div>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-year {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-3);\n }\n\n .v-calendar-year-month {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-2);\n }\n\n .v-calendar-year-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--vectis-space-2);\n padding: var(--vectis-space-1) var(--vectis-space-2);\n border-radius: var(--vectis-radius-interactive);\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-heading-4-size);\n font-weight: var(--vectis-text-heading-4-weight);\n text-align: start;\n text-transform: capitalize;\n }\n\n .v-calendar-year-title:hover {\n background: var(--vectis-color-surface-muted);\n }\n\n .v-calendar-year-count {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-font-weight-medium);\n }\n\n /* As many columns as weekdays on show, set inline by the template exactly as the month\n view does. Written as a literal 7, a calendar showing the working week alone wrapped\n every five-day row of `monthWeeks` onto the next line. */\n .v-calendar-year-grid {\n display: grid;\n grid-template-columns: repeat(var(--calendar-columns), 1fr);\n gap: 1px;\n }\n\n .v-calendar-year-day {\n display: flex;\n align-items: center;\n justify-content: center;\n aspect-ratio: 1;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-caption-size);\n }\n\n /*\n * TRAP — both states are written DISJOINT from today rather than below it. Today is very\n * often also busy, and its paint is `.v-calendar-today`, in VCalendar's sheet: at equal\n * specificity the winner between two sheets is whichever the consumer's bundler emitted last,\n * and losing that draw paints today as an ordinary busy day — the one square a reader looks\n * for first, quietly indistinguishable.\n */\n .v-calendar-year-day[data-adjacent]:not(.v-calendar-today) {\n color: var(--vectis-color-text-subtle);\n }\n\n /* A busy day is RINGED rather than dotted: at this size a dot would be about one pixel,\n and it would be drawn as a background, which Windows forced-colors flattens away —\n where a border keeps a colour of its own. The tint is a second, redundant signal for\n anyone the ring alone is too fine for — and the ring alone is what today keeps, being\n painted over the tint. */\n .v-calendar-year-day[data-busy] {\n border: 1px solid var(--vectis-color-accent-border);\n }\n\n .v-calendar-year-day[data-busy]:not(.v-calendar-today) {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n}\n</style>\n"],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ import { Ref } from 'vue';
2
+ import { CalendarIntent } from './keyboard.js';
3
+ import { GridGeometry } from './layout.js';
4
+ import { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types.js';
5
+ /**
6
+ * The id the ghost of a dragged event carries. It has to DIFFER from the event's own, or the
7
+ * two would collide in every map the layout keys by id and only one would ever be drawn.
8
+ */
9
+ export declare const ghostIdOf: (id: CalendarEventId) => string;
10
+ /**
11
+ * The dragged event's own id, read back off its ghost's. It is what the card is handed as
12
+ * `ghostOf`: an event's colour is derived from its id, so a ghost coloured from its own
13
+ * would not match the card it belongs to. `hueOf` reads a number and its digits as the same
14
+ * event, so the string form returned here is enough.
15
+ */
16
+ export declare const originalIdOf: (id: CalendarEventId) => string;
17
+ export declare const isGhostId: (id: CalendarEventId) => boolean;
18
+ /**
19
+ * The id a card belongs to, read back off the DOM.
20
+ *
21
+ * An id may be a NUMBER and an attribute is always text, so a numeric one has to be turned
22
+ * back into one — otherwise every card of a numerically-keyed calendar would look up as a
23
+ * miss and nothing would drag. Which of the two it is, is settled by asking the map that
24
+ * holds the originals rather than by guessing from the text.
25
+ */
26
+ export declare function cardIdOf(card: HTMLElement, has: (id: CalendarEventId) => boolean): string | number;
27
+ /**
28
+ * A grid's measured box as the pure geometry wants it: plain numbers, no element.
29
+ *
30
+ * `inlineStart` is the edge the first column starts at, which is the RIGHT one in a
31
+ * right-to-left page — which is also why containment never goes through this, see
32
+ * `pointWithin`.
33
+ */
34
+ export declare function gridGeometryOf(rect: DOMRect, columns: number, rtl: boolean): GridGeometry;
35
+ /** The state every gesture carries, whatever each grid adds to it. */
36
+ export interface GestureBase {
37
+ id: CalendarEventId;
38
+ /**
39
+ * Where the event was when the gesture began. Every pointer frame is computed from THIS and
40
+ * never from the frame before it, so a long drag cannot accumulate rounding drift.
41
+ */
42
+ origin: CalendarEventTimes;
43
+ /** What the card shows right now. The model is not touched until the gesture ends. */
44
+ preview: CalendarEventTimes;
45
+ /** The pointer holding the gesture, or null for a keyboard grab. */
46
+ pointerId: number | null;
47
+ originX: number;
48
+ originY: number;
49
+ /**
50
+ * Where the pointer last was. Two things move the calendar UNDER a still pointer — paging at
51
+ * an edge, and auto-scrolling — and each has to work out afresh what the pointer is now over.
52
+ */
53
+ lastX: number;
54
+ lastY: number;
55
+ /** Whether it moved past the threshold, which is what separates a drag from a click. */
56
+ moved: boolean;
57
+ /**
58
+ * Whether the pointer is off the calendar altogether — over the toolbar, or over the page
59
+ * beside it. Letting go there abandons the gesture whole and writes nothing.
60
+ *
61
+ * A KEYBOARD grab can never set it, and structurally rather than by a guard: `onPointermove`
62
+ * is the only writer, and it returns on the id mismatch first — a grab's `pointerId` is null,
63
+ * which no real pointer's id ever equals.
64
+ */
65
+ outside: boolean;
66
+ /**
67
+ * The reading direction, read ONCE when the gesture begins. It cannot change under a live
68
+ * drag, and asking the document on every frame costs a style resolution each time.
69
+ */
70
+ rtl: boolean;
71
+ }
72
+ /** What a grid hands over to start a gesture; the rest is filled in here. */
73
+ export type GestureInit<G extends GestureBase> = Omit<G, 'preview' | 'lastX' | 'lastY' | 'moved' | 'outside' | 'rtl'>;
74
+ /**
75
+ * A gesture held by the KEYBOARD rather than by a pointer: grabbed with Space, and waiting
76
+ * for the arrows to move it. Both grids draw the card differently in that state, which is
77
+ * what makes it worth a name.
78
+ */
79
+ export declare const isGrabbed: (state: GestureBase | null) => boolean;
80
+ /** The two intents that move a grabbed event, which only a grid can turn into times. */
81
+ export type GrabStep = Extract<CalendarIntent, {
82
+ kind: 'grabMove' | 'grabResize';
83
+ }>;
84
+ export interface CalendarGestureOptions<E extends CalendarEvent, G extends GestureBase> {
85
+ /** Every event as it is currently drawn, the ghost's original among them. */
86
+ events: () => readonly E[];
87
+ /** The event drawn under an id, for the handlers. */
88
+ eventOf: (id: CalendarEventId) => E | undefined;
89
+ /** The view's own box: what "outside the calendar" is measured against. */
90
+ rootEl: Ref<HTMLElement | null>;
91
+ /**
92
+ * The element the pointer is captured on once a press travels. It must contain every surface
93
+ * a gesture can start on, and carry the move, up, cancel and leave bindings: capture retargets
94
+ * every later pointer event to it, which is what makes one set of bindings serve every kind of
95
+ * gesture.
96
+ */
97
+ captureEl: Ref<HTMLElement | null>;
98
+ /** The box the cells occupy, which points and edges are read against. */
99
+ measureEl: Ref<HTMLElement | null>;
100
+ /** How many columns that box is divided into. */
101
+ columns: () => number;
102
+ /** Whether events may be moved at all. */
103
+ editable: () => boolean;
104
+ /** The node every card points at to say how it can be moved. */
105
+ hintId: () => string;
106
+ /** The step a grabbed event moves by, handed to the keyboard table. */
107
+ slotMinutes: () => number;
108
+ edgeStepDelay: () => number;
109
+ /** Whatever the grid's cells are made of, so paging under a still pointer re-places the card. */
110
+ layout: () => unknown;
111
+ /** Works out where the gesture's event belongs from the pointer's last position. */
112
+ applyPoint: (state: G, rect: DOMRect) => void;
113
+ /** Called on every pointer move past the threshold, after the edge watch, with both rects. */
114
+ onEdges?: (state: G, rootRect: DOMRect | undefined) => void;
115
+ /** Everything else a gesture leaves running, dropped on every path out of one. */
116
+ onRelease?: () => void;
117
+ /**
118
+ * A pointer gesture let go inside the calendar. Returns true when the grid has answered it
119
+ * itself — a slot drawn out — and nothing is left to drop.
120
+ */
121
+ onLetGo?: (state: G) => boolean;
122
+ /** A gesture that moved, committed: the grid reports the new times. */
123
+ onDrop: (state: G) => void;
124
+ /** What a keyboard grab of this event starts, or null when it cannot be grabbed. */
125
+ grab: (item: E) => GestureInit<G> | null;
126
+ /** Applies one arrow step to a grabbed event. Returns false when the step means nothing here. */
127
+ onGrabStep: (state: G, step: GrabStep, item: E) => boolean;
128
+ step: (direction: -1 | 1) => void;
129
+ announce: (message: string) => void;
130
+ }
131
+ export declare function useCalendarGesture<E extends CalendarEvent, G extends GestureBase>(options: CalendarGestureOptions<E, G>): {
132
+ gesture: Ref<G | null, G | null>;
133
+ grabbing: import('vue').ComputedRef<boolean>;
134
+ ghostEvent: import('vue').ComputedRef<E | null>;
135
+ withPreview: (events: readonly E[]) => E[];
136
+ edgeCue: import('vue').ComputedRef<"start" | "end" | undefined>;
137
+ isRtl: () => boolean;
138
+ start: (init: GestureInit<G>, rtl?: boolean) => void;
139
+ reapply: (state: G) => void;
140
+ release: () => void;
141
+ endLastGesture: () => void;
142
+ consumeDrag: () => boolean;
143
+ onPointermove: (event: PointerEvent) => void;
144
+ onPointerup: (event: PointerEvent) => void;
145
+ onPointercancel: () => void;
146
+ onPointerleave: (event: PointerEvent) => void;
147
+ onCardKeydown: (event: KeyboardEvent, card: HTMLElement) => void;
148
+ refocusCard: (id: CalendarEventId) => void;
149
+ focusCell: (id: string, deferred?: boolean) => void;
150
+ idOfCard: (card: HTMLElement) => string | number;
151
+ cardState: (id: CalendarEventId) => {
152
+ dragging: boolean;
153
+ rejected: boolean;
154
+ grabbed: boolean;
155
+ hintId: string | undefined;
156
+ ghostOf: string | undefined;
157
+ };
158
+ };
@@ -0,0 +1,170 @@
1
+ import { useMessages as e } from "../../i18n/state.js";
2
+ import { isRtl as t } from "../../utils/direction.js";
3
+ import { useEdgeStep as n } from "./edgeStep.js";
4
+ import { inlineEdgeAt as r, pointWithin as i } from "./layout.js";
5
+ import { calendarIntent as a } from "./keyboard.js";
6
+ import { computed as o, nextTick as s, ref as c, watch as l } from "vue";
7
+ //#region src/components/VCalendar/gesture.ts
8
+ var u = "__vectis-calendar-ghost__", d = (e) => `${u}${e}`, f = (e) => String(e).slice(25), p = (e) => String(e).startsWith(u);
9
+ function m(e, t) {
10
+ let n = e.dataset.eventId ?? "";
11
+ return t(n) ? n : Number(n);
12
+ }
13
+ function h(e, t, n) {
14
+ return {
15
+ top: e.top,
16
+ height: e.height,
17
+ inlineStart: n ? e.right : e.left,
18
+ inlineSize: e.width,
19
+ columns: t
20
+ };
21
+ }
22
+ var g = (e) => e !== null && e.pointerId === null;
23
+ function _(u) {
24
+ let _ = e(), v = c(null), y = o(() => g(v.value)), b = () => t(u.measureEl.value), x = o(() => {
25
+ let e = v.value;
26
+ if (!e?.moved) return null;
27
+ let t = u.events().find((t) => t.id === e.id);
28
+ return t ? {
29
+ ...t,
30
+ ...e.origin,
31
+ id: d(e.id)
32
+ } : null;
33
+ });
34
+ function S(e) {
35
+ let t = v.value;
36
+ if (!t) return [...e];
37
+ let n = e.map((e) => e.id === t.id ? {
38
+ ...e,
39
+ ...t.preview
40
+ } : e);
41
+ return x.value ? [...n, x.value] : n;
42
+ }
43
+ let C = !1;
44
+ function w() {
45
+ C = !1;
46
+ }
47
+ function T() {
48
+ let e = C;
49
+ return C = !1, e;
50
+ }
51
+ let E = n(u.step, u.edgeStepDelay), D = o(() => E.pending.value === -1 ? "start" : E.pending.value === 1 ? "end" : void 0);
52
+ function O() {
53
+ E.cancel(), u.onRelease?.();
54
+ }
55
+ function k(e, t = b()) {
56
+ v.value = {
57
+ ...e,
58
+ preview: { ...e.origin },
59
+ lastX: e.originX,
60
+ lastY: e.originY,
61
+ moved: !1,
62
+ outside: !1,
63
+ rtl: t
64
+ };
65
+ }
66
+ function A(e) {
67
+ try {
68
+ u.captureEl.value?.setPointerCapture(e);
69
+ } catch {}
70
+ }
71
+ function j(e) {
72
+ let t = u.measureEl.value?.getBoundingClientRect();
73
+ t && u.applyPoint(e, t);
74
+ }
75
+ function M(e) {
76
+ let t = v.value;
77
+ if (!t || t.pointerId !== e.pointerId || (t.lastX = e.clientX, t.lastY = e.clientY, !t.moved && Math.abs(e.clientX - t.originX) < 3 && Math.abs(e.clientY - t.originY) < 3)) return;
78
+ t.moved || A(e.pointerId), t.moved = !0;
79
+ let n = u.rootEl.value?.getBoundingClientRect(), a = u.measureEl.value?.getBoundingClientRect();
80
+ t.outside = n ? !i({
81
+ x: t.lastX,
82
+ y: t.lastY
83
+ }, n) : !1, a && (u.applyPoint(t, a), E.watchEdge(r(t.lastX, h(a, u.columns(), t.rtl), 48, t.rtl)), u.onEdges?.(t, n));
84
+ }
85
+ function N(e) {
86
+ let t = v.value;
87
+ !t || t.pointerId !== e.pointerId || (v.value = null, C = t.moved, O(), !t.outside && (u.onLetGo?.(t) || t.moved && u.onDrop(t)));
88
+ }
89
+ function P() {
90
+ v.value = null, O();
91
+ }
92
+ function F(e) {
93
+ let t = v.value;
94
+ !t || t.pointerId !== e.pointerId || t.moved || P();
95
+ }
96
+ l(u.layout, () => {
97
+ let e = v.value;
98
+ e?.moved && j(e);
99
+ }, { flush: "post" });
100
+ function I(e) {
101
+ s(() => {
102
+ let t = u.measureEl.value?.querySelectorAll(".v-calendar-event");
103
+ Array.from(t ?? []).find((t) => t.dataset.eventId === String(e))?.focus();
104
+ });
105
+ }
106
+ function L(e, t = !1) {
107
+ let n = () => document.getElementById(e)?.focus();
108
+ t ? s(n) : n();
109
+ }
110
+ let R = (e) => m(e, (e) => u.eventOf(e) !== void 0);
111
+ function z(e, t) {
112
+ let n = u.eventOf(R(t));
113
+ if (!n) return;
114
+ let r = y.value && v.value?.id === n.id, i = r ? v.value : null, o = a(e.key, e.shiftKey, r ? "grabbed" : "event", u.slotMinutes(), i?.rtl ?? b());
115
+ if (o) {
116
+ if (!i) {
117
+ let t = o.kind === "grab" ? u.grab(n) : null;
118
+ if (!t) return;
119
+ e.preventDefault(), k(t), u.announce(_.value.calendar.grabbed);
120
+ return;
121
+ }
122
+ if (e.preventDefault(), o.kind === "grabMove" || o.kind === "grabResize") {
123
+ if (!u.onGrabStep(i, o, n)) return;
124
+ i.moved = !0, I(i.id);
125
+ return;
126
+ }
127
+ if (o.kind === "activate") {
128
+ v.value = null, i.moved && u.onDrop(i), u.announce(_.value.calendar.dropped), I(i.id);
129
+ return;
130
+ }
131
+ o.kind === "cancel" && (v.value = null, u.announce(_.value.calendar.reverted), I(i.id));
132
+ }
133
+ }
134
+ function B(e) {
135
+ let t = v.value, n = t !== null && t.id === e;
136
+ return {
137
+ dragging: n && t.pointerId !== null && t.moved,
138
+ rejected: n && t.outside,
139
+ grabbed: n && t.pointerId === null,
140
+ hintId: u.editable() && !p(e) ? u.hintId() : void 0,
141
+ ghostOf: p(e) ? f(e) : void 0
142
+ };
143
+ }
144
+ return {
145
+ gesture: v,
146
+ grabbing: y,
147
+ ghostEvent: x,
148
+ withPreview: S,
149
+ edgeCue: D,
150
+ isRtl: b,
151
+ start: k,
152
+ reapply: j,
153
+ release: O,
154
+ endLastGesture: w,
155
+ consumeDrag: T,
156
+ onPointermove: M,
157
+ onPointerup: N,
158
+ onPointercancel: P,
159
+ onPointerleave: F,
160
+ onCardKeydown: z,
161
+ refocusCard: I,
162
+ focusCell: L,
163
+ idOfCard: R,
164
+ cardState: B
165
+ };
166
+ }
167
+ //#endregion
168
+ export { m as cardIdOf, d as ghostIdOf, h as gridGeometryOf, p as isGhostId, g as isGrabbed, f as originalIdOf, _ as useCalendarGesture };
169
+
170
+ //# sourceMappingURL=gesture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gesture.js","names":[],"sources":["../../../src/components/VCalendar/gesture.ts"],"sourcesContent":["// @keyboard @a11y @core\n/**\n * What the two grids' drag engines share, written once.\n *\n * VCalendarMonth and VCalendarTimeGrid both let an event be picked up, moved and dropped —\n * with a pointer and with the keyboard. Everything that does not depend on what a CELL is\n * lives here: the gesture state and its ghost, the pointer's move, release and cancel, the\n * capture, paging at an edge, the keyboard grab, drop and cancel, the focus handed back to a\n * card, and the flag that stops a drop from also reading as a click.\n *\n * What is NOT here is what genuinely differs, which is also why the two components exist\n * separately: turning a point into a cell (a day square on one side, a day and a minute on\n * the other), working out the new times from it, and the gesture kinds each grid adds. Those\n * stay with each grid, as hooks this composable calls, and the pure half of them is already\n * in `layout.ts`.\n *\n * It lives in the component's folder rather than in `composables/`, the `edgeStep.ts` and\n * `VCombobox/infiniteScroll.ts` arrangement: both consumers are inside this component, so it\n * fails the admission rule that folder keeps.\n */\nimport { computed, nextTick, ref, watch } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { isRtl as isElementRtl } from '../../utils/direction'\n\nimport { useMessages } from '../../i18n/state'\n\nimport { EDGE_BAND, useEdgeStep } from './edgeStep'\nimport { calendarIntent, type CalendarIntent } from './keyboard'\nimport { DRAG_THRESHOLD, inlineEdgeAt, pointWithin, type GridGeometry } from './layout'\nimport type { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types'\n\n/**\n * The prefix marking the copy an event leaves behind at its old place while it is being\n * dragged. It is written into the id rather than held beside it so that the ghost travels\n * through the same list, the same layout and the same `v-for` key as everything else.\n */\nconst GHOST_PREFIX = '__vectis-calendar-ghost__'\n\n/**\n * The id the ghost of a dragged event carries. It has to DIFFER from the event's own, or the\n * two would collide in every map the layout keys by id and only one would ever be drawn.\n */\nexport const ghostIdOf = (id: CalendarEventId) => `${GHOST_PREFIX}${id}`\n/**\n * The dragged event's own id, read back off its ghost's. It is what the card is handed as\n * `ghostOf`: an event's colour is derived from its id, so a ghost coloured from its own\n * would not match the card it belongs to. `hueOf` reads a number and its digits as the same\n * event, so the string form returned here is enough.\n */\nexport const originalIdOf = (id: CalendarEventId) => String(id).slice(GHOST_PREFIX.length)\nexport const isGhostId = (id: CalendarEventId) => String(id).startsWith(GHOST_PREFIX)\n\n/**\n * The id a card belongs to, read back off the DOM.\n *\n * An id may be a NUMBER and an attribute is always text, so a numeric one has to be turned\n * back into one — otherwise every card of a numerically-keyed calendar would look up as a\n * miss and nothing would drag. Which of the two it is, is settled by asking the map that\n * holds the originals rather than by guessing from the text.\n */\nexport function cardIdOf(card: HTMLElement, has: (id: CalendarEventId) => boolean) {\n const raw = card.dataset.eventId ?? ''\n return has(raw) ? raw : Number(raw)\n}\n\n/**\n * A grid's measured box as the pure geometry wants it: plain numbers, no element.\n *\n * `inlineStart` is the edge the first column starts at, which is the RIGHT one in a\n * right-to-left page — which is also why containment never goes through this, see\n * `pointWithin`.\n */\nexport function gridGeometryOf(rect: DOMRect, columns: number, rtl: boolean): GridGeometry {\n return {\n top: rect.top,\n height: rect.height,\n inlineStart: rtl ? rect.right : rect.left,\n inlineSize: rect.width,\n columns,\n }\n}\n\n/** The state every gesture carries, whatever each grid adds to it. */\nexport interface GestureBase {\n id: CalendarEventId\n /**\n * Where the event was when the gesture began. Every pointer frame is computed from THIS and\n * never from the frame before it, so a long drag cannot accumulate rounding drift.\n */\n origin: CalendarEventTimes\n /** What the card shows right now. The model is not touched until the gesture ends. */\n preview: CalendarEventTimes\n /** The pointer holding the gesture, or null for a keyboard grab. */\n pointerId: number | null\n originX: number\n originY: number\n /**\n * Where the pointer last was. Two things move the calendar UNDER a still pointer — paging at\n * an edge, and auto-scrolling — and each has to work out afresh what the pointer is now over.\n */\n lastX: number\n lastY: number\n /** Whether it moved past the threshold, which is what separates a drag from a click. */\n moved: boolean\n /**\n * Whether the pointer is off the calendar altogether — over the toolbar, or over the page\n * beside it. Letting go there abandons the gesture whole and writes nothing.\n *\n * A KEYBOARD grab can never set it, and structurally rather than by a guard: `onPointermove`\n * is the only writer, and it returns on the id mismatch first — a grab's `pointerId` is null,\n * which no real pointer's id ever equals.\n */\n outside: boolean\n /**\n * The reading direction, read ONCE when the gesture begins. It cannot change under a live\n * drag, and asking the document on every frame costs a style resolution each time.\n */\n rtl: boolean\n}\n\n/** What a grid hands over to start a gesture; the rest is filled in here. */\nexport type GestureInit<G extends GestureBase> = Omit<\n G,\n 'preview' | 'lastX' | 'lastY' | 'moved' | 'outside' | 'rtl'\n>\n\n/**\n * A gesture held by the KEYBOARD rather than by a pointer: grabbed with Space, and waiting\n * for the arrows to move it. Both grids draw the card differently in that state, which is\n * what makes it worth a name.\n */\nexport const isGrabbed = (state: GestureBase | null) => state !== null && state.pointerId === null\n\n/** The two intents that move a grabbed event, which only a grid can turn into times. */\nexport type GrabStep = Extract<CalendarIntent, { kind: 'grabMove' | 'grabResize' }>\n\nexport interface CalendarGestureOptions<E extends CalendarEvent, G extends GestureBase> {\n /** Every event as it is currently drawn, the ghost's original among them. */\n events: () => readonly E[]\n /** The event drawn under an id, for the handlers. */\n eventOf: (id: CalendarEventId) => E | undefined\n /** The view's own box: what \"outside the calendar\" is measured against. */\n rootEl: Ref<HTMLElement | null>\n /**\n * The element the pointer is captured on once a press travels. It must contain every surface\n * a gesture can start on, and carry the move, up, cancel and leave bindings: capture retargets\n * every later pointer event to it, which is what makes one set of bindings serve every kind of\n * gesture.\n */\n captureEl: Ref<HTMLElement | null>\n /** The box the cells occupy, which points and edges are read against. */\n measureEl: Ref<HTMLElement | null>\n /** How many columns that box is divided into. */\n columns: () => number\n /** Whether events may be moved at all. */\n editable: () => boolean\n /** The node every card points at to say how it can be moved. */\n hintId: () => string\n /** The step a grabbed event moves by, handed to the keyboard table. */\n slotMinutes: () => number\n edgeStepDelay: () => number\n /** Whatever the grid's cells are made of, so paging under a still pointer re-places the card. */\n layout: () => unknown\n /** Works out where the gesture's event belongs from the pointer's last position. */\n applyPoint: (state: G, rect: DOMRect) => void\n /** Called on every pointer move past the threshold, after the edge watch, with both rects. */\n onEdges?: (state: G, rootRect: DOMRect | undefined) => void\n /** Everything else a gesture leaves running, dropped on every path out of one. */\n onRelease?: () => void\n /**\n * A pointer gesture let go inside the calendar. Returns true when the grid has answered it\n * itself — a slot drawn out — and nothing is left to drop.\n */\n onLetGo?: (state: G) => boolean\n /** A gesture that moved, committed: the grid reports the new times. */\n onDrop: (state: G) => void\n /** What a keyboard grab of this event starts, or null when it cannot be grabbed. */\n grab: (item: E) => GestureInit<G> | null\n /** Applies one arrow step to a grabbed event. Returns false when the step means nothing here. */\n onGrabStep: (state: G, step: GrabStep, item: E) => boolean\n step: (direction: -1 | 1) => void\n announce: (message: string) => void\n}\n\nexport function useCalendarGesture<E extends CalendarEvent, G extends GestureBase>(\n options: CalendarGestureOptions<E, G>,\n) {\n const m = useMessages()\n const gesture = ref<G | null>(null) as Ref<G | null>\n\n /** True while a card is being held by the keyboard rather than dragged by a pointer. */\n const grabbing = computed(() => isGrabbed(gesture.value))\n\n const isRtl = () => isElementRtl(options.measureEl.value)\n\n /**\n * The echo of where the gestured event began, so the reader can see what they are moving it\n * FROM. A press that has not travelled yet produces none, or a click would flash a second\n * card over the first.\n */\n const ghostEvent = computed<E | null>(() => {\n const state = gesture.value\n if (!state?.moved) return null\n const original = options.events().find((event) => event.id === state.id)\n return original ? ({ ...original, ...state.origin, id: ghostIdOf(state.id) } as E) : null\n })\n\n /**\n * A list with the gestured event moved to wherever it is now, plus its echo.\n *\n * The echo is listed whether or not it has a box to draw on, because this is what the id maps\n * are built from and the template reads a card's event back out of them. An echo whose day\n * the view has paged past simply produces no placement, as any event off show does.\n */\n function withPreview(events: readonly E[]): E[] {\n const state = gesture.value\n if (!state) return [...events]\n const moving = events.map((event) =>\n event.id === state.id ? ({ ...event, ...state.preview } as E) : event,\n )\n return ghostEvent.value ? [...moving, ghostEvent.value] : moving\n }\n\n /**\n * The flag that keeps a drop from also reading as a click.\n *\n * A pointer that moved past the threshold ends on a `click` the browser fires anyway, and\n * without this the card would be dropped AND opened. It is a plain variable rather than a\n * ref: nothing renders from it, and a reactive one would re-render the grid at the end of\n * every gesture for no visible change.\n *\n * TRAP — three writes, and each is load-bearing.\n *\n * `pointerup` SETS it, outside the calendar included, because `pointerup` fires before\n * `click`: an abandoned drag would otherwise end by opening the very event it refused to move.\n *\n * `pointercancel` does NOT, and must never share a helper with the release that does: no click\n * follows a cancel, so a `true` left behind there would swallow the next genuine one.\n *\n * Every press CLEARS it before any guard runs. The click that lowers it only reaches a card\n * when it lands on one, and drawing out a new event ends on a CELL, so the flag would stay up\n * — and a press that starts no gesture, which `creatable` without `editable` reaches every\n * time, would never overwrite it. The reader clicks an event, nothing happens, they click\n * again. Clearing at the press is what makes the flag unable to outlive its own interaction,\n * and the order is the argument: the click it exists to swallow follows its own `pointerup`\n * with no press in between.\n */\n let dragged = false\n\n /** Closes the books on the previous gesture. Every press handler calls it first. */\n function endLastGesture() {\n dragged = false\n }\n\n /** Whether the gesture that just ended actually moved; asking lowers the flag. */\n function consumeDrag() {\n const was = dragged\n dragged = false\n return was\n }\n\n const edge = useEdgeStep(options.step, options.edgeStepDelay)\n\n /** Which edge is counting down, as the attribute the stylesheet reads. */\n const edgeCue = computed(() =>\n edge.pending.value === -1 ? 'start' : edge.pending.value === 1 ? 'end' : undefined,\n )\n\n function release() {\n edge.cancel()\n options.onRelease?.()\n }\n\n /**\n * Starts a gesture. Every entry point funnels through here, so the rules that make a gesture\n * safe — one at a time, the origin captured once — are written once. The pointer itself is\n * only taken hold of once the press travels, in `onPointermove`.\n */\n function start(init: GestureInit<G>, rtl = isRtl()) {\n gesture.value = {\n ...init,\n preview: { ...init.origin },\n lastX: init.originX,\n lastY: init.originY,\n moved: false,\n outside: false,\n rtl,\n } as G\n }\n\n /**\n * Takes hold of the pointer on the capture element, so the drag keeps following it past the\n * calendar's edges.\n *\n * TRAP — called when the press crosses the drag threshold, NEVER at the press. The browser\n * sends the `click` that follows a captured `pointerup` to the CAPTURE element, so a press\n * captured at once reaches the scroller instead of the card or the cell under it: clicking an\n * event would open nothing and clicking an empty slot would report nothing, on every calendar\n * whose events can be moved or drawn. Neither jsdom nor a synthetic pointer event reproduces\n * the retargeting (a synthetic pointer cannot be captured), so the unit suite pins WHEN the\n * capture is asked for rather than where the click lands.\n */\n function capture(pointerId: number) {\n // @fallback\n /*\n * Wrapped because a pointer event fired by a TEST refers to no real pointer,\n * and the call then throws. Failing to capture merely means the drag stops at the edge of\n * the capture element, which no test is checking.\n */\n try {\n options.captureEl.value?.setPointerCapture(pointerId)\n } catch {\n /* a synthetic pointer: nothing to capture */\n }\n }\n\n /** Re-reads the measured box and works the gesture out again, for a caller outside a handler. */\n function reapply(state: G) {\n const rect = options.measureEl.value?.getBoundingClientRect()\n if (rect) options.applyPoint(state, rect)\n }\n\n function onPointermove(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n\n state.lastX = event.clientX\n state.lastY = event.clientY\n\n // Below the threshold nothing has happened yet. That is what keeps a click a click: the\n // hand's tremor during a press would otherwise register as a one-pixel drag.\n if (\n !state.moved &&\n Math.abs(event.clientX - state.originX) < DRAG_THRESHOLD &&\n Math.abs(event.clientY - state.originY) < DRAG_THRESHOLD\n ) {\n return\n }\n\n if (!state.moved) capture(event.pointerId)\n state.moved = true\n // Each box is measured ONCE per move and handed to everything that reads it.\n const rootRect = options.rootEl.value?.getBoundingClientRect()\n const rect = options.measureEl.value?.getBoundingClientRect()\n\n /*\n * Outside is measured against the view's own box — never the cells' box, whose rect\n * excludes the day names, the all-day band and the hour gutter — and the rect goes in RAW:\n * containment has no reading direction, where `inlineStart` is the right edge in RTL.\n *\n * TRAP — neither the placement nor the edge watch below is gated on it, and neither may\n * become so. The card must keep following the pointer while it is out, which is what makes\n * coming back in seamless, and paging must keep running, pushing past the edge being how one\n * crosses into the next period. Being outside decides what happens on RELEASE, nothing else.\n */\n state.outside = rootRect ? !pointWithin({ x: state.lastX, y: state.lastY }, rootRect) : false\n\n if (!rect) return\n options.applyPoint(state, rect)\n edge.watchEdge(\n inlineEdgeAt(\n state.lastX,\n gridGeometryOf(rect, options.columns(), state.rtl),\n EDGE_BAND,\n state.rtl,\n ),\n )\n options.onEdges?.(state, rootRect)\n }\n\n function onPointerup(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n gesture.value = null\n dragged = state.moved\n release()\n\n /*\n * Let go with the pointer off the calendar and the gesture is abandoned whole. Nothing is\n * announced: the pointer says nothing on a SUCCESSFUL drop either — `grabbed`, `dropped` and\n * `reverted` belong to the keyboard grab, which has no pointer to show where the event went.\n */\n if (state.outside) return\n if (options.onLetGo?.(state)) return\n // A press that never travelled is an ordinary click, which the button's own click event is\n // about to report. Writing anything here would move an event nobody dragged.\n if (state.moved) options.onDrop(state)\n }\n\n /*\n * The gesture was taken away — a system gesture, a context menu, the page starting to scroll.\n * Nothing is written and nothing is announced: the card goes back to where the model still\n * says it is.\n */\n function onPointercancel() {\n gesture.value = null\n release()\n }\n\n /*\n * A press that leaves the capture element before it has travelled far enough to be captured.\n * Its `pointerup` then lands outside and never reaches the bindings, so without this the\n * gesture would outlive the press: a mouse keeps the same pointer id, and bringing it back over\n * the calendar with the button up would pick the event up and carry it. A captured pointer\n * never leaves, so a real drag is untouched.\n */\n function onPointerleave(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId || state.moved) return\n onPointercancel()\n }\n\n /*\n * Paging swaps the cells out from under a live drag, and the dragged event's day is then off\n * screen — the card would vanish until the next pointer move, which never comes if the hand is\n * holding still against the edge. Re-applying the last position once the new cells are\n * rendered is what keeps the card under the pointer across the boundary.\n */\n watch(\n options.layout,\n () => {\n const state = gesture.value\n if (state?.moved) reapply(state)\n },\n { flush: 'post' },\n )\n\n /**\n * Hands the focus back to a card once it has landed somewhere else, which the re-render has\n * just taken it from.\n *\n * TRAP — the card is found by WALKING the cards rather than by building an attribute\n * selector. An id belongs to the consumer, so it may hold a quote or a backslash a selector\n * would need escaped, and `CSS.escape` cannot do that escaping here: jsdom defines no `CSS`\n * object at all, so the call threw on every keyboard grab, from inside a `nextTick` where\n * nothing could catch it — an unhandled rejection, which fails the run while every assertion\n * still passes. Comparing the attribute's own text sidesteps the question, `data-event-id`\n * being written as exactly `String(event.id)`.\n */\n function refocusCard(id: CalendarEventId) {\n void nextTick(() => {\n const cards = options.measureEl.value?.querySelectorAll<HTMLElement>('.v-calendar-event')\n Array.from(cards ?? [])\n .find((card) => card.dataset.eventId === String(id))\n ?.focus()\n })\n }\n\n /** Puts the focus on a cell by its id, once the render that made it tabbable has run. */\n function focusCell(id: string, deferred = false) {\n const move = () => document.getElementById(id)?.focus()\n if (deferred) void nextTick(move)\n else move()\n }\n\n /** The event a card stands for, read back off the attribute the card publishes. */\n const idOfCard = (card: HTMLElement) => cardIdOf(card, (id) => options.eventOf(id) !== undefined)\n\n /**\n * A card answers a different table from the grid it sits in — that is what a grab mode IS.\n * Without it the grid would offer a gesture the pointer alone could reach (WCAG 2.1.1).\n */\n function onCardKeydown(event: KeyboardEvent, card: HTMLElement) {\n const item = options.eventOf(idOfCard(card))\n if (!item) return\n\n const held = grabbing.value && gesture.value?.id === item.id\n const state = held ? gesture.value! : null\n const intent = calendarIntent(\n event.key,\n event.shiftKey,\n held ? 'grabbed' : 'event',\n options.slotMinutes(),\n state?.rtl ?? isRtl(),\n )\n if (!intent) return\n\n if (!state) {\n // An event that cannot be moved keeps a button's ordinary behaviour: Space presses it,\n // which the card's click handler reports.\n const init = intent.kind === 'grab' ? options.grab(item) : null\n if (!init) return\n /*\n * Space is ALSO how a button is pressed, on its release. Cancelling the keydown is what\n * stops that press, so the keystroke that takes hold of the event does not open it too:\n * without it every attempt to move something would fire the consumer's editor over it.\n */\n event.preventDefault()\n start(init)\n options.announce(m.value.calendar.grabbed)\n return\n }\n\n event.preventDefault()\n\n if (intent.kind === 'grabMove' || intent.kind === 'grabResize') {\n if (!options.onGrabStep(state, intent, item)) return\n state.moved = true\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'activate') {\n gesture.value = null\n if (state.moved) options.onDrop(state)\n options.announce(m.value.calendar.dropped)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'cancel') {\n gesture.value = null\n options.announce(m.value.calendar.reverted)\n refocusCard(state.id)\n }\n }\n\n /**\n * The five things every card is told about the gesture, bound with `v-bind` so the two grids\n * cannot describe the same state in two different ways.\n */\n function cardState(id: CalendarEventId) {\n const state = gesture.value\n const mine = state !== null && state.id === id\n return {\n /*\n * TRAP — only once the press has travelled. A dragged card takes no pointer events, so\n * marked at the press it lets the release land on the cell beneath it: the click then goes\n * to that cell, and clicking an event reports an empty slot instead of opening it.\n */\n dragging: mine && state.pointerId !== null && state.moved,\n rejected: mine && state.outside,\n grabbed: mine && state.pointerId === null,\n hintId: options.editable() && !isGhostId(id) ? options.hintId() : undefined,\n ghostOf: isGhostId(id) ? originalIdOf(id) : undefined,\n }\n }\n\n return {\n gesture,\n grabbing,\n ghostEvent,\n withPreview,\n edgeCue,\n isRtl,\n start,\n reapply,\n release,\n endLastGesture,\n consumeDrag,\n onPointermove,\n onPointerup,\n onPointercancel,\n onPointerleave,\n onCardKeydown,\n refocusCard,\n focusCell,\n idOfCard,\n cardState,\n }\n}\n"],"mappings":"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"}
@@ -39,11 +39,15 @@ export type CalendarIntent =
39
39
  kind: 'period';
40
40
  delta: -1 | 1;
41
41
  }
42
- /** Take up what is focused: create here, open a card, or commit a move under way. */
42
+ /** Take up what is focused: report an empty cell, or commit a move under way. */
43
43
  | {
44
44
  kind: 'activate';
45
45
  }
46
- /** Back out: leave a card for its cell, or abandon a move and put the event back. */
46
+ /** Take hold of a card, so the arrows move it. */
47
+ | {
48
+ kind: 'grab';
49
+ }
50
+ /** Abandon a move under way and put the event back. */
47
51
  | {
48
52
  kind: 'cancel';
49
53
  }
@@ -62,7 +66,9 @@ export type CalendarIntent =
62
66
  * Where the focus is when the key arrives, which is what decides the answer:
63
67
  *
64
68
  * - `cell` — an empty part of the grid. The arrows travel, Enter creates.
65
- * - `event` — a card, at rest. Enter takes hold of it, Escape goes back to the grid.
69
+ * - `event` — a card, at rest. Space takes hold of it; every other key is the browser's,
70
+ * Enter included, which presses the card as a button and so opens the event. Enter is the
71
+ * one a reader tries first on a button, and `event-activate` has no other keyboard route.
66
72
  * - `grabbed` — a card being moved. The arrows now move the EVENT, Enter commits, Escape
67
73
  * puts it back where it was.
68
74
  */
@@ -1,3 +1,4 @@
1
+ //#region src/components/VCalendar/keyboard.ts
1
2
  function e(e, t, n, r, i) {
2
3
  let a = r > 0 ? r : 1, o = i ? -1 : 1;
3
4
  if (n === "grabbed") switch (e) {
@@ -32,12 +33,7 @@ function e(e, t, n, r, i) {
32
33
  case "Escape": return { kind: "cancel" };
33
34
  default: return;
34
35
  }
35
- if (n === "event") switch (e) {
36
- case "Enter":
37
- case " ": return { kind: "activate" };
38
- case "Escape": return { kind: "cancel" };
39
- default: return;
40
- }
36
+ if (n === "event") return e === " " ? { kind: "grab" } : void 0;
41
37
  switch (e) {
42
38
  case "ArrowLeft": return {
43
39
  kind: "moveFocus",