vectis-ui 0.1.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 (676) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +27 -0
  3. package/README.md +354 -0
  4. package/dist/_virtual/_plugin-vue_export-helper.js +8 -0
  5. package/dist/components/VAccordion/VAccordion.css +2 -0
  6. package/dist/components/VAccordion/VAccordion.d.ts +59 -0
  7. package/dist/components/VAccordion/VAccordion.js +9 -0
  8. package/dist/components/VAccordion/VAccordion.js.map +1 -0
  9. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +42 -0
  10. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/components/VAccordion/VAccordionItem.css +2 -0
  12. package/dist/components/VAccordion/VAccordionItem.d.ts +64 -0
  13. package/dist/components/VAccordion/VAccordionItem.js +9 -0
  14. package/dist/components/VAccordion/VAccordionItem.js.map +1 -0
  15. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +70 -0
  16. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  17. package/dist/components/VAccordion/context.d.ts +18 -0
  18. package/dist/components/VAccordion/context.js +6 -0
  19. package/dist/components/VAccordion/context.js.map +1 -0
  20. package/dist/components/VAvatar/VAvatar.css +2 -0
  21. package/dist/components/VAvatar/VAvatar.d.ts +68 -0
  22. package/dist/components/VAvatar/VAvatar.js +9 -0
  23. package/dist/components/VAvatar/VAvatar.js.map +1 -0
  24. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +87 -0
  25. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  26. package/dist/components/VAvatar/VAvatarGroup.css +2 -0
  27. package/dist/components/VAvatar/VAvatarGroup.d.ts +59 -0
  28. package/dist/components/VAvatar/VAvatarGroup.js +9 -0
  29. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -0
  30. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +43 -0
  31. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  32. package/dist/components/VAvatar/context.d.ts +17 -0
  33. package/dist/components/VAvatar/context.js +6 -0
  34. package/dist/components/VAvatar/context.js.map +1 -0
  35. package/dist/components/VBadge/VBadge.css +2 -0
  36. package/dist/components/VBadge/VBadge.d.ts +74 -0
  37. package/dist/components/VBadge/VBadge.js +9 -0
  38. package/dist/components/VBadge/VBadge.js.map +1 -0
  39. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +40 -0
  40. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/components/VBreadcrumb/VBreadcrumb.css +2 -0
  42. package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +68 -0
  43. package/dist/components/VBreadcrumb/VBreadcrumb.js +9 -0
  44. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -0
  45. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +70 -0
  46. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
  47. package/dist/components/VButton/VButton.css +2 -0
  48. package/dist/components/VButton/VButton.d.ts +88 -0
  49. package/dist/components/VButton/VButton.js +9 -0
  50. package/dist/components/VButton/VButton.js.map +1 -0
  51. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +86 -0
  52. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  53. package/dist/components/VButton/VButtonGroup.css +2 -0
  54. package/dist/components/VButton/VButtonGroup.d.ts +32 -0
  55. package/dist/components/VButton/VButtonGroup.js +9 -0
  56. package/dist/components/VButton/VButtonGroup.js.map +1 -0
  57. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +17 -0
  58. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/VCalendar/VCalendar.css +2 -0
  60. package/dist/components/VCalendar/VCalendar.d.ts +129 -0
  61. package/dist/components/VCalendar/VCalendar.js +9 -0
  62. package/dist/components/VCalendar/VCalendar.js.map +1 -0
  63. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +374 -0
  64. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  65. package/dist/components/VCalendar/VCalendarEvent.css +2 -0
  66. package/dist/components/VCalendar/VCalendarEvent.d.ts +71 -0
  67. package/dist/components/VCalendar/VCalendarEvent.js +9 -0
  68. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -0
  69. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +106 -0
  70. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/VCalendar/VCalendarMonth.css +2 -0
  72. package/dist/components/VCalendar/VCalendarMonth.d.ts +60 -0
  73. package/dist/components/VCalendar/VCalendarMonth.js +9 -0
  74. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -0
  75. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +342 -0
  76. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -0
  77. package/dist/components/VCalendar/VCalendarTimeGrid.css +2 -0
  78. package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +85 -0
  79. package/dist/components/VCalendar/VCalendarTimeGrid.js +9 -0
  80. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -0
  81. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +621 -0
  82. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/VCalendar/VCalendarYear.css +2 -0
  84. package/dist/components/VCalendar/VCalendarYear.d.ts +31 -0
  85. package/dist/components/VCalendar/VCalendarYear.js +9 -0
  86. package/dist/components/VCalendar/VCalendarYear.js.map +1 -0
  87. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +76 -0
  88. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -0
  89. package/dist/components/VCalendar/color.d.ts +9 -0
  90. package/dist/components/VCalendar/color.js +9 -0
  91. package/dist/components/VCalendar/color.js.map +1 -0
  92. package/dist/components/VCalendar/edgeStep.d.ts +38 -0
  93. package/dist/components/VCalendar/edgeStep.js +28 -0
  94. package/dist/components/VCalendar/edgeStep.js.map +1 -0
  95. package/dist/components/VCalendar/keyboard.d.ts +78 -0
  96. package/dist/components/VCalendar/keyboard.js +86 -0
  97. package/dist/components/VCalendar/keyboard.js.map +1 -0
  98. package/dist/components/VCalendar/layout.d.ts +355 -0
  99. package/dist/components/VCalendar/layout.js +292 -0
  100. package/dist/components/VCalendar/layout.js.map +1 -0
  101. package/dist/components/VCalendar/types.d.ts +78 -0
  102. package/dist/components/VCarousel/VCarousel.css +2 -0
  103. package/dist/components/VCarousel/VCarousel.d.ts +241 -0
  104. package/dist/components/VCarousel/VCarousel.js +9 -0
  105. package/dist/components/VCarousel/VCarousel.js.map +1 -0
  106. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +262 -0
  107. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  108. package/dist/components/VCarousel/VCarouselItem.d.ts +41 -0
  109. package/dist/components/VCarousel/VCarouselItem.js +7 -0
  110. package/dist/components/VCarousel/VCarouselItem.js.map +1 -0
  111. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js +25 -0
  112. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  113. package/dist/components/VCarousel/context.d.ts +23 -0
  114. package/dist/components/VCarousel/context.js +6 -0
  115. package/dist/components/VCarousel/context.js.map +1 -0
  116. package/dist/components/VCheckbox/VCheckbox.css +2 -0
  117. package/dist/components/VCheckbox/VCheckbox.d.ts +63 -0
  118. package/dist/components/VCheckbox/VCheckbox.js +9 -0
  119. package/dist/components/VCheckbox/VCheckbox.js.map +1 -0
  120. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +83 -0
  121. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  122. package/dist/components/VChip/VChip.css +2 -0
  123. package/dist/components/VChip/VChip.d.ts +120 -0
  124. package/dist/components/VChip/VChip.js +9 -0
  125. package/dist/components/VChip/VChip.js.map +1 -0
  126. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +118 -0
  127. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  128. package/dist/components/VCombobox/VCombobox.css +2 -0
  129. package/dist/components/VCombobox/VCombobox.d.ts +183 -0
  130. package/dist/components/VCombobox/VCombobox.js +9 -0
  131. package/dist/components/VCombobox/VCombobox.js.map +1 -0
  132. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +428 -0
  133. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  134. package/dist/components/VCombobox/VComboboxGroup.css +2 -0
  135. package/dist/components/VCombobox/VComboboxGroup.d.ts +26 -0
  136. package/dist/components/VCombobox/VComboboxGroup.js +9 -0
  137. package/dist/components/VCombobox/VComboboxGroup.js.map +1 -0
  138. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +21 -0
  139. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  140. package/dist/components/VCombobox/VComboboxOption.css +2 -0
  141. package/dist/components/VCombobox/VComboboxOption.d.ts +48 -0
  142. package/dist/components/VCombobox/VComboboxOption.js +9 -0
  143. package/dist/components/VCombobox/VComboboxOption.js.map +1 -0
  144. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +56 -0
  145. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -0
  146. package/dist/components/VCombobox/VComboboxSeparator.css +2 -0
  147. package/dist/components/VCombobox/VComboboxSeparator.d.ts +3 -0
  148. package/dist/components/VCombobox/VComboboxSeparator.js +9 -0
  149. package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -0
  150. package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js +16 -0
  151. package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  152. package/dist/components/VCombobox/infiniteScroll.d.ts +22 -0
  153. package/dist/components/VCombobox/infiniteScroll.js +28 -0
  154. package/dist/components/VCombobox/infiniteScroll.js.map +1 -0
  155. package/dist/components/VDataTable/VDataTable.css +2 -0
  156. package/dist/components/VDataTable/VDataTable.d.ts +214 -0
  157. package/dist/components/VDataTable/VDataTable.js +9 -0
  158. package/dist/components/VDataTable/VDataTable.js.map +1 -0
  159. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +396 -0
  160. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  161. package/dist/components/VDateInput/VDateInput.css +2 -0
  162. package/dist/components/VDateInput/VDateInput.d.ts +152 -0
  163. package/dist/components/VDateInput/VDateInput.js +9 -0
  164. package/dist/components/VDateInput/VDateInput.js.map +1 -0
  165. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +324 -0
  166. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  167. package/dist/components/VDatePicker/VDatePicker.css +2 -0
  168. package/dist/components/VDatePicker/VDatePicker.d.ts +143 -0
  169. package/dist/components/VDatePicker/VDatePicker.js +9 -0
  170. package/dist/components/VDatePicker/VDatePicker.js.map +1 -0
  171. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +454 -0
  172. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  173. package/dist/components/VDatePicker/keyboard.d.ts +56 -0
  174. package/dist/components/VDatePicker/keyboard.js +26 -0
  175. package/dist/components/VDatePicker/keyboard.js.map +1 -0
  176. package/dist/components/VDialog/VDialog.css +2 -0
  177. package/dist/components/VDialog/VDialog.d.ts +96 -0
  178. package/dist/components/VDialog/VDialog.js +9 -0
  179. package/dist/components/VDialog/VDialog.js.map +1 -0
  180. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +134 -0
  181. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  182. package/dist/components/VDialog/VDialogAlert.d.ts +67 -0
  183. package/dist/components/VDialog/VDialogAlert.js +7 -0
  184. package/dist/components/VDialog/VDialogAlert.js.map +1 -0
  185. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +60 -0
  186. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/components/VFileInput/VFileInput.css +2 -0
  188. package/dist/components/VFileInput/VFileInput.d.ts +156 -0
  189. package/dist/components/VFileInput/VFileInput.js +9 -0
  190. package/dist/components/VFileInput/VFileInput.js.map +1 -0
  191. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +244 -0
  192. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  193. package/dist/components/VFileInput/truncate.d.ts +29 -0
  194. package/dist/components/VFileInput/truncate.js +10 -0
  195. package/dist/components/VFileInput/truncate.js.map +1 -0
  196. package/dist/components/VFilePicker/VFilePicker.css +2 -0
  197. package/dist/components/VFilePicker/VFilePicker.d.ts +203 -0
  198. package/dist/components/VFilePicker/VFilePicker.js +9 -0
  199. package/dist/components/VFilePicker/VFilePicker.js.map +1 -0
  200. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +266 -0
  201. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  202. package/dist/components/VFilePicker/fileKind.d.ts +29 -0
  203. package/dist/components/VFilePicker/fileKind.js +91 -0
  204. package/dist/components/VFilePicker/fileKind.js.map +1 -0
  205. package/dist/components/VHotkeys/VHotkeys.css +2 -0
  206. package/dist/components/VHotkeys/VHotkeys.d.ts +100 -0
  207. package/dist/components/VHotkeys/VHotkeys.js +9 -0
  208. package/dist/components/VHotkeys/VHotkeys.js.map +1 -0
  209. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +76 -0
  210. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/components/VHotkeys/platform.d.ts +82 -0
  212. package/dist/components/VHotkeys/platform.js +115 -0
  213. package/dist/components/VHotkeys/platform.js.map +1 -0
  214. package/dist/components/VIcon/VIcon.css +2 -0
  215. package/dist/components/VIcon/VIcon.d.ts +57 -0
  216. package/dist/components/VIcon/VIcon.js +9 -0
  217. package/dist/components/VIcon/VIcon.js.map +1 -0
  218. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +99 -0
  219. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -0
  220. package/dist/components/VIcon/iconProps.d.ts +30 -0
  221. package/dist/components/VIcon/iconProps.js +6 -0
  222. package/dist/components/VIcon/iconProps.js.map +1 -0
  223. package/dist/components/VIcon/icons/arrow_downward.d.ts +5 -0
  224. package/dist/components/VIcon/icons/arrow_downward.js +9 -0
  225. package/dist/components/VIcon/icons/arrow_downward.js.map +1 -0
  226. package/dist/components/VIcon/icons/arrow_downward_alt.d.ts +5 -0
  227. package/dist/components/VIcon/icons/arrow_downward_alt.js +9 -0
  228. package/dist/components/VIcon/icons/arrow_downward_alt.js.map +1 -0
  229. package/dist/components/VIcon/icons/arrow_drop_down.d.ts +5 -0
  230. package/dist/components/VIcon/icons/arrow_drop_down.js +9 -0
  231. package/dist/components/VIcon/icons/arrow_drop_down.js.map +1 -0
  232. package/dist/components/VIcon/icons/arrow_drop_up.d.ts +5 -0
  233. package/dist/components/VIcon/icons/arrow_drop_up.js +9 -0
  234. package/dist/components/VIcon/icons/arrow_drop_up.js.map +1 -0
  235. package/dist/components/VIcon/icons/arrow_left_alt.d.ts +5 -0
  236. package/dist/components/VIcon/icons/arrow_left_alt.js +9 -0
  237. package/dist/components/VIcon/icons/arrow_left_alt.js.map +1 -0
  238. package/dist/components/VIcon/icons/arrow_right_alt.d.ts +5 -0
  239. package/dist/components/VIcon/icons/arrow_right_alt.js +9 -0
  240. package/dist/components/VIcon/icons/arrow_right_alt.js.map +1 -0
  241. package/dist/components/VIcon/icons/arrow_upward.d.ts +5 -0
  242. package/dist/components/VIcon/icons/arrow_upward.js +9 -0
  243. package/dist/components/VIcon/icons/arrow_upward.js.map +1 -0
  244. package/dist/components/VIcon/icons/arrow_upward_alt.d.ts +5 -0
  245. package/dist/components/VIcon/icons/arrow_upward_alt.js +9 -0
  246. package/dist/components/VIcon/icons/arrow_upward_alt.js.map +1 -0
  247. package/dist/components/VIcon/icons/attach_file.d.ts +5 -0
  248. package/dist/components/VIcon/icons/attach_file.js +9 -0
  249. package/dist/components/VIcon/icons/attach_file.js.map +1 -0
  250. package/dist/components/VIcon/icons/audio_file.d.ts +5 -0
  251. package/dist/components/VIcon/icons/audio_file.js +9 -0
  252. package/dist/components/VIcon/icons/audio_file.js.map +1 -0
  253. package/dist/components/VIcon/icons/calendar_today.d.ts +5 -0
  254. package/dist/components/VIcon/icons/calendar_today.js +9 -0
  255. package/dist/components/VIcon/icons/calendar_today.js.map +1 -0
  256. package/dist/components/VIcon/icons/check.d.ts +5 -0
  257. package/dist/components/VIcon/icons/check.js +9 -0
  258. package/dist/components/VIcon/icons/check.js.map +1 -0
  259. package/dist/components/VIcon/icons/check_circle.d.ts +5 -0
  260. package/dist/components/VIcon/icons/check_circle.js +9 -0
  261. package/dist/components/VIcon/icons/check_circle.js.map +1 -0
  262. package/dist/components/VIcon/icons/chevron_left.d.ts +5 -0
  263. package/dist/components/VIcon/icons/chevron_left.js +9 -0
  264. package/dist/components/VIcon/icons/chevron_left.js.map +1 -0
  265. package/dist/components/VIcon/icons/chevron_right.d.ts +5 -0
  266. package/dist/components/VIcon/icons/chevron_right.js +9 -0
  267. package/dist/components/VIcon/icons/chevron_right.js.map +1 -0
  268. package/dist/components/VIcon/icons/close.d.ts +5 -0
  269. package/dist/components/VIcon/icons/close.js +9 -0
  270. package/dist/components/VIcon/icons/close.js.map +1 -0
  271. package/dist/components/VIcon/icons/cloud_upload.d.ts +5 -0
  272. package/dist/components/VIcon/icons/cloud_upload.js +9 -0
  273. package/dist/components/VIcon/icons/cloud_upload.js.map +1 -0
  274. package/dist/components/VIcon/icons/code.d.ts +5 -0
  275. package/dist/components/VIcon/icons/code.js +9 -0
  276. package/dist/components/VIcon/icons/code.js.map +1 -0
  277. package/dist/components/VIcon/icons/description.d.ts +5 -0
  278. package/dist/components/VIcon/icons/description.js +9 -0
  279. package/dist/components/VIcon/icons/description.js.map +1 -0
  280. package/dist/components/VIcon/icons/error.d.ts +5 -0
  281. package/dist/components/VIcon/icons/error.js +9 -0
  282. package/dist/components/VIcon/icons/error.js.map +1 -0
  283. package/dist/components/VIcon/icons/expand_less.d.ts +5 -0
  284. package/dist/components/VIcon/icons/expand_less.js +9 -0
  285. package/dist/components/VIcon/icons/expand_less.js.map +1 -0
  286. package/dist/components/VIcon/icons/expand_more.d.ts +5 -0
  287. package/dist/components/VIcon/icons/expand_more.js +9 -0
  288. package/dist/components/VIcon/icons/expand_more.js.map +1 -0
  289. package/dist/components/VIcon/icons/folder_zip.d.ts +5 -0
  290. package/dist/components/VIcon/icons/folder_zip.js +9 -0
  291. package/dist/components/VIcon/icons/folder_zip.js.map +1 -0
  292. package/dist/components/VIcon/icons/image.d.ts +5 -0
  293. package/dist/components/VIcon/icons/image.js +9 -0
  294. package/dist/components/VIcon/icons/image.js.map +1 -0
  295. package/dist/components/VIcon/icons/index.d.ts +183 -0
  296. package/dist/components/VIcon/icons/index.js +77 -0
  297. package/dist/components/VIcon/icons/index.js.map +1 -0
  298. package/dist/components/VIcon/icons/info.d.ts +5 -0
  299. package/dist/components/VIcon/icons/info.js +9 -0
  300. package/dist/components/VIcon/icons/info.js.map +1 -0
  301. package/dist/components/VIcon/icons/more_horiz.d.ts +5 -0
  302. package/dist/components/VIcon/icons/more_horiz.js +9 -0
  303. package/dist/components/VIcon/icons/more_horiz.js.map +1 -0
  304. package/dist/components/VIcon/icons/names.d.ts +11 -0
  305. package/dist/components/VIcon/icons/names.js +5 -0
  306. package/dist/components/VIcon/icons/names.js.map +1 -0
  307. package/dist/components/VIcon/icons/notifications.d.ts +5 -0
  308. package/dist/components/VIcon/icons/notifications.js +9 -0
  309. package/dist/components/VIcon/icons/notifications.js.map +1 -0
  310. package/dist/components/VIcon/icons/picture_as_pdf.d.ts +5 -0
  311. package/dist/components/VIcon/icons/picture_as_pdf.js +9 -0
  312. package/dist/components/VIcon/icons/picture_as_pdf.js.map +1 -0
  313. package/dist/components/VIcon/icons/schedule.d.ts +5 -0
  314. package/dist/components/VIcon/icons/schedule.js +9 -0
  315. package/dist/components/VIcon/icons/schedule.js.map +1 -0
  316. package/dist/components/VIcon/icons/search.d.ts +5 -0
  317. package/dist/components/VIcon/icons/search.js +9 -0
  318. package/dist/components/VIcon/icons/search.js.map +1 -0
  319. package/dist/components/VIcon/icons/swap_vert.d.ts +5 -0
  320. package/dist/components/VIcon/icons/swap_vert.js +9 -0
  321. package/dist/components/VIcon/icons/swap_vert.js.map +1 -0
  322. package/dist/components/VIcon/icons/table_chart.d.ts +5 -0
  323. package/dist/components/VIcon/icons/table_chart.js +9 -0
  324. package/dist/components/VIcon/icons/table_chart.js.map +1 -0
  325. package/dist/components/VIcon/icons/video_file.d.ts +5 -0
  326. package/dist/components/VIcon/icons/video_file.js +9 -0
  327. package/dist/components/VIcon/icons/video_file.js.map +1 -0
  328. package/dist/components/VIcon/icons/viewBox.d.ts +6 -0
  329. package/dist/components/VIcon/icons/viewBox.js +6 -0
  330. package/dist/components/VIcon/icons/viewBox.js.map +1 -0
  331. package/dist/components/VIcon/icons/warning.d.ts +5 -0
  332. package/dist/components/VIcon/icons/warning.js +9 -0
  333. package/dist/components/VIcon/icons/warning.js.map +1 -0
  334. package/dist/components/VIcon/resolver.d.ts +76 -0
  335. package/dist/components/VIcon/resolver.js +35 -0
  336. package/dist/components/VIcon/resolver.js.map +1 -0
  337. package/dist/components/VIcon/types.d.ts +77 -0
  338. package/dist/components/VIconButton/VIconButton.css +2 -0
  339. package/dist/components/VIconButton/VIconButton.d.ts +66 -0
  340. package/dist/components/VIconButton/VIconButton.js +9 -0
  341. package/dist/components/VIconButton/VIconButton.js.map +1 -0
  342. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +70 -0
  343. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  344. package/dist/components/VInput/VInput.css +2 -0
  345. package/dist/components/VInput/VInput.d.ts +152 -0
  346. package/dist/components/VInput/VInput.js +9 -0
  347. package/dist/components/VInput/VInput.js.map +1 -0
  348. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +185 -0
  349. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  350. package/dist/components/VInputOTP/VInputOTP.css +2 -0
  351. package/dist/components/VInputOTP/VInputOTP.d.ts +76 -0
  352. package/dist/components/VInputOTP/VInputOTP.js +9 -0
  353. package/dist/components/VInputOTP/VInputOTP.js.map +1 -0
  354. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +149 -0
  355. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -0
  356. package/dist/components/VMenu/VMenu.d.ts +91 -0
  357. package/dist/components/VMenu/VMenu.js +7 -0
  358. package/dist/components/VMenu/VMenu.js.map +1 -0
  359. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +73 -0
  360. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  361. package/dist/components/VMenu/VMenuGroup.css +2 -0
  362. package/dist/components/VMenu/VMenuGroup.d.ts +22 -0
  363. package/dist/components/VMenu/VMenuGroup.js +9 -0
  364. package/dist/components/VMenu/VMenuGroup.js.map +1 -0
  365. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +21 -0
  366. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  367. package/dist/components/VMenu/VMenuItem.css +2 -0
  368. package/dist/components/VMenu/VMenuItem.d.ts +85 -0
  369. package/dist/components/VMenu/VMenuItem.js +9 -0
  370. package/dist/components/VMenu/VMenuItem.js.map +1 -0
  371. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +121 -0
  372. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  373. package/dist/components/VMenu/VMenuPanel.css +2 -0
  374. package/dist/components/VMenu/VMenuPanel.d.ts +91 -0
  375. package/dist/components/VMenu/VMenuPanel.js +9 -0
  376. package/dist/components/VMenu/VMenuPanel.js.map +1 -0
  377. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +103 -0
  378. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  379. package/dist/components/VMenu/VMenuSeparator.css +2 -0
  380. package/dist/components/VMenu/VMenuSeparator.d.ts +3 -0
  381. package/dist/components/VMenu/VMenuSeparator.js +9 -0
  382. package/dist/components/VMenu/VMenuSeparator.js.map +1 -0
  383. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js +13 -0
  384. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  385. package/dist/components/VMenu/context.d.ts +33 -0
  386. package/dist/components/VMenu/context.js +9 -0
  387. package/dist/components/VMenu/context.js.map +1 -0
  388. package/dist/components/VPagination/VPagination.css +2 -0
  389. package/dist/components/VPagination/VPagination.d.ts +103 -0
  390. package/dist/components/VPagination/VPagination.js +9 -0
  391. package/dist/components/VPagination/VPagination.js.map +1 -0
  392. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +270 -0
  393. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
  394. package/dist/components/VPopover/VPopover.css +2 -0
  395. package/dist/components/VPopover/VPopover.d.ts +82 -0
  396. package/dist/components/VPopover/VPopover.js +9 -0
  397. package/dist/components/VPopover/VPopover.js.map +1 -0
  398. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +65 -0
  399. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  400. package/dist/components/VProgressCircular/VProgressCircular.css +2 -0
  401. package/dist/components/VProgressCircular/VProgressCircular.d.ts +60 -0
  402. package/dist/components/VProgressCircular/VProgressCircular.js +9 -0
  403. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -0
  404. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +74 -0
  405. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -0
  406. package/dist/components/VProgressLinear/VProgressLinear.css +2 -0
  407. package/dist/components/VProgressLinear/VProgressLinear.d.ts +74 -0
  408. package/dist/components/VProgressLinear/VProgressLinear.js +9 -0
  409. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -0
  410. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +74 -0
  411. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -0
  412. package/dist/components/VRadio/VRadio.css +2 -0
  413. package/dist/components/VRadio/VRadio.d.ts +58 -0
  414. package/dist/components/VRadio/VRadio.js +9 -0
  415. package/dist/components/VRadio/VRadio.js.map +1 -0
  416. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +60 -0
  417. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -0
  418. package/dist/components/VSeparator/VSeparator.css +2 -0
  419. package/dist/components/VSeparator/VSeparator.d.ts +23 -0
  420. package/dist/components/VSeparator/VSeparator.js +9 -0
  421. package/dist/components/VSeparator/VSeparator.js.map +1 -0
  422. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js +17 -0
  423. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  424. package/dist/components/VSideNavigation/VSideNavigation.css +2 -0
  425. package/dist/components/VSideNavigation/VSideNavigation.d.ts +64 -0
  426. package/dist/components/VSideNavigation/VSideNavigation.js +9 -0
  427. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -0
  428. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +67 -0
  429. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -0
  430. package/dist/components/VSideNavigation/VSideNavigationGroup.css +2 -0
  431. package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +33 -0
  432. package/dist/components/VSideNavigation/VSideNavigationGroup.js +9 -0
  433. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -0
  434. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +20 -0
  435. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  436. package/dist/components/VSideNavigation/VSideNavigationItem.css +2 -0
  437. package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +103 -0
  438. package/dist/components/VSideNavigation/VSideNavigationItem.js +9 -0
  439. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -0
  440. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +154 -0
  441. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  442. package/dist/components/VSideNavigation/VSideNavigationSeparator.css +2 -0
  443. package/dist/components/VSideNavigation/VSideNavigationSeparator.d.ts +3 -0
  444. package/dist/components/VSideNavigation/VSideNavigationSeparator.js +17 -0
  445. package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -0
  446. package/dist/components/VSideNavigation/context.d.ts +37 -0
  447. package/dist/components/VSideNavigation/context.js +6 -0
  448. package/dist/components/VSideNavigation/context.js.map +1 -0
  449. package/dist/components/VSkeletonLoader/VSkeletonLoader.css +2 -0
  450. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +75 -0
  451. package/dist/components/VSkeletonLoader/VSkeletonLoader.js +9 -0
  452. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -0
  453. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +61 -0
  454. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  455. package/dist/components/VSlider/VSlider.css +2 -0
  456. package/dist/components/VSlider/VSlider.d.ts +82 -0
  457. package/dist/components/VSlider/VSlider.js +9 -0
  458. package/dist/components/VSlider/VSlider.js.map +1 -0
  459. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +220 -0
  460. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  461. package/dist/components/VSnackbar/VSnackbar.css +2 -0
  462. package/dist/components/VSnackbar/VSnackbar.d.ts +51 -0
  463. package/dist/components/VSnackbar/VSnackbar.js +9 -0
  464. package/dist/components/VSnackbar/VSnackbar.js.map +1 -0
  465. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +83 -0
  466. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  467. package/dist/components/VSnackbar/state.d.ts +92 -0
  468. package/dist/components/VSnackbar/state.js +18 -0
  469. package/dist/components/VSnackbar/state.js.map +1 -0
  470. package/dist/components/VSpinner/VSpinner.css +2 -0
  471. package/dist/components/VSpinner/VSpinner.d.ts +21 -0
  472. package/dist/components/VSpinner/VSpinner.js +9 -0
  473. package/dist/components/VSpinner/VSpinner.js.map +1 -0
  474. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +25 -0
  475. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  476. package/dist/components/VSwitch/VSwitch.css +2 -0
  477. package/dist/components/VSwitch/VSwitch.d.ts +46 -0
  478. package/dist/components/VSwitch/VSwitch.js +9 -0
  479. package/dist/components/VSwitch/VSwitch.js.map +1 -0
  480. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +51 -0
  481. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -0
  482. package/dist/components/VTabs/VTab.css +2 -0
  483. package/dist/components/VTabs/VTab.d.ts +42 -0
  484. package/dist/components/VTabs/VTab.js +9 -0
  485. package/dist/components/VTabs/VTab.js.map +1 -0
  486. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +66 -0
  487. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -0
  488. package/dist/components/VTabs/VTabPanel.css +2 -0
  489. package/dist/components/VTabs/VTabPanel.d.ts +34 -0
  490. package/dist/components/VTabs/VTabPanel.js +9 -0
  491. package/dist/components/VTabs/VTabPanel.js.map +1 -0
  492. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +34 -0
  493. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  494. package/dist/components/VTabs/VTabs.css +2 -0
  495. package/dist/components/VTabs/VTabs.d.ts +107 -0
  496. package/dist/components/VTabs/VTabs.js +9 -0
  497. package/dist/components/VTabs/VTabs.js.map +1 -0
  498. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +199 -0
  499. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  500. package/dist/components/VTabs/context.d.ts +43 -0
  501. package/dist/components/VTabs/context.js +6 -0
  502. package/dist/components/VTabs/context.js.map +1 -0
  503. package/dist/components/VTextarea/VTextarea.css +2 -0
  504. package/dist/components/VTextarea/VTextarea.d.ts +140 -0
  505. package/dist/components/VTextarea/VTextarea.js +9 -0
  506. package/dist/components/VTextarea/VTextarea.js.map +1 -0
  507. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +187 -0
  508. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  509. package/dist/components/VTimeInput/VTimeInput.css +2 -0
  510. package/dist/components/VTimeInput/VTimeInput.d.ts +112 -0
  511. package/dist/components/VTimeInput/VTimeInput.js +9 -0
  512. package/dist/components/VTimeInput/VTimeInput.js.map +1 -0
  513. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +385 -0
  514. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  515. package/dist/components/VTimePicker/VTimePicker.css +2 -0
  516. package/dist/components/VTimePicker/VTimePicker.d.ts +89 -0
  517. package/dist/components/VTimePicker/VTimePicker.js +9 -0
  518. package/dist/components/VTimePicker/VTimePicker.js.map +1 -0
  519. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +257 -0
  520. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  521. package/dist/components/VToast/VToast.css +2 -0
  522. package/dist/components/VToast/VToast.d.ts +24 -0
  523. package/dist/components/VToast/VToast.js +9 -0
  524. package/dist/components/VToast/VToast.js.map +1 -0
  525. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +62 -0
  526. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -0
  527. package/dist/components/VToast/VToaster.css +2 -0
  528. package/dist/components/VToast/VToaster.d.ts +42 -0
  529. package/dist/components/VToast/VToaster.js +9 -0
  530. package/dist/components/VToast/VToaster.js.map +1 -0
  531. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +112 -0
  532. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -0
  533. package/dist/components/VToast/state.d.ts +74 -0
  534. package/dist/components/VToast/state.js +25 -0
  535. package/dist/components/VToast/state.js.map +1 -0
  536. package/dist/components/VToggle/VToggle.css +2 -0
  537. package/dist/components/VToggle/VToggle.d.ts +84 -0
  538. package/dist/components/VToggle/VToggle.js +9 -0
  539. package/dist/components/VToggle/VToggle.js.map +1 -0
  540. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +103 -0
  541. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -0
  542. package/dist/components/VToggle/VToggleItem.css +2 -0
  543. package/dist/components/VToggle/VToggleItem.d.ts +35 -0
  544. package/dist/components/VToggle/VToggleItem.js +9 -0
  545. package/dist/components/VToggle/VToggleItem.js.map +1 -0
  546. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +51 -0
  547. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  548. package/dist/components/VToggle/context.d.ts +37 -0
  549. package/dist/components/VToggle/context.js +6 -0
  550. package/dist/components/VToggle/context.js.map +1 -0
  551. package/dist/components/VTooltip/VTooltip.css +2 -0
  552. package/dist/components/VTooltip/VTooltip.d.ts +76 -0
  553. package/dist/components/VTooltip/VTooltip.js +9 -0
  554. package/dist/components/VTooltip/VTooltip.js.map +1 -0
  555. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +50 -0
  556. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  557. package/dist/components/VTypography/VTypography.css +2 -0
  558. package/dist/components/VTypography/VTypography.d.ts +46 -0
  559. package/dist/components/VTypography/VTypography.js +9 -0
  560. package/dist/components/VTypography/VTypography.js.map +1 -0
  561. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js +49 -0
  562. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -0
  563. package/dist/composables/useAriaLabel.d.ts +19 -0
  564. package/dist/composables/useAriaLabel.js +10 -0
  565. package/dist/composables/useAriaLabel.js.map +1 -0
  566. package/dist/composables/useFieldIds.d.ts +21 -0
  567. package/dist/composables/useFieldIds.js +14 -0
  568. package/dist/composables/useFieldIds.js.map +1 -0
  569. package/dist/composables/useFieldPanel.d.ts +61 -0
  570. package/dist/composables/useFieldPanel.js +39 -0
  571. package/dist/composables/useFieldPanel.js.map +1 -0
  572. package/dist/composables/useFileDrop.d.ts +30 -0
  573. package/dist/composables/useFileDrop.js +28 -0
  574. package/dist/composables/useFileDrop.js.map +1 -0
  575. package/dist/composables/useFileField.d.ts +36 -0
  576. package/dist/composables/useFileField.js +45 -0
  577. package/dist/composables/useFileField.js.map +1 -0
  578. package/dist/composables/useFocusoutDismiss.d.ts +17 -0
  579. package/dist/composables/useFocusoutDismiss.js +11 -0
  580. package/dist/composables/useFocusoutDismiss.js.map +1 -0
  581. package/dist/composables/useIconClickHandlers.d.ts +27 -0
  582. package/dist/composables/useIconClickHandlers.js +13 -0
  583. package/dist/composables/useIconClickHandlers.js.map +1 -0
  584. package/dist/composables/useMaskedField.d.ts +65 -0
  585. package/dist/composables/useMaskedField.js +54 -0
  586. package/dist/composables/useMaskedField.js.map +1 -0
  587. package/dist/composables/usePopover.d.ts +7 -0
  588. package/dist/composables/usePopover.js +24 -0
  589. package/dist/composables/usePopover.js.map +1 -0
  590. package/dist/composables/useProgressValue.d.ts +13 -0
  591. package/dist/composables/useProgressValue.js +14 -0
  592. package/dist/composables/useProgressValue.js.map +1 -0
  593. package/dist/composables/useRootAttrs.d.ts +34 -0
  594. package/dist/composables/useRootAttrs.js +15 -0
  595. package/dist/composables/useRootAttrs.js.map +1 -0
  596. package/dist/composables/useTextLimit.d.ts +31 -0
  597. package/dist/composables/useTextLimit.js +19 -0
  598. package/dist/composables/useTextLimit.js.map +1 -0
  599. package/dist/composables/useTimer.d.ts +18 -0
  600. package/dist/composables/useTimer.js +19 -0
  601. package/dist/composables/useTimer.js.map +1 -0
  602. package/dist/i18n/en.d.ts +10 -0
  603. package/dist/i18n/en.js +179 -0
  604. package/dist/i18n/en.js.map +1 -0
  605. package/dist/i18n/fr.d.ts +18 -0
  606. package/dist/i18n/fr.js +179 -0
  607. package/dist/i18n/fr.js.map +1 -0
  608. package/dist/i18n/state.d.ts +64 -0
  609. package/dist/i18n/state.js +40 -0
  610. package/dist/i18n/state.js.map +1 -0
  611. package/dist/i18n/types.d.ts +345 -0
  612. package/dist/icons.d.ts +16 -0
  613. package/dist/icons.js +38 -0
  614. package/dist/index.d.ts +90 -0
  615. package/dist/index.js +64 -0
  616. package/dist/styles.css +1 -0
  617. package/dist/tokens/css.d.ts +25 -0
  618. package/dist/tokens/css.js +29 -0
  619. package/dist/tokens/css.js.map +1 -0
  620. package/dist/tokens/index.d.ts +370 -0
  621. package/dist/tokens/index.js +15 -0
  622. package/dist/tokens/index.js.map +1 -0
  623. package/dist/tokens/primitives.d.ts +101 -0
  624. package/dist/tokens/primitives.js +166 -0
  625. package/dist/tokens/primitives.js.map +1 -0
  626. package/dist/tokens/semantic.d.ts +236 -0
  627. package/dist/tokens/semantic.js +219 -0
  628. package/dist/tokens/semantic.js.map +1 -0
  629. package/dist/tokens/themes/dark.d.ts +49 -0
  630. package/dist/tokens/themes/dark.js +53 -0
  631. package/dist/tokens/themes/dark.js.map +1 -0
  632. package/dist/tokens/types.d.ts +38 -0
  633. package/dist/tokens/types.js +16 -0
  634. package/dist/tokens/types.js.map +1 -0
  635. package/dist/tokens.json +1516 -0
  636. package/dist/utils/array.d.ts +10 -0
  637. package/dist/utils/array.js +8 -0
  638. package/dist/utils/array.js.map +1 -0
  639. package/dist/utils/arrowNav.d.ts +27 -0
  640. package/dist/utils/arrowNav.js +26 -0
  641. package/dist/utils/arrowNav.js.map +1 -0
  642. package/dist/utils/chip.d.ts +26 -0
  643. package/dist/utils/chip.js +13 -0
  644. package/dist/utils/chip.js.map +1 -0
  645. package/dist/utils/css.d.ts +19 -0
  646. package/dist/utils/css.js +13 -0
  647. package/dist/utils/css.js.map +1 -0
  648. package/dist/utils/date.d.ts +199 -0
  649. package/dist/utils/date.js +225 -0
  650. package/dist/utils/date.js.map +1 -0
  651. package/dist/utils/direction.d.ts +18 -0
  652. package/dist/utils/direction.js +8 -0
  653. package/dist/utils/direction.js.map +1 -0
  654. package/dist/utils/env.d.ts +10 -0
  655. package/dist/utils/file.d.ts +95 -0
  656. package/dist/utils/file.js +70 -0
  657. package/dist/utils/file.js.map +1 -0
  658. package/dist/utils/focus.d.ts +24 -0
  659. package/dist/utils/focus.js +13 -0
  660. package/dist/utils/focus.js.map +1 -0
  661. package/dist/utils/matcher.d.ts +13 -0
  662. package/dist/utils/matcher.js +11 -0
  663. package/dist/utils/matcher.js.map +1 -0
  664. package/dist/utils/number.d.ts +9 -0
  665. package/dist/utils/number.js +8 -0
  666. package/dist/utils/number.js.map +1 -0
  667. package/dist/utils/text.d.ts +19 -0
  668. package/dist/utils/text.js +12 -0
  669. package/dist/utils/text.js.map +1 -0
  670. package/dist/utils/time.d.ts +138 -0
  671. package/dist/utils/time.js +123 -0
  672. package/dist/utils/time.js.map +1 -0
  673. package/dist/utils/vnode.d.ts +21 -0
  674. package/dist/utils/vnode.js +14 -0
  675. package/dist/utils/vnode.js.map +1 -0
  676. package/package.json +114 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VCalendarMonth.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VCalendar/VCalendarMonth.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @keyboard @core\n/**\n * The month view: the weeks stacked one under another, each day a square holding as many of\n * its events as will fit.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it. Like the time grid it computes nothing about dates: it is\n * handed the weeks already cut and filtered, and turns them into boxes.\n *\n * A day here is not a column of hours but a SUMMARY, so the events are drawn as chips in\n * the order the day would be read out — the all-day ones first, then the rest by when they\n * start — and a day with more than it can show says how many are left rather than silently\n * dropping them.\n */\nimport { computed, nextTick, ref, useId, watch } from 'vue'\n\nimport { formatDisplay as formatDate } from '../../utils/date'\nimport { isRtl as isElementRtl } from '../../utils/direction'\nimport { clamp } from '../../utils/number'\nimport { formatDisplay as formatTimeDisplay, type HourFormat } from '../../utils/time'\n\nimport { useMessages } from '../../i18n/state'\n\nimport VCalendarEvent from './VCalendarEvent.vue'\nimport { calendarIntent } from './keyboard'\nimport { EDGE_BAND, useEdgeStep } from './edgeStep'\nimport {\n DRAG_THRESHOLD,\n eventsByDay,\n inlineEdgeAt,\n isAllDayEvent,\n moveEventToDay,\n pointToMonthCell,\n pointWithin,\n timesOf,\n type MonthCell,\n} from './layout'\nimport type { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types'\n\nexport interface CalendarMonthProps<T> {\n /** The weeks, already padded to a fixed height and filtered to the visible weekdays. */\n weeks: MonthCell[][]\n events: T[]\n locale: string\n hourFormat: HourFormat\n today: string | null\n /** How many events a day shows before it starts counting the rest. */\n eventLimit: number\n /** Whether events can be moved from one day to another. */\n editable: boolean\n /** The node telling a reader how a chip can be moved, shared by every one of them. */\n hintId: string\n /** How long a drag rests against an edge before the month turns. Zero turns paging off. */\n edgeStepDelay: number\n label: string\n}\n\nconst props = defineProps<CalendarMonthProps<E>>()\n\nconst emit = defineEmits<{\n /** A day was asked to be opened on its own. */\n 'day-activate': [iso: string]\n /** An empty part of a day was activated. */\n 'cell-activate': [iso: string]\n 'event-activate': [event: E]\n /** An event was dropped on another day. A month has no hours, so it is only ever a move. */\n 'event-drop': [id: CalendarEventId, times: CalendarEventTimes, kind: 'move']\n /** Something happened that a reader who cannot see the grid needs told. */\n announce: [message: string]\n step: [delta: -1 | 1]\n}>()\n\n/** Which day holds the tab stop. Only the date matters here; the hour is the grid's affair. */\nconst focused = defineModel<string>('focused', { required: true })\n\ndefineSlots<{\n event?(props: {\n event: E\n layout: 'block' | 'chip'\n timeText: string\n continuesBefore: boolean\n continuesAfter: boolean\n }): unknown\n}>()\n\nconst m = useMessages()\nconst uid = useId()\n\nconst cellId = (iso: string) => `${uid}-m-${iso}`\n\n/** The column headings, taken from the first week so they always match the columns drawn. */\nconst weekdayNames = computed(() =>\n (props.weeks[0] ?? []).map((cell) => formatDate(cell.iso, props.locale, { weekday: 'short' })),\n)\n\n/*\n * The two labels every square carries, worked out once per cell rather than once per USE.\n *\n * `longDay` is asked for twice in the template — the square's own `aria-label`, then the\n * name of the button that opens the day — so the 42 cells cost 126 `Intl` formats a render,\n * and the drag re-renders the whole grid on every `pointermove` through `gesture.preview`.\n * The map depends on the weeks and the locale alone, so it survives every frame of a drag.\n */\nconst dayLabels = computed(() => {\n const map = new Map<string, { number: string; long: string }>()\n for (const week of props.weeks) {\n for (const cell of week) {\n map.set(cell.iso, {\n number: formatDate(cell.iso, props.locale, { day: 'numeric' }),\n long: formatDate(cell.iso, props.locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n }),\n })\n }\n }\n return map\n})\n\nconst dayNumber = (iso: string) =>\n dayLabels.value.get(iso)?.number ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/*\n * A day outside the grid can reach this — the announcement after a move names the day the\n * event landed on, which may be the next month — so it falls back to formatting rather than\n * assuming the map holds it.\n */\nconst longDay = (iso: string) =>\n dayLabels.value.get(iso)?.long ??\n formatDate(iso, props.locale, { weekday: 'long', day: 'numeric', month: 'long' })\n\n/* ------------------------------------------------------------------- the gesture */\n\n/**\n * A chip being carried from one day to another, by pointer or by keyboard.\n *\n * A month has no hours, so there is one kind and no resize: only which day an event starts\n * on moves, and its length in days and its times come along untouched.\n */\ninterface Gesture {\n id: CalendarEventId\n /** Where the event was when the gesture began — every frame is computed from THIS. */\n origin: CalendarEventTimes\n /** What the chip shows right now. The model is not touched until the gesture ends. */\n preview: CalendarEventTimes\n pointerId: number | null\n originX: number\n originY: number\n /** Which square the pointer took hold in, so a long bar does not jump under it. */\n grabIndex: number\n /**\n * Where the pointer last was — needed because turning the month moves the squares under a\n * hand that is holding still, and the chip has to be worked out again against the new ones.\n */\n lastX: number\n lastY: number\n moved: boolean\n /**\n * Whether the pointer is off the month altogether — over the toolbar, or over the page beside\n * it. Letting go here abandons the gesture and writes nothing.\n *\n * A KEYBOARD grab can never set it: `onPointermove` is the only writer, and it returns on the\n * id mismatch before reaching that line — a grab's `pointerId` is null.\n */\n outside: boolean\n}\n\nconst gesture = ref<Gesture | null>(null)\nconst grabbing = computed(() => gesture.value !== null && gesture.value.pointerId === null)\nconst gridEl = ref<HTMLElement | null>(null)\n/** The view's own box, which a drag is measured against to know whether it has left it. */\nconst rootEl = ref<HTMLElement | null>(null)\n\n/**\n * The id the faded echo of a dragged chip carries.\n *\n * It must DIFFER from the event's own, or the two would collide in the map the day grouping\n * keys by id. The original is recovered from it and handed to the card as `ghostOf`, because\n * the colour of an event is derived from its id — under a fresh one the echo would come out\n * a different colour from the chip it belongs to.\n */\nconst GHOST_PREFIX = '__vectis-calendar-ghost__'\nconst ghostIdOf = (id: CalendarEventId) => `${GHOST_PREFIX}${id}`\nconst originalIdOf = (id: CalendarEventId) => String(id).slice(GHOST_PREFIX.length)\nconst isGhostId = (id: CalendarEventId) => String(id).startsWith(GHOST_PREFIX)\n\n/**\n * The events as the month should currently DRAW them — the model, with the one being carried\n * put wherever it now is. Running the preview through the same grouping as everything else is\n * what makes the day it leaves and the day it arrives at both redraw with no special case.\n */\nconst drawnEvents = computed<E[]>(() => {\n const state = gesture.value\n if (!state) return props.events\n\n const moving = props.events.map((item) =>\n item.id === state.id ? ({ ...item, ...state.preview } as E) : item,\n )\n\n /*\n * The faded echo of where the chip started, so the reader can see what they are moving it\n * FROM. Added only once the drag has travelled, or a click would flash a second chip in\n * the same day.\n *\n * Nothing has to be held out of a layout here, unlike the time grid: a month cell simply\n * stacks its chips, so the echo takes its own line in the day it came from and disturbs\n * nothing.\n */\n const original = state.moved ? props.events.find((item) => item.id === state.id) : undefined\n if (!original) return moving\n\n return [...moving, { ...original, ...state.origin, id: ghostIdOf(state.id) } as E]\n})\n\n/** Every day's events, worked out once rather than once per chip. */\nconst byDay = computed(() =>\n eventsByDay(\n drawnEvents.value,\n props.weeks.flatMap((week) => week.map((cell) => cell.iso)),\n ),\n)\n\nconst eventsById = computed(() => new Map(drawnEvents.value.map((item) => [item.id, item])))\n\nconst shownOf = (iso: string) => (byDay.value.get(iso) ?? []).slice(0, props.eventLimit)\nconst hiddenOf = (iso: string) =>\n Math.max(0, (byDay.value.get(iso) ?? []).length - props.eventLimit)\n\n/**\n * A chip says when it happens only when that is not obvious: an all-day event has no time\n * to give, and the day it sits in already says which day it is.\n */\nfunction timeTextOf(event: E): string {\n if (isAllDayEvent(event)) return ''\n return formatTimeDisplay(event.startTime, props.locale, props.hourFormat)\n}\n\n/** The flattened list of days, which is what the arrows travel along. */\nconst flat = computed(() => props.weeks.flat().map((cell) => cell.iso))\n\nfunction moveFocusTo(iso: string) {\n focused.value = iso\n // @a11y — the model decides which cell is tabbable, so the focus can only follow once the\n // render that applied it has run.\n void nextTick(() => document.getElementById(cellId(iso))?.focus())\n}\n\nconst tabbable = computed(() =>\n flat.value.includes(focused.value) ? focused.value : (flat.value[0] ?? null),\n)\n\nfunction onKeydown(event: KeyboardEvent) {\n const target = event.target as HTMLElement | null\n\n // A chip answers its own table, delegated here on the same element as the pointer so the\n // two input paths cannot drift apart.\n const card = target?.closest<HTMLElement>('.v-calendar-event')\n if (card) {\n onCardKeydown(event, card)\n return\n }\n\n const cell = target?.closest<HTMLElement>('.v-calendar-month-cell')\n if (!cell) return\n\n // The step is irrelevant to a month, which has no hours: 1 keeps the table honest without\n // asking the calendar for a number this view never uses.\n const intent = calendarIntent(event.key, event.shiftKey, 'cell', 1, isRtl())\n if (!intent) return\n\n const iso = cell.dataset.iso!\n const index = flat.value.indexOf(iso)\n const columns = props.weeks[0]?.length ?? 1\n\n if (intent.kind === 'moveFocus') {\n /*\n * The same table serves both views, so its two axes are read differently here: a\n * sideways step is one day, and a vertical one is a whole week rather than an hour.\n * That is the only place the month reinterprets it, and it is why the table returns a\n * direction rather than a date.\n */\n const delta = intent.days !== 0 ? intent.days : Math.sign(intent.minutes) * columns\n const next = flat.value[clamp(index + delta, 0, flat.value.length - 1)]\n if (!next) return\n event.preventDefault()\n moveFocusTo(next)\n return\n }\n\n if (intent.kind === 'rowEdge') {\n const row = Math.floor(index / columns)\n const edge = intent.edge === 'start' ? row * columns : row * columns + columns - 1\n const next = flat.value[clamp(edge, 0, flat.value.length - 1)]\n if (!next) return\n event.preventDefault()\n moveFocusTo(next)\n return\n }\n\n if (intent.kind === 'period') {\n event.preventDefault()\n emit('step', intent.delta)\n return\n }\n\n if (intent.kind === 'activate') {\n event.preventDefault()\n emit('cell-activate', iso)\n }\n}\n\n/* ------------------------------------------------------- the gesture, by pointer */\n\nconst isRtl = () => isElementRtl(gridEl.value)\n\n/** The grid as the pure geometry wants it: plain numbers, no element. */\nfunction geometryOf(rect: DOMRect) {\n const rtl = isRtl()\n return {\n top: rect.top,\n height: rect.height,\n inlineStart: rtl ? rect.right : rect.left,\n inlineSize: rect.width,\n columns: props.weeks[0]?.length ?? 1,\n rows: props.weeks.length || 1,\n }\n}\n\n/** Which of the flattened squares a point falls on. */\nfunction indexAt(x: number, y: number): number | null {\n const rect = gridEl.value?.getBoundingClientRect()\n if (!rect) return null\n const cell = pointToMonthCell({ x, y }, geometryOf(rect), isRtl())\n const columns = props.weeks[0]?.length ?? 1\n return cell.rowIndex * columns + cell.columnIndex\n}\n\nconst edge = useEdgeStep(\n (direction) => emit('step', direction),\n () => props.edgeStepDelay,\n)\n\n/** Which edge is counting down, in words, for the stylesheet to light up. */\nconst edgeCue = computed(() =>\n edge.pending.value === -1 ? 'start' : edge.pending.value === 1 ? 'end' : undefined,\n)\n\n/*\n * Turning the month swaps every square out from under a live drag, and the chip's day is then\n * a different one — it would vanish until the next pointer move, which never comes if the hand\n * is holding still against the edge. Re-applying the last position once the new month is\n * rendered is what carries the chip across the boundary.\n */\nwatch(\n () => props.weeks,\n () => {\n const state = gesture.value\n if (state?.moved) applyPoint(state)\n },\n { flush: 'post' },\n)\n\nfunction onGridPointerdown(event: PointerEvent) {\n endLastGesture()\n if (gesture.value || !props.editable || event.button !== 0) return\n\n const card = (event.target as HTMLElement | null)?.closest<HTMLElement>('.v-calendar-event')\n if (!card) return\n const item = eventsById.value.get(cardIdOf(card))\n const index = indexAt(event.clientX, event.clientY)\n if (!item || index === null) return\n\n gesture.value = {\n id: item.id,\n origin: timesOf(item),\n preview: timesOf(item),\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n grabIndex: index,\n lastX: event.clientX,\n lastY: event.clientY,\n moved: false,\n outside: false,\n }\n\n /*\n * @fallback — captured on the GRID rather than on the chip, because a chip is redrawn on\n * another day the moment the drag starts and a captured element that moves takes the\n * pointer with it. Wrapped because a pointer event fired by a TEST refers to no real\n * pointer and the call then throws; failing to capture only means the drag stops at the\n * edge, which no test is checking.\n */\n try {\n gridEl.value?.setPointerCapture(event.pointerId)\n } catch {\n /* a synthetic pointer: nothing to capture */\n }\n}\n\n/** The event a chip stands for, read back off the attribute the card publishes. */\nfunction cardIdOf(card: HTMLElement): CalendarEventId {\n const raw = card.dataset.eventId ?? ''\n // An id may be a number and an attribute is always text; the map is keyed by the original.\n return eventsById.value.has(raw) ? raw : Number(raw)\n}\n\nfunction 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 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 state.moved = true\n state.outside = isPointerOutside(state)\n applyPoint(state)\n\n const rect = gridEl.value?.getBoundingClientRect()\n if (rect) edge.watchEdge(inlineEdgeAt(state.lastX, geometryOf(rect), EDGE_BAND, isRtl()))\n}\n\n/**\n * Whether the pointer has left the month's own box.\n *\n * Measured against the ROOT and not against `gridEl`, whose rect leaves out the row of weekday\n * names above it — the month's own version of the all-day band the time grid has to include, and\n * the same mistake to make. The rect goes in raw, never through `geometryOf`: containment has no\n * reading direction, where `inlineStart` is the right edge in a right-to-left page.\n *\n * Neither `applyPoint` nor the edge watch is gated on the result — see the twin of this function\n * in VCalendarTimeGrid.vue, which carries the reasoning for both.\n */\nfunction isPointerOutside(state: Gesture): boolean {\n const rect = rootEl.value?.getBoundingClientRect()\n return rect ? !pointWithin({ x: state.lastX, y: state.lastY }, rect) : false\n}\n\n/**\n * Works out which day the chip now belongs to, from wherever the pointer last was.\n *\n * Separate from the handler because the month turning calls it too: the squares change under\n * a hand that has not moved, and the chip has to be placed against the new ones.\n */\nfunction applyPoint(state: Gesture) {\n const index = indexAt(state.lastX, state.lastY)\n if (index === null) return\n\n /*\n * The target is the event's START shifted by however many squares the pointer has crossed,\n * not the square it is over — so a bar grabbed by its third day keeps its third day under\n * the finger. The days come out of the flattened grid, which is already filtered to the\n * weekdays on show, so a hidden weekend is not counted.\n */\n const days = flat.value\n const from = days.indexOf(state.origin.start)\n const target =\n days[\n clamp((from === -1 ? state.grabIndex : from) + index - state.grabIndex, 0, days.length - 1)\n ]\n if (target) state.preview = moveEventToDay(state.origin, target)\n}\n\nlet justDragged = false\n\n/**\n * Closes the books on whatever gesture came before, at the start of a new press — without which\n * the flag can be left standing and swallow a deliberate click on some chip, long after the drag\n * that raised it. The month cannot reach that on its own, having no gesture that runs without\n * `editable`; it is kept in step with the time grid, whose twin of this function carries the\n * reasoning, so the two cannot answer a press differently.\n */\nfunction endLastGesture() {\n justDragged = false\n}\n\nfunction onPointerup(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n gesture.value = null\n justDragged = state.moved\n edge.cancel()\n\n // Let go off the month altogether: nothing is written and the chip goes back where it was.\n // `justDragged` above still matters, and the two revert paths must stay apart — the twin of\n // this branch in VCalendarTimeGrid.vue carries the reasoning for both.\n if (state.outside) return\n\n if (!state.moved) return\n emit('event-drop', state.id, state.preview, 'move')\n}\n\nfunction onPointercancel() {\n // The gesture was taken away. Nothing is written: the chip goes back to where the model\n // still says it is.\n gesture.value = null\n edge.cancel()\n}\n\nfunction onCardClick(item: E) {\n // `pointerup` fires before `click`, so letting go at the end of a drag would ALSO open the\n // event — the consumer's editor over every chip the reader had just moved.\n if (justDragged) {\n justDragged = false\n return\n }\n emit('event-activate', item)\n}\n\n/* ------------------------------------------------------ the gesture, by keyboard */\n\nfunction announceMoved(title: string, times: CalendarEventTimes) {\n emit('announce', m.value.calendar.movedTo(title, longDay(times.start)))\n}\n\nfunction refocusCard(id: CalendarEventId) {\n void nextTick(() => {\n /*\n * Walked rather than selected, for the reason spelled out at the twin of this function in\n * VCalendarTimeGrid.vue: a consumer's id may need escaping, and `CSS.escape` is unavailable\n * in jsdom — where the throw lands inside a `nextTick`, so it surfaces as an unhandled\n * rejection rather than as a failing test.\n */\n const cards = gridEl.value?.querySelectorAll<HTMLElement>('.v-calendar-event')\n Array.from(cards ?? [])\n .find((card) => card.dataset.eventId === String(id))\n ?.focus()\n })\n}\n\n/**\n * A chip answers a different table from the grid it sits in — that is what a grab mode IS.\n * Without it the month would offer a gesture the pointer alone could reach, which is the\n * WCAG 2.1.1 failure the time grid already avoids.\n */\nfunction onCardKeydown(event: KeyboardEvent, card: HTMLElement) {\n const item = eventsById.value.get(cardIdOf(card))\n if (!item) return\n\n const held = grabbing.value && gesture.value?.id === item.id\n const intent = calendarIntent(event.key, event.shiftKey, held ? 'grabbed' : 'event', 1, isRtl())\n if (!intent) return\n\n if (!held) {\n if (intent.kind !== 'activate' || !props.editable) return\n // Enter is also how a button is pressed: without this the same keystroke would take hold\n // of the event and open it at once.\n event.preventDefault()\n gesture.value = {\n id: item.id,\n origin: timesOf(item),\n preview: timesOf(item),\n pointerId: null,\n originX: 0,\n originY: 0,\n grabIndex: 0,\n // There is no pointer to remember; the arrows work off the preview, not off a position.\n lastX: 0,\n lastY: 0,\n moved: false,\n outside: false,\n }\n emit('announce', m.value.calendar.grabbed)\n return\n }\n\n const state = gesture.value!\n event.preventDefault()\n\n // A month has no hours to stretch, so Shift with an arrow is simply not a gesture here.\n if (intent.kind === 'grabMove') {\n const days = flat.value\n const columns = props.weeks[0]?.length ?? 1\n // The same reinterpretation the cell arrows make: sideways is a day, vertical is a week.\n const delta = intent.days !== 0 ? intent.days : Math.sign(intent.minutes) * columns\n const from = days.indexOf(state.preview.start)\n const target = days[clamp(from + delta, 0, days.length - 1)]\n if (!target) return\n state.preview = moveEventToDay(state.preview, target)\n state.moved = true\n announceMoved(item.title, state.preview)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'activate') {\n gesture.value = null\n if (state.moved) emit('event-drop', state.id, state.preview, 'move')\n emit('announce', m.value.calendar.dropped)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'cancel') {\n gesture.value = null\n emit('announce', m.value.calendar.reverted)\n refocusCard(state.id)\n }\n}\n\nfunction focus() {\n if (tabbable.value) document.getElementById(cellId(tabbable.value))?.focus()\n}\n\ndefineExpose({ focus, scrollToMinutes: () => {} })\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-calendar-month\"\n :data-outside=\"gesture?.outside ? '' : undefined\"\n :style=\"{ '--calendar-columns': String(weekdayNames.length) }\"\n >\n <div class=\"v-calendar-month-head\" aria-hidden=\"true\">\n <span v-for=\"name in weekdayNames\" :key=\"name\" class=\"v-calendar-month-weekday\">\n {{ name }}\n </span>\n </div>\n\n <div\n ref=\"gridEl\"\n class=\"v-calendar-month-grid\"\n role=\"grid\"\n :aria-label=\"label\"\n :data-gesture=\"gesture ? '' : undefined\"\n :data-edge=\"edgeCue\"\n @keydown=\"onKeydown\"\n @pointerdown=\"onGridPointerdown\"\n @pointermove=\"onPointermove\"\n @pointerup=\"onPointerup\"\n @pointercancel=\"onPointercancel\"\n >\n <div\n v-for=\"(week, row) in weeks\"\n :key=\"week[0]?.iso ?? row\"\n role=\"row\"\n class=\"v-calendar-month-week\"\n >\n <div\n v-for=\"cell in week\"\n :id=\"cellId(cell.iso)\"\n :key=\"cell.iso\"\n role=\"gridcell\"\n class=\"v-calendar-month-cell\"\n :data-iso=\"cell.iso\"\n :data-adjacent=\"cell.adjacent ?? undefined\"\n :data-today=\"cell.iso === today ? '' : undefined\"\n :tabindex=\"tabbable === cell.iso ? 0 : -1\"\n :aria-label=\"longDay(cell.iso)\"\n >\n <button\n type=\"button\"\n class=\"v-calendar-month-day\"\n tabindex=\"-1\"\n :aria-label=\"m.calendar.openDay(longDay(cell.iso))\"\n @click=\"emit('day-activate', cell.iso)\"\n >\n {{ dayNumber(cell.iso) }}\n </button>\n\n <VCalendarEvent\n v-for=\"item in shownOf(cell.iso)\"\n :key=\"item.id\"\n class=\"v-calendar-month-chip\"\n :event=\"item\"\n layout=\"chip\"\n :time-text=\"timeTextOf(item)\"\n :dragging=\"gesture?.id === item.id && gesture.pointerId !== null\"\n :rejected=\"gesture?.id === item.id && gesture.outside\"\n :grabbed=\"grabbing && gesture?.id === item.id\"\n :hint-id=\"editable && !isGhostId(item.id) ? hintId : undefined\"\n :ghost-of=\"isGhostId(item.id) ? originalIdOf(item.id) : undefined\"\n @click=\"onCardClick(item)\"\n >\n <template v-if=\"$slots.event\" #default=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarEvent>\n\n <button\n v-if=\"hiddenOf(cell.iso) > 0\"\n type=\"button\"\n class=\"v-calendar-month-more\"\n tabindex=\"-1\"\n @click=\"emit('day-activate', cell.iso)\"\n >\n {{ m.calendar.moreEvents(hiddenOf(cell.iso)) }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-month {\n display: flex;\n flex-direction: column;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n /* A drag currently held off the month. Best-effort only, and never the signal — the twin rule\n in VCalendarTimeGrid.vue carries the reasoning. */\n .v-calendar-month[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-month-head,\n .v-calendar-month-week {\n display: grid;\n grid-template-columns: repeat(var(--calendar-columns), minmax(0, 1fr));\n }\n\n .v-calendar-month-head {\n position: sticky;\n inset-block-start: 0;\n z-index: 1;\n background: var(--vectis-color-surface);\n border-block-end: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-month-weekday {\n padding-block: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-overline-size);\n font-weight: var(--vectis-text-overline-weight);\n letter-spacing: var(--vectis-text-overline-tracking);\n text-align: center;\n text-transform: uppercase;\n }\n\n /* The strip that lights up while a drag rests against an edge, counting down to turn the\n month. Its width is `--vectis-control-size-calendar-edge`, whose twin is `EDGE_BAND` in\n `edgeStep.ts` — the JavaScript deciding where that countdown actually starts. */\n .v-calendar-month-grid[data-edge]::after {\n content: '';\n position: absolute;\n inset-block: 0;\n inline-size: var(--vectis-control-size-calendar-edge);\n background: var(--vectis-color-accent-surface);\n z-index: 1;\n pointer-events: none;\n }\n\n .v-calendar-month-grid[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-month-grid[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n .v-calendar-month-grid {\n /* The strip above is placed against this box. */\n position: relative;\n display: flex;\n /* The rows share what height there is, so a month fills the box it was given instead of\n leaving a band of nothing under the last week. The floor keeps a day readable when\n that box is short. */\n flex: 1;\n flex-direction: column;\n min-block-size: 0;\n }\n\n .v-calendar-month-week {\n flex: 1;\n min-block-size: var(--vectis-control-size-calendar-month-cell);\n }\n\n .v-calendar-month-cell {\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow: hidden;\n padding: var(--vectis-space-1);\n border-block-start: 1px solid var(--vectis-color-border);\n border-inline-start: 1px solid var(--vectis-color-border);\n cursor: pointer;\n }\n\n .v-calendar-month-cell:first-child {\n border-inline-start: none;\n }\n\n .v-calendar-month-cell:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n /* Inwards: the month scrolls, and an outward ring on a cell at the edge would be cropped. */\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n /* The days of the neighbouring months are kept — the grid is a fixed six rows, so the\n page never jumps — but pushed back, since they are context rather than content. */\n .v-calendar-month-cell[data-adjacent] {\n background: var(--vectis-color-surface-sunken);\n color: var(--vectis-color-text-subtle);\n }\n\n .v-calendar-month-day {\n align-self: center;\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: var(--vectis-control-height-sm);\n block-size: var(--vectis-control-height-sm);\n /* A button carries a border from the browser, which around a round day number reads as a\n stray ring. It goes together with the background, and neither is optional. */\n border: none;\n border-radius: var(--vectis-radius-pill);\n background: none;\n color: inherit;\n font-family: inherit;\n font-size: var(--vectis-text-body-md-size);\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-month-day:hover {\n background: var(--vectis-color-surface-muted);\n }\n\n .v-calendar-month-day: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 /* Semibold here marks a state — which day is today — and is not a type role. */\n .v-calendar-month-cell[data-today] .v-calendar-month-day {\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 /*\n * A day in the month view is a summary, so a chip is capped at one lane however long the\n * event really is — an all-day bar and a two-hour meeting look the same here, and several\n * have to fit under the date.\n *\n * The height is SET AS A PROPERTY rather than as `block-size`. The chip rule in\n * VCalendarEvent's own sheet is (0,2,0) against this (0,1,0), so declaring the size\n * directly would lose — and matching its specificity would only hand the decision to\n * whichever sheet the consumer's bundler emitted last, which is the failure the library's\n * one-sheet-per-component rule exists to prevent.\n */\n .v-calendar-month-chip {\n --calendar-chip-height: var(--vectis-control-size-calendar-allday-lane);\n\n flex: none;\n }\n\n .v-calendar-month-more {\n flex: none;\n padding-inline: var(--vectis-space-1);\n border: none;\n background: none;\n color: var(--vectis-color-text-muted);\n font-family: inherit;\n font-size: var(--vectis-text-caption-size);\n text-align: start;\n cursor: pointer;\n }\n\n .v-calendar-month-more:hover {\n color: var(--vectis-color-text);\n text-decoration: underline;\n }\n\n .v-calendar-month-more: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 @media (prefers-reduced-motion: reduce) {\n .v-calendar-month-day {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;qDAuLM,IAAe;;;;;;;;;;;;;;;;;;;;;;;;;;EA7HrB,IAAM,IAAQ,GAER,IAAO,GAcP,IAAU,GAAmB,GAAC,SAA6B,GAY3D,IAAI,EAAY,GAChB,KAAM,GAAM,GAEZ,KAAU,MAAgB,GAAG,GAAI,KAAK,KAGtC,IAAe,SAClB,EAAM,MAAM,MAAM,CAAC,EAAA,CAAG,KAAK,MAAS,EAAW,EAAK,KAAK,EAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC,CAAC,CAC/F,GAUM,IAAY,QAAe;GAC/B,IAAM,oBAAM,IAAI,IAA8C;GAC9D,KAAK,IAAM,KAAQ,EAAM,OACvB,KAAK,IAAM,KAAQ,GACjB,EAAI,IAAI,EAAK,KAAK;IAChB,QAAQ,EAAW,EAAK,KAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC;IAC7D,MAAM,EAAW,EAAK,KAAK,EAAM,QAAQ;KACvC,SAAS;KACT,KAAK;KACL,OAAO;IACT,CAAC;GACH,CAAC;GAGL,OAAO;EACT,CAAC,GAEK,MAAa,MACjB,EAAU,MAAM,IAAI,CAAG,CAAC,EAAE,UAAU,EAAW,GAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC,GAOhF,KAAW,MACf,EAAU,MAAM,IAAI,CAAG,CAAC,EAAE,QAC1B,EAAW,GAAK,EAAM,QAAQ;GAAE,SAAS;GAAQ,KAAK;GAAW,OAAO;EAAO,CAAC,GAsC5E,IAAU,EAAoB,IAAI,GAClC,IAAW,QAAe,EAAQ,UAAU,QAAQ,EAAQ,MAAM,cAAc,IAAI,GACpF,IAAS,EAAwB,IAAI,GAErC,IAAS,EAAwB,IAAI,GAWrC,MAAa,MAAwB,GAAG,IAAe,KACvD,MAAgB,MAAwB,OAAO,CAAE,CAAC,CAAC,MAAM,EAAmB,GAC5E,KAAa,MAAwB,OAAO,CAAE,CAAC,CAAC,WAAW,CAAY,GAOvE,IAAc,QAAoB;GACtC,IAAM,IAAQ,EAAQ;GACtB,IAAI,CAAC,GAAO,OAAO,EAAM;GAEzB,IAAM,IAAS,EAAM,OAAO,KAAK,MAC/B,EAAK,OAAO,EAAM,KAAM;IAAE,GAAG;IAAM,GAAG,EAAM;GAAQ,IAAU,CAChE,GAWM,IAAW,EAAM,QAAQ,EAAM,OAAO,MAAM,MAAS,EAAK,OAAO,EAAM,EAAE,IAAI,KAAA;GAGnF,OAFK,IAEE,CAAC,GAAG,GAAQ;IAAE,GAAG;IAAU,GAAG,EAAM;IAAQ,IAAI,GAAU,EAAM,EAAE;GAAE,CAAM,IAF3D;EAGxB,CAAC,GAGK,IAAQ,QACZ,EACE,EAAY,OACZ,EAAM,MAAM,SAAS,MAAS,EAAK,KAAK,MAAS,EAAK,GAAG,CAAC,CAC5D,CACF,GAEM,IAAa,QAAe,IAAI,IAAI,EAAY,MAAM,KAAK,MAAS,CAAC,EAAK,IAAI,CAAI,CAAC,CAAC,CAAC,GAErF,MAAW,OAAiB,EAAM,MAAM,IAAI,CAAG,KAAK,CAAC,EAAA,CAAG,MAAM,GAAG,EAAM,UAAU,GACjF,KAAY,MAChB,KAAK,IAAI,IAAI,EAAM,MAAM,IAAI,CAAG,KAAK,CAAC,EAAA,CAAG,SAAS,EAAM,UAAU;EAMpE,SAAS,GAAW,GAAkB;GAEpC,OADI,GAAc,CAAK,IAAU,KAC1B,EAAkB,EAAM,WAAW,EAAM,QAAQ,EAAM,UAAU;EAC1E;EAGA,IAAM,IAAO,QAAe,EAAM,MAAM,KAAK,CAAC,CAAC,KAAK,MAAS,EAAK,GAAG,CAAC;EAEtE,SAAS,EAAY,GAAa;GAIhC,AAHA,EAAQ,QAAQ,GAGhB,QAAoB,SAAS,eAAe,EAAO,CAAG,CAAC,CAAC,EAAE,MAAM,CAAC;EACnE;EAEA,IAAM,IAAW,QACf,EAAK,MAAM,SAAS,EAAQ,KAAK,IAAI,EAAQ,QAAS,EAAK,MAAM,MAAM,IACzE;EAEA,SAAS,GAAU,GAAsB;GACvC,IAAM,IAAS,EAAM,QAIf,IAAO,GAAQ,QAAqB,mBAAmB;GAC7D,IAAI,GAAM;IACR,GAAc,GAAO,CAAI;IACzB;GACF;GAEA,IAAM,IAAO,GAAQ,QAAqB,wBAAwB;GAClE,IAAI,CAAC,GAAM;GAIX,IAAM,IAAS,EAAe,EAAM,KAAK,EAAM,UAAU,QAAQ,GAAG,EAAM,CAAC;GAC3E,IAAI,CAAC,GAAQ;GAEb,IAAM,IAAM,EAAK,QAAQ,KACnB,IAAQ,EAAK,MAAM,QAAQ,CAAG,GAC9B,IAAU,EAAM,MAAM,EAAE,EAAE,UAAU;GAE1C,IAAI,EAAO,SAAS,aAAa;IAO/B,IAAM,IAAQ,EAAO,SAAS,IAAkB,KAAK,KAAK,EAAO,OAAO,IAAI,IAA1C,EAAO,MACnC,IAAO,EAAK,MAAM,EAAM,IAAQ,GAAO,GAAG,EAAK,MAAM,SAAS,CAAC;IACrE,IAAI,CAAC,GAAM;IAEX,AADA,EAAM,eAAe,GACrB,EAAY,CAAI;IAChB;GACF;GAEA,IAAI,EAAO,SAAS,WAAW;IAC7B,IAAM,IAAM,KAAK,MAAM,IAAQ,CAAO,GAChC,IAAO,EAAO,SAAS,UAAU,IAAM,IAAU,IAAM,IAAU,IAAU,GAC3E,IAAO,EAAK,MAAM,EAAM,GAAM,GAAG,EAAK,MAAM,SAAS,CAAC;IAC5D,IAAI,CAAC,GAAM;IAEX,AADA,EAAM,eAAe,GACrB,EAAY,CAAI;IAChB;GACF;GAEA,IAAI,EAAO,SAAS,UAAU;IAE5B,AADA,EAAM,eAAe,GACrB,EAAK,QAAQ,EAAO,KAAK;IACzB;GACF;GAEA,AAAI,EAAO,SAAS,eAClB,EAAM,eAAe,GACrB,EAAK,iBAAiB,CAAG;EAE7B;EAIA,IAAM,UAAc,EAAa,EAAO,KAAK;EAG7C,SAAS,EAAW,GAAe;GACjC,IAAM,IAAM,EAAM;GAClB,OAAO;IACL,KAAK,EAAK;IACV,QAAQ,EAAK;IACb,aAAa,IAAM,EAAK,QAAQ,EAAK;IACrC,YAAY,EAAK;IACjB,SAAS,EAAM,MAAM,EAAE,EAAE,UAAU;IACnC,MAAM,EAAM,MAAM,UAAU;GAC9B;EACF;EAGA,SAAS,EAAQ,GAAW,GAA0B;GACpD,IAAM,IAAO,EAAO,OAAO,sBAAsB;GACjD,IAAI,CAAC,GAAM,OAAO;GAClB,IAAM,IAAO,GAAiB;IAAE;IAAG;GAAE,GAAG,EAAW,CAAI,GAAG,EAAM,CAAC,GAC3D,IAAU,EAAM,MAAM,EAAE,EAAE,UAAU;GAC1C,OAAO,EAAK,WAAW,IAAU,EAAK;EACxC;EAEA,IAAM,IAAO,GACV,MAAc,EAAK,QAAQ,CAAS,SAC/B,EAAM,aACd,GAGM,KAAU,QACd,EAAK,QAAQ,UAAU,KAAK,UAAU,EAAK,QAAQ,UAAU,IAAI,QAAQ,KAAA,CAC3E;EAQA,SACQ,EAAM,aACN;GACJ,IAAM,IAAQ,EAAQ;GACtB,AAAI,GAAO,SAAO,EAAW,CAAK;EACpC,GACA,EAAE,OAAO,OAAO,CAClB;EAEA,SAAS,GAAkB,GAAqB;GAE9C,IADA,GAAe,GACX,EAAQ,SAAS,CAAC,EAAM,YAAY,EAAM,WAAW,GAAG;GAE5D,IAAM,IAAQ,EAAM,QAA+B,QAAqB,mBAAmB;GAC3F,IAAI,CAAC,GAAM;GACX,IAAM,IAAO,EAAW,MAAM,IAAI,EAAS,CAAI,CAAC,GAC1C,IAAQ,EAAQ,EAAM,SAAS,EAAM,OAAO;GAC9C,OAAC,KAAQ,MAAU,OAEvB;MAAQ,QAAQ;KACd,IAAI,EAAK;KACT,QAAQ,EAAQ,CAAI;KACpB,SAAS,EAAQ,CAAI;KACrB,WAAW,EAAM;KACjB,SAAS,EAAM;KACf,SAAS,EAAM;KACf,WAAW;KACX,OAAO,EAAM;KACb,OAAO,EAAM;KACb,OAAO;KACP,SAAS;IACX;IASA,IAAI;KACF,EAAO,OAAO,kBAAkB,EAAM,SAAS;IACjD,QAAQ,CAER;GAbA;EAcF;EAGA,SAAS,EAAS,GAAoC;GACpD,IAAM,IAAM,EAAK,QAAQ,WAAW;GAEpC,OAAO,EAAW,MAAM,IAAI,CAAG,IAAI,IAAM,OAAO,CAAG;EACrD;EAEA,SAAS,GAAc,GAAqB;GAC1C,IAAM,IAAQ,EAAQ;GAMtB,IALI,CAAC,KAAS,EAAM,cAAc,EAAM,cAExC,EAAM,QAAQ,EAAM,SACpB,EAAM,QAAQ,EAAM,SAGlB,CAAC,EAAM,SACP,KAAK,IAAI,EAAM,UAAU,EAAM,OAAO,IAAA,KACtC,KAAK,IAAI,EAAM,UAAU,EAAM,OAAO,IAAA,IAEtC;GAKF,AAFA,EAAM,QAAQ,IACd,EAAM,UAAU,GAAiB,CAAK,GACtC,EAAW,CAAK;GAEhB,IAAM,IAAO,EAAO,OAAO,sBAAsB;GACjD,AAAI,KAAM,EAAK,UAAU,EAAa,EAAM,OAAO,EAAW,CAAI,GAAA,IAAc,EAAM,CAAC,CAAC;EAC1F;EAaA,SAAS,GAAiB,GAAyB;GACjD,IAAM,IAAO,EAAO,OAAO,sBAAsB;GACjD,OAAO,IAAO,CAAC,GAAY;IAAE,GAAG,EAAM;IAAO,GAAG,EAAM;GAAM,GAAG,CAAI,IAAI;EACzE;EAQA,SAAS,EAAW,GAAgB;GAClC,IAAM,IAAQ,EAAQ,EAAM,OAAO,EAAM,KAAK;GAC9C,IAAI,MAAU,MAAM;GAQpB,IAAM,IAAO,EAAK,OACZ,IAAO,EAAK,QAAQ,EAAM,OAAO,KAAK,GACtC,IACJ,EACE,GAAO,MAAS,KAAK,EAAM,YAAY,KAAQ,IAAQ,EAAM,WAAW,GAAG,EAAK,SAAS,CAAC;GAE9F,AAAI,MAAQ,EAAM,UAAU,EAAe,EAAM,QAAQ,CAAM;EACjE;EAEA,IAAI,IAAc;EASlB,SAAS,KAAiB;GACxB,IAAc;EAChB;EAEA,SAAS,GAAY,GAAqB;GACxC,IAAM,IAAQ,EAAQ;GAClB,CAAC,KAAS,EAAM,cAAc,EAAM,cACxC,EAAQ,QAAQ,MAChB,IAAc,EAAM,OACpB,EAAK,OAAO,GAKR,GAAM,WAEL,EAAM,SACX,EAAK,cAAc,EAAM,IAAI,EAAM,SAAS,MAAM;EACpD;EAEA,SAAS,KAAkB;GAIzB,AADA,EAAQ,QAAQ,MAChB,EAAK,OAAO;EACd;EAEA,SAAS,GAAY,GAAS;GAG5B,IAAI,GAAa;IACf,IAAc;IACd;GACF;GACA,EAAK,kBAAkB,CAAI;EAC7B;EAIA,SAAS,GAAc,GAAe,GAA2B;GAC/D,EAAK,YAAY,EAAE,MAAM,SAAS,QAAQ,GAAO,EAAQ,EAAM,KAAK,CAAC,CAAC;EACxE;EAEA,SAAS,EAAY,GAAqB;GACxC,QAAoB;IAOlB,IAAM,IAAQ,EAAO,OAAO,iBAA8B,mBAAmB;IAC7E,MAAM,KAAK,KAAS,CAAC,CAAC,CAAA,CACnB,MAAM,MAAS,EAAK,QAAQ,YAAY,OAAO,CAAE,CAAC,CAAA,EACjD,MAAM;GACZ,CAAC;EACH;EAOA,SAAS,GAAc,GAAsB,GAAmB;GAC9D,IAAM,IAAO,EAAW,MAAM,IAAI,EAAS,CAAI,CAAC;GAChD,IAAI,CAAC,GAAM;GAEX,IAAM,IAAO,EAAS,SAAS,EAAQ,OAAO,OAAO,EAAK,IACpD,IAAS,EAAe,EAAM,KAAK,EAAM,UAAU,IAAO,YAAY,SAAS,GAAG,EAAM,CAAC;GAC/F,IAAI,CAAC,GAAQ;GAEb,IAAI,CAAC,GAAM;IACT,IAAI,EAAO,SAAS,cAAc,CAAC,EAAM,UAAU;IAkBnD,AAfA,EAAM,eAAe,GACrB,EAAQ,QAAQ;KACd,IAAI,EAAK;KACT,QAAQ,EAAQ,CAAI;KACpB,SAAS,EAAQ,CAAI;KACrB,WAAW;KACX,SAAS;KACT,SAAS;KACT,WAAW;KAEX,OAAO;KACP,OAAO;KACP,OAAO;KACP,SAAS;IACX,GACA,EAAK,YAAY,EAAE,MAAM,SAAS,OAAO;IACzC;GACF;GAEA,IAAM,IAAQ,EAAQ;GAItB,IAHA,EAAM,eAAe,GAGjB,EAAO,SAAS,YAAY;IAC9B,IAAM,IAAO,EAAK,OACZ,IAAU,EAAM,MAAM,EAAE,EAAE,UAAU,GAEpC,IAAQ,EAAO,SAAS,IAAkB,KAAK,KAAK,EAAO,OAAO,IAAI,IAA1C,EAAO,MAEnC,IAAS,EAAK,EADP,EAAK,QAAQ,EAAM,QAAQ,KACd,IAAO,GAAO,GAAG,EAAK,SAAS,CAAC;IAC1D,IAAI,CAAC,GAAQ;IAIb,AAHA,EAAM,UAAU,EAAe,EAAM,SAAS,CAAM,GACpD,EAAM,QAAQ,IACd,GAAc,EAAK,OAAO,EAAM,OAAO,GACvC,EAAY,EAAM,EAAE;IACpB;GACF;GAEA,IAAI,EAAO,SAAS,YAAY;IAI9B,AAHA,EAAQ,QAAQ,MACZ,EAAM,SAAO,EAAK,cAAc,EAAM,IAAI,EAAM,SAAS,MAAM,GACnE,EAAK,YAAY,EAAE,MAAM,SAAS,OAAO,GACzC,EAAY,EAAM,EAAE;IACpB;GACF;GAEA,AAAI,EAAO,SAAS,aAClB,EAAQ,QAAQ,MAChB,EAAK,YAAY,EAAE,MAAM,SAAS,QAAQ,GAC1C,EAAY,EAAM,EAAE;EAExB;EAEA,SAAS,KAAQ;GACf,AAAI,EAAS,SAAO,SAAS,eAAe,EAAO,EAAS,KAAK,CAAC,CAAC,EAAE,MAAM;EAC7E;SAEA,EAAa;GAAE;GAAO,uBAAuB,CAAC;EAAE,CAAC,mBAI/C,EAoFM,OAAA;YAnFA;GAAJ,KAAI;GACJ,OAAM;GACL,gBAAc,EAAA,OAAS,UAAO,KAAQ,KAAA;GACtC,OAAK,GAAA,EAAA,sBAA0B,OAAO,EAAA,MAAa,MAAM,EAAA,CAAA;MAE1D,EAIM,OAJN,IAIM,EAAA,EAAA,EAAA,GAHJ,EAEO,GAAA,MAAA,EAFc,EAAA,QAAR,YAAb,EAEO,QAAA;GAF6B,KAAK;GAAM,OAAM;OAChD,CAAI,GAAA,CAAA,cAIX,EAuEM,OAAA;YAtEA;GAAJ,KAAI;GACJ,OAAM;GACN,MAAK;GACJ,cAAY,EAAA;GACZ,gBAAc,EAAA,QAAO,KAAQ,KAAA;GAC7B,aAAW,GAAA;GACF;GACT,eAAa;GACA;GACF;GACI;cAEhB,EAyDM,GAAA,MAAA,EAxDkB,EAAA,QAAd,GAAM,YADhB,EAyDM,OAAA;GAvDH,KAAK,EAAI,EAAA,EAAK,OAAO;GACtB,MAAK;GACL,OAAM;cAEN,EAkDM,GAAA,MAAA,EAjDW,IAAR,YADT,EAkDM,OAAA;GAhDH,IAAI,EAAO,EAAK,GAAG;GACnB,KAAK,EAAK;GACX,MAAK;GACL,OAAM;GACL,YAAU,EAAK;GACf,iBAAe,EAAK,YAAY,KAAA;GAChC,cAAY,EAAK,QAAQ,EAAA,QAAK,KAAQ,KAAA;GACtC,UAAU,EAAA,UAAa,EAAK,MAAG,IAAA;GAC/B,cAAY,EAAQ,EAAK,GAAG;;GAE7B,EAQS,UAAA;IAPP,MAAK;IACL,OAAM;IACN,UAAS;IACR,cAAY,EAAA,CAAA,CAAC,CAAC,SAAS,QAAQ,EAAQ,EAAK,GAAG,CAAA;IAC/C,UAAK,MAAE,EAAI,gBAAiB,EAAK,GAAG;QAElC,GAAU,EAAK,GAAG,CAAA,GAAA,GAAA,EAAA;WAGvB,EAiBiB,GAAA,MAAA,EAhBA,GAAQ,EAAK,GAAG,IAAxB,YADT,GAiBiB,GAAA;IAfd,KAAK,EAAK;IACX,OAAM;IACL,OAAO;IACR,QAAO;IACN,aAAW,GAAW,CAAI;IAC1B,UAAU,EAAA,OAAS,OAAO,EAAK,MAAM,EAAA,MAAQ,cAAS;IACtD,UAAU,EAAA,OAAS,OAAO,EAAK,MAAM,EAAA,MAAQ;IAC7C,SAAS,EAAA,SAAY,EAAA,OAAS,OAAO,EAAK;IAC1C,WAAS,EAAA,YAAQ,CAAK,EAAU,EAAK,EAAE,IAAI,EAAA,SAAS,KAAA;IACpD,YAAU,EAAU,EAAK,EAAE,IAAI,GAAa,EAAK,EAAE,IAAI,KAAA;IACvD,UAAK,MAAE,GAAY,CAAI;oBAERA,EAAAA,OAAO,QAAA;UAAQ;YAAS,MAAS,CAC/C,GAAwC,EAAA,QAAA,SAAxC,GAAwC,EAAA,SAAA,GAAA,GAAb,CAAS,CAAA,CAAA,CAAA;;;;;;;;;;;;GAKhC,EAAS,EAAK,GAAG,IAAA,KAAA,EAAA,GADzB,EAQS,UAAA;;IANP,MAAK;IACL,OAAM;IACN,UAAS;IACR,UAAK,MAAE,EAAI,gBAAiB,EAAK,GAAG;QAElC,EAAA,CAAA,CAAC,CAAC,SAAS,WAAW,EAAS,EAAK,GAAG,CAAA,CAAA,GAAA,GAAA,EAAA,KAAA,GAAA,IAAA,EAAA"}
@@ -0,0 +1,2 @@
1
+ @layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
2
+ @layer vectis.components{.v-calendar-grid{--calendar-hour:var(--vectis-control-size-calendar-hour);--calendar-gutter:var(--vectis-control-size-calendar-gutter);--calendar-hour-lift:calc(var(--vectis-text-caption-size) * var(--vectis-text-caption-leading) / 2);block-size:100%;min-block-size:0;font-family:var(--vectis-text-family);color:var(--vectis-color-text);position:relative;overflow:auto}.v-calendar-grid[data-outside]{cursor:not-allowed}.v-calendar-head,.v-calendar-canvas{grid-template-columns:var(--calendar-gutter) repeat(var(--calendar-columns), minmax(var(--vectis-control-size-calendar-day-min), 1fr));min-inline-size:min-content;display:grid}.v-calendar-head{z-index:4;background:var(--vectis-color-surface);border-block-end:1px solid var(--vectis-color-border);position:sticky;inset-block-start:0}.v-calendar-head-gutter{border-inline-end:1px solid var(--vectis-color-border)}.v-calendar-head-day{align-items:center;gap:var(--vectis-space-1);padding-block:var(--vectis-space-2);padding-inline:var(--vectis-space-1);flex-direction:column;display:flex}.v-calendar-head-weekday{color:var(--vectis-color-text-muted);font-size:var(--vectis-text-overline-size);font-weight:var(--vectis-text-overline-weight);letter-spacing:var(--vectis-text-overline-tracking);text-transform:uppercase}.v-calendar-head-number{inline-size:var(--vectis-control-height-sm);block-size:var(--vectis-control-height-sm);border-radius:var(--vectis-radius-pill);font-size:var(--vectis-text-body-lg-size);justify-content:center;align-items:center;display:flex}.v-calendar-head-day[data-today] .v-calendar-head-number{background:var(--vectis-color-accent);color:var(--vectis-color-text-on-accent);font-weight:var(--vectis-font-weight-semibold)}.v-calendar-allday-label{border-block-start:1px solid var(--vectis-color-border);border-inline-end:1px solid var(--vectis-color-border);color:var(--vectis-color-text-muted);font-size:var(--vectis-text-caption-size);line-height:var(--vectis-text-caption-leading);justify-content:end;align-items:start;padding-block-start:var(--vectis-space-1);padding-inline-end:var(--vectis-space-2);display:flex}.v-calendar-allday{grid-column:2/-1;grid-template-columns:repeat(var(--calendar-columns), minmax(var(--vectis-control-size-calendar-day-min), 1fr));grid-template-rows:repeat(var(--calendar-lanes), var(--vectis-control-size-calendar-allday-lane));max-block-size:var(--vectis-control-size-calendar-allday-max);padding-block:var(--vectis-space-1);border-block-start:1px solid var(--vectis-color-border);gap:1px;display:grid;overflow-y:auto}.v-calendar-bar{grid-column:calc(var(--event-day) + 1) / span var(--event-span);grid-row:calc(var(--event-lane) + 1);min-inline-size:0}.v-calendar-hours{grid-auto-rows:var(--calendar-hour);border-inline-end:1px solid var(--vectis-color-border);display:grid}.v-calendar-hour{color:var(--vectis-color-text-muted);font-size:var(--vectis-text-caption-size);line-height:var(--vectis-text-caption-leading);text-align:end;align-self:start;margin-block-start:calc(-1 * var(--calendar-hour-lift));padding-inline-end:var(--vectis-space-2);position:relative}.v-calendar-hour:before{content:"";inline-size:var(--vectis-control-size-calendar-tick);border-block-start:1px solid var(--vectis-color-border);position:absolute;inset-block-start:var(--calendar-hour-lift);inset-inline-end:0}.v-calendar-hour:first-child{visibility:hidden}.v-calendar-row:first-child .v-calendar-cell{border-block-start:none}.v-calendar-columns{grid-column:2/-1;grid-template-columns:repeat(var(--calendar-columns), minmax(var(--vectis-control-size-calendar-day-min), 1fr));grid-auto-rows:var(--calendar-hour);display:grid;position:relative}.v-calendar-columns[data-edge]:after{content:"";inline-size:var(--vectis-control-size-calendar-edge);background:var(--vectis-color-accent-surface);z-index:2;pointer-events:none;position:absolute;inset-block:0}.v-calendar-columns[data-edge=start]:after{inset-inline-start:0}.v-calendar-columns[data-edge=end]:after{inset-inline-end:0}.v-calendar-row{display:contents}.v-calendar-cell{border-block-start:1px solid var(--vectis-color-border);border-inline-start:1px solid var(--vectis-color-border);cursor:pointer}.v-calendar-cell:first-child{border-inline-start:none}.v-calendar-cell:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:calc(-1 * var(--vectis-focus-ring-width))}.v-calendar-cell[data-today]{background:var(--vectis-color-accent-surface)}.v-calendar-block{block-size:calc((var(--event-end) - var(--event-start)) * 100%);inline-size:calc(var(--event-span) / var(--event-columns) / var(--calendar-columns) * 100% - 2px);z-index:1;position:absolute;inset-block-start:calc(var(--event-start) * 100%);inset-inline-start:calc((var(--event-day) + var(--event-column) / var(--event-columns)) / var(--calendar-columns) * 100%)}.v-calendar-now{inline-size:calc(100% / var(--calendar-columns));border-block-start:1px solid var(--vectis-color-danger);z-index:2;pointer-events:none;position:absolute;inset-block-start:calc(var(--calendar-now) * 100%);inset-inline-start:calc(var(--event-day) / var(--calendar-columns) * 100%)}.v-calendar-now:before{content:"";inline-size:var(--vectis-control-size-calendar-now-dot);block-size:var(--vectis-control-size-calendar-now-dot);border-radius:var(--vectis-radius-pill);background:var(--vectis-color-danger);margin-block-start:calc(var(--vectis-control-size-calendar-now-dot) / -2);margin-inline-start:calc(var(--vectis-control-size-calendar-now-dot) / -2);position:absolute;inset-inline-start:0}}
@@ -0,0 +1,85 @@
1
+ import { HourFormat } from '../../utils/time.js';
2
+ import { TimeWindow } from './layout.js';
3
+ import { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types.js';
4
+ /** Where the keyboard focus is in the grid, as a day and a moment in it. */
5
+ export interface FocusedCell {
6
+ iso: string;
7
+ minutes: number;
8
+ }
9
+ export interface TimeGridProps<T> {
10
+ days: string[];
11
+ events: T[];
12
+ window: TimeWindow;
13
+ slotDuration: number;
14
+ locale: string;
15
+ hourFormat: HourFormat;
16
+ /** Today's date, or nothing on the server, where it cannot be known. */
17
+ today: string | null;
18
+ /**
19
+ * The time it is now, in minutes since midnight — again nothing on the server. It is
20
+ * passed in rather than read here so that one clock drives every view, and so that a
21
+ * calendar showing no time grid still costs no timer.
22
+ */
23
+ now: number | null;
24
+ /** Whether events can be moved and stretched. */
25
+ editable: boolean;
26
+ /** Whether an empty part of the grid makes an event when it is taken up. */
27
+ creatable: boolean;
28
+ /** The node telling a reader how a card can be moved, shared by every card. */
29
+ hintId: string;
30
+ /** How long a drag rests against an edge before the view pages. Zero turns paging off. */
31
+ edgeStepDelay: number;
32
+ /** Whether dragging near the top or bottom scrolls the grid. */
33
+ autoScroll: boolean;
34
+ /** What the grid as a whole is called — the range it is showing. */
35
+ label: string;
36
+ }
37
+ declare const __VLS_export: <E extends CalendarEvent>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
38
+ props: import('vue').PublicProps & __VLS_PrettifyLocal<(TimeGridProps<E> & {
39
+ /** Which cell holds the tab stop. The calendar owns it, so the toolbar can move it too. */
40
+ focused: FocusedCell;
41
+ }) & {
42
+ onAnnounce?: ((message: string) => any) | undefined;
43
+ onStep?: ((delta: 1 | -1) => any) | undefined;
44
+ "onCell-activate"?: ((iso: string, minutes: number) => any) | undefined;
45
+ "onEvent-activate"?: ((event: E) => any) | undefined;
46
+ "onEvent-drop"?: ((id: CalendarEventId, times: CalendarEventTimes, kind: "move" | "resize") => any) | undefined;
47
+ "onUpdate:focused"?: ((value: FocusedCell) => any) | undefined;
48
+ "onSlot-create"?: ((times: CalendarEventTimes) => any) | undefined;
49
+ }> & (typeof globalThis extends {
50
+ __VLS_PROPS_FALLBACK: infer P;
51
+ } ? P : {});
52
+ expose: (exposed: import('vue').ShallowUnwrapRef<{
53
+ focus: () => void;
54
+ scrollToMinutes: (minutes: number) => void;
55
+ }>) => void;
56
+ attrs: any;
57
+ slots: {
58
+ event?(props: {
59
+ event: E;
60
+ layout: "block" | "chip";
61
+ timeText: string;
62
+ continuesBefore: boolean;
63
+ continuesAfter: boolean;
64
+ dragging: boolean;
65
+ grabbed: boolean;
66
+ }): unknown;
67
+ 'day-header'?(props: {
68
+ iso: string;
69
+ weekday: string;
70
+ day: string;
71
+ today: boolean;
72
+ }): unknown;
73
+ 'all-day-label'?(): unknown;
74
+ };
75
+ emit: (((evt: "announce", message: string) => void) & ((evt: "step", delta: 1 | -1) => void) & ((evt: "cell-activate", iso: string, minutes: number) => void) & ((evt: "event-activate", event: E) => void) & ((evt: "event-drop", id: CalendarEventId, times: CalendarEventTimes, kind: "move" | "resize") => void) & ((evt: "slot-create", times: CalendarEventTimes) => void)) & ((event: "update:focused", value: FocusedCell) => void);
76
+ }>) => import('vue').VNode & {
77
+ __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
78
+ };
79
+ declare const _default: typeof __VLS_export;
80
+ export default _default;
81
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
82
+ [K in keyof T]: T[K];
83
+ } : {
84
+ [K in keyof T as K]: T[K];
85
+ }) & {};
@@ -0,0 +1,9 @@
1
+ import './VCalendarTimeGrid.css';
2
+ import e from "./VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js";
3
+ /* empty css */
4
+ //#region src/components/VCalendar/VCalendarTimeGrid.vue
5
+ var t = e;
6
+ //#endregion
7
+ export { t as default };
8
+
9
+ //# sourceMappingURL=VCalendarTimeGrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VCalendarTimeGrid.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarTimeGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @keyboard @core\n/**\n * The time grid: a column per day on show, an hour per row, and the events drawn over it.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it. It computes nothing about dates or overlaps: it is handed\n * the days and the already-placed segments, and its whole job is to turn them into boxes.\n *\n * WHY EVERY CELL EXISTS. Twenty-four rows times seven days is a hundred and sixty-eight\n * elements, where the rules between the hours could have been one repeating gradient. Two\n * things pay for them. A background is forced to `Canvas` under Windows forced-colors and\n * the ruling would vanish, where a border is forced to `CanvasText` and survives — the\n * argument VSeparator and the VIcon registry both make. And the ARIA \"grid\" pattern needs\n * real cells to move a focus between, which is what gives the keyboard somewhere to be and\n * what satisfies the rule that a scrolling region must hold something reachable by Tab.\n *\n * WHY THE CARDS SIT INSIDE THE CELLS. An event is placed absolutely against the whole\n * columns box, so putting the cards in one overlay layer would have been simpler CSS. They\n * are instead children of the cell their start falls in, because an absolutely positioned\n * element leaves its parent's box for LAYOUT while staying inside it in the document — and\n * therefore in the accessibility tree. In an overlay they would sit outside the grid\n * entirely, which breaks the reading order and fails `aria-required-children` the moment\n * anything tries to put them back.\n *\n * The day names are NOT marked up as column headers. They live above the scrolling area so\n * that they can stay in view, which puts them outside the grid; instead every cell names\n * its own day in full (\"Wednesday 10 June, 09:00\"), so nothing is lost to a reader who\n * never sees the row at all.\n */\nimport { computed, nextTick, onBeforeUnmount, ref, useId, watch } from 'vue'\n\nimport { formatDisplay as formatDate } from '../../utils/date'\nimport { isRtl as isElementRtl } from '../../utils/direction'\nimport { clamp } from '../../utils/number'\nimport { formatDisplay as formatTimeDisplay, type HourFormat } from '../../utils/time'\n\nimport { useMessages } from '../../i18n/state'\n\nimport VCalendarEvent from './VCalendarEvent.vue'\nimport {\n DRAG_THRESHOLD,\n blockEdgeAt,\n floorToSlot,\n fractionOf,\n inlineEdgeAt,\n isAllDayEvent,\n minutesAt,\n moveEvent,\n moveEventToDay,\n packAllDay,\n packDayColumn,\n pointToCell,\n pointWithin,\n resizeEvent,\n snapToSlot,\n timeOf,\n timedSegments,\n timesOf,\n type AllDaySpan,\n type PlacedSegment,\n type TimeWindow,\n} from './layout'\nimport { calendarIntent } from './keyboard'\nimport { EDGE_BAND, useEdgeStep } from './edgeStep'\nimport type { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types'\n\n/** Where the keyboard focus is in the grid, as a day and a moment in it. */\nexport interface FocusedCell {\n iso: string\n minutes: number\n}\n\nexport interface TimeGridProps<T> {\n days: string[]\n events: T[]\n window: TimeWindow\n slotDuration: number\n locale: string\n hourFormat: HourFormat\n /** Today's date, or nothing on the server, where it cannot be known. */\n today: string | null\n /**\n * The time it is now, in minutes since midnight — again nothing on the server. It is\n * passed in rather than read here so that one clock drives every view, and so that a\n * calendar showing no time grid still costs no timer.\n */\n now: number | null\n /** Whether events can be moved and stretched. */\n editable: boolean\n /** Whether an empty part of the grid makes an event when it is taken up. */\n creatable: boolean\n /** The node telling a reader how a card can be moved, shared by every card. */\n hintId: string\n /** How long a drag rests against an edge before the view pages. Zero turns paging off. */\n edgeStepDelay: number\n /** Whether dragging near the top or bottom scrolls the grid. */\n autoScroll: boolean\n /** What the grid as a whole is called — the range it is showing. */\n label: string\n}\n\nconst props = defineProps<TimeGridProps<E>>()\n\nconst emit = defineEmits<{\n /** An empty part of the grid was activated, at this day and this moment. */\n 'cell-activate': [iso: string, minutes: number]\n /** A card was clicked or activated. */\n 'event-activate': [event: E]\n /** An event was dropped somewhere else, or stretched to a new end. */\n 'event-drop': [id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize']\n /** An empty stretch of a day was drawn out, and is asking to become an event. */\n 'slot-create': [times: CalendarEventTimes]\n /** Something happened that a reader who cannot see the grid needs told. */\n announce: [message: string]\n /** A page key asked for the previous or next period, which only the calendar can do. */\n step: [delta: -1 | 1]\n}>()\n\n/** Which cell holds the tab stop. The calendar owns it, so the toolbar can move it too. */\nconst focused = defineModel<FocusedCell>('focused', { required: true })\n\ndefineSlots<{\n event?(props: {\n event: E\n layout: 'block' | 'chip'\n timeText: string\n continuesBefore: boolean\n continuesAfter: boolean\n dragging: boolean\n grabbed: boolean\n }): unknown\n 'day-header'?(props: { iso: string; weekday: string; day: string; today: boolean }): unknown\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst uid = useId()\n\nconst MINUTES_PER_HOUR = 60\n\n/** The hour each row stands for, as minutes since midnight. */\nconst hours = computed(() => {\n const rows: number[] = []\n for (let at = props.window.start; at < props.window.end; at += MINUTES_PER_HOUR) rows.push(at)\n return rows\n})\n\n/**\n * The id a stretch of empty grid carries while it is being drawn out. It never leaves this\n * component: on release the calendar is handed the times alone and mints an id of its own.\n */\nconst DRAFT_ID = '__vectis-calendar-draft__'\n\n/**\n * The id the faded echo of a dragged event carries.\n *\n * It has to DIFFER from the event's own, or the two would collide in every map the layout\n * keys by id and only one of them would ever be drawn. The original is recovered from it —\n * and handed to the card as `ghostOf` — because the colour of an event is derived from its\n * id, so an echo under a fresh id would come out a different colour from the card it belongs\n * to. `hueOf` reads a number and its digits as the same event, so the string form is enough.\n */\nconst GHOST_PREFIX = '__vectis-calendar-ghost__'\nconst ghostIdOf = (id: CalendarEventId) => `${GHOST_PREFIX}${id}`\nconst originalIdOf = (id: CalendarEventId) => String(id).slice(GHOST_PREFIX.length)\nconst isGhostId = (id: CalendarEventId) => String(id).startsWith(GHOST_PREFIX)\n\n/**\n * A gesture under way, whether it came from a pointer or from the keyboard.\n *\n * `move-days` is the whole-day one: an all-day bar dragged along the band above the grid. It\n * is a kind of its own rather than a flag on `move` because the two answer different\n * questions — one asks what MOMENT the pointer is over, the other only what day — and because\n * a bar spanning three days must keep spanning three when it lands.\n */\ninterface Gesture {\n kind: 'move' | 'move-days' | 'resize' | 'create'\n id: CalendarEventId\n /**\n * Where the event was when the gesture began. Every frame is computed from THIS and never\n * 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 pointerId: number | null\n originX: number\n originY: number\n /** How far into the card the pointer took hold, so the card does not jump under it. */\n grabOffset: number\n grabColumn: number\n /**\n * Where the pointer last was.\n *\n * Kept because two things move the calendar UNDER a still pointer — paging at an edge, and\n * auto-scrolling — and each has to work out afresh what the pointer is now over. Without it\n * a hand held motionless at an edge would page the view and leave the card behind on a day\n * that is no longer on screen.\n */\n lastX: number\n lastY: number\n /**\n * The share of its column the dragged card had when the gesture began — and nothing else.\n *\n * That much is recorded because the echo must not take part in the overlap layout: were it\n * packed alongside the card being dragged, the two would share the width of their column\n * the moment they overlapped, and the card under the pointer would halve in width and then\n * grow back as it moved away.\n *\n * WHERE the echo goes is deliberately NOT recorded, and is recomputed on every render from\n * the origin times against the days currently on show. Holding at an edge pages the view\n * under a live drag, and both of these boxes are described by INDEX into `props.days`: a\n * `dayIndex` captured in one week names a different date in the next, so a frozen box would\n * follow the column rather than the day — an event dragged out of Tuesday the 9th leaving\n * its echo on Tuesday the 2nd, instead of leaving with the week it belonged to.\n *\n * Exactly one of the two is ever set — a timed event is a segment, an all-day one a bar.\n */\n ghostColumn: Pick<PlacedSegment, 'column' | 'span' | 'columns'> | null\n ghostLane: number | null\n /** Whether the pointer has travelled far enough for this to be a drag and not 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 here 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 thing that writes it, and it returns on the id mismatch before reaching that\n * line — a grab's `pointerId` is null, which no real pointer's id ever equals.\n */\n outside: boolean\n}\n\nconst gesture = ref<Gesture | null>(null)\n\n/** True while a card is being held by the keyboard rather than dragged by a pointer. */\nconst grabbing = computed(() => gesture.value !== null && gesture.value.pointerId === null)\n\n/**\n * The event the echo stands for: the one being dragged, back where the drag began.\n *\n * ONE predicate, read by the three places that have to agree — the event list, the packing\n * and the band. They were briefly allowed to disagree, and the failure was immediate and\n * total: a placement with no event behind it, and every card in the grid failing to render.\n * A press that has not travelled yet produces none, or a click would flash a second card\n * over the first.\n */\nconst ghostEvent = computed<E | null>(() => {\n const state = gesture.value\n if (!state?.moved) return null\n const original = props.events.find((event) => event.id === state.id)\n return original ? ({ ...original, ...state.origin, id: ghostIdOf(state.id) } as E) : null\n})\n\n/**\n * Where the echo goes, worked out afresh on every render rather than remembered.\n *\n * The two helpers are the SAME ones every other box goes through, run on a list of one — so\n * the echo answers to the days on show exactly as an ordinary event does, and in particular\n * is dropped when its day is not among them. That is what makes it leave with its week when\n * a drag held at an edge pages the view, instead of staying on the column it used to occupy.\n * It is also what keeps the two kinds mutually exclusive by construction rather than by\n * chance: `timedSegments` passes over an all-day event and `packAllDay` over a timed one.\n *\n * Only the packing captured at the start of the gesture is put back on top — see\n * `ghostColumn` above for why that one part must NOT be recomputed.\n */\nconst ghostSegment = computed<PlacedSegment | null>(() => {\n const state = gesture.value\n const event = ghostEvent.value\n if (!event || !state?.ghostColumn) return null\n const [segment] = timedSegments([event], props.days, props.window, props.slotDuration)\n return segment ? { ...segment, ...state.ghostColumn } : null\n})\n\nconst ghostSpan = computed<AllDaySpan | null>(() => {\n const state = gesture.value\n const event = ghostEvent.value\n if (!event || state?.ghostLane == null) return null\n const [span] = packAllDay([event], props.days)\n return span ? { ...span, lane: state.ghostLane } : null\n})\n\n/**\n * The events as the grid should currently DRAW them — which is the model, with the one being\n * gestured at moved to wherever it is now.\n *\n * Running the preview through the same packing as everything else is what makes the other\n * events reflow live around the one being dragged, with no special case anywhere: the layout\n * does not know a gesture is happening, only that an event is somewhere.\n */\nconst drawnEvents = computed<E[]>(() => {\n const state = gesture.value\n if (!state) return props.events\n\n if (state.kind === 'create') {\n const draft = {\n id: DRAFT_ID,\n title: m.value.calendar.newEvent(props.events.length + 1),\n ...state.preview,\n // A draft carries exactly the fields `CalendarEvent` declares, and a consumer's own\n // type may require more. It exists for one render and never reaches the model, which\n // is what makes the cast safe — the calendar mints the real event on release.\n } as unknown as E\n return [...props.events, draft]\n }\n\n const moving = props.events.map((event) =>\n event.id === state.id ? ({ ...event, ...state.preview } as E) : event,\n )\n\n /*\n * The echo of where it started. It is listed here whether or not it has a box to draw on,\n * because this is what `eventsById` is built from and the template reads a card's event\n * back out of that map. An echo whose day the view has paged past simply produces no\n * placement below — which is what happens to any ordinary event on a day that is off show.\n */\n return ghostEvent.value ? [...moving, ghostEvent.value] : moving\n})\n\nconst eventsById = computed(() => new Map(drawnEvents.value.map((event) => [event.id, event])))\n\n/**\n * The bars above the grid, and how many rows they need between them.\n *\n * The echo is taken OUT of the packing and put back with the position it had when the drag\n * began. Left in, it would compete for lanes with the bar being dragged, and both would jump\n * a row whenever they happened to overlap.\n */\nconst allDay = computed(() => {\n const ghost = ghostSpan.value\n const spans = packAllDay(\n ghost ? drawnEvents.value.filter((event) => event.id !== ghost.id) : drawnEvents.value,\n props.days,\n )\n return ghost ? [...spans, ghost] : spans\n})\nconst allDayLanes = computed(() =>\n allDay.value.reduce((most, span) => Math.max(most, span.lane + 1), 0),\n)\n\n/**\n * Where the current-time line goes, or nothing when it has no business being drawn: on the\n * server, on a range that does not include today, or at an hour the window has cropped\n * away.\n */\nconst nowMark = computed(() => {\n if (props.now === null || props.today === null) return null\n const dayIndex = props.days.indexOf(props.today)\n if (dayIndex === -1) return null\n if (props.now < props.window.start || props.now > props.window.end) return null\n const row = Math.floor((props.now - props.window.start) / MINUTES_PER_HOUR)\n return {\n dayIndex,\n // Clamped so the line at the very end of the window still has a cell to live in.\n cell: `${dayIndex}:${clamp(row, 0, hours.value.length - 1)}`,\n fraction: fractionOf(props.now, props.window),\n }\n})\n\n/**\n * The placed boxes, day by day. `packDayColumn` works on one column at a time, so the\n * segments are split before it sees them: events on different days never compete for width,\n * and packing them together would make a busy Monday narrow a quiet Tuesday.\n */\nconst placed = computed(() => {\n const segments = timedSegments(drawnEvents.value, props.days, props.window, props.slotDuration)\n const ghost = ghostSegment.value\n\n const byDay = new Map<number, typeof segments>()\n for (const segment of segments) {\n /*\n * The echo is held OUT of the packing and put back below with the width and column it had\n * when the drag began. Packed with the rest, it would share its column with the card\n * being dragged the moment the two overlapped — so the card under the pointer would halve\n * in width and then grow back as it moved away, which reads as the drag going wrong.\n */\n if (ghost && segment.id === ghost.id) continue\n const list = byDay.get(segment.dayIndex)\n if (list) list.push(segment)\n else byDay.set(segment.dayIndex, [segment])\n }\n\n const real = [...byDay.values()].flatMap((list) => packDayColumn(list))\n return ghost ? [...real, ghost] : real\n})\n\n/**\n * The cards, filed under the cell their start falls in. Grouping once here is what keeps\n * the template from asking every cell to search the whole list — a hundred and sixty-eight\n * searches per render otherwise.\n */\nconst byCell = computed(() => {\n const map = new Map<string, PlacedSegment[]>()\n for (const segment of placed.value) {\n const row = Math.floor((segment.start - props.window.start) / MINUTES_PER_HOUR)\n const key = `${segment.dayIndex}:${clamp(row, 0, hours.value.length - 1)}`\n const list = map.get(key)\n if (list) list.push(segment)\n else map.set(key, [segment])\n }\n return map\n})\n\nconst cellId = (iso: string, minutes: number) => `${uid}-c-${iso}-${minutes}`\n\n/*\n * Every label the grid writes, worked out once per day and once per hour instead of once\n * per CELL — the shape `byCell` above already uses, and for the same reason.\n *\n * The grid renders `hours × days` cells, 24 × 7 by default. Reading these straight from\n * `formatDate` in the template meant 168 `cellLabel` calls per render, each doing a\n * `parseISO`, a `JSON.stringify` to build the formatter's cache key and two `Intl` formats,\n * plus `dayName`/`dayNumber` twice per column (slot props, then the fallback content). None\n * of it depends on the pointer — yet `applyPoint` assigns a new `state.preview` on every\n * `pointermove`, so the whole template re-renders at pointer rate and all of it was\n * recomputed on every frame of a drag.\n *\n * Two maps of 7 and 24 entries replace that: they recompute when the locale, the days or\n * the window change, and never because a card moved.\n */\nconst dayLabels = computed(() => {\n const map = new Map<string, { short: string; number: string; full: string }>()\n for (const iso of props.days) {\n map.set(iso, {\n short: formatDate(iso, props.locale, { weekday: 'short' }),\n number: formatDate(iso, props.locale, { day: 'numeric' }),\n full: formatDate(iso, props.locale, { weekday: 'long', day: 'numeric', month: 'long' }),\n })\n }\n return map\n})\n\nconst hourLabels = computed(() => {\n const map = new Map<number, string>()\n for (const minutes of hours.value)\n map.set(minutes, formatTimeDisplay(timeOf(minutes), props.locale, props.hourFormat))\n return map\n})\n\n/*\n * The hour gutter and the drag readout both ask for an hour that is not always one of the\n * rows — a preview lands between them — so this falls back to formatting rather than\n * assuming the map holds every minute.\n */\nconst hourLabel = (minutes: number) =>\n hourLabels.value.get(minutes) ??\n formatTimeDisplay(timeOf(minutes), props.locale, props.hourFormat)\n\nconst dayName = (iso: string, weekday: 'short' | 'long') =>\n weekday === 'short'\n ? (dayLabels.value.get(iso)?.short ?? formatDate(iso, props.locale, { weekday }))\n : formatDate(iso, props.locale, { weekday })\n\nconst dayNumber = (iso: string) =>\n dayLabels.value.get(iso)?.number ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/** What one cell is called: the day in full, then the hour. */\nconst cellLabel = (iso: string, minutes: number) =>\n `${dayLabels.value.get(iso)?.full ?? iso}, ${hourLabel(minutes)}`\n\n/**\n * An event's times, written out for the reader. The time zone is appended as an annotation\n * and never applied: the card's place in the grid comes from the local times given, which\n * is the whole of the design system's position on the matter.\n */\nfunction timeTextOf(event: E): string {\n const start = formatTimeDisplay(event.startTime, props.locale, props.hourFormat)\n const end = formatTimeDisplay(event.endTime, props.locale, props.hourFormat)\n const range = `${start} – ${end}`\n return event.timezone ? `${range} (${event.timezone})` : range\n}\n\nfunction styleFor(segment: PlacedSegment) {\n return {\n '--event-start': String(fractionOf(segment.start, props.window)),\n '--event-end': String(fractionOf(segment.end, props.window)),\n '--event-day': String(segment.dayIndex),\n '--event-column': String(segment.column),\n '--event-span': String(segment.span),\n '--event-columns': String(segment.columns),\n }\n}\n\nconst isFocused = (iso: string, minutes: number) =>\n focused.value.iso === iso && focused.value.minutes === minutes\n\n/**\n * Where the tab stop goes when the focused cell is not one of the cells on screen — after\n * a view change, or before anything has been focused at all. Without it no cell would carry\n * `tabindex=\"0\"`, the grid would drop out of the tab order, and the scrolling region would\n * have nothing reachable inside it, which is an accessibility failure and not merely an\n * inconvenience.\n */\nconst fallbackCell = computed(() => {\n const iso = props.days[0]\n if (!iso) return null\n return { iso, minutes: props.window.start }\n})\n\nconst tabbable = computed<FocusedCell | null>(() => {\n const current = focused.value\n if (props.days.includes(current.iso)) {\n const rounded =\n Math.floor((current.minutes - props.window.start) / MINUTES_PER_HOUR) * MINUTES_PER_HOUR +\n props.window.start\n if (rounded >= props.window.start && rounded < props.window.end) {\n return { iso: current.iso, minutes: rounded }\n }\n }\n return fallbackCell.value\n})\n\nconst isTabStop = (iso: string, minutes: number) =>\n tabbable.value?.iso === iso && tabbable.value.minutes === minutes\n\nfunction moveFocusTo(iso: string, minutes: number) {\n focused.value = { iso, minutes }\n // @a11y — the model is what decides which cell is tabbable, so the DOM focus can only be\n // moved once the render that applied it has run.\n void nextTick(() => document.getElementById(cellId(iso, minutes))?.focus())\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const target = event.target as HTMLElement | null\n\n // A card answers a different table from the grid it sits in — that is what a grab mode IS.\n // Delegated here, on the same element as the pointer, so the two never drift apart.\n const card = target?.closest<HTMLElement>('.v-calendar-event')\n if (card) {\n onCardKeydown(event, card)\n return\n }\n\n const cell = target?.closest<HTMLElement>('.v-calendar-cell')\n if (!cell) return\n\n const intent = calendarIntent(event.key, event.shiftKey, 'cell', props.slotDuration, isRtl())\n if (!intent) return\n\n const iso = cell.dataset.iso!\n const minutes = Number(cell.dataset.minutes)\n const index = props.days.indexOf(iso)\n\n if (intent.kind === 'moveFocus') {\n const day = props.days[clamp(index + intent.days, 0, props.days.length - 1)]!\n const at = clamp(\n minutes + intent.minutes,\n props.window.start,\n props.window.end - MINUTES_PER_HOUR,\n )\n event.preventDefault()\n moveFocusTo(day, at)\n return\n }\n\n if (intent.kind === 'rowEdge') {\n const day = intent.edge === 'start' ? props.days[0] : props.days.at(-1)\n if (!day) return\n event.preventDefault()\n moveFocusTo(day, minutes)\n return\n }\n\n if (intent.kind === 'period') {\n event.preventDefault()\n emit('step', intent.delta)\n return\n }\n\n if (intent.kind === 'activate') {\n event.preventDefault()\n emit('cell-activate', iso, minutes)\n }\n}\n\n/* ------------------------------------------------------------------ the gestures */\n\n/**\n * Starts a gesture, from whichever of the three ways one can begin.\n *\n * Every entry point funnels through here, so the rules that make a gesture safe — one at a\n * time, the origin captured once, the pointer taken hold of on the GRID — are written once\n * rather than three times.\n */\nfunction begin(\n state: Omit<\n Gesture,\n 'preview' | 'moved' | 'outside' | 'lastX' | 'lastY' | 'ghostColumn' | 'ghostLane'\n >,\n event?: PointerEvent,\n) {\n /*\n * Read BEFORE the gesture is set. Both are derived from `drawnEvents`, which the gesture\n * immediately starts rewriting — a line later and they would already describe the preview\n * rather than the place it came from. Which of the two answers is also what says whether\n * this is a timed card or an all-day bar, and therefore which of the echo's two shapes the\n * gesture has to carry.\n */\n const segment = placed.value.find((item) => item.id === state.id)\n const span = allDay.value.find((item) => item.id === state.id)\n\n gesture.value = {\n ...state,\n preview: { ...state.origin },\n lastX: state.originX,\n lastY: state.originY,\n ghostColumn: segment\n ? { column: segment.column, span: segment.span, columns: segment.columns }\n : null,\n ghostLane: span ? span.lane : null,\n moved: false,\n outside: false,\n }\n\n if (!event) return\n /*\n * @fallback — capturing the pointer on the COLUMNS box, and not on the card, is what makes\n * one set of move and up handlers serve all three gestures and what keeps a drag alive\n * when the pointer wanders off the grid: capture retargets every later pointer event back\n * to the captured element, so the bindings in the template are the whole of it — no\n * document listener, no release, nothing to tear down on unmount.\n *\n * It is wrapped because a pointer event fired by a TEST refers to no real pointer, and the\n * call then throws. Failing to capture merely means the drag stops at the edge, which no\n * test is checking.\n */\n try {\n // The SCROLLER, not the columns box: the all-day band sits in the sticky header, and this\n // is the only element that contains both it and the canvas. Capture retargets every later\n // pointer event here, which is why one set of move and up bindings serves all four kinds.\n rootEl.value?.setPointerCapture(event.pointerId)\n } catch {\n /* a synthetic pointer: nothing to capture */\n }\n}\n\n/**\n * Every press on the grid, dispatched by WHAT it landed on.\n *\n * One delegated handler rather than a listener per card and per strip. That is not only\n * fewer bindings on a grid that may hold a hundred: it is what removes the question of\n * which listener runs first. Three handlers stacked on nested elements would each have to\n * guard against the others, and `stopPropagation` would make the answer depend on the order\n * they happened to be bound in. Here the target is examined once and the gesture chosen\n * once, so the strip inside a card and the card inside a cell cannot disagree.\n */\nfunction onGridPointerdown(event: PointerEvent) {\n endLastGesture()\n // Left button only: a right-click is opening a context menu, not starting a drag.\n if (gesture.value || event.button !== 0) return\n\n const target = event.target as HTMLElement | null\n if (!target) return\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n\n const point = pointToCell(\n { x: event.clientX, y: event.clientY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n const card = target.closest<HTMLElement>('.v-calendar-event')\n if (card) {\n if (!props.editable) return\n const item = eventsById.value.get(cardIdOf(card))\n if (!item || isAllDayEvent(item)) return\n\n const resizing = target.closest('[data-calendar-handle]') !== null\n begin(\n {\n kind: resizing ? 'resize' : 'move',\n id: item.id,\n origin: timesOf(item),\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n // Where inside the card the pointer took hold, so it does not jump under the finger.\n grabOffset: resizing ? 0 : point.minutes - minutesAt(item.startTime, props.window.start),\n grabColumn: point.columnIndex,\n },\n event,\n )\n return\n }\n\n if (!props.creatable || !target.closest('.v-calendar-cell')) return\n const iso = props.days[point.columnIndex]\n if (!iso) return\n\n /*\n * A new event begins at the top of the slot the pointer went down in — rounded DOWN, never\n * to the nearest — because a press at 09:07 means \"the nine o'clock slot\" and not the\n * quarter past. It is one slot long to begin with, so a press that never moves creates\n * exactly the short event a click is meant to create, and a press that travels stretches\n * its end instead. One path serves both, and a click is simply the drag that stayed still.\n */\n const start = floorToSlot(point.minutes, props.slotDuration)\n begin(\n {\n kind: 'create',\n id: DRAFT_ID,\n origin: {\n start: iso,\n end: iso,\n startTime: timeOf(start),\n endTime: timeOf(Math.min(start + props.slotDuration, props.window.end)),\n },\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n grabOffset: 0,\n grabColumn: point.columnIndex,\n },\n event,\n )\n}\n\n/**\n * A press on the band of all-day bars above the grid.\n *\n * It has a handler of its own rather than joining the delegated one below it, because the\n * band is not inside `.v-calendar-columns` — it lives in the sticky header, which is the one\n * part of the calendar that scroll does not carry. Everything after the press IS shared: the\n * capture, the move, the release, all of them on the scroller both boxes sit in.\n */\nfunction onBandPointerdown(event: PointerEvent) {\n endLastGesture()\n if (gesture.value || !props.editable || event.button !== 0) return\n\n const card = (event.target as HTMLElement | null)?.closest<HTMLElement>('.v-calendar-event')\n if (!card) return\n const item = eventsById.value.get(cardIdOf(card))\n if (!item) return\n\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n const point = pointToCell(\n { x: event.clientX, y: event.clientY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n begin(\n {\n kind: 'move-days',\n id: item.id,\n origin: timesOf(item),\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n grabOffset: 0,\n grabColumn: point.columnIndex,\n },\n event,\n )\n}\n\n/** The event a card stands for, read back off the attribute the card publishes. */\nfunction cardIdOf(card: HTMLElement): CalendarEventId {\n const raw = card.dataset.eventId ?? ''\n /*\n * An id may be a number, and an attribute is always text. The map is keyed by the ORIGINAL\n * value, so a numeric id has to be turned back into one — otherwise every card belonging\n * to a numerically-keyed calendar would look up as a miss and nothing would drag.\n */\n return eventsById.value.has(raw) ? raw : Number(raw)\n}\n\nfunction 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 state.moved = true\n state.outside = isPointerOutside(state)\n applyPoint(state)\n watchEdges(state)\n}\n\n/**\n * Whether the pointer has left the calendar's own box.\n *\n * The box is the WHOLE view — the scroller, the element carrying `.v-calendar-view` — and\n * deliberately not `.v-calendar-columns`, whose rect excludes the sticky day names, the all-day\n * band and the hour gutter: a bar dropped on the band is an ordinary thing to do, and measured\n * against the columns it would read as dropped off the calendar and silently revert.\n *\n * The rect goes in RAW and never through `geometryOf`, whose `inlineStart` is the box's RIGHT\n * edge in a right-to-left page: containment has no reading direction, and flipping the axis here\n * would answer a question nobody asked — every right-to-left drop would read as outside.\n *\n * It is called from `onPointermove` ALONE, and not from `applyPoint`. That function has three\n * callers, and the other two — the view paging, and the auto-scroll frame — move the days and\n * the scroll position under a pointer that has not moved at all: they cannot change this answer,\n * and asking them to recompute it would force a layout on every animation frame.\n *\n * TRAP — neither `applyPoint` nor `watchEdges` is gated on the result, and neither may become\n * so. The card must keep following the pointer while it is out (that is what makes coming back\n * in seamless), and paging must keep running (pushing past the edge is how one crosses into the\n * next week). Being outside decides what happens on RELEASE, and nothing else.\n */\nfunction isPointerOutside(state: Gesture): boolean {\n const rect = rootEl.value?.getBoundingClientRect()\n return rect ? !pointWithin({ x: state.lastX, y: state.lastY }, rect) : false\n}\n\n/**\n * Works out where the dragged event now belongs, from wherever the pointer last was.\n *\n * It is separate from the handler because THREE things call it: the pointer moving, the view\n * paging out from under a still pointer, and the grid scrolling under one. The last two would\n * otherwise leave the card behind on a day or an hour that is no longer where the pointer is.\n */\nfunction applyPoint(state: Gesture) {\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n // Measuring here is safe: this runs from a handler or a frame, hence in a browser, never\n // in a render.\n const point = pointToCell(\n { x: state.lastX, y: state.lastY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n if (state.kind === 'move-days') {\n /*\n * A bar keeps its length in days, so the target is its START shifted by however many\n * columns the pointer has crossed — not the column the pointer is over. Grab a\n * Monday-to-Wednesday bar by its Tuesday and the pointer stays on its Tuesday.\n */\n const column = clamp(\n originColumn(state) + (point.columnIndex - state.grabColumn),\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column]\n if (iso) state.preview = moveEventToDay(state.origin, iso)\n return\n }\n\n if (state.kind === 'move') {\n /*\n * The day comes from the COLUMN the pointer is over, read out of the list of days on\n * show — never from date arithmetic on how many columns were crossed, which would count\n * the days the calendar is hiding and land the event on a Saturday nobody can see.\n */\n const column = clamp(\n originColumn(state) + (point.columnIndex - state.grabColumn),\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column]!\n const start = snapToSlot(point.minutes - state.grabOffset, props.slotDuration)\n const delta = start - minutesAt(state.origin.startTime, props.window.start)\n state.preview = { ...moveEvent(state.origin, 0, delta, props.window), start: iso, end: iso }\n return\n }\n\n state.preview = resizeEvent(\n state.origin,\n snapToSlot(point.minutes, props.slotDuration),\n props.slotDuration,\n props.window,\n )\n}\n\n/* ------------------------------------------------------- crossing the boundaries */\n\n/**\n * How many pixels a frame the grid scrolls at full tilt.\n *\n * At sixty frames a second that is roughly eight hundred a second, which crosses a whole\n * twenty-four-hour day in about two — fast enough to be worth doing, slow enough to stop on.\n */\nconst AUTO_SCROLL_SPEED = 14\n\nconst edge = useEdgeStep(\n (direction) => emit('step', direction),\n () => props.edgeStepDelay,\n)\n\n/** Which edge is counting down, in words, for the stylesheet to light up. */\nconst edgeCue = computed(() =>\n edge.pending.value === -1 ? 'start' : edge.pending.value === 1 ? 'end' : undefined,\n)\n\n/** Tells the two boundary mechanisms where the pointer now is. */\nfunction watchEdges(state: Gesture) {\n const columns = columnsEl.value?.getBoundingClientRect()\n const scroller = rootEl.value?.getBoundingClientRect()\n if (!columns || !scroller) return\n\n // Paging is measured against the COLUMNS, which is what the days occupy; scrolling against\n // the SCROLLER, which is what actually moves.\n edge.watchEdge(inlineEdgeAt(state.lastX, geometryOf(columns), EDGE_BAND, isRtl()))\n setScrollSpeed(props.autoScroll ? blockEdgeAt(state.lastY, scroller, EDGE_BAND) : 0)\n}\n\n/*\n * The design system's only `requestAnimationFrame` loop, and it earns that: a pointer held\n * still fires no events at all, so nothing else can drive continuous motion. Everything else\n * that moves here is either a transition or a timer.\n */\nlet scrollFrame: number | null = null\nlet scrollSpeed = 0\n\nfunction setScrollSpeed(speed: number) {\n scrollSpeed = speed\n if (speed === 0) {\n stopScrolling()\n return\n }\n scrollFrame ??= requestAnimationFrame(scrollStep)\n}\n\nfunction scrollStep() {\n scrollFrame = null\n const root = rootEl.value\n const state = gesture.value\n if (!root || !state || scrollSpeed === 0) return\n\n root.scrollTop += scrollSpeed * AUTO_SCROLL_SPEED\n // The hours have moved under a pointer that has not, so what it is over has changed.\n applyPoint(state)\n scrollFrame = requestAnimationFrame(scrollStep)\n}\n\nfunction stopScrolling() {\n if (scrollFrame !== null) cancelAnimationFrame(scrollFrame)\n scrollFrame = null\n scrollSpeed = 0\n}\n\n/** Everything a gesture leaves running, dropped on every path out of one. */\nfunction releaseBoundaries() {\n edge.cancel()\n stopScrolling()\n}\n\nonBeforeUnmount(stopScrolling)\n\n/*\n * Paging swaps the days 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\n * is holding still against the edge. Re-applying the last position as soon as the new days\n * are rendered is what keeps the card under the pointer across the boundary.\n */\nwatch(\n () => props.days,\n () => {\n const state = gesture.value\n if (state?.moved) applyPoint(state)\n },\n { flush: 'post' },\n)\n\n/**\n * Which column the event being moved started in.\n *\n * The fallback is what makes the formula above general rather than a special case. For a\n * TIMED card these two are necessarily equal — you grab a card, and a card lives inside its\n * own column — so the offset is zero and the event simply follows the pointer. For a BAR they\n * differ, which is what keeps a three-day one from jumping when grabbed by its middle. And\n * when the origin day is not on screen at all — a bar that began before this range, or an\n * event whose view has been paged out from under the drag — falling back to the grab column\n * makes the offset zero again, so the event lands under the pointer instead of nowhere.\n */\nfunction originColumn(state: Gesture): number {\n const index = props.days.indexOf(state.origin.start)\n return index === -1 ? state.grabColumn : index\n}\n\n/**\n * Whether the press that is about to become a click was a drag.\n *\n * A plain `let`, since nothing renders it: `pointerup` always fires before `click`, so this\n * is written on the way out of the gesture and read by the click that immediately follows.\n * Without it, letting go of a card at the end of a drag would ALSO open it — the consumer's\n * editor would appear over every event the reader had just moved.\n */\nlet justDragged = false\n\n/**\n * Closes the books on whatever gesture came before, at the start of a new press.\n *\n * TRAP — without this the flag can be left STANDING, and what it then breaks surfaces nowhere\n * near its cause. It is lowered by the click that reads it, and that click only reaches\n * `onCardClick` when it lands on a card: draw a new event and the press began on a CELL, so the\n * click goes there and the flag stays raised.\n *\n * What normally hides that is `onPointerup` overwriting the flag with its own `moved` — so the\n * next press heals it, and only a press that starts NO gesture does not. Which is a real\n * configuration and not a curiosity: a calendar that lets events be drawn but not moved\n * (`creatable` without `editable`) reaches it every time. The reader clicks an event to open it,\n * nothing happens, they click again and it works.\n *\n * Clearing it HERE makes the flag incapable of outliving its own interaction, and the ordering\n * is the whole argument: the click this exists to swallow follows its own `pointerup` with no\n * press in between, so it is still protected — while any LATER click on a card is necessarily\n * preceded by a press on that card, which arrives here first.\n *\n * It runs before every guard in the three handlers that call it, deliberately: a press that\n * starts no gesture at all is still the start of a new interaction, and those are precisely the\n * cases this is for.\n */\nfunction endLastGesture() {\n justDragged = false\n}\n\nfunction onPointerup(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n gesture.value = null\n justDragged = state.moved\n releaseBoundaries()\n\n /*\n * Let go with the pointer off the calendar and the gesture is abandoned whole: no move, no new\n * length, and no new event either. The card goes back to where the model still says it is,\n * which is where the echo has been showing all along. It is the hand's version of the Escape\n * the keyboard grab already has — a gesture that ends somewhere it cannot mean anything must\n * mean nothing.\n *\n * TRAP — `justDragged` above is what still has to happen, and it is the ONE thing the cancel\n * path deliberately does not do: `pointerup` fires before `click`, so without it an abandoned\n * drag would end by OPENING the very event it has just refused to move. Which is also why\n * this branch and `onPointercancel` must NOT be factored into one helper. They differ by\n * exactly that line and it is correct in both directions — no click follows a cancel, so a\n * `true` left behind there would swallow the next genuine one instead.\n *\n * Nothing is announced. The pointer says nothing on a SUCCESSFUL drop either: `grabbed`,\n * `dropped` and `reverted` belong to the keyboard grab, which has no pointer to show where the\n * event went. A revert that spoke would be the only thing the pointer ever said.\n */\n if (state.outside) return\n\n if (state.kind === 'create') {\n emit('slot-create', state.preview)\n return\n }\n\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) return\n\n emit('event-drop', state.id, state.preview, state.kind === 'resize' ? 'resize' : 'move')\n}\n\nfunction onCardClick(id: CalendarEventId) {\n if (justDragged) {\n justDragged = false\n return\n }\n const item = eventsById.value.get(id)\n if (item && id !== DRAFT_ID) emit('event-activate', item)\n}\n\n/**\n * A click on an empty part of a day, for a calendar that does NOT make events itself.\n *\n * When it does, the press has already become a `create` gesture and reported itself on\n * release; saying it again here would report the same click twice. So this path exists only\n * for a consumer who turned creation off to run their own form — they still get told where\n * the reader pointed, which is the whole point of turning it off rather than ignoring it.\n */\nfunction onGridClick(event: MouseEvent) {\n if (props.creatable) return\n const target = event.target as HTMLElement | null\n if (target?.closest('.v-calendar-event')) return\n const cell = target?.closest<HTMLElement>('.v-calendar-cell')\n if (!cell) return\n emit('cell-activate', cell.dataset.iso!, Number(cell.dataset.minutes))\n}\n\nfunction onPointercancel() {\n /*\n * The gesture was taken away — a system gesture, a context menu, the page starting to\n * scroll. Nothing is written and nothing is announced: the card simply goes back to where\n * the model still says it is.\n */\n gesture.value = null\n releaseBoundaries()\n}\n\n/* ------------------------------------------------------------ the keyboard's version */\n\nfunction announceTimes(title: string, times: CalendarEventTimes) {\n const start = formatTimeDisplay(times.startTime, props.locale, props.hourFormat)\n const end = formatTimeDisplay(times.endTime, props.locale, props.hourFormat)\n const day = formatDate(times.start, props.locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n })\n emit('announce', m.value.calendar.movedTo(title, `${day}, ${start} – ${end}`))\n}\n\n/** Puts the focus back on a card that has just been redrawn somewhere else. */\nfunction refocusCard(id: CalendarEventId) {\n void nextTick(() => {\n /*\n * The card is found by WALKING the cards rather than by building an attribute selector.\n * An id belongs to the consumer, so it may hold a quote or a backslash that a selector\n * would need escaped — and `CSS.escape` cannot do that escaping here: jsdom defines no\n * `CSS` object at all, so the call threw on every keyboard grab, from inside a `nextTick`\n * where nothing could catch it (an unhandled rejection, which fails the run while every\n * assertion still passes). `menuInvoker` in VMenu/context.ts escapes by hand for the same\n * reason; comparing the attribute's own text sidesteps the question entirely, since\n * `data-event-id` is written as exactly `String(event.id)`.\n */\n const cards = columnsEl.value?.querySelectorAll<HTMLElement>('.v-calendar-event')\n Array.from(cards ?? [])\n .find((card) => card.dataset.eventId === String(id))\n ?.focus()\n })\n}\n\nfunction onCardKeydown(event: KeyboardEvent, card: HTMLElement) {\n const item = eventsById.value.get(cardIdOf(card))\n if (!item) return\n\n const held = grabbing.value && gesture.value?.id === item.id\n const intent = calendarIntent(\n event.key,\n event.shiftKey,\n held ? 'grabbed' : 'event',\n props.slotDuration,\n isRtl(),\n )\n if (!intent) return\n\n if (!held) {\n if (intent.kind !== 'activate') return\n // An event that cannot be moved keeps a button's ordinary behaviour: Enter opens it,\n // which the click handler below already reports.\n if (!props.editable || isAllDayEvent(item)) return\n /*\n * Enter and Space are ALSO how a button is pressed. Without this the same keystroke\n * would take hold of the event and open it at once, and every attempt to move something\n * would fire the consumer's editor over the top of it.\n */\n event.preventDefault()\n begin({\n kind: 'move',\n id: item.id,\n origin: timesOf(item),\n pointerId: null,\n originX: 0,\n originY: 0,\n grabOffset: 0,\n grabColumn: 0,\n })\n emit('announce', m.value.calendar.grabbed)\n return\n }\n\n const state = gesture.value!\n event.preventDefault()\n\n if (intent.kind === 'grabResize') {\n /*\n * Each step is applied to the PREVIEW rather than to the origin, so the arrows accumulate\n * the way a reader expects — three presses of Down move three slots, not one. That is the\n * opposite of the pointer, which recomputes from the origin every frame because it always\n * knows where it is; the keyboard only knows how far it has just asked to go.\n */\n state.preview = resizeEvent(\n state.preview,\n minutesAt(state.preview.endTime, props.window.end) + intent.minutes,\n props.slotDuration,\n props.window,\n )\n state.moved = true\n announceTimes(item.title, state.preview)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'grabMove') {\n // Sideways is a step along the days ON SHOW, exactly as the pointer's is: date\n // arithmetic would count the days the calendar is hiding.\n const column = clamp(\n props.days.indexOf(state.preview.start) + intent.days,\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column] ?? state.preview.start\n state.preview = {\n ...moveEvent(state.preview, 0, intent.minutes, props.window),\n start: iso,\n end: iso,\n }\n state.moved = true\n announceTimes(item.title, state.preview)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'activate') {\n gesture.value = null\n if (state.moved) {\n emit('event-drop', state.id, state.preview, state.kind === 'resize' ? 'resize' : 'move')\n }\n emit('announce', m.value.calendar.dropped)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'cancel') {\n gesture.value = null\n emit('announce', m.value.calendar.reverted)\n refocusCard(state.id)\n }\n}\n\n/* ---------------------------------------------------------------------- measurement */\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst canvasEl = ref<HTMLElement | null>(null)\nconst columnsEl = ref<HTMLElement | null>(null)\n\n/** The columns box as the pure geometry wants it: plain numbers, no element. */\nfunction geometryOf(rect: DOMRect) {\n const rtl = isRtl()\n return {\n top: rect.top,\n height: rect.height,\n // The edge the first column starts at, which is the other one in a right-to-left page.\n inlineStart: rtl ? rect.right : rect.left,\n inlineSize: rect.width,\n columns: props.days.length,\n }\n}\n\nconst isRtl = () => isElementRtl(columnsEl.value)\n\n/**\n * Brings a moment of the day to the top of the visible area.\n *\n * The row height is measured rather than read from the token, because the token is a length\n * a consumer may override and the browser is the only thing that knows what it came to. It\n * is a handler-time read, never a render-time one, and it degrades to doing nothing where\n * nothing has been laid out — which is exactly what the test environment wants.\n */\nfunction scrollToMinutes(minutes: number) {\n const root = rootEl.value\n const canvas = canvasEl.value\n if (!root || !canvas || hours.value.length === 0) return\n const rowHeight = canvas.offsetHeight / hours.value.length\n if (rowHeight <= 0) return\n root.scrollTop = ((minutes - props.window.start) / MINUTES_PER_HOUR) * rowHeight\n}\n\n/** Puts the focus on whichever cell currently holds the tab stop. */\nfunction focus() {\n const cell = tabbable.value\n if (cell) document.getElementById(cellId(cell.iso, cell.minutes))?.focus()\n}\n\ndefineExpose({ focus, scrollToMinutes })\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-calendar-grid\"\n :data-outside=\"gesture?.outside ? '' : undefined\"\n :style=\"{ '--calendar-columns': String(days.length) }\"\n @pointermove=\"onPointermove\"\n @pointerup=\"onPointerup\"\n @pointercancel=\"onPointercancel\"\n >\n <div class=\"v-calendar-head\">\n <div class=\"v-calendar-head-gutter\" />\n <div\n v-for=\"iso in days\"\n :key=\"iso\"\n class=\"v-calendar-head-day\"\n :data-today=\"iso === today ? '' : undefined\"\n >\n <slot\n name=\"day-header\"\n :iso=\"iso\"\n :weekday=\"dayName(iso, 'short')\"\n :day=\"dayNumber(iso)\"\n :today=\"iso === today\"\n >\n <span class=\"v-calendar-head-weekday\">{{ dayName(iso, 'short') }}</span>\n <span class=\"v-calendar-head-number\">{{ dayNumber(iso) }}</span>\n </slot>\n </div>\n\n <!-- The band of all-day bars, kept INSIDE the header so that the whole of it is one\n sticky box: two boxes would each need to know how tall the other was. -->\n <template v-if=\"allDay.length > 0\">\n <div class=\"v-calendar-allday-label\">\n <slot name=\"all-day-label\">{{ m.calendar.allDay }}</slot>\n </div>\n <div\n class=\"v-calendar-allday\"\n role=\"group\"\n :aria-label=\"m.calendar.allDay\"\n :style=\"{ '--calendar-lanes': String(allDayLanes) }\"\n @pointerdown=\"onBandPointerdown\"\n >\n <VCalendarEvent\n v-for=\"span in allDay\"\n :key=\"span.id\"\n class=\"v-calendar-bar\"\n :event=\"eventsById.get(span.id)!\"\n layout=\"chip\"\n :continues-before=\"span.continuesBefore\"\n :continues-after=\"span.continuesAfter\"\n :dragging=\"gesture?.id === span.id && gesture.pointerId !== null\"\n :rejected=\"gesture?.id === span.id && gesture.outside\"\n :grabbed=\"grabbing && gesture?.id === span.id\"\n :hint-id=\"editable && !isGhostId(span.id) ? hintId : undefined\"\n :ghost-of=\"isGhostId(span.id) ? originalIdOf(span.id) : undefined\"\n :style=\"{\n '--event-day': String(span.startIndex),\n '--event-span': String(span.span),\n '--event-lane': String(span.lane),\n }\"\n @click=\"onCardClick(span.id)\"\n >\n <template v-if=\"$slots.event\" #default=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarEvent>\n </div>\n </template>\n </div>\n\n <div ref=\"canvasEl\" class=\"v-calendar-canvas\">\n <div class=\"v-calendar-hours\" aria-hidden=\"true\">\n <span v-for=\"minutes in hours\" :key=\"minutes\" class=\"v-calendar-hour\">\n {{ hourLabel(minutes) }}\n </span>\n </div>\n\n <div\n ref=\"columnsEl\"\n class=\"v-calendar-columns\"\n role=\"grid\"\n :aria-label=\"label\"\n :data-gesture=\"gesture?.kind\"\n :data-edge=\"edgeCue\"\n @keydown=\"onKeydown\"\n @click=\"onGridClick\"\n @pointerdown=\"onGridPointerdown\"\n >\n <div v-for=\"(minutes, row) in hours\" :key=\"minutes\" role=\"row\" class=\"v-calendar-row\">\n <div\n v-for=\"(iso, day) in days\"\n :id=\"cellId(iso, minutes)\"\n :key=\"iso\"\n role=\"gridcell\"\n class=\"v-calendar-cell\"\n :data-iso=\"iso\"\n :data-minutes=\"minutes\"\n :data-today=\"iso === today ? '' : undefined\"\n :tabindex=\"isTabStop(iso, minutes) ? 0 : -1\"\n :aria-label=\"cellLabel(iso, minutes)\"\n :aria-selected=\"isFocused(iso, minutes) ? true : undefined\"\n >\n <VCalendarEvent\n v-for=\"segment in byCell.get(`${day}:${row}`) ?? []\"\n :key=\"segment.id\"\n class=\"v-calendar-block\"\n :event=\"eventsById.get(segment.id)!\"\n layout=\"block\"\n :time-text=\"timeTextOf(eventsById.get(segment.id)!)\"\n :continues-before=\"segment.clippedStart\"\n :continues-after=\"segment.clippedEnd\"\n :resizable=\"editable && segment.id !== DRAFT_ID\"\n :dragging=\"gesture?.id === segment.id && gesture.pointerId !== null\"\n :rejected=\"gesture?.id === segment.id && gesture.outside\"\n :grabbed=\"grabbing && gesture?.id === segment.id\"\n :hint-id=\"editable && !isGhostId(segment.id) ? hintId : undefined\"\n :ghost-of=\"isGhostId(segment.id) ? originalIdOf(segment.id) : undefined\"\n :style=\"styleFor(segment)\"\n @click=\"onCardClick(segment.id)\"\n >\n <template v-if=\"$slots.event\" #default=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarEvent>\n\n <!-- The line is drawn INSIDE the cell holding the current hour, never as a\n direct child of the grid or of a row: a `grid` owns only rows and a row only\n cells, so an extra box at either level fails `aria-required-children`. -->\n <div\n v-if=\"nowMark && nowMark.cell === `${day}:${row}`\"\n class=\"v-calendar-now\"\n aria-hidden=\"true\"\n :style=\"{\n '--event-day': String(nowMark.dayIndex),\n '--calendar-now': String(nowMark.fraction),\n }\"\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-grid {\n /*\n * The one scrolling box. The day names are sticky INSIDE it rather than in a container\n * of their own, which is what keeps them aligned with the columns for free: a separate\n * header would have to be told how far the body had scrolled sideways, and told again\n * every time the column widths changed.\n */\n --calendar-hour: var(--vectis-control-size-calendar-hour);\n --calendar-gutter: var(--vectis-control-size-calendar-gutter);\n /*\n * Half a line of an hour label. It is used TWICE and in opposite directions — the label\n * is pulled up by it so it straddles its rule, and the tick is pushed back down by it so\n * it lands on that same rule. One number, so the two cannot drift apart; two literals\n * would misalign the moment the caption's leading changed, with nothing to point at it.\n */\n --calendar-hour-lift: calc(\n var(--vectis-text-caption-size) * var(--vectis-text-caption-leading) / 2\n );\n\n position: relative;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n /*\n * A drag currently held off the calendar. `not-allowed` is the word the library already uses\n * for \"you cannot do this\", on every disabled control.\n *\n * BEST-EFFORT, and never the signal: while a pointer is captured the cursor is resolved\n * against the capture target rather than against whatever sits under the pointer, and engines\n * differ on it. What carries the message is the card's own paint, which is why this is a\n * second cue and not the first.\n */\n .v-calendar-grid[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-head,\n .v-calendar-canvas {\n display: grid;\n grid-template-columns: var(--calendar-gutter) repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n /*\n * The tracks have a floor, so on a narrow screen they add up to more than the box and\n * the calendar scrolls sideways. Without this the BOX would stay the width of the\n * scroller while the tracks spilled out of it: the sticky day names would paint their\n * background only as far as the original width, and the columns would run out from\n * under them halfway across. `min-content` on a grid is the sum of its track minimums,\n * which is exactly the width wanted here.\n */\n min-inline-size: min-content;\n }\n\n /*\n * THE STACKING ORDER OF THE WHOLE GRID, in one place because it is decided in four:\n *\n * 1 .v-calendar-block an event card\n * 2 .v-calendar-now the current-time line, over every card\n * 3 [data-dragging] / [data-grabbed] a card being moved, over the line\n * 4 .v-calendar-head the sticky day names, over everything\n *\n * Neither `.v-calendar-grid` nor `.v-calendar-columns` establishes a stacking context —\n * both are `relative` with no `z-index` — so all four compete at the root, and any TIE is\n * broken by document order. That is what put the current-time line over the header while\n * both sat at 2: the line is further down the template. The header has to sit above the\n * dragged card as well, which is why it is 4 and not 3.\n */\n .v-calendar-head {\n position: sticky;\n inset-block-start: 0;\n z-index: 4;\n background: var(--vectis-color-surface);\n border-block-end: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-head-gutter {\n /* The corner above the hour labels. It is empty, and it is here so the day names line\n up with their columns rather than starting at the edge of the box. */\n border-inline-end: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-head-day {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: var(--vectis-space-2);\n padding-inline: var(--vectis-space-1);\n }\n\n .v-calendar-head-weekday {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-overline-size);\n font-weight: var(--vectis-text-overline-weight);\n letter-spacing: var(--vectis-text-overline-tracking);\n text-transform: uppercase;\n }\n\n .v-calendar-head-number {\n display: flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--vectis-control-height-sm);\n block-size: var(--vectis-control-height-sm);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-body-lg-size);\n }\n\n /* Today is marked on the number alone, the way a calendar marks a date rather than a\n column. Semibold here is state emphasis, not a type role. */\n .v-calendar-head-day[data-today] .v-calendar-head-number {\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 .v-calendar-allday-label {\n display: flex;\n align-items: start;\n justify-content: end;\n padding-block-start: var(--vectis-space-1);\n padding-inline-end: var(--vectis-space-2);\n border-block-start: 1px solid var(--vectis-color-border);\n border-inline-end: 1px solid var(--vectis-color-border);\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n }\n\n .v-calendar-allday {\n /*\n * The band's two axes are DISCRETE — a day, and a row — where the time grid's vertical\n * axis is continuous. That is why the bars are placed with real grid lines here and\n * with fractions there: forcing one mechanism onto both would cost a translation in\n * each direction and buy nothing.\n */\n display: grid;\n grid-column: 2 / -1;\n grid-template-columns: repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n grid-template-rows: repeat(\n var(--calendar-lanes),\n var(--vectis-control-size-calendar-allday-lane)\n );\n gap: 1px;\n overflow-y: auto;\n max-block-size: var(--vectis-control-size-calendar-allday-max);\n padding-block: var(--vectis-space-1);\n /*\n * No inline padding, deliberately. The band's tracks have to line up with the canvas's\n * exactly, because dragging a bar reads the pointer against the CANVAS geometry — the two\n * boxes span the same grid columns, so one measurement serves both. A few pixels of\n * padding here would put the last column out by that much, and a bar dropped on the right\n * edge would land a day early.\n */\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-bar {\n grid-column: calc(var(--event-day) + 1) / span var(--event-span);\n grid-row: calc(var(--event-lane) + 1);\n min-inline-size: 0;\n }\n\n .v-calendar-hours {\n display: grid;\n grid-auto-rows: var(--calendar-hour);\n border-inline-end: 1px solid var(--vectis-color-border);\n }\n\n /*\n * The label names the hour its row BEGINS at, and it is drawn ON that rule rather than\n * under it: `align-self: start` shrinks the span from its 4rem row down to its one line,\n * and the negative margin then straddles it across the rule above.\n */\n .v-calendar-hour {\n position: relative;\n align-self: start;\n margin-block-start: calc(-1 * var(--calendar-hour-lift));\n padding-inline-end: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-align: end;\n }\n\n /* The rule carried a little way back into the gutter, so the eye joins the label to the\n line it names. A border and not a background: Windows forced-colors flattens a\n background to Canvas and the tick would vanish, where a border keeps a colour — the\n argument VSeparator and the icon registry both make. */\n .v-calendar-hour::before {\n content: '';\n position: absolute;\n inset-block-start: var(--calendar-hour-lift);\n inset-inline-end: 0;\n inline-size: var(--vectis-control-size-calendar-tick);\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n /*\n * The first hour has no rule of its own: the sticky header already draws a border along\n * that edge, and a second one under it reads as a thick smudge. Its label goes with it,\n * since half of it would sit above the top of the canvas anyway — the cost you accepted,\n * paid in one label a reader can work out from the one below.\n *\n * `visibility` carries the tick away too, being inherited, so the pseudo-element needs no\n * rule of its own here.\n *\n * TRAP — HIDDEN and not removed. The span has to go on occupying its grid row: `display:\n * none` would take the row with it and shift every hour below up by one.\n */\n .v-calendar-hour:first-child {\n visibility: hidden;\n }\n\n .v-calendar-row:first-child .v-calendar-cell {\n border-block-start: none;\n }\n\n .v-calendar-columns {\n /* The containing block every card is placed against. The rows below are `display:\n contents`, so the cells themselves are this grid's items. */\n position: relative;\n display: grid;\n grid-column: 2 / -1;\n /*\n * The same track recipe as the canvas above, deliberately restated rather than borrowed\n * with `subgrid`. This box spans exactly the canvas columns it repeats, and both sides\n * divide the same width by the same rule, so the two resolve identically — which makes\n * subgrid a second mechanism buying nothing, the conclusion the library's own audit of\n * it reached.\n */\n grid-template-columns: repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n grid-auto-rows: var(--calendar-hour);\n }\n\n /*\n * The strip that lights up when a drag is resting against an edge, counting down to turn\n * the page. It is what stops the paging being a surprise.\n *\n * Drawn INSIDE the columns box rather than on the scroller, because a scroller's absolutely\n * positioned child is placed against its content and scrolls away with it — here the box is\n * as tall as the whole day, so the strip is visible wherever the reader happens to be. An\n * absolutely positioned pseudo-element is not a grid item, so it disturbs no column.\n *\n * Its width is `--vectis-control-size-calendar-edge`, whose twin is `EDGE_BAND` in\n * `edgeStep.ts` — the JavaScript that decides where the countdown actually starts. Neither\n * may move without the other.\n */\n .v-calendar-columns[data-edge]::after {\n content: '';\n position: absolute;\n inset-block: 0;\n inline-size: var(--vectis-control-size-calendar-edge);\n background: var(--vectis-color-accent-surface);\n z-index: 2;\n pointer-events: none;\n }\n\n .v-calendar-columns[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-columns[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n .v-calendar-row {\n /* The row exists for the accessibility tree and must not exist for the layout: a real\n box here would make the cells its children instead of the grid's, and every column\n would collapse. */\n display: contents;\n }\n\n .v-calendar-cell {\n border-block-start: 1px solid var(--vectis-color-border);\n border-inline-start: 1px solid var(--vectis-color-border);\n cursor: pointer;\n }\n\n .v-calendar-cell:first-child {\n border-inline-start: none;\n }\n\n .v-calendar-cell:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n /* Drawn inwards: the grid is a scrolling box, and an outward ring on a cell at the edge\n would be cropped by it. */\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-calendar-cell[data-today] {\n background: var(--vectis-color-accent-surface);\n }\n\n /*\n * A card is positioned against the whole columns box, not against its cell — which is why\n * the horizontal formula carries the day index. Being a child of the cell is what keeps\n * it in the accessibility tree in the right place; being placed against the grid is what\n * lets it be any length at all.\n */\n /*\n * TRAP — the height is the event's own length and NOTHING ELSE. There used to be a `max()`\n * against a floor token here, and it is what made a quarter of an hour spill over the slot\n * below it.\n *\n * The floor it was providing is already applied where it belongs: `timedSegments` stretches\n * every segment to at least `slotDuration` BEFORE the overlap packing sees it, so what is\n * drawn and what the packing believes are the same box. A second floor in CSS could only\n * ever disagree with the first — the packing cannot see a stylesheet — which is exactly how\n * two cards came to be laid out side by side and then drawn on top of each other.\n *\n * So a card is never taller than its slot, whatever `slotDuration` is set to. Making the\n * text fit inside a slot that short is the stylesheet's problem, and VCalendarEvent solves\n * it by asking how tall the card actually came out.\n */\n .v-calendar-block {\n position: absolute;\n inset-block-start: calc(var(--event-start) * 100%);\n block-size: calc((var(--event-end) - var(--event-start)) * 100%);\n inset-inline-start: calc(\n (var(--event-day) + var(--event-column) / var(--event-columns)) / var(--calendar-columns) *\n 100%\n );\n inline-size: calc(\n var(--event-span) / var(--event-columns) / var(--calendar-columns) * 100% - 2px\n );\n z-index: 1;\n }\n\n /*\n * The current-time line, placed the same way a card is — against the whole columns box,\n * so its formula carries the day index too. It is `aria-hidden`: it is a second rendering\n * of something the cell labels and the day marked as today already say, and announcing\n * \"current time\" from the middle of a grid would interrupt without informing.\n */\n .v-calendar-now {\n position: absolute;\n inset-block-start: calc(var(--calendar-now) * 100%);\n inset-inline-start: calc(var(--event-day) / var(--calendar-columns) * 100%);\n inline-size: calc(100% / var(--calendar-columns));\n border-block-start: 1px solid var(--vectis-color-danger);\n /* Above the cards: it is the one thing that must stay readable over a full day. */\n z-index: 2;\n pointer-events: none;\n }\n\n .v-calendar-now::before {\n content: '';\n position: absolute;\n inset-inline-start: 0;\n inline-size: var(--vectis-control-size-calendar-now-dot);\n block-size: var(--vectis-control-size-calendar-now-dot);\n /* Half its own size upwards and backwards, so the dot is centred ON the line's start\n rather than hanging below it. */\n margin-block-start: calc(var(--vectis-control-size-calendar-now-dot) / -2);\n margin-inline-start: calc(var(--vectis-control-size-calendar-now-dot) / -2);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-danger);\n }\n}\n</style>\n"],"mappings":""}