vectis-ui 0.14.0 → 0.15.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 (375) hide show
  1. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  2. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  4. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/VAccordion/context.js.map +1 -1
  6. package/dist/components/VAlert/VAlert.js.map +1 -1
  7. package/dist/components/VAlert/VAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  8. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  9. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  11. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/VAvatar/context.js.map +1 -1
  13. package/dist/components/VBadge/VBadge.js.map +1 -1
  14. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  15. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  16. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  17. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/dist/components/VButton/VButton.js.map +1 -1
  19. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  20. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  21. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/VButton/context.js.map +1 -1
  23. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  24. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  26. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  28. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +5 -17
  29. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  31. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +19 -31
  32. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  34. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/VCalendar/color.js.map +1 -1
  36. package/dist/components/VCalendar/edgeStep.js +1 -5
  37. package/dist/components/VCalendar/edgeStep.js.map +1 -1
  38. package/dist/components/VCalendar/gesture.js +4 -12
  39. package/dist/components/VCalendar/gesture.js.map +1 -1
  40. package/dist/components/VCalendar/keyboard.js.map +1 -1
  41. package/dist/components/VCalendar/layout.js +8 -12
  42. package/dist/components/VCalendar/layout.js.map +1 -1
  43. package/dist/components/VCalendar/timeGrid.js +5 -5
  44. package/dist/components/VCalendar/timeGrid.js.map +1 -1
  45. package/dist/components/VCard/VCard.js.map +1 -1
  46. package/dist/components/VCard/VCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  48. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  50. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/VCarousel/context.js.map +1 -1
  52. package/dist/components/VCheckbox/VCheckMark.js.map +1 -1
  53. package/dist/components/VCheckbox/VCheckMark.vue_vue_type_script_setup_true_lang.js.map +1 -1
  54. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  55. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  56. package/dist/components/VChip/VChip.js.map +1 -1
  57. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/VColorInput/VColorInput.js.map +1 -1
  59. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js +62 -62
  60. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  61. package/dist/components/VColorPicker/VColorPicker.js.map +1 -1
  62. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js +1 -5
  63. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/VColorPicker/color.js.map +1 -1
  65. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  66. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +114 -122
  67. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/VCommandPalette/VCommandPalette.js.map +1 -1
  69. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js +0 -1
  70. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js.map +1 -1
  71. package/dist/components/VCommandPalette/VCommandPaletteItem.js.map +1 -1
  72. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js +1 -5
  73. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/VContextMenu/VContextMenu.js.map +1 -1
  75. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js +3 -5
  76. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  77. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  78. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +1 -5
  79. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  81. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +35 -35
  82. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/components/VDateInput/mask.js.map +1 -1
  84. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  85. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +2 -1
  86. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  87. package/dist/components/VDatePicker/keyboard.js.map +1 -1
  88. package/dist/components/VDatePicker/names.js.map +1 -1
  89. package/dist/components/VDialog/VDialog.js.map +1 -1
  90. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  92. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/VDrawer/VDrawer.js.map +1 -1
  94. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/VEmptyState/VEmptyState.js.map +1 -1
  96. package/dist/components/VEmptyState/VEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/components/VField/VField.js.map +1 -1
  98. package/dist/components/VField/VField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/VField/VFieldAnnouncer.js.map +1 -1
  100. package/dist/components/VField/VFieldAnnouncer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/VField/VFieldMessage.js.map +1 -1
  102. package/dist/components/VField/VFieldMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  103. package/dist/components/VFieldset/VFieldset.js.map +1 -1
  104. package/dist/components/VFieldset/VFieldset.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  106. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +85 -85
  107. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/VFileInput/truncate.js.map +1 -1
  109. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  110. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  111. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  113. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  114. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/VHotkeys/platform.js +1 -1
  116. package/dist/components/VHotkeys/platform.js.map +1 -1
  117. package/dist/components/VHoverCard/VHoverCard.js.map +1 -1
  118. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js +2 -12
  119. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/VIcon/VIcon.js.map +1 -1
  121. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VIcon/iconProps.js.map +1 -1
  123. package/dist/components/VIcon/icons/add.js.map +1 -1
  124. package/dist/components/VIcon/icons/arrow_downward.js.map +1 -1
  125. package/dist/components/VIcon/icons/arrow_downward_alt.js.map +1 -1
  126. package/dist/components/VIcon/icons/arrow_drop_down.js.map +1 -1
  127. package/dist/components/VIcon/icons/arrow_drop_up.js.map +1 -1
  128. package/dist/components/VIcon/icons/arrow_left_alt.js.map +1 -1
  129. package/dist/components/VIcon/icons/arrow_right_alt.js.map +1 -1
  130. package/dist/components/VIcon/icons/arrow_upward.js.map +1 -1
  131. package/dist/components/VIcon/icons/arrow_upward_alt.js.map +1 -1
  132. package/dist/components/VIcon/icons/attach_file.js.map +1 -1
  133. package/dist/components/VIcon/icons/audio_file.js.map +1 -1
  134. package/dist/components/VIcon/icons/calendar_today.js.map +1 -1
  135. package/dist/components/VIcon/icons/check.js.map +1 -1
  136. package/dist/components/VIcon/icons/check_circle.js.map +1 -1
  137. package/dist/components/VIcon/icons/chevron_left.js.map +1 -1
  138. package/dist/components/VIcon/icons/chevron_right.js.map +1 -1
  139. package/dist/components/VIcon/icons/close.js.map +1 -1
  140. package/dist/components/VIcon/icons/cloud_upload.js.map +1 -1
  141. package/dist/components/VIcon/icons/code.js.map +1 -1
  142. package/dist/components/VIcon/icons/colorize.js.map +1 -1
  143. package/dist/components/VIcon/icons/description.js.map +1 -1
  144. package/dist/components/VIcon/icons/error.js.map +1 -1
  145. package/dist/components/VIcon/icons/expand_less.js.map +1 -1
  146. package/dist/components/VIcon/icons/expand_more.js.map +1 -1
  147. package/dist/components/VIcon/icons/first_page.js.map +1 -1
  148. package/dist/components/VIcon/icons/folder_zip.js.map +1 -1
  149. package/dist/components/VIcon/icons/image.js.map +1 -1
  150. package/dist/components/VIcon/icons/inbox.js.map +1 -1
  151. package/dist/components/VIcon/icons/index.js.map +1 -1
  152. package/dist/components/VIcon/icons/info.js.map +1 -1
  153. package/dist/components/VIcon/icons/last_page.js.map +1 -1
  154. package/dist/components/VIcon/icons/more_horiz.js.map +1 -1
  155. package/dist/components/VIcon/icons/names.js.map +1 -1
  156. package/dist/components/VIcon/icons/notifications.js.map +1 -1
  157. package/dist/components/VIcon/icons/open_in_new.js.map +1 -1
  158. package/dist/components/VIcon/icons/picture_as_pdf.js.map +1 -1
  159. package/dist/components/VIcon/icons/priority_high.js.map +1 -1
  160. package/dist/components/VIcon/icons/remove.js.map +1 -1
  161. package/dist/components/VIcon/icons/schedule.js.map +1 -1
  162. package/dist/components/VIcon/icons/search.js.map +1 -1
  163. package/dist/components/VIcon/icons/search_off.js.map +1 -1
  164. package/dist/components/VIcon/icons/star.js.map +1 -1
  165. package/dist/components/VIcon/icons/swap_vert.js.map +1 -1
  166. package/dist/components/VIcon/icons/table_chart.js.map +1 -1
  167. package/dist/components/VIcon/icons/video_file.js.map +1 -1
  168. package/dist/components/VIcon/icons/viewBox.js.map +1 -1
  169. package/dist/components/VIcon/icons/warning.js.map +1 -1
  170. package/dist/components/VIcon/resolver.js.map +1 -1
  171. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  172. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  173. package/dist/components/VInput/VInput.js.map +1 -1
  174. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +20 -20
  175. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  176. package/dist/components/VInput/VInputGroup.js.map +1 -1
  177. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  178. package/dist/components/VInput/context.js.map +1 -1
  179. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  180. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +2 -8
  181. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  182. package/dist/components/VLink/VLink.js.map +1 -1
  183. package/dist/components/VLink/VLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  184. package/dist/components/VListbox/VListboxChevron.js.map +1 -1
  185. package/dist/components/VListbox/VListboxChevron.vue_vue_type_script_setup_true_lang.js.map +1 -1
  186. package/dist/components/VListbox/VListboxGroup.js.map +1 -1
  187. package/dist/components/VListbox/VListboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  188. package/dist/components/VListbox/VListboxOption.js.map +1 -1
  189. package/dist/components/VListbox/VListboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  190. package/dist/components/VListbox/VListboxPanel.js.map +1 -1
  191. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  192. package/dist/components/VListbox/VListboxSeparator.js.map +1 -1
  193. package/dist/components/VListbox/VListboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  194. package/dist/components/VListbox/VListboxValues.js.map +1 -1
  195. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js.map +1 -1
  196. package/dist/components/VMenu/VMenu.js.map +1 -1
  197. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  199. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  200. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  201. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +6 -12
  202. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  204. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +9 -10
  205. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  206. package/dist/components/VMenu/VMenuSeparator.js.map +1 -1
  207. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  208. package/dist/components/VMenu/context.js.map +1 -1
  209. package/dist/components/VMeter/VMeter.js.map +1 -1
  210. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/components/VNumberInput/VNumberInput.js.map +1 -1
  212. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js +86 -85
  213. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/components/VNumberInput/number.js.map +1 -1
  215. package/dist/components/VPagination/VPagination.js.map +1 -1
  216. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  217. package/dist/components/VPopover/VPopover.js.map +1 -1
  218. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  219. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  220. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  221. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  222. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/components/VRadio/VRadio.js.map +1 -1
  224. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  225. package/dist/components/VRating/VRating.js.map +1 -1
  226. package/dist/components/VRating/VRating.vue_vue_type_script_setup_true_lang.js.map +1 -1
  227. package/dist/components/VResizable/VResizable.js.map +1 -1
  228. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js +8 -6
  229. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  230. package/dist/components/VResizable/VResizablePanel.js.map +1 -1
  231. package/dist/components/VResizable/VResizablePanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  232. package/dist/components/VResizable/context.js.map +1 -1
  233. package/dist/components/VResizable/layout.js.map +1 -1
  234. package/dist/components/VSelect/VSelect.js.map +1 -1
  235. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js +124 -125
  236. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  237. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  238. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  239. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  240. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +1 -1
  241. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  242. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  243. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  245. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +1 -5
  246. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  247. package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -1
  248. package/dist/components/VSideNavigation/context.js.map +1 -1
  249. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  250. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  251. package/dist/components/VSlider/VSlider.js.map +1 -1
  252. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +22 -22
  253. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  254. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  255. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  256. package/dist/components/VSnackbar/state.js.map +1 -1
  257. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  258. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  259. package/dist/components/VSplitButton/VSplitButton.js.map +1 -1
  260. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  261. package/dist/components/VStepper/VStepper.js.map +1 -1
  262. package/dist/components/VStepper/VStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  263. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  264. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  265. package/dist/components/VTabs/VTab.js.map +1 -1
  266. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  267. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  268. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  269. package/dist/components/VTabs/VTabs.js.map +1 -1
  270. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  271. package/dist/components/VTabs/context.js.map +1 -1
  272. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  273. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  274. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  275. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +45 -45
  276. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  277. package/dist/components/VTimeInput/search.js.map +1 -1
  278. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  279. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +9 -9
  280. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  281. package/dist/components/VTimePicker/limits.js.map +1 -1
  282. package/dist/components/VTimeline/VTimeline.js.map +1 -1
  283. package/dist/components/VTimeline/VTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -1
  284. package/dist/components/VTimeline/VTimelineItem.js.map +1 -1
  285. package/dist/components/VTimeline/VTimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  286. package/dist/components/VTimeline/context.js.map +1 -1
  287. package/dist/components/VTimeline/datetime.js.map +1 -1
  288. package/dist/components/VToast/VToast.js.map +1 -1
  289. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  290. package/dist/components/VToast/VToaster.js.map +1 -1
  291. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +1 -1
  292. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  293. package/dist/components/VToast/state.js.map +1 -1
  294. package/dist/components/VToggle/VToggle.js.map +1 -1
  295. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +1 -7
  296. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  297. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  298. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  299. package/dist/components/VToggle/context.js.map +1 -1
  300. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  301. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  302. package/dist/components/VTreeView/VTreeView.js.map +1 -1
  303. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js +1 -5
  304. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  305. package/dist/components/VTypography/VTypography.js.map +1 -1
  306. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  307. package/dist/components/VVirtualList/VVirtualList.js.map +1 -1
  308. package/dist/components/VVirtualList/VVirtualList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  309. package/dist/composables/useAriaLabel.js.map +1 -1
  310. package/dist/composables/useChoice.js.map +1 -1
  311. package/dist/composables/useClearable.js.map +1 -1
  312. package/dist/composables/useControlShape.js.map +1 -1
  313. package/dist/composables/useDebouncedSearch.js.map +1 -1
  314. package/dist/composables/useDetailsOpen.js.map +1 -1
  315. package/dist/composables/useEscapeDismiss.js.map +1 -1
  316. package/dist/composables/useFieldIds.js.map +1 -1
  317. package/dist/composables/useFieldPanel.js +3 -7
  318. package/dist/composables/useFieldPanel.js.map +1 -1
  319. package/dist/composables/useFileDrop.js.map +1 -1
  320. package/dist/composables/useFileField.js +2 -2
  321. package/dist/composables/useFileField.js.map +1 -1
  322. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  323. package/dist/composables/useHotkeyListener.js.map +1 -1
  324. package/dist/composables/useIconClickHandlers.js.map +1 -1
  325. package/dist/composables/useInertLink.js.map +1 -1
  326. package/dist/composables/useInfiniteScroll.js +2 -2
  327. package/dist/composables/useInfiniteScroll.js.map +1 -1
  328. package/dist/composables/useListbox.js +3 -9
  329. package/dist/composables/useListbox.js.map +1 -1
  330. package/dist/composables/useLiveAnnouncer.js.map +1 -1
  331. package/dist/composables/useMaskedField.js +28 -48
  332. package/dist/composables/useMaskedField.js.map +1 -1
  333. package/dist/composables/useModalDialog.js +1 -1
  334. package/dist/composables/useModalDialog.js.map +1 -1
  335. package/dist/composables/usePopover.js +1 -1
  336. package/dist/composables/usePopover.js.map +1 -1
  337. package/dist/composables/useProgressValue.js.map +1 -1
  338. package/dist/composables/useRootAttrs.js.map +1 -1
  339. package/dist/composables/useSlotNodes.js.map +1 -1
  340. package/dist/composables/useTextLimit.js.map +1 -1
  341. package/dist/composables/useTimer.js.map +1 -1
  342. package/dist/composables/useTypeahead.js.map +1 -1
  343. package/dist/composables/useVirtualList.js.map +1 -1
  344. package/dist/i18n/en.js.map +1 -1
  345. package/dist/i18n/fr.js.map +1 -1
  346. package/dist/i18n/state.js.map +1 -1
  347. package/dist/tokens/css.js.map +1 -1
  348. package/dist/tokens/index.js.map +1 -1
  349. package/dist/tokens/primitives.js.map +1 -1
  350. package/dist/tokens/semantic.js.map +1 -1
  351. package/dist/tokens/themes/dark.js.map +1 -1
  352. package/dist/tokens/types.js.map +1 -1
  353. package/dist/utils/array.js.map +1 -1
  354. package/dist/utils/arrowNav.js.map +1 -1
  355. package/dist/utils/attrs.js.map +1 -1
  356. package/dist/utils/chip.js.map +1 -1
  357. package/dist/utils/clock.js +3 -1
  358. package/dist/utils/clock.js.map +1 -1
  359. package/dist/utils/css.js +1 -1
  360. package/dist/utils/css.js.map +1 -1
  361. package/dist/utils/date.js.map +1 -1
  362. package/dist/utils/direction.js.map +1 -1
  363. package/dist/utils/env.js.map +1 -1
  364. package/dist/utils/file.js +13 -31
  365. package/dist/utils/file.js.map +1 -1
  366. package/dist/utils/focus.js.map +1 -1
  367. package/dist/utils/hostWarns.js.map +1 -1
  368. package/dist/utils/ids.js.map +1 -1
  369. package/dist/utils/matcher.js.map +1 -1
  370. package/dist/utils/memo.js.map +1 -1
  371. package/dist/utils/number.js.map +1 -1
  372. package/dist/utils/text.js.map +1 -1
  373. package/dist/utils/time.js.map +1 -1
  374. package/dist/utils/vnode.js.map +1 -1
  375. package/package.json +19 -19
@@ -1 +1 @@
1
- {"version":3,"file":"VCalendar.js","names":[],"sources":["../../../src/components/VCalendar/VCalendar.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @ssr @core\n/**\n * Calendar layout is pure; JavaScript supplies grid navigation, editing gestures and\n * announcements because HTML has no native agenda widget. Editing forms remain consumer-owned.\n */\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { arrow_drop_down as arrowDropDownIcon } from '../VIcon/icons/arrow_drop_down'\nimport { chevron_left as chevronLeftIcon } from '../VIcon/icons/chevron_left'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useLiveAnnouncer } from '../../composables/useLiveAnnouncer'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTimer } from '../../composables/useTimer'\nimport { firstDayOfWeekFor, formatDateDisplay, formatDisplayRange } from '../../utils/date'\nimport { hourCycleFor, minutesOf } from '../../utils/time'\n\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\nimport VCalendarMonth from './VCalendarMonth.vue'\nimport VCalendarTimeGrid, { type FocusedCell } from './VCalendarTimeGrid.vue'\nimport VCalendarYear from './VCalendarYear.vue'\nimport { EDGE_STEP_DELAY } from './edgeStep'\nimport {\n monthWeeks,\n monthsOfYear,\n normalizeWeekdays,\n stepAnchor,\n sameTimes,\n timeOf,\n timesOf,\n todayISO,\n visibleDays,\n visibleRange,\n windowOf,\n} from './layout'\nimport type {\n ActivatedCell,\n CalendarCell,\n CalendarEvent,\n CalendarEventId,\n CalendarEventSlotProps,\n CalendarEventTimes,\n CalendarFormat,\n CalendarVariant,\n CalendarView,\n} from './types'\n\nexport interface CalendarProps {\n /**\n * How the view is framed: nothing at all (`flat`), or rounded corners set off by a border on\n * the page surface (`outline`, the default), a shadow over a raised surface (`elevated`), or\n * a muted fill (`filled`). The toolbar stays outside the frame.\n */\n variant?: CalendarVariant\n /**\n * Which views the menu offers, in the order it lists them. Narrowing it is how a\n * calendar that only ever shows weeks stops offering anything else.\n */\n views?: CalendarView[]\n /** How many days the custom view shows, and how far Previous and Next step in it. */\n customDays?: number\n /**\n * Which weekdays are on show, as numbers from 0 for Sunday. The ORDER matters as well: the\n * first entry is the day a week starts on, and it wins over `firstDayOfWeek`.\n */\n weekdays?: number[]\n /**\n * The day a week starts on, from 0 for Sunday, when `weekdays` is not given. Left out,\n * the locale decides.\n */\n firstDayOfWeek?: number\n /** The language the days, months and times are written in. Falls back to the global one. */\n locale?: string\n /**\n * Whether times are shown on a twelve or twenty-four hour clock. Left out, the reader's\n * language decides. It is the same prop, under the same name, as VTimePicker's.\n */\n format?: CalendarFormat\n /** The hour the grid starts at, from 0. */\n dayStart?: number\n /** The hour it ends at, up to 24. */\n dayEnd?: number\n /**\n * The step everything snaps to, in minutes: how far a nudge moves an event, and the unit a\n * slot is drawn out in.\n */\n slotDuration?: number\n /** Where the grid is scrolled to when it first appears, so the working day is in view. */\n scrollTime?: string\n /**\n * Leaves out the line drawn across today's column at the time it is now, and the dot on\n * its leading edge. Left in, it ticks once a minute while the calendar is on screen.\n */\n hideCurrentTime?: boolean\n /** How many events a day of the month view shows before it starts counting the rest. */\n monthEventLimit?: number\n /**\n * Stops events being moved and stretched, by dragging or with the keyboard. They\n * stay readable and clickable, and nothing else.\n */\n readonly?: boolean\n /**\n * Freezes the whole calendar: nothing can be moved, created or opened, no other period can be\n * reached, and everything greys out through the colour tokens. That is what separates this\n * from `readonly`, where only the editing stops.\n */\n disabled?: boolean\n /**\n * Lets an empty stretch of a time grid be drawn out with the pointer, up or down from the\n * slot pressed.\n */\n creatable?: boolean\n /**\n * How long a dragged event has to rest against the side of the calendar before the view turns\n * to the previous or next period, in milliseconds.\n */\n edgeStepDelay?: number\n /** Stops dragging near the top or bottom of a time grid from scrolling it. */\n noEdgeScroll?: boolean\n /** What the calendar is called, for anyone who cannot see it. */\n label?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n variant: 'outline',\n views: () => ['day', '4days', 'week'],\n customDays: 4,\n weekdays: undefined,\n firstDayOfWeek: undefined,\n locale: undefined,\n format: undefined,\n dayStart: 0,\n dayEnd: 24,\n slotDuration: 15,\n scrollTime: '08:00',\n hideCurrentTime: false,\n monthEventLimit: 3,\n readonly: false,\n disabled: false,\n creatable: false,\n edgeStepDelay: EDGE_STEP_DELAY,\n noEdgeScroll: false,\n label: undefined,\n})\n\n/*\n * The wrapper-root pattern: the consumer's class and style stay on the outer box, and\n * everything else; their `id`, their `aria-*`; goes on the region, which is the part that\n * carries the role and is therefore the part they mean.\n */\ndefineOptions({ inheritAttrs: false })\n\n/** Which span the calendar is showing. It opens on the week. */\nconst view = defineModel<CalendarView>('view', { default: 'week' })\n\n// @ssr\n/*\n * Today's date, which marks a single column, is a different matter and is read below in\n * `onMounted` where the server cannot see it at all.\n */\n/**\n * The day the calendar is anchored on, as `YYYY-MM-DD`: the view shows the week, month or\n * year holding it. It opens on today.\n */\nconst date = defineModel<string>('date', { default: () => todayISO() })\n/** What is on the calendar, empty to begin with. */\nconst events = defineModel<E[]>('events', { default: () => [] })\n\nconst emit = defineEmits<{\n /** A card was clicked or activated: the cue to open an editor of your own. */\n 'event-activate': [event: E]\n /**\n * An empty part of the grid was activated, at this day and this time. A day of the month\n * view has no hour of its own, and reports the one the time grids start at.\n */\n 'cell-activate': [cell: CalendarCell]\n /** An event was dragged or nudged somewhere else. */\n 'event-move': [event: E, previous: CalendarEventTimes]\n /** An event's end was dragged or nudged, in the same two parts. */\n 'event-resize': [event: E, previous: CalendarEventTimes]\n /**\n * An empty stretch of a day was drawn out, and these are its times. Nothing has been added\n * to `events`: this is the cue to make the event, in your own model or through your own form.\n */\n 'event-create': [times: CalendarEventTimes]\n}>()\n\ndefineSlots<{\n /** Extra controls in the toolbar, between the range and the view menu. */\n actions?(): unknown\n /** The content of one event's card, replacing the title and times. */\n event?(props: CalendarEventSlotProps<E>): unknown\n /** The head of one day column, replacing the weekday and the number. */\n 'day-header'?(props: { iso: string; weekday: string; dayText: string; today: boolean }): unknown\n /** The label beside the band of all-day events. */\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed(() => props.format ?? hourCycleFor(resolvedLocale.value))\nconst resolvedWeekdays = computed(() =>\n normalizeWeekdays(\n props.weekdays,\n props.firstDayOfWeek ?? firstDayOfWeekFor(resolvedLocale.value),\n ),\n)\n\nconst timeWindow = computed(() => windowOf(props.dayStart, props.dayEnd))\n\nconst days = computed(() =>\n visibleDays(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/** Which view is a time grid, and which is a summary. Several things below turn on this. */\nconst isTimeGrid = computed(() => view.value !== 'month' && view.value !== 'year')\n\nconst weeks = computed(() =>\n view.value === 'month' ? monthWeeks(date.value, resolvedWeekdays.value) : [],\n)\n\nconst months = computed(() => (view.value === 'year' ? monthsOfYear(date.value) : []))\n\n// @ssr\n// Way to tell either where the reader is, and rendering a guess would make the two markups\n// differ. Both stay null until then, and every rule that draws them is written to expect it.\nconst today = ref<string | null>(null)\nconst now = ref<number | null>(null)\n\nconst clock = useTimer()\n\n/**\n * The floor on the delay is not a nicety. `useTimer` runs a delay of zero or less\n * synchronously, by design, so a tick that ever computed one would call itself straight back\n * and go on doing so until the stack gave out.\n */\nfunction tick() {\n const at = new Date()\n now.value = at.getHours() * 60 + at.getMinutes()\n clock.start(tick, Math.max(1000, (60 - at.getSeconds()) * 1000))\n}\n\n/** Scrolls the time grid on show to `scrollTime`. */\nfunction scrollToStart() {\n const at = minutesOf(props.scrollTime)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n}\n\nonMounted(() => {\n today.value = todayISO()\n if (!props.hideCurrentTime) tick()\n scrollToStart()\n})\n\n// @core\n// Watch the visibility prop so toggling the current-time line starts or stops its timer after\n// mount.\nwatch(\n () => props.hideCurrentTime,\n (hidden) => {\n if (!hidden) return tick()\n clock.cancel()\n now.value = null\n },\n)\n\n/**\n * The usual form does not work here and the error it gives says nothing useful about why. A\n * generic `<script setup>` compiles to a FUNCTION, not to a class, so it has no construct\n * signature for `InstanceType` to read: the message complains that the component \"provides no\n * match for the signature `new (...args: any)`\", pointing at the template.\n */\nconst gridRef = ref<{\n focus(options?: FocusOptions): void\n scrollToMinutes(minutes: number): void\n} | null>(null)\n\n// @core\n// A time grid that appears after mount, a month switched to a week, opens at `scrollTime`\n// too. Post-flush, so the new grid is rendered and measurable when it is asked to scroll.\nwatch(gridRef, scrollToStart, { flush: 'post' })\n\n/** The region, the element a consumer's attributes land on. */\nconst regionEl = ref<HTMLElement | null>(null)\n\n/*\n * Which cell holds the tab stop, kept as two refs because the two kinds of view mean different\n * things by it: a time grid needs a day and an hour, a month only a day. One ref carrying an\n * hour the month ignores would leave that hour to go stale, and the grid would then reopen on\n * whatever the month happened to leave behind.\n */\nconst focused = ref<FocusedCell>({ iso: date.value, minutes: timeWindow.value.start })\nconst focusedDay = ref(date.value)\n\nconst range = computed(() =>\n visibleRange(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/**\n * What the toolbar says the calendar is showing. Each view names itself at the coarsest\n * granularity that still identifies it: a single day says its weekday, a year says nothing\n * but the number.\n */\nconst rangeText = computed(() => {\n const locale = resolvedLocale.value\n if (view.value === 'year')\n return formatDateDisplay(range.value.start, locale, { year: 'numeric' })\n if (view.value === 'month') {\n return formatDateDisplay(range.value.start, locale, { month: 'long', year: 'numeric' })\n }\n if (view.value === 'day') {\n return formatDateDisplay(range.value.start, locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n }\n return formatDisplayRange(range.value.start, range.value.end, locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n})\n\nconst viewLabel = (value: CalendarView) => {\n const words = m.value.calendar\n if (value === 'day') return words.viewDay\n if (value === '4days') return words.view4Days\n if (value === 'week') return words.viewWeek\n if (value === 'month') return words.viewMonth\n if (value === 'year') return words.viewYear\n return words.viewCustom(props.customDays)\n}\n\n/** What the two navigation buttons are called. */\nconst stepLabels = computed(() => {\n const words = m.value.calendar\n if (view.value === 'day') return { previous: words.previousDay, next: words.nextDay }\n if (view.value === 'week') return { previous: words.previousWeek, next: words.nextWeek }\n if (view.value === 'month') return { previous: words.previousMonth, next: words.nextMonth }\n if (view.value === 'year') return { previous: words.previousYear, next: words.nextYear }\n return { previous: words.previousPeriod, next: words.nextPeriod }\n})\n\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.calendar.label)\n\n/*\n * The four ways of reaching another period all pass through here, and `disabled` is refused in\n * every one of them rather than on the controls alone: the edge step pages the view from a\n * drag, and the year grid opens a month from a cell, neither of which is a button this\n * component disabled. It is the VDatePicker arrangement, where the guard sits on `goTo`.\n */\nfunction step(delta: -1 | 1) {\n if (props.disabled) return\n date.value = stepAnchor(date.value, view.value, delta, resolvedWeekdays.value, props.customDays)\n}\n\nfunction goToToday() {\n if (props.disabled) return\n date.value = todayISO()\n}\n\nfunction setView(value: CalendarView) {\n if (props.disabled) return\n view.value = value\n}\n\n/**\n * `disabled` is refused here, and not by the stylesheet's `pointer-events: none` alone. That\n * rule stops a click, but the grid keeps its tab stop so the agenda stays readable, and Enter\n * on a focused cell reaches this with nothing in its way; a frozen calendar would go on\n * reporting cells to a consumer's form.\n */\nfunction onCellActivate(cell: ActivatedCell) {\n if (props.disabled) return\n emit('cell-activate', {\n date: cell.date,\n time: timeOf(cell.minutes ?? timeWindow.value.start),\n })\n}\n\n/**\n * Drill into an allowed detail view; if views excludes it, update the date while preserving the\n * current view.\n */\nfunction openIn(iso: string, target: CalendarView) {\n if (props.disabled) return\n date.value = iso\n if (props.views.includes(target)) view.value = target\n}\n\n/**\n * What a reader who cannot see the grid is told: the range after every step of a move, and\n * whether the move was taken or given up.\n */\nconst { polite: announcement, announce: say } = useLiveAnnouncer()\nconst uid = useId()\nconst hintId = `${uid}-hint`\n\n/*\n * Through the shared announcer, which empties the region and writes on the next tick: the\n * same words twice in a row are no change to a live region, and would not be read again.\n */\nfunction announce(message: string) {\n say(message, false)\n}\n\n/** Writes one event's new times into the model and says what happened. */\nfunction onEventDrop(id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize') {\n const current = events.value.find((item) => item.id === id)\n if (!current) return\n\n const previous = timesOf(current)\n // A gesture that ends where it began moved nothing, and a consumer's undo stack must not\n // gain an entry for it, nor its watchers a new array.\n if (sameTimes(previous, times)) return\n const next = { ...current, ...times }\n events.value = events.value.map((item) => (item.id === id ? next : item))\n // Written out rather than picking the name with a conditional: the emit signatures are an\n // overload set, and TypeScript resolves one only against a literal.\n if (kind === 'resize') emit('event-resize', next, previous)\n else emit('event-move', next, previous)\n}\n\n/*\n * A drawn slot is REPORTED and never added. What an event is called, what else it carries and\n * whether it exists at all are the consumer's decisions, so the calendar hands over the times\n * and draws nothing once the pointer is let go.\n */\nfunction onSlotCreate(times: CalendarEventTimes) {\n emit('event-create', times)\n}\n\ndefineExpose({\n /**\n * Brings the focus into the view: the cell the grid is showing, or the first month heading\n * in the year view.\n */\n focus: (options?: FocusOptions) => gridRef.value?.focus(options),\n /** The region, which is where your `id` and `aria-*` attributes land. */\n el: regionEl,\n /** Goes back to the current day, exactly as the Today button does. */\n today: goToToday,\n /** Moves back one view (a week, a month or a year), exactly as the toolbar's arrow does. */\n previous: () => step(-1),\n /** Moves forward one view. */\n next: () => step(1),\n /** Scrolls the grid so a given `HH:mm` sits at the top of the visible area. */\n scrollTo: (time: string) => {\n const at = minutesOf(time)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-calendar\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-variant=\"variant\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <section\n ref=\"regionEl\"\n :aria-roledescription=\"m.calendar.roleDescription\"\n v-bind=\"forwardedAttrs\"\n class=\"v-calendar-region\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"v-calendar-toolbar\">\n <div class=\"v-calendar-nav\">\n <VIconButton\n :label=\"stepLabels.previous\"\n size=\"sm\"\n :disabled=\"disabled\"\n @click=\"step(-1)\"\n >\n <VIcon :name=\"chevronLeftIcon\" mirrored />\n </VIconButton>\n <VIconButton :label=\"stepLabels.next\" size=\"sm\" :disabled=\"disabled\" @click=\"step(1)\">\n <VIcon :name=\"chevronRightIcon\" mirrored />\n </VIconButton>\n </div>\n\n <VButton variant=\"outline\" tone=\"neutral\" size=\"sm\" :disabled=\"disabled\" @click=\"goToToday\">\n {{ m.calendar.today }}\n </VButton>\n\n <VTypography variant=\"heading-4\" as=\"h2\" class=\"v-calendar-title\">\n {{ rangeText }}\n </VTypography>\n\n <div class=\"v-calendar-actions\">\n <slot name=\"actions\" />\n\n <VMenu v-if=\"views.length > 1\" size=\"sm\" placement=\"bottom-end\" match-trigger>\n <template #trigger=\"{ triggerProps }\">\n <VButton\n variant=\"outline\"\n tone=\"neutral\"\n size=\"sm\"\n :disabled=\"disabled\"\n v-bind=\"triggerProps\"\n :aria-label=\"`${m.calendar.view}: ${viewLabel(view)}`\"\n >\n {{ viewLabel(view) }}\n <VIcon :name=\"arrowDropDownIcon\" />\n </VButton>\n </template>\n <VMenuItem\n v-for=\"value in views\"\n :key=\"value\"\n :label=\"viewLabel(value)\"\n :selected=\"value === view\"\n @select=\"setView(value)\"\n />\n </VMenu>\n </div>\n </div>\n\n <!--\n Invert opt-out public props once at the internal-grid boundary; internal view contracts\n use positive booleans.\n -->\n <VCalendarTimeGrid\n v-if=\"isTimeGrid\"\n ref=\"gridRef\"\n v-model:focused=\"focused\"\n class=\"v-calendar-view\"\n :days=\"days\"\n :events=\"events\"\n :time-window=\"timeWindow\"\n :slot-duration=\"slotDuration\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :now=\"hideCurrentTime ? null : now\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :creatable=\"creatable && !disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :auto-scroll=\"!noEdgeScroll\"\n :label=\"rangeText\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @slot-create=\"onSlotCreate\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['day-header']\" #day-header=\"slotProps\">\n <slot name=\"day-header\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['all-day-label']\" #all-day-label>\n <slot name=\"all-day-label\" />\n </template>\n </VCalendarTimeGrid>\n\n <VCalendarMonth\n v-else-if=\"view === 'month'\"\n ref=\"gridRef\"\n v-model:focused=\"focusedDay\"\n class=\"v-calendar-view\"\n :weeks=\"weeks\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :month-event-limit=\"monthEventLimit\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :label=\"rangeText\"\n @day-activate=\"openIn($event, 'day')\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarMonth>\n\n <VCalendarYear\n v-else\n ref=\"gridRef\"\n class=\"v-calendar-view\"\n :disabled=\"disabled\"\n :months=\"months\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :weekdays=\"resolvedWeekdays\"\n :today=\"today\"\n :label=\"rangeText\"\n @month-activate=\"openIn($event, 'month')\"\n />\n\n <!--\n Both of these are rendered from the first paint and never conditionally. The live region\n has to EXIST before it has anything to say: one inserted along with its first message is\n not announced at all.\n -->\n <div class=\"v-visually-hidden\" role=\"status\" aria-live=\"polite\">{{ announcement }}</div>\n <span :id=\"hintId\" class=\"v-visually-hidden\">{{ m.calendar.eventHint }}</span>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar {\n /*\n * The surface under the view, which its sticky headings repeat to stay opaque, and the\n * hover tint that has to stand out from it. Unframed, the page surface is the best guess at\n * what lies behind.\n */\n --calendar-surface: var(--vectis-color-surface);\n --calendar-hover-bg: var(--vectis-color-surface-muted);\n\n display: flex;\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 frozen calendar greys out through the colour tokens and never through opacity, the\n design system rule: what a reader keeps here is the agenda itself, which has to stay\n readable. The cards are real disabled buttons, so they grey themselves. */\n .v-calendar[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n .v-calendar[data-disabled] .v-calendar-view {\n pointer-events: none;\n }\n\n /*\n * `min-block-size: 0` on the grid is what lets it shrink below its content and therefore\n * scroll; without it the automatic minimum of a flex item would hold it at its full 24-hour\n * height and the whole page would scroll instead. All of it is a no-op when the parent's\n * height is auto, where the percentage falls back to auto and the calendar is simply as tall\n * as its content.\n */\n .v-calendar-region {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-inline-size: 0;\n min-block-size: 0;\n }\n\n .v-calendar-toolbar {\n display: flex;\n flex: none;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--vectis-space-2);\n padding-block-end: var(--vectis-space-3);\n }\n\n .v-calendar-nav {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-calendar-title {\n /*\n * It may be long; a full weekday and month in the day view; so it is the part that gives\n * way first, and the controls keep their size.\n */\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-2);\n /* The two siblings are pushed apart from here rather than by a `justify-content` on the\n toolbar, which would space every control equally instead of grouping them. */\n margin-inline-start: auto;\n }\n\n /*\n * The view on show, whichever it is: the one box that scrolls. The views inherit the family\n * and the colour from `.v-calendar` and declare neither again.\n */\n .v-calendar-view {\n flex: 1;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n /* Transparent rather than absent: forced colours paint it. Only `elevated` drops it, so\n that the grid's rules reach the edge its shadow draws. */\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-surface);\n }\n\n .v-calendar[data-variant='outline'] .v-calendar-view {\n background: var(--calendar-surface);\n border-color: var(--vectis-color-border);\n }\n\n .v-calendar[data-variant='elevated'] {\n --calendar-surface: var(--vectis-color-surface-raised);\n }\n\n .v-calendar[data-variant='elevated'] .v-calendar-view {\n border: none;\n background: var(--calendar-surface);\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-calendar[data-variant='filled'] {\n --calendar-surface: var(--vectis-color-surface-muted);\n --calendar-hover-bg: color-mix(\n in oklab,\n var(--vectis-color-surface-muted),\n var(--vectis-color-text) 4%\n );\n }\n\n .v-calendar[data-variant='filled'] .v-calendar-view {\n background: var(--calendar-surface);\n }\n\n /*\n * Every rule a view writes against one of these classes is either disjoint from it or more\n * specific, never tied: a tie between two sheets would be settled by the consumer's bundler.\n */\n\n /*\n * `not-allowed` is the word the library already uses for \"you cannot do this\", on every\n * disabled control. BEST-EFFORT, and never the signal: while a pointer is captured the cursor\n * is resolved against the capture target rather than against whatever sits under the pointer,\n * and engines differ on it.\n */\n .v-calendar-view[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-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 /*\n * Today's date, marked on the number the way a calendar marks a date rather than a column.\n * Semibold here marks a state, not a type role.\n */\n .v-calendar-view .v-calendar-today {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /*\n * A cell of either grid: ruled on two sides, the other two drawn by its neighbours. It keeps\n * the default cursor: the pointer hand belongs to what can be opened, the events, and a grid\n * of hands would say every square of the week is a link.\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 }\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 view 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-button {\n /* A button carries a border and a background from the browser, which around a round day\n number read as a stray ring. Neither is optional. */\n border: none;\n background: none;\n font-family: inherit;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-button: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 /*\n * Drawn INSIDE the box the cells occupy rather than on the scroller, because a scroller's\n * absolutely positioned child is placed against its content and scrolls away with it. That\n * box has to be positioned, which each view's own sheet sees to.\n */\n .v-calendar-edge-cue[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-edge-cue[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-edge-cue[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-button {\n transition: none;\n }\n }\n\n /*\n * Windows forced colors flattens every background to Canvas, and today and the paging strip\n * are drawn with nothing else. Today takes the system selection pair, the one every other\n * \"current\" mark in the library takes, and the strip takes Highlight.\n */\n @media (forced-colors: active) {\n .v-calendar-view .v-calendar-today {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-calendar-edge-cue[data-edge]::after {\n forced-color-adjust: none;\n background: Highlight;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VCalendar.js","names":["_sfc_main","VCalendar_vue_vue_type_script_setup_true_lang_default","VCalendar_default"],"sources":["../../../src/components/VCalendar/VCalendar.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @ssr @core\n/**\n * Calendar layout is pure; JavaScript supplies grid navigation, editing gestures and\n * announcements because HTML has no native agenda widget. Editing forms remain consumer-owned.\n */\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { arrow_drop_down as arrowDropDownIcon } from '../VIcon/icons/arrow_drop_down'\nimport { chevron_left as chevronLeftIcon } from '../VIcon/icons/chevron_left'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useLiveAnnouncer } from '../../composables/useLiveAnnouncer'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTimer } from '../../composables/useTimer'\nimport { firstDayOfWeekFor, formatDateDisplay, formatDisplayRange } from '../../utils/date'\nimport { hourCycleFor, minutesOf } from '../../utils/time'\n\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\nimport VCalendarMonth from './VCalendarMonth.vue'\nimport VCalendarTimeGrid, { type FocusedCell } from './VCalendarTimeGrid.vue'\nimport VCalendarYear from './VCalendarYear.vue'\nimport { EDGE_STEP_DELAY } from './edgeStep'\nimport {\n monthWeeks,\n monthsOfYear,\n normalizeWeekdays,\n stepAnchor,\n sameTimes,\n timeOf,\n timesOf,\n todayISO,\n visibleDays,\n visibleRange,\n windowOf,\n} from './layout'\nimport type {\n ActivatedCell,\n CalendarCell,\n CalendarEvent,\n CalendarEventId,\n CalendarEventSlotProps,\n CalendarEventTimes,\n CalendarFormat,\n CalendarVariant,\n CalendarView,\n} from './types'\n\nexport interface CalendarProps {\n /**\n * How the view is framed: nothing at all (`flat`), or rounded corners set off by a border on\n * the page surface (`outline`, the default), a shadow over a raised surface (`elevated`), or\n * a muted fill (`filled`). The toolbar stays outside the frame.\n */\n variant?: CalendarVariant\n /**\n * Which views the menu offers, in the order it lists them. Narrowing it is how a\n * calendar that only ever shows weeks stops offering anything else.\n */\n views?: CalendarView[]\n /** How many days the custom view shows, and how far Previous and Next step in it. */\n customDays?: number\n /**\n * Which weekdays are on show, as numbers from 0 for Sunday. The ORDER matters as well: the\n * first entry is the day a week starts on, and it wins over `firstDayOfWeek`.\n */\n weekdays?: number[]\n /**\n * The day a week starts on, from 0 for Sunday, when `weekdays` is not given. Left out,\n * the locale decides.\n */\n firstDayOfWeek?: number\n /** The language the days, months and times are written in. Falls back to the global one. */\n locale?: string\n /**\n * Whether times are shown on a twelve or twenty-four hour clock. Left out, the reader's\n * language decides. It is the same prop, under the same name, as VTimePicker's.\n */\n format?: CalendarFormat\n /** The hour the grid starts at, from 0. */\n dayStart?: number\n /** The hour it ends at, up to 24. */\n dayEnd?: number\n /**\n * The step everything snaps to, in minutes: how far a nudge moves an event, and the unit a\n * slot is drawn out in.\n */\n slotDuration?: number\n /** Where the grid is scrolled to when it first appears, so the working day is in view. */\n scrollTime?: string\n /**\n * Leaves out the line drawn across today's column at the time it is now, and the dot on\n * its leading edge. Left in, it ticks once a minute while the calendar is on screen.\n */\n hideCurrentTime?: boolean\n /** How many events a day of the month view shows before it starts counting the rest. */\n monthEventLimit?: number\n /**\n * Stops events being moved and stretched, by dragging or with the keyboard. They\n * stay readable and clickable, and nothing else.\n */\n readonly?: boolean\n /**\n * Freezes the whole calendar: nothing can be moved, created or opened, no other period can be\n * reached, and everything greys out through the colour tokens. That is what separates this\n * from `readonly`, where only the editing stops.\n */\n disabled?: boolean\n /**\n * Lets an empty stretch of a time grid be drawn out with the pointer, up or down from the\n * slot pressed.\n */\n creatable?: boolean\n /**\n * How long a dragged event has to rest against the side of the calendar before the view turns\n * to the previous or next period, in milliseconds.\n */\n edgeStepDelay?: number\n /** Stops dragging near the top or bottom of a time grid from scrolling it. */\n noEdgeScroll?: boolean\n /** What the calendar is called, for anyone who cannot see it. */\n label?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n variant: 'outline',\n views: () => ['day', '4days', 'week'],\n customDays: 4,\n weekdays: undefined,\n firstDayOfWeek: undefined,\n locale: undefined,\n format: undefined,\n dayStart: 0,\n dayEnd: 24,\n slotDuration: 15,\n scrollTime: '08:00',\n hideCurrentTime: false,\n monthEventLimit: 3,\n readonly: false,\n disabled: false,\n creatable: false,\n edgeStepDelay: EDGE_STEP_DELAY,\n noEdgeScroll: false,\n label: undefined,\n})\n\n/*\n * The wrapper-root pattern: the consumer's class and style stay on the outer box, and\n * everything else; their `id`, their `aria-*`; goes on the region, which is the part that\n * carries the role and is therefore the part they mean.\n */\ndefineOptions({ inheritAttrs: false })\n\n/** Which span the calendar is showing. It opens on the week. */\nconst view = defineModel<CalendarView>('view', { default: 'week' })\n\n// @ssr\n/*\n * Today's date, which marks a single column, is a different matter and is read below in\n * `onMounted` where the server cannot see it at all.\n */\n/**\n * The day the calendar is anchored on, as `YYYY-MM-DD`: the view shows the week, month or\n * year holding it. It opens on today.\n */\nconst date = defineModel<string>('date', { default: () => todayISO() })\n/** What is on the calendar, empty to begin with. */\nconst events = defineModel<E[]>('events', { default: () => [] })\n\nconst emit = defineEmits<{\n /** A card was clicked or activated: the cue to open an editor of your own. */\n 'event-activate': [event: E]\n /**\n * An empty part of the grid was activated, at this day and this time. A day of the month\n * view has no hour of its own, and reports the one the time grids start at.\n */\n 'cell-activate': [cell: CalendarCell]\n /** An event was dragged or nudged somewhere else. */\n 'event-move': [event: E, previous: CalendarEventTimes]\n /** An event's end was dragged or nudged, in the same two parts. */\n 'event-resize': [event: E, previous: CalendarEventTimes]\n /**\n * An empty stretch of a day was drawn out, and these are its times. Nothing has been added\n * to `events`: this is the cue to make the event, in your own model or through your own form.\n */\n 'event-create': [times: CalendarEventTimes]\n}>()\n\ndefineSlots<{\n /** Extra controls in the toolbar, between the range and the view menu. */\n actions?(): unknown\n /** The content of one event's card, replacing the title and times. */\n event?(props: CalendarEventSlotProps<E>): unknown\n /** The head of one day column, replacing the weekday and the number. */\n 'day-header'?(props: { iso: string; weekday: string; dayText: string; today: boolean }): unknown\n /** The label beside the band of all-day events. */\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed(() => props.format ?? hourCycleFor(resolvedLocale.value))\nconst resolvedWeekdays = computed(() =>\n normalizeWeekdays(\n props.weekdays,\n props.firstDayOfWeek ?? firstDayOfWeekFor(resolvedLocale.value),\n ),\n)\n\nconst timeWindow = computed(() => windowOf(props.dayStart, props.dayEnd))\n\nconst days = computed(() =>\n visibleDays(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/** Which view is a time grid, and which is a summary. Several things below turn on this. */\nconst isTimeGrid = computed(() => view.value !== 'month' && view.value !== 'year')\n\nconst weeks = computed(() =>\n view.value === 'month' ? monthWeeks(date.value, resolvedWeekdays.value) : [],\n)\n\nconst months = computed(() => (view.value === 'year' ? monthsOfYear(date.value) : []))\n\n// @ssr\n// Way to tell either where the reader is, and rendering a guess would make the two markups\n// differ. Both stay null until then, and every rule that draws them is written to expect it.\nconst today = ref<string | null>(null)\nconst now = ref<number | null>(null)\n\nconst clock = useTimer()\n\n/**\n * The floor on the delay is not a nicety. `useTimer` runs a delay of zero or less\n * synchronously, by design, so a tick that ever computed one would call itself straight back\n * and go on doing so until the stack gave out.\n */\nfunction tick() {\n const at = new Date()\n now.value = at.getHours() * 60 + at.getMinutes()\n clock.start(tick, Math.max(1000, (60 - at.getSeconds()) * 1000))\n}\n\n/** Scrolls the time grid on show to `scrollTime`. */\nfunction scrollToStart() {\n const at = minutesOf(props.scrollTime)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n}\n\nonMounted(() => {\n today.value = todayISO()\n if (!props.hideCurrentTime) tick()\n scrollToStart()\n})\n\n// @core\n// Watch the visibility prop so toggling the current-time line starts or stops its timer after\n// mount.\nwatch(\n () => props.hideCurrentTime,\n (hidden) => {\n if (!hidden) return tick()\n clock.cancel()\n now.value = null\n },\n)\n\n/**\n * The usual form does not work here and the error it gives says nothing useful about why. A\n * generic `<script setup>` compiles to a FUNCTION, not to a class, so it has no construct\n * signature for `InstanceType` to read: the message complains that the component \"provides no\n * match for the signature `new (...args: any)`\", pointing at the template.\n */\nconst gridRef = ref<{\n focus(options?: FocusOptions): void\n scrollToMinutes(minutes: number): void\n} | null>(null)\n\n// @core\n// A time grid that appears after mount, a month switched to a week, opens at `scrollTime`\n// too. Post-flush, so the new grid is rendered and measurable when it is asked to scroll.\nwatch(gridRef, scrollToStart, { flush: 'post' })\n\n/** The region, the element a consumer's attributes land on. */\nconst regionEl = ref<HTMLElement | null>(null)\n\n/*\n * Which cell holds the tab stop, kept as two refs because the two kinds of view mean different\n * things by it: a time grid needs a day and an hour, a month only a day. One ref carrying an\n * hour the month ignores would leave that hour to go stale, and the grid would then reopen on\n * whatever the month happened to leave behind.\n */\nconst focused = ref<FocusedCell>({ iso: date.value, minutes: timeWindow.value.start })\nconst focusedDay = ref(date.value)\n\nconst range = computed(() =>\n visibleRange(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/**\n * What the toolbar says the calendar is showing. Each view names itself at the coarsest\n * granularity that still identifies it: a single day says its weekday, a year says nothing\n * but the number.\n */\nconst rangeText = computed(() => {\n const locale = resolvedLocale.value\n if (view.value === 'year')\n return formatDateDisplay(range.value.start, locale, { year: 'numeric' })\n if (view.value === 'month') {\n return formatDateDisplay(range.value.start, locale, { month: 'long', year: 'numeric' })\n }\n if (view.value === 'day') {\n return formatDateDisplay(range.value.start, locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n }\n return formatDisplayRange(range.value.start, range.value.end, locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n})\n\nconst viewLabel = (value: CalendarView) => {\n const words = m.value.calendar\n if (value === 'day') return words.viewDay\n if (value === '4days') return words.view4Days\n if (value === 'week') return words.viewWeek\n if (value === 'month') return words.viewMonth\n if (value === 'year') return words.viewYear\n return words.viewCustom(props.customDays)\n}\n\n/** What the two navigation buttons are called. */\nconst stepLabels = computed(() => {\n const words = m.value.calendar\n if (view.value === 'day') return { previous: words.previousDay, next: words.nextDay }\n if (view.value === 'week') return { previous: words.previousWeek, next: words.nextWeek }\n if (view.value === 'month') return { previous: words.previousMonth, next: words.nextMonth }\n if (view.value === 'year') return { previous: words.previousYear, next: words.nextYear }\n return { previous: words.previousPeriod, next: words.nextPeriod }\n})\n\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.calendar.label)\n\n/*\n * The four ways of reaching another period all pass through here, and `disabled` is refused in\n * every one of them rather than on the controls alone: the edge step pages the view from a\n * drag, and the year grid opens a month from a cell, neither of which is a button this\n * component disabled. It is the VDatePicker arrangement, where the guard sits on `goTo`.\n */\nfunction step(delta: -1 | 1) {\n if (props.disabled) return\n date.value = stepAnchor(date.value, view.value, delta, resolvedWeekdays.value, props.customDays)\n}\n\nfunction goToToday() {\n if (props.disabled) return\n date.value = todayISO()\n}\n\nfunction setView(value: CalendarView) {\n if (props.disabled) return\n view.value = value\n}\n\n/**\n * `disabled` is refused here, and not by the stylesheet's `pointer-events: none` alone. That\n * rule stops a click, but the grid keeps its tab stop so the agenda stays readable, and Enter\n * on a focused cell reaches this with nothing in its way; a frozen calendar would go on\n * reporting cells to a consumer's form.\n */\nfunction onCellActivate(cell: ActivatedCell) {\n if (props.disabled) return\n emit('cell-activate', {\n date: cell.date,\n time: timeOf(cell.minutes ?? timeWindow.value.start),\n })\n}\n\n/**\n * Drill into an allowed detail view; if views excludes it, update the date while preserving the\n * current view.\n */\nfunction openIn(iso: string, target: CalendarView) {\n if (props.disabled) return\n date.value = iso\n if (props.views.includes(target)) view.value = target\n}\n\n/**\n * What a reader who cannot see the grid is told: the range after every step of a move, and\n * whether the move was taken or given up.\n */\nconst { polite: announcement, announce: say } = useLiveAnnouncer()\nconst uid = useId()\nconst hintId = `${uid}-hint`\n\n/*\n * Through the shared announcer, which empties the region and writes on the next tick: the\n * same words twice in a row are no change to a live region, and would not be read again.\n */\nfunction announce(message: string) {\n say(message, false)\n}\n\n/** Writes one event's new times into the model and says what happened. */\nfunction onEventDrop(id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize') {\n const current = events.value.find((item) => item.id === id)\n if (!current) return\n\n const previous = timesOf(current)\n // A gesture that ends where it began moved nothing, and a consumer's undo stack must not\n // gain an entry for it, nor its watchers a new array.\n if (sameTimes(previous, times)) return\n const next = { ...current, ...times }\n events.value = events.value.map((item) => (item.id === id ? next : item))\n // Written out rather than picking the name with a conditional: the emit signatures are an\n // overload set, and TypeScript resolves one only against a literal.\n if (kind === 'resize') emit('event-resize', next, previous)\n else emit('event-move', next, previous)\n}\n\n/*\n * A drawn slot is REPORTED and never added. What an event is called, what else it carries and\n * whether it exists at all are the consumer's decisions, so the calendar hands over the times\n * and draws nothing once the pointer is let go.\n */\nfunction onSlotCreate(times: CalendarEventTimes) {\n emit('event-create', times)\n}\n\ndefineExpose({\n /**\n * Brings the focus into the view: the cell the grid is showing, or the first month heading\n * in the year view.\n */\n focus: (options?: FocusOptions) => gridRef.value?.focus(options),\n /** The region, which is where your `id` and `aria-*` attributes land. */\n el: regionEl,\n /** Goes back to the current day, exactly as the Today button does. */\n today: goToToday,\n /** Moves back one view (a week, a month or a year), exactly as the toolbar's arrow does. */\n previous: () => step(-1),\n /** Moves forward one view. */\n next: () => step(1),\n /** Scrolls the grid so a given `HH:mm` sits at the top of the visible area. */\n scrollTo: (time: string) => {\n const at = minutesOf(time)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-calendar\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-variant=\"variant\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <section\n ref=\"regionEl\"\n :aria-roledescription=\"m.calendar.roleDescription\"\n v-bind=\"forwardedAttrs\"\n class=\"v-calendar-region\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"v-calendar-toolbar\">\n <div class=\"v-calendar-nav\">\n <VIconButton\n :label=\"stepLabels.previous\"\n size=\"sm\"\n :disabled=\"disabled\"\n @click=\"step(-1)\"\n >\n <VIcon :name=\"chevronLeftIcon\" mirrored />\n </VIconButton>\n <VIconButton :label=\"stepLabels.next\" size=\"sm\" :disabled=\"disabled\" @click=\"step(1)\">\n <VIcon :name=\"chevronRightIcon\" mirrored />\n </VIconButton>\n </div>\n\n <VButton variant=\"outline\" tone=\"neutral\" size=\"sm\" :disabled=\"disabled\" @click=\"goToToday\">\n {{ m.calendar.today }}\n </VButton>\n\n <VTypography variant=\"heading-4\" as=\"h2\" class=\"v-calendar-title\">\n {{ rangeText }}\n </VTypography>\n\n <div class=\"v-calendar-actions\">\n <slot name=\"actions\" />\n\n <VMenu v-if=\"views.length > 1\" size=\"sm\" placement=\"bottom-end\" match-trigger>\n <template #trigger=\"{ triggerProps }\">\n <VButton\n variant=\"outline\"\n tone=\"neutral\"\n size=\"sm\"\n :disabled=\"disabled\"\n v-bind=\"triggerProps\"\n :aria-label=\"`${m.calendar.view}: ${viewLabel(view)}`\"\n >\n {{ viewLabel(view) }}\n <VIcon :name=\"arrowDropDownIcon\" />\n </VButton>\n </template>\n <VMenuItem\n v-for=\"value in views\"\n :key=\"value\"\n :label=\"viewLabel(value)\"\n :selected=\"value === view\"\n @select=\"setView(value)\"\n />\n </VMenu>\n </div>\n </div>\n\n <!--\n Invert opt-out public props once at the internal-grid boundary; internal view contracts\n use positive booleans.\n -->\n <VCalendarTimeGrid\n v-if=\"isTimeGrid\"\n ref=\"gridRef\"\n v-model:focused=\"focused\"\n class=\"v-calendar-view\"\n :days=\"days\"\n :events=\"events\"\n :time-window=\"timeWindow\"\n :slot-duration=\"slotDuration\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :now=\"hideCurrentTime ? null : now\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :creatable=\"creatable && !disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :auto-scroll=\"!noEdgeScroll\"\n :label=\"rangeText\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @slot-create=\"onSlotCreate\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['day-header']\" #day-header=\"slotProps\">\n <slot name=\"day-header\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['all-day-label']\" #all-day-label>\n <slot name=\"all-day-label\" />\n </template>\n </VCalendarTimeGrid>\n\n <VCalendarMonth\n v-else-if=\"view === 'month'\"\n ref=\"gridRef\"\n v-model:focused=\"focusedDay\"\n class=\"v-calendar-view\"\n :weeks=\"weeks\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :month-event-limit=\"monthEventLimit\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :label=\"rangeText\"\n @day-activate=\"openIn($event, 'day')\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarMonth>\n\n <VCalendarYear\n v-else\n ref=\"gridRef\"\n class=\"v-calendar-view\"\n :disabled=\"disabled\"\n :months=\"months\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :weekdays=\"resolvedWeekdays\"\n :today=\"today\"\n :label=\"rangeText\"\n @month-activate=\"openIn($event, 'month')\"\n />\n\n <!--\n Both of these are rendered from the first paint and never conditionally. The live region\n has to EXIST before it has anything to say: one inserted along with its first message is\n not announced at all.\n -->\n <div class=\"v-visually-hidden\" role=\"status\" aria-live=\"polite\">{{ announcement }}</div>\n <span :id=\"hintId\" class=\"v-visually-hidden\">{{ m.calendar.eventHint }}</span>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar {\n /*\n * The surface under the view, which its sticky headings repeat to stay opaque, and the\n * hover tint that has to stand out from it. Unframed, the page surface is the best guess at\n * what lies behind.\n */\n --calendar-surface: var(--vectis-color-surface);\n --calendar-hover-bg: var(--vectis-color-surface-muted);\n\n display: flex;\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 frozen calendar greys out through the colour tokens and never through opacity, the\n design system rule: what a reader keeps here is the agenda itself, which has to stay\n readable. The cards are real disabled buttons, so they grey themselves. */\n .v-calendar[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n .v-calendar[data-disabled] .v-calendar-view {\n pointer-events: none;\n }\n\n /*\n * `min-block-size: 0` on the grid is what lets it shrink below its content and therefore\n * scroll; without it the automatic minimum of a flex item would hold it at its full 24-hour\n * height and the whole page would scroll instead. All of it is a no-op when the parent's\n * height is auto, where the percentage falls back to auto and the calendar is simply as tall\n * as its content.\n */\n .v-calendar-region {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-inline-size: 0;\n min-block-size: 0;\n }\n\n .v-calendar-toolbar {\n display: flex;\n flex: none;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--vectis-space-2);\n padding-block-end: var(--vectis-space-3);\n }\n\n .v-calendar-nav {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-calendar-title {\n /*\n * It may be long; a full weekday and month in the day view; so it is the part that gives\n * way first, and the controls keep their size.\n */\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-2);\n /* The two siblings are pushed apart from here rather than by a `justify-content` on the\n toolbar, which would space every control equally instead of grouping them. */\n margin-inline-start: auto;\n }\n\n /*\n * The view on show, whichever it is: the one box that scrolls. The views inherit the family\n * and the colour from `.v-calendar` and declare neither again.\n */\n .v-calendar-view {\n flex: 1;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n /* Transparent rather than absent: forced colours paint it. Only `elevated` drops it, so\n that the grid's rules reach the edge its shadow draws. */\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-surface);\n }\n\n .v-calendar[data-variant='outline'] .v-calendar-view {\n background: var(--calendar-surface);\n border-color: var(--vectis-color-border);\n }\n\n .v-calendar[data-variant='elevated'] {\n --calendar-surface: var(--vectis-color-surface-raised);\n }\n\n .v-calendar[data-variant='elevated'] .v-calendar-view {\n border: none;\n background: var(--calendar-surface);\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-calendar[data-variant='filled'] {\n --calendar-surface: var(--vectis-color-surface-muted);\n --calendar-hover-bg: color-mix(\n in oklab,\n var(--vectis-color-surface-muted),\n var(--vectis-color-text) 4%\n );\n }\n\n .v-calendar[data-variant='filled'] .v-calendar-view {\n background: var(--calendar-surface);\n }\n\n /*\n * Every rule a view writes against one of these classes is either disjoint from it or more\n * specific, never tied: a tie between two sheets would be settled by the consumer's bundler.\n */\n\n /*\n * `not-allowed` is the word the library already uses for \"you cannot do this\", on every\n * disabled control. BEST-EFFORT, and never the signal: while a pointer is captured the cursor\n * is resolved against the capture target rather than against whatever sits under the pointer,\n * and engines differ on it.\n */\n .v-calendar-view[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-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 /*\n * Today's date, marked on the number the way a calendar marks a date rather than a column.\n * Semibold here marks a state, not a type role.\n */\n .v-calendar-view .v-calendar-today {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /*\n * A cell of either grid: ruled on two sides, the other two drawn by its neighbours. It keeps\n * the default cursor: the pointer hand belongs to what can be opened, the events, and a grid\n * of hands would say every square of the week is a link.\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 }\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 view 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-button {\n /* A button carries a border and a background from the browser, which around a round day\n number read as a stray ring. Neither is optional. */\n border: none;\n background: none;\n font-family: inherit;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-button: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 /*\n * Drawn INSIDE the box the cells occupy rather than on the scroller, because a scroller's\n * absolutely positioned child is placed against its content and scrolls away with it. That\n * box has to be positioned, which each view's own sheet sees to.\n */\n .v-calendar-edge-cue[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-edge-cue[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-edge-cue[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-button {\n transition: none;\n }\n }\n\n /*\n * Windows forced colors flattens every background to Canvas, and today and the paging strip\n * are drawn with nothing else. Today takes the system selection pair, the one every other\n * \"current\" mark in the library takes, and the strip takes Highlight.\n */\n @media (forced-colors: active) {\n .v-calendar-view .v-calendar-today {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-calendar-edge-cue[data-edge]::after {\n forced-color-adjust: none;\n background: Highlight;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VCalendar.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VCalendar/VCalendar.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @ssr @core\n/**\n * Calendar layout is pure; JavaScript supplies grid navigation, editing gestures and\n * announcements because HTML has no native agenda widget. Editing forms remain consumer-owned.\n */\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { arrow_drop_down as arrowDropDownIcon } from '../VIcon/icons/arrow_drop_down'\nimport { chevron_left as chevronLeftIcon } from '../VIcon/icons/chevron_left'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useLiveAnnouncer } from '../../composables/useLiveAnnouncer'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTimer } from '../../composables/useTimer'\nimport { firstDayOfWeekFor, formatDateDisplay, formatDisplayRange } from '../../utils/date'\nimport { hourCycleFor, minutesOf } from '../../utils/time'\n\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\nimport VCalendarMonth from './VCalendarMonth.vue'\nimport VCalendarTimeGrid, { type FocusedCell } from './VCalendarTimeGrid.vue'\nimport VCalendarYear from './VCalendarYear.vue'\nimport { EDGE_STEP_DELAY } from './edgeStep'\nimport {\n monthWeeks,\n monthsOfYear,\n normalizeWeekdays,\n stepAnchor,\n sameTimes,\n timeOf,\n timesOf,\n todayISO,\n visibleDays,\n visibleRange,\n windowOf,\n} from './layout'\nimport type {\n ActivatedCell,\n CalendarCell,\n CalendarEvent,\n CalendarEventId,\n CalendarEventSlotProps,\n CalendarEventTimes,\n CalendarFormat,\n CalendarVariant,\n CalendarView,\n} from './types'\n\nexport interface CalendarProps {\n /**\n * How the view is framed: nothing at all (`flat`), or rounded corners set off by a border on\n * the page surface (`outline`, the default), a shadow over a raised surface (`elevated`), or\n * a muted fill (`filled`). The toolbar stays outside the frame.\n */\n variant?: CalendarVariant\n /**\n * Which views the menu offers, in the order it lists them. Narrowing it is how a\n * calendar that only ever shows weeks stops offering anything else.\n */\n views?: CalendarView[]\n /** How many days the custom view shows, and how far Previous and Next step in it. */\n customDays?: number\n /**\n * Which weekdays are on show, as numbers from 0 for Sunday. The ORDER matters as well: the\n * first entry is the day a week starts on, and it wins over `firstDayOfWeek`.\n */\n weekdays?: number[]\n /**\n * The day a week starts on, from 0 for Sunday, when `weekdays` is not given. Left out,\n * the locale decides.\n */\n firstDayOfWeek?: number\n /** The language the days, months and times are written in. Falls back to the global one. */\n locale?: string\n /**\n * Whether times are shown on a twelve or twenty-four hour clock. Left out, the reader's\n * language decides. It is the same prop, under the same name, as VTimePicker's.\n */\n format?: CalendarFormat\n /** The hour the grid starts at, from 0. */\n dayStart?: number\n /** The hour it ends at, up to 24. */\n dayEnd?: number\n /**\n * The step everything snaps to, in minutes: how far a nudge moves an event, and the unit a\n * slot is drawn out in.\n */\n slotDuration?: number\n /** Where the grid is scrolled to when it first appears, so the working day is in view. */\n scrollTime?: string\n /**\n * Leaves out the line drawn across today's column at the time it is now, and the dot on\n * its leading edge. Left in, it ticks once a minute while the calendar is on screen.\n */\n hideCurrentTime?: boolean\n /** How many events a day of the month view shows before it starts counting the rest. */\n monthEventLimit?: number\n /**\n * Stops events being moved and stretched, by dragging or with the keyboard. They\n * stay readable and clickable, and nothing else.\n */\n readonly?: boolean\n /**\n * Freezes the whole calendar: nothing can be moved, created or opened, no other period can be\n * reached, and everything greys out through the colour tokens. That is what separates this\n * from `readonly`, where only the editing stops.\n */\n disabled?: boolean\n /**\n * Lets an empty stretch of a time grid be drawn out with the pointer, up or down from the\n * slot pressed.\n */\n creatable?: boolean\n /**\n * How long a dragged event has to rest against the side of the calendar before the view turns\n * to the previous or next period, in milliseconds.\n */\n edgeStepDelay?: number\n /** Stops dragging near the top or bottom of a time grid from scrolling it. */\n noEdgeScroll?: boolean\n /** What the calendar is called, for anyone who cannot see it. */\n label?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n variant: 'outline',\n views: () => ['day', '4days', 'week'],\n customDays: 4,\n weekdays: undefined,\n firstDayOfWeek: undefined,\n locale: undefined,\n format: undefined,\n dayStart: 0,\n dayEnd: 24,\n slotDuration: 15,\n scrollTime: '08:00',\n hideCurrentTime: false,\n monthEventLimit: 3,\n readonly: false,\n disabled: false,\n creatable: false,\n edgeStepDelay: EDGE_STEP_DELAY,\n noEdgeScroll: false,\n label: undefined,\n})\n\n/*\n * The wrapper-root pattern: the consumer's class and style stay on the outer box, and\n * everything else; their `id`, their `aria-*`; goes on the region, which is the part that\n * carries the role and is therefore the part they mean.\n */\ndefineOptions({ inheritAttrs: false })\n\n/** Which span the calendar is showing. It opens on the week. */\nconst view = defineModel<CalendarView>('view', { default: 'week' })\n\n// @ssr\n/*\n * Today's date, which marks a single column, is a different matter and is read below in\n * `onMounted` where the server cannot see it at all.\n */\n/**\n * The day the calendar is anchored on, as `YYYY-MM-DD`: the view shows the week, month or\n * year holding it. It opens on today.\n */\nconst date = defineModel<string>('date', { default: () => todayISO() })\n/** What is on the calendar, empty to begin with. */\nconst events = defineModel<E[]>('events', { default: () => [] })\n\nconst emit = defineEmits<{\n /** A card was clicked or activated: the cue to open an editor of your own. */\n 'event-activate': [event: E]\n /**\n * An empty part of the grid was activated, at this day and this time. A day of the month\n * view has no hour of its own, and reports the one the time grids start at.\n */\n 'cell-activate': [cell: CalendarCell]\n /** An event was dragged or nudged somewhere else. */\n 'event-move': [event: E, previous: CalendarEventTimes]\n /** An event's end was dragged or nudged, in the same two parts. */\n 'event-resize': [event: E, previous: CalendarEventTimes]\n /**\n * An empty stretch of a day was drawn out, and these are its times. Nothing has been added\n * to `events`: this is the cue to make the event, in your own model or through your own form.\n */\n 'event-create': [times: CalendarEventTimes]\n}>()\n\ndefineSlots<{\n /** Extra controls in the toolbar, between the range and the view menu. */\n actions?(): unknown\n /** The content of one event's card, replacing the title and times. */\n event?(props: CalendarEventSlotProps<E>): unknown\n /** The head of one day column, replacing the weekday and the number. */\n 'day-header'?(props: { iso: string; weekday: string; dayText: string; today: boolean }): unknown\n /** The label beside the band of all-day events. */\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed(() => props.format ?? hourCycleFor(resolvedLocale.value))\nconst resolvedWeekdays = computed(() =>\n normalizeWeekdays(\n props.weekdays,\n props.firstDayOfWeek ?? firstDayOfWeekFor(resolvedLocale.value),\n ),\n)\n\nconst timeWindow = computed(() => windowOf(props.dayStart, props.dayEnd))\n\nconst days = computed(() =>\n visibleDays(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/** Which view is a time grid, and which is a summary. Several things below turn on this. */\nconst isTimeGrid = computed(() => view.value !== 'month' && view.value !== 'year')\n\nconst weeks = computed(() =>\n view.value === 'month' ? monthWeeks(date.value, resolvedWeekdays.value) : [],\n)\n\nconst months = computed(() => (view.value === 'year' ? monthsOfYear(date.value) : []))\n\n// @ssr\n// Way to tell either where the reader is, and rendering a guess would make the two markups\n// differ. Both stay null until then, and every rule that draws them is written to expect it.\nconst today = ref<string | null>(null)\nconst now = ref<number | null>(null)\n\nconst clock = useTimer()\n\n/**\n * The floor on the delay is not a nicety. `useTimer` runs a delay of zero or less\n * synchronously, by design, so a tick that ever computed one would call itself straight back\n * and go on doing so until the stack gave out.\n */\nfunction tick() {\n const at = new Date()\n now.value = at.getHours() * 60 + at.getMinutes()\n clock.start(tick, Math.max(1000, (60 - at.getSeconds()) * 1000))\n}\n\n/** Scrolls the time grid on show to `scrollTime`. */\nfunction scrollToStart() {\n const at = minutesOf(props.scrollTime)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n}\n\nonMounted(() => {\n today.value = todayISO()\n if (!props.hideCurrentTime) tick()\n scrollToStart()\n})\n\n// @core\n// Watch the visibility prop so toggling the current-time line starts or stops its timer after\n// mount.\nwatch(\n () => props.hideCurrentTime,\n (hidden) => {\n if (!hidden) return tick()\n clock.cancel()\n now.value = null\n },\n)\n\n/**\n * The usual form does not work here and the error it gives says nothing useful about why. A\n * generic `<script setup>` compiles to a FUNCTION, not to a class, so it has no construct\n * signature for `InstanceType` to read: the message complains that the component \"provides no\n * match for the signature `new (...args: any)`\", pointing at the template.\n */\nconst gridRef = ref<{\n focus(options?: FocusOptions): void\n scrollToMinutes(minutes: number): void\n} | null>(null)\n\n// @core\n// A time grid that appears after mount, a month switched to a week, opens at `scrollTime`\n// too. Post-flush, so the new grid is rendered and measurable when it is asked to scroll.\nwatch(gridRef, scrollToStart, { flush: 'post' })\n\n/** The region, the element a consumer's attributes land on. */\nconst regionEl = ref<HTMLElement | null>(null)\n\n/*\n * Which cell holds the tab stop, kept as two refs because the two kinds of view mean different\n * things by it: a time grid needs a day and an hour, a month only a day. One ref carrying an\n * hour the month ignores would leave that hour to go stale, and the grid would then reopen on\n * whatever the month happened to leave behind.\n */\nconst focused = ref<FocusedCell>({ iso: date.value, minutes: timeWindow.value.start })\nconst focusedDay = ref(date.value)\n\nconst range = computed(() =>\n visibleRange(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/**\n * What the toolbar says the calendar is showing. Each view names itself at the coarsest\n * granularity that still identifies it: a single day says its weekday, a year says nothing\n * but the number.\n */\nconst rangeText = computed(() => {\n const locale = resolvedLocale.value\n if (view.value === 'year')\n return formatDateDisplay(range.value.start, locale, { year: 'numeric' })\n if (view.value === 'month') {\n return formatDateDisplay(range.value.start, locale, { month: 'long', year: 'numeric' })\n }\n if (view.value === 'day') {\n return formatDateDisplay(range.value.start, locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n }\n return formatDisplayRange(range.value.start, range.value.end, locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n})\n\nconst viewLabel = (value: CalendarView) => {\n const words = m.value.calendar\n if (value === 'day') return words.viewDay\n if (value === '4days') return words.view4Days\n if (value === 'week') return words.viewWeek\n if (value === 'month') return words.viewMonth\n if (value === 'year') return words.viewYear\n return words.viewCustom(props.customDays)\n}\n\n/** What the two navigation buttons are called. */\nconst stepLabels = computed(() => {\n const words = m.value.calendar\n if (view.value === 'day') return { previous: words.previousDay, next: words.nextDay }\n if (view.value === 'week') return { previous: words.previousWeek, next: words.nextWeek }\n if (view.value === 'month') return { previous: words.previousMonth, next: words.nextMonth }\n if (view.value === 'year') return { previous: words.previousYear, next: words.nextYear }\n return { previous: words.previousPeriod, next: words.nextPeriod }\n})\n\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.calendar.label)\n\n/*\n * The four ways of reaching another period all pass through here, and `disabled` is refused in\n * every one of them rather than on the controls alone: the edge step pages the view from a\n * drag, and the year grid opens a month from a cell, neither of which is a button this\n * component disabled. It is the VDatePicker arrangement, where the guard sits on `goTo`.\n */\nfunction step(delta: -1 | 1) {\n if (props.disabled) return\n date.value = stepAnchor(date.value, view.value, delta, resolvedWeekdays.value, props.customDays)\n}\n\nfunction goToToday() {\n if (props.disabled) return\n date.value = todayISO()\n}\n\nfunction setView(value: CalendarView) {\n if (props.disabled) return\n view.value = value\n}\n\n/**\n * `disabled` is refused here, and not by the stylesheet's `pointer-events: none` alone. That\n * rule stops a click, but the grid keeps its tab stop so the agenda stays readable, and Enter\n * on a focused cell reaches this with nothing in its way; a frozen calendar would go on\n * reporting cells to a consumer's form.\n */\nfunction onCellActivate(cell: ActivatedCell) {\n if (props.disabled) return\n emit('cell-activate', {\n date: cell.date,\n time: timeOf(cell.minutes ?? timeWindow.value.start),\n })\n}\n\n/**\n * Drill into an allowed detail view; if views excludes it, update the date while preserving the\n * current view.\n */\nfunction openIn(iso: string, target: CalendarView) {\n if (props.disabled) return\n date.value = iso\n if (props.views.includes(target)) view.value = target\n}\n\n/**\n * What a reader who cannot see the grid is told: the range after every step of a move, and\n * whether the move was taken or given up.\n */\nconst { polite: announcement, announce: say } = useLiveAnnouncer()\nconst uid = useId()\nconst hintId = `${uid}-hint`\n\n/*\n * Through the shared announcer, which empties the region and writes on the next tick: the\n * same words twice in a row are no change to a live region, and would not be read again.\n */\nfunction announce(message: string) {\n say(message, false)\n}\n\n/** Writes one event's new times into the model and says what happened. */\nfunction onEventDrop(id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize') {\n const current = events.value.find((item) => item.id === id)\n if (!current) return\n\n const previous = timesOf(current)\n // A gesture that ends where it began moved nothing, and a consumer's undo stack must not\n // gain an entry for it, nor its watchers a new array.\n if (sameTimes(previous, times)) return\n const next = { ...current, ...times }\n events.value = events.value.map((item) => (item.id === id ? next : item))\n // Written out rather than picking the name with a conditional: the emit signatures are an\n // overload set, and TypeScript resolves one only against a literal.\n if (kind === 'resize') emit('event-resize', next, previous)\n else emit('event-move', next, previous)\n}\n\n/*\n * A drawn slot is REPORTED and never added. What an event is called, what else it carries and\n * whether it exists at all are the consumer's decisions, so the calendar hands over the times\n * and draws nothing once the pointer is let go.\n */\nfunction onSlotCreate(times: CalendarEventTimes) {\n emit('event-create', times)\n}\n\ndefineExpose({\n /**\n * Brings the focus into the view: the cell the grid is showing, or the first month heading\n * in the year view.\n */\n focus: (options?: FocusOptions) => gridRef.value?.focus(options),\n /** The region, which is where your `id` and `aria-*` attributes land. */\n el: regionEl,\n /** Goes back to the current day, exactly as the Today button does. */\n today: goToToday,\n /** Moves back one view (a week, a month or a year), exactly as the toolbar's arrow does. */\n previous: () => step(-1),\n /** Moves forward one view. */\n next: () => step(1),\n /** Scrolls the grid so a given `HH:mm` sits at the top of the visible area. */\n scrollTo: (time: string) => {\n const at = minutesOf(time)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-calendar\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-variant=\"variant\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <section\n ref=\"regionEl\"\n :aria-roledescription=\"m.calendar.roleDescription\"\n v-bind=\"forwardedAttrs\"\n class=\"v-calendar-region\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"v-calendar-toolbar\">\n <div class=\"v-calendar-nav\">\n <VIconButton\n :label=\"stepLabels.previous\"\n size=\"sm\"\n :disabled=\"disabled\"\n @click=\"step(-1)\"\n >\n <VIcon :name=\"chevronLeftIcon\" mirrored />\n </VIconButton>\n <VIconButton :label=\"stepLabels.next\" size=\"sm\" :disabled=\"disabled\" @click=\"step(1)\">\n <VIcon :name=\"chevronRightIcon\" mirrored />\n </VIconButton>\n </div>\n\n <VButton variant=\"outline\" tone=\"neutral\" size=\"sm\" :disabled=\"disabled\" @click=\"goToToday\">\n {{ m.calendar.today }}\n </VButton>\n\n <VTypography variant=\"heading-4\" as=\"h2\" class=\"v-calendar-title\">\n {{ rangeText }}\n </VTypography>\n\n <div class=\"v-calendar-actions\">\n <slot name=\"actions\" />\n\n <VMenu v-if=\"views.length > 1\" size=\"sm\" placement=\"bottom-end\" match-trigger>\n <template #trigger=\"{ triggerProps }\">\n <VButton\n variant=\"outline\"\n tone=\"neutral\"\n size=\"sm\"\n :disabled=\"disabled\"\n v-bind=\"triggerProps\"\n :aria-label=\"`${m.calendar.view}: ${viewLabel(view)}`\"\n >\n {{ viewLabel(view) }}\n <VIcon :name=\"arrowDropDownIcon\" />\n </VButton>\n </template>\n <VMenuItem\n v-for=\"value in views\"\n :key=\"value\"\n :label=\"viewLabel(value)\"\n :selected=\"value === view\"\n @select=\"setView(value)\"\n />\n </VMenu>\n </div>\n </div>\n\n <!--\n Invert opt-out public props once at the internal-grid boundary; internal view contracts\n use positive booleans.\n -->\n <VCalendarTimeGrid\n v-if=\"isTimeGrid\"\n ref=\"gridRef\"\n v-model:focused=\"focused\"\n class=\"v-calendar-view\"\n :days=\"days\"\n :events=\"events\"\n :time-window=\"timeWindow\"\n :slot-duration=\"slotDuration\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :now=\"hideCurrentTime ? null : now\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :creatable=\"creatable && !disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :auto-scroll=\"!noEdgeScroll\"\n :label=\"rangeText\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @slot-create=\"onSlotCreate\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['day-header']\" #day-header=\"slotProps\">\n <slot name=\"day-header\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['all-day-label']\" #all-day-label>\n <slot name=\"all-day-label\" />\n </template>\n </VCalendarTimeGrid>\n\n <VCalendarMonth\n v-else-if=\"view === 'month'\"\n ref=\"gridRef\"\n v-model:focused=\"focusedDay\"\n class=\"v-calendar-view\"\n :weeks=\"weeks\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :month-event-limit=\"monthEventLimit\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :label=\"rangeText\"\n @day-activate=\"openIn($event, 'day')\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarMonth>\n\n <VCalendarYear\n v-else\n ref=\"gridRef\"\n class=\"v-calendar-view\"\n :disabled=\"disabled\"\n :months=\"months\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :weekdays=\"resolvedWeekdays\"\n :today=\"today\"\n :label=\"rangeText\"\n @month-activate=\"openIn($event, 'month')\"\n />\n\n <!--\n Both of these are rendered from the first paint and never conditionally. The live region\n has to EXIST before it has anything to say: one inserted along with its first message is\n not announced at all.\n -->\n <div class=\"v-visually-hidden\" role=\"status\" aria-live=\"polite\">{{ announcement }}</div>\n <span :id=\"hintId\" class=\"v-visually-hidden\">{{ m.calendar.eventHint }}</span>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar {\n /*\n * The surface under the view, which its sticky headings repeat to stay opaque, and the\n * hover tint that has to stand out from it. Unframed, the page surface is the best guess at\n * what lies behind.\n */\n --calendar-surface: var(--vectis-color-surface);\n --calendar-hover-bg: var(--vectis-color-surface-muted);\n\n display: flex;\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 frozen calendar greys out through the colour tokens and never through opacity, the\n design system rule: what a reader keeps here is the agenda itself, which has to stay\n readable. The cards are real disabled buttons, so they grey themselves. */\n .v-calendar[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n .v-calendar[data-disabled] .v-calendar-view {\n pointer-events: none;\n }\n\n /*\n * `min-block-size: 0` on the grid is what lets it shrink below its content and therefore\n * scroll; without it the automatic minimum of a flex item would hold it at its full 24-hour\n * height and the whole page would scroll instead. All of it is a no-op when the parent's\n * height is auto, where the percentage falls back to auto and the calendar is simply as tall\n * as its content.\n */\n .v-calendar-region {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-inline-size: 0;\n min-block-size: 0;\n }\n\n .v-calendar-toolbar {\n display: flex;\n flex: none;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--vectis-space-2);\n padding-block-end: var(--vectis-space-3);\n }\n\n .v-calendar-nav {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-calendar-title {\n /*\n * It may be long; a full weekday and month in the day view; so it is the part that gives\n * way first, and the controls keep their size.\n */\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-2);\n /* The two siblings are pushed apart from here rather than by a `justify-content` on the\n toolbar, which would space every control equally instead of grouping them. */\n margin-inline-start: auto;\n }\n\n /*\n * The view on show, whichever it is: the one box that scrolls. The views inherit the family\n * and the colour from `.v-calendar` and declare neither again.\n */\n .v-calendar-view {\n flex: 1;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n /* Transparent rather than absent: forced colours paint it. Only `elevated` drops it, so\n that the grid's rules reach the edge its shadow draws. */\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-surface);\n }\n\n .v-calendar[data-variant='outline'] .v-calendar-view {\n background: var(--calendar-surface);\n border-color: var(--vectis-color-border);\n }\n\n .v-calendar[data-variant='elevated'] {\n --calendar-surface: var(--vectis-color-surface-raised);\n }\n\n .v-calendar[data-variant='elevated'] .v-calendar-view {\n border: none;\n background: var(--calendar-surface);\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-calendar[data-variant='filled'] {\n --calendar-surface: var(--vectis-color-surface-muted);\n --calendar-hover-bg: color-mix(\n in oklab,\n var(--vectis-color-surface-muted),\n var(--vectis-color-text) 4%\n );\n }\n\n .v-calendar[data-variant='filled'] .v-calendar-view {\n background: var(--calendar-surface);\n }\n\n /*\n * Every rule a view writes against one of these classes is either disjoint from it or more\n * specific, never tied: a tie between two sheets would be settled by the consumer's bundler.\n */\n\n /*\n * `not-allowed` is the word the library already uses for \"you cannot do this\", on every\n * disabled control. BEST-EFFORT, and never the signal: while a pointer is captured the cursor\n * is resolved against the capture target rather than against whatever sits under the pointer,\n * and engines differ on it.\n */\n .v-calendar-view[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-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 /*\n * Today's date, marked on the number the way a calendar marks a date rather than a column.\n * Semibold here marks a state, not a type role.\n */\n .v-calendar-view .v-calendar-today {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /*\n * A cell of either grid: ruled on two sides, the other two drawn by its neighbours. It keeps\n * the default cursor: the pointer hand belongs to what can be opened, the events, and a grid\n * of hands would say every square of the week is a link.\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 }\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 view 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-button {\n /* A button carries a border and a background from the browser, which around a round day\n number read as a stray ring. Neither is optional. */\n border: none;\n background: none;\n font-family: inherit;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-button: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 /*\n * Drawn INSIDE the box the cells occupy rather than on the scroller, because a scroller's\n * absolutely positioned child is placed against its content and scrolls away with it. That\n * box has to be positioned, which each view's own sheet sees to.\n */\n .v-calendar-edge-cue[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-edge-cue[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-edge-cue[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-button {\n transition: none;\n }\n }\n\n /*\n * Windows forced colors flattens every background to Canvas, and today and the paging strip\n * are drawn with nothing else. Today takes the system selection pair, the one every other\n * \"current\" mark in the library takes, and the strip takes Highlight.\n */\n @media (forced-colors: active) {\n .v-calendar-view .v-calendar-today {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-calendar-edge-cue[data-edge]::after {\n forced-color-adjust: none;\n background: Highlight;\n }\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VCalendar.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_createVNode","VIconButton","_withCtx","VIcon","chevronLeftIcon","chevronRightIcon","VButton","_createTextVNode","_toDisplayString","VTypography","_renderSlot","_createBlock","VMenu","arrowDropDownIcon","_Fragment","_renderList","VMenuItem","_createCommentVNode","VCalendarTimeGrid","_createSlots","_normalizeProps","_guardReactiveProps","VCalendarMonth","VCalendarYear","VIcon_default","VTypography_default","VButton_default","VIconButton_default","VMenu_default","VMenuItem_default","VCalendarMonth_default","VCalendarTimeGrid_default","VCalendarYear_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","VCalendar_vue_vue_type_script_setup_true_lang_default","\"view\"","\"viewModifiers\"","\"date\"","todayISO","\"dateModifiers\"","\"events\"","\"eventsModifiers\"","__expose","__emit","props","__props","view","useModel","date","events","emit","m","useMessages","useRootAttrs","resolvedLocale","useResolvedLocale","resolvedFormat","computed","hourCycleFor","resolvedWeekdays","normalizeWeekdays","firstDayOfWeekFor","timeWindow","windowOf","days","visibleDays","isTimeGrid","weeks","monthWeeks","months","monthsOfYear","today","ref","now","clock","useTimer","tick","at","scrollToStart","minutesOf","gridRef","onMounted","watch","hidden","regionEl","focused","focusedDay","range","visibleRange","rangeText","locale","formatDateDisplay","formatDisplayRange","viewLabel","words","value","stepLabels","ariaLabel","useAriaLabel","step","stepAnchor","delta","goToToday","setView","onCellActivate","cell","timeOf","openIn","iso","target","announcement","say","useLiveAnnouncer","hintId","useId","announce","message","onEventDrop","current","item","id","previous","timesOf","sameTimes","times","next","kind","onSlotCreate","options","time","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","rootStyle","createElementVNode","mergeProps","forwardedAttrs","createVNode","_cache","withCtx","chevron_left","chevron_right","createTextVNode","toDisplayString","renderSlot","_ctx","createBlock","triggerProps","arrow_drop_down","Fragment","renderList","createCommentVNode","$event","createSlots","normalizeProps","guardReactiveProps","slotProps"],"sources":["../../../src/components/VCalendar/VCalendar.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @ssr @core\n/**\n * Calendar layout is pure; JavaScript supplies grid navigation, editing gestures and\n * announcements because HTML has no native agenda widget. Editing forms remain consumer-owned.\n */\nimport { computed, onMounted, ref, useId, watch } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VIcon from '../VIcon/VIcon.vue'\nimport { arrow_drop_down as arrowDropDownIcon } from '../VIcon/icons/arrow_drop_down'\nimport { chevron_left as chevronLeftIcon } from '../VIcon/icons/chevron_left'\nimport { chevron_right as chevronRightIcon } from '../VIcon/icons/chevron_right'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VMenu from '../VMenu/VMenu.vue'\nimport VMenuItem from '../VMenu/VMenuItem.vue'\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useLiveAnnouncer } from '../../composables/useLiveAnnouncer'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { useTimer } from '../../composables/useTimer'\nimport { firstDayOfWeekFor, formatDateDisplay, formatDisplayRange } from '../../utils/date'\nimport { hourCycleFor, minutesOf } from '../../utils/time'\n\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\nimport VCalendarMonth from './VCalendarMonth.vue'\nimport VCalendarTimeGrid, { type FocusedCell } from './VCalendarTimeGrid.vue'\nimport VCalendarYear from './VCalendarYear.vue'\nimport { EDGE_STEP_DELAY } from './edgeStep'\nimport {\n monthWeeks,\n monthsOfYear,\n normalizeWeekdays,\n stepAnchor,\n sameTimes,\n timeOf,\n timesOf,\n todayISO,\n visibleDays,\n visibleRange,\n windowOf,\n} from './layout'\nimport type {\n ActivatedCell,\n CalendarCell,\n CalendarEvent,\n CalendarEventId,\n CalendarEventSlotProps,\n CalendarEventTimes,\n CalendarFormat,\n CalendarVariant,\n CalendarView,\n} from './types'\n\nexport interface CalendarProps {\n /**\n * How the view is framed: nothing at all (`flat`), or rounded corners set off by a border on\n * the page surface (`outline`, the default), a shadow over a raised surface (`elevated`), or\n * a muted fill (`filled`). The toolbar stays outside the frame.\n */\n variant?: CalendarVariant\n /**\n * Which views the menu offers, in the order it lists them. Narrowing it is how a\n * calendar that only ever shows weeks stops offering anything else.\n */\n views?: CalendarView[]\n /** How many days the custom view shows, and how far Previous and Next step in it. */\n customDays?: number\n /**\n * Which weekdays are on show, as numbers from 0 for Sunday. The ORDER matters as well: the\n * first entry is the day a week starts on, and it wins over `firstDayOfWeek`.\n */\n weekdays?: number[]\n /**\n * The day a week starts on, from 0 for Sunday, when `weekdays` is not given. Left out,\n * the locale decides.\n */\n firstDayOfWeek?: number\n /** The language the days, months and times are written in. Falls back to the global one. */\n locale?: string\n /**\n * Whether times are shown on a twelve or twenty-four hour clock. Left out, the reader's\n * language decides. It is the same prop, under the same name, as VTimePicker's.\n */\n format?: CalendarFormat\n /** The hour the grid starts at, from 0. */\n dayStart?: number\n /** The hour it ends at, up to 24. */\n dayEnd?: number\n /**\n * The step everything snaps to, in minutes: how far a nudge moves an event, and the unit a\n * slot is drawn out in.\n */\n slotDuration?: number\n /** Where the grid is scrolled to when it first appears, so the working day is in view. */\n scrollTime?: string\n /**\n * Leaves out the line drawn across today's column at the time it is now, and the dot on\n * its leading edge. Left in, it ticks once a minute while the calendar is on screen.\n */\n hideCurrentTime?: boolean\n /** How many events a day of the month view shows before it starts counting the rest. */\n monthEventLimit?: number\n /**\n * Stops events being moved and stretched, by dragging or with the keyboard. They\n * stay readable and clickable, and nothing else.\n */\n readonly?: boolean\n /**\n * Freezes the whole calendar: nothing can be moved, created or opened, no other period can be\n * reached, and everything greys out through the colour tokens. That is what separates this\n * from `readonly`, where only the editing stops.\n */\n disabled?: boolean\n /**\n * Lets an empty stretch of a time grid be drawn out with the pointer, up or down from the\n * slot pressed.\n */\n creatable?: boolean\n /**\n * How long a dragged event has to rest against the side of the calendar before the view turns\n * to the previous or next period, in milliseconds.\n */\n edgeStepDelay?: number\n /** Stops dragging near the top or bottom of a time grid from scrolling it. */\n noEdgeScroll?: boolean\n /** What the calendar is called, for anyone who cannot see it. */\n label?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n variant: 'outline',\n views: () => ['day', '4days', 'week'],\n customDays: 4,\n weekdays: undefined,\n firstDayOfWeek: undefined,\n locale: undefined,\n format: undefined,\n dayStart: 0,\n dayEnd: 24,\n slotDuration: 15,\n scrollTime: '08:00',\n hideCurrentTime: false,\n monthEventLimit: 3,\n readonly: false,\n disabled: false,\n creatable: false,\n edgeStepDelay: EDGE_STEP_DELAY,\n noEdgeScroll: false,\n label: undefined,\n})\n\n/*\n * The wrapper-root pattern: the consumer's class and style stay on the outer box, and\n * everything else; their `id`, their `aria-*`; goes on the region, which is the part that\n * carries the role and is therefore the part they mean.\n */\ndefineOptions({ inheritAttrs: false })\n\n/** Which span the calendar is showing. It opens on the week. */\nconst view = defineModel<CalendarView>('view', { default: 'week' })\n\n// @ssr\n/*\n * Today's date, which marks a single column, is a different matter and is read below in\n * `onMounted` where the server cannot see it at all.\n */\n/**\n * The day the calendar is anchored on, as `YYYY-MM-DD`: the view shows the week, month or\n * year holding it. It opens on today.\n */\nconst date = defineModel<string>('date', { default: () => todayISO() })\n/** What is on the calendar, empty to begin with. */\nconst events = defineModel<E[]>('events', { default: () => [] })\n\nconst emit = defineEmits<{\n /** A card was clicked or activated: the cue to open an editor of your own. */\n 'event-activate': [event: E]\n /**\n * An empty part of the grid was activated, at this day and this time. A day of the month\n * view has no hour of its own, and reports the one the time grids start at.\n */\n 'cell-activate': [cell: CalendarCell]\n /** An event was dragged or nudged somewhere else. */\n 'event-move': [event: E, previous: CalendarEventTimes]\n /** An event's end was dragged or nudged, in the same two parts. */\n 'event-resize': [event: E, previous: CalendarEventTimes]\n /**\n * An empty stretch of a day was drawn out, and these are its times. Nothing has been added\n * to `events`: this is the cue to make the event, in your own model or through your own form.\n */\n 'event-create': [times: CalendarEventTimes]\n}>()\n\ndefineSlots<{\n /** Extra controls in the toolbar, between the range and the view menu. */\n actions?(): unknown\n /** The content of one event's card, replacing the title and times. */\n event?(props: CalendarEventSlotProps<E>): unknown\n /** The head of one day column, replacing the weekday and the number. */\n 'day-header'?(props: { iso: string; weekday: string; dayText: string; today: boolean }): unknown\n /** The label beside the band of all-day events. */\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed(() => props.format ?? hourCycleFor(resolvedLocale.value))\nconst resolvedWeekdays = computed(() =>\n normalizeWeekdays(\n props.weekdays,\n props.firstDayOfWeek ?? firstDayOfWeekFor(resolvedLocale.value),\n ),\n)\n\nconst timeWindow = computed(() => windowOf(props.dayStart, props.dayEnd))\n\nconst days = computed(() =>\n visibleDays(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/** Which view is a time grid, and which is a summary. Several things below turn on this. */\nconst isTimeGrid = computed(() => view.value !== 'month' && view.value !== 'year')\n\nconst weeks = computed(() =>\n view.value === 'month' ? monthWeeks(date.value, resolvedWeekdays.value) : [],\n)\n\nconst months = computed(() => (view.value === 'year' ? monthsOfYear(date.value) : []))\n\n// @ssr\n// Way to tell either where the reader is, and rendering a guess would make the two markups\n// differ. Both stay null until then, and every rule that draws them is written to expect it.\nconst today = ref<string | null>(null)\nconst now = ref<number | null>(null)\n\nconst clock = useTimer()\n\n/**\n * The floor on the delay is not a nicety. `useTimer` runs a delay of zero or less\n * synchronously, by design, so a tick that ever computed one would call itself straight back\n * and go on doing so until the stack gave out.\n */\nfunction tick() {\n const at = new Date()\n now.value = at.getHours() * 60 + at.getMinutes()\n clock.start(tick, Math.max(1000, (60 - at.getSeconds()) * 1000))\n}\n\n/** Scrolls the time grid on show to `scrollTime`. */\nfunction scrollToStart() {\n const at = minutesOf(props.scrollTime)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n}\n\nonMounted(() => {\n today.value = todayISO()\n if (!props.hideCurrentTime) tick()\n scrollToStart()\n})\n\n// @core\n// Watch the visibility prop so toggling the current-time line starts or stops its timer after\n// mount.\nwatch(\n () => props.hideCurrentTime,\n (hidden) => {\n if (!hidden) return tick()\n clock.cancel()\n now.value = null\n },\n)\n\n/**\n * The usual form does not work here and the error it gives says nothing useful about why. A\n * generic `<script setup>` compiles to a FUNCTION, not to a class, so it has no construct\n * signature for `InstanceType` to read: the message complains that the component \"provides no\n * match for the signature `new (...args: any)`\", pointing at the template.\n */\nconst gridRef = ref<{\n focus(options?: FocusOptions): void\n scrollToMinutes(minutes: number): void\n} | null>(null)\n\n// @core\n// A time grid that appears after mount, a month switched to a week, opens at `scrollTime`\n// too. Post-flush, so the new grid is rendered and measurable when it is asked to scroll.\nwatch(gridRef, scrollToStart, { flush: 'post' })\n\n/** The region, the element a consumer's attributes land on. */\nconst regionEl = ref<HTMLElement | null>(null)\n\n/*\n * Which cell holds the tab stop, kept as two refs because the two kinds of view mean different\n * things by it: a time grid needs a day and an hour, a month only a day. One ref carrying an\n * hour the month ignores would leave that hour to go stale, and the grid would then reopen on\n * whatever the month happened to leave behind.\n */\nconst focused = ref<FocusedCell>({ iso: date.value, minutes: timeWindow.value.start })\nconst focusedDay = ref(date.value)\n\nconst range = computed(() =>\n visibleRange(date.value, view.value, resolvedWeekdays.value, props.customDays),\n)\n\n/**\n * What the toolbar says the calendar is showing. Each view names itself at the coarsest\n * granularity that still identifies it: a single day says its weekday, a year says nothing\n * but the number.\n */\nconst rangeText = computed(() => {\n const locale = resolvedLocale.value\n if (view.value === 'year')\n return formatDateDisplay(range.value.start, locale, { year: 'numeric' })\n if (view.value === 'month') {\n return formatDateDisplay(range.value.start, locale, { month: 'long', year: 'numeric' })\n }\n if (view.value === 'day') {\n return formatDateDisplay(range.value.start, locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n }\n return formatDisplayRange(range.value.start, range.value.end, locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n })\n})\n\nconst viewLabel = (value: CalendarView) => {\n const words = m.value.calendar\n if (value === 'day') return words.viewDay\n if (value === '4days') return words.view4Days\n if (value === 'week') return words.viewWeek\n if (value === 'month') return words.viewMonth\n if (value === 'year') return words.viewYear\n return words.viewCustom(props.customDays)\n}\n\n/** What the two navigation buttons are called. */\nconst stepLabels = computed(() => {\n const words = m.value.calendar\n if (view.value === 'day') return { previous: words.previousDay, next: words.nextDay }\n if (view.value === 'week') return { previous: words.previousWeek, next: words.nextWeek }\n if (view.value === 'month') return { previous: words.previousMonth, next: words.nextMonth }\n if (view.value === 'year') return { previous: words.previousYear, next: words.nextYear }\n return { previous: words.previousPeriod, next: words.nextPeriod }\n})\n\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.calendar.label)\n\n/*\n * The four ways of reaching another period all pass through here, and `disabled` is refused in\n * every one of them rather than on the controls alone: the edge step pages the view from a\n * drag, and the year grid opens a month from a cell, neither of which is a button this\n * component disabled. It is the VDatePicker arrangement, where the guard sits on `goTo`.\n */\nfunction step(delta: -1 | 1) {\n if (props.disabled) return\n date.value = stepAnchor(date.value, view.value, delta, resolvedWeekdays.value, props.customDays)\n}\n\nfunction goToToday() {\n if (props.disabled) return\n date.value = todayISO()\n}\n\nfunction setView(value: CalendarView) {\n if (props.disabled) return\n view.value = value\n}\n\n/**\n * `disabled` is refused here, and not by the stylesheet's `pointer-events: none` alone. That\n * rule stops a click, but the grid keeps its tab stop so the agenda stays readable, and Enter\n * on a focused cell reaches this with nothing in its way; a frozen calendar would go on\n * reporting cells to a consumer's form.\n */\nfunction onCellActivate(cell: ActivatedCell) {\n if (props.disabled) return\n emit('cell-activate', {\n date: cell.date,\n time: timeOf(cell.minutes ?? timeWindow.value.start),\n })\n}\n\n/**\n * Drill into an allowed detail view; if views excludes it, update the date while preserving the\n * current view.\n */\nfunction openIn(iso: string, target: CalendarView) {\n if (props.disabled) return\n date.value = iso\n if (props.views.includes(target)) view.value = target\n}\n\n/**\n * What a reader who cannot see the grid is told: the range after every step of a move, and\n * whether the move was taken or given up.\n */\nconst { polite: announcement, announce: say } = useLiveAnnouncer()\nconst uid = useId()\nconst hintId = `${uid}-hint`\n\n/*\n * Through the shared announcer, which empties the region and writes on the next tick: the\n * same words twice in a row are no change to a live region, and would not be read again.\n */\nfunction announce(message: string) {\n say(message, false)\n}\n\n/** Writes one event's new times into the model and says what happened. */\nfunction onEventDrop(id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize') {\n const current = events.value.find((item) => item.id === id)\n if (!current) return\n\n const previous = timesOf(current)\n // A gesture that ends where it began moved nothing, and a consumer's undo stack must not\n // gain an entry for it, nor its watchers a new array.\n if (sameTimes(previous, times)) return\n const next = { ...current, ...times }\n events.value = events.value.map((item) => (item.id === id ? next : item))\n // Written out rather than picking the name with a conditional: the emit signatures are an\n // overload set, and TypeScript resolves one only against a literal.\n if (kind === 'resize') emit('event-resize', next, previous)\n else emit('event-move', next, previous)\n}\n\n/*\n * A drawn slot is REPORTED and never added. What an event is called, what else it carries and\n * whether it exists at all are the consumer's decisions, so the calendar hands over the times\n * and draws nothing once the pointer is let go.\n */\nfunction onSlotCreate(times: CalendarEventTimes) {\n emit('event-create', times)\n}\n\ndefineExpose({\n /**\n * Brings the focus into the view: the cell the grid is showing, or the first month heading\n * in the year view.\n */\n focus: (options?: FocusOptions) => gridRef.value?.focus(options),\n /** The region, which is where your `id` and `aria-*` attributes land. */\n el: regionEl,\n /** Goes back to the current day, exactly as the Today button does. */\n today: goToToday,\n /** Moves back one view (a week, a month or a year), exactly as the toolbar's arrow does. */\n previous: () => step(-1),\n /** Moves forward one view. */\n next: () => step(1),\n /** Scrolls the grid so a given `HH:mm` sits at the top of the visible area. */\n scrollTo: (time: string) => {\n const at = minutesOf(time)\n if (at !== null) gridRef.value?.scrollToMinutes(at)\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-calendar\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-variant=\"variant\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <section\n ref=\"regionEl\"\n :aria-roledescription=\"m.calendar.roleDescription\"\n v-bind=\"forwardedAttrs\"\n class=\"v-calendar-region\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"v-calendar-toolbar\">\n <div class=\"v-calendar-nav\">\n <VIconButton\n :label=\"stepLabels.previous\"\n size=\"sm\"\n :disabled=\"disabled\"\n @click=\"step(-1)\"\n >\n <VIcon :name=\"chevronLeftIcon\" mirrored />\n </VIconButton>\n <VIconButton :label=\"stepLabels.next\" size=\"sm\" :disabled=\"disabled\" @click=\"step(1)\">\n <VIcon :name=\"chevronRightIcon\" mirrored />\n </VIconButton>\n </div>\n\n <VButton variant=\"outline\" tone=\"neutral\" size=\"sm\" :disabled=\"disabled\" @click=\"goToToday\">\n {{ m.calendar.today }}\n </VButton>\n\n <VTypography variant=\"heading-4\" as=\"h2\" class=\"v-calendar-title\">\n {{ rangeText }}\n </VTypography>\n\n <div class=\"v-calendar-actions\">\n <slot name=\"actions\" />\n\n <VMenu v-if=\"views.length > 1\" size=\"sm\" placement=\"bottom-end\" match-trigger>\n <template #trigger=\"{ triggerProps }\">\n <VButton\n variant=\"outline\"\n tone=\"neutral\"\n size=\"sm\"\n :disabled=\"disabled\"\n v-bind=\"triggerProps\"\n :aria-label=\"`${m.calendar.view}: ${viewLabel(view)}`\"\n >\n {{ viewLabel(view) }}\n <VIcon :name=\"arrowDropDownIcon\" />\n </VButton>\n </template>\n <VMenuItem\n v-for=\"value in views\"\n :key=\"value\"\n :label=\"viewLabel(value)\"\n :selected=\"value === view\"\n @select=\"setView(value)\"\n />\n </VMenu>\n </div>\n </div>\n\n <!--\n Invert opt-out public props once at the internal-grid boundary; internal view contracts\n use positive booleans.\n -->\n <VCalendarTimeGrid\n v-if=\"isTimeGrid\"\n ref=\"gridRef\"\n v-model:focused=\"focused\"\n class=\"v-calendar-view\"\n :days=\"days\"\n :events=\"events\"\n :time-window=\"timeWindow\"\n :slot-duration=\"slotDuration\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :now=\"hideCurrentTime ? null : now\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :creatable=\"creatable && !disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :auto-scroll=\"!noEdgeScroll\"\n :label=\"rangeText\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @slot-create=\"onSlotCreate\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['day-header']\" #day-header=\"slotProps\">\n <slot name=\"day-header\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['all-day-label']\" #all-day-label>\n <slot name=\"all-day-label\" />\n </template>\n </VCalendarTimeGrid>\n\n <VCalendarMonth\n v-else-if=\"view === 'month'\"\n ref=\"gridRef\"\n v-model:focused=\"focusedDay\"\n class=\"v-calendar-view\"\n :weeks=\"weeks\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :format=\"resolvedFormat\"\n :today=\"today\"\n :month-event-limit=\"monthEventLimit\"\n :editable=\"!readonly && !disabled\"\n :disabled=\"disabled\"\n :hint-id=\"hintId\"\n :edge-step-delay=\"edgeStepDelay\"\n :label=\"rangeText\"\n @day-activate=\"openIn($event, 'day')\"\n @cell-activate=\"onCellActivate\"\n @event-activate=\"emit('event-activate', $event)\"\n @event-drop=\"onEventDrop\"\n @announce=\"announce\"\n @step=\"step\"\n >\n <template v-if=\"$slots.event\" #event=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarMonth>\n\n <VCalendarYear\n v-else\n ref=\"gridRef\"\n class=\"v-calendar-view\"\n :disabled=\"disabled\"\n :months=\"months\"\n :events=\"events\"\n :locale=\"resolvedLocale\"\n :weekdays=\"resolvedWeekdays\"\n :today=\"today\"\n :label=\"rangeText\"\n @month-activate=\"openIn($event, 'month')\"\n />\n\n <!--\n Both of these are rendered from the first paint and never conditionally. The live region\n has to EXIST before it has anything to say: one inserted along with its first message is\n not announced at all.\n -->\n <div class=\"v-visually-hidden\" role=\"status\" aria-live=\"polite\">{{ announcement }}</div>\n <span :id=\"hintId\" class=\"v-visually-hidden\">{{ m.calendar.eventHint }}</span>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar {\n /*\n * The surface under the view, which its sticky headings repeat to stay opaque, and the\n * hover tint that has to stand out from it. Unframed, the page surface is the best guess at\n * what lies behind.\n */\n --calendar-surface: var(--vectis-color-surface);\n --calendar-hover-bg: var(--vectis-color-surface-muted);\n\n display: flex;\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 frozen calendar greys out through the colour tokens and never through opacity, the\n design system rule: what a reader keeps here is the agenda itself, which has to stay\n readable. The cards are real disabled buttons, so they grey themselves. */\n .v-calendar[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n .v-calendar[data-disabled] .v-calendar-view {\n pointer-events: none;\n }\n\n /*\n * `min-block-size: 0` on the grid is what lets it shrink below its content and therefore\n * scroll; without it the automatic minimum of a flex item would hold it at its full 24-hour\n * height and the whole page would scroll instead. All of it is a no-op when the parent's\n * height is auto, where the percentage falls back to auto and the calendar is simply as tall\n * as its content.\n */\n .v-calendar-region {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-inline-size: 0;\n min-block-size: 0;\n }\n\n .v-calendar-toolbar {\n display: flex;\n flex: none;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--vectis-space-2);\n padding-block-end: var(--vectis-space-3);\n }\n\n .v-calendar-nav {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-calendar-title {\n /*\n * It may be long; a full weekday and month in the day view; so it is the part that gives\n * way first, and the controls keep their size.\n */\n min-inline-size: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-2);\n /* The two siblings are pushed apart from here rather than by a `justify-content` on the\n toolbar, which would space every control equally instead of grouping them. */\n margin-inline-start: auto;\n }\n\n /*\n * The view on show, whichever it is: the one box that scrolls. The views inherit the family\n * and the colour from `.v-calendar` and declare neither again.\n */\n .v-calendar-view {\n flex: 1;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n /* Transparent rather than absent: forced colours paint it. Only `elevated` drops it, so\n that the grid's rules reach the edge its shadow draws. */\n border: 1px solid transparent;\n border-radius: var(--vectis-radius-surface);\n }\n\n .v-calendar[data-variant='outline'] .v-calendar-view {\n background: var(--calendar-surface);\n border-color: var(--vectis-color-border);\n }\n\n .v-calendar[data-variant='elevated'] {\n --calendar-surface: var(--vectis-color-surface-raised);\n }\n\n .v-calendar[data-variant='elevated'] .v-calendar-view {\n border: none;\n background: var(--calendar-surface);\n box-shadow: var(--vectis-shadow-sm);\n }\n\n .v-calendar[data-variant='filled'] {\n --calendar-surface: var(--vectis-color-surface-muted);\n --calendar-hover-bg: color-mix(\n in oklab,\n var(--vectis-color-surface-muted),\n var(--vectis-color-text) 4%\n );\n }\n\n .v-calendar[data-variant='filled'] .v-calendar-view {\n background: var(--calendar-surface);\n }\n\n /*\n * Every rule a view writes against one of these classes is either disjoint from it or more\n * specific, never tied: a tie between two sheets would be settled by the consumer's bundler.\n */\n\n /*\n * `not-allowed` is the word the library already uses for \"you cannot do this\", on every\n * disabled control. BEST-EFFORT, and never the signal: while a pointer is captured the cursor\n * is resolved against the capture target rather than against whatever sits under the pointer,\n * and engines differ on it.\n */\n .v-calendar-view[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-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 /*\n * Today's date, marked on the number the way a calendar marks a date rather than a column.\n * Semibold here marks a state, not a type role.\n */\n .v-calendar-view .v-calendar-today {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /*\n * A cell of either grid: ruled on two sides, the other two drawn by its neighbours. It keeps\n * the default cursor: the pointer hand belongs to what can be opened, the events, and a grid\n * of hands would say every square of the week is a link.\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 }\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 view 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-button {\n /* A button carries a border and a background from the browser, which around a round day\n number read as a stray ring. Neither is optional. */\n border: none;\n background: none;\n font-family: inherit;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-button: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 /*\n * Drawn INSIDE the box the cells occupy rather than on the scroller, because a scroller's\n * absolutely positioned child is placed against its content and scrolls away with it. That\n * box has to be positioned, which each view's own sheet sees to.\n */\n .v-calendar-edge-cue[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-edge-cue[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-edge-cue[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-button {\n transition: none;\n }\n }\n\n /*\n * Windows forced colors flattens every background to Canvas, and today and the paging strip\n * are drawn with nothing else. Today takes the system selection pair, the one every other\n * \"current\" mark in the library takes, and the strip takes Highlight.\n */\n @media (forced-colors: active) {\n .v-calendar-view .v-calendar-today {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .v-calendar-edge-cue[data-edge]::after {\n forced-color-adjust: none;\n background: Highlight;\n }\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VCalendarEvent.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * Share the native event button across calendar views so accessible naming and event-slot\n * rendering remain consistent.\n */\nimport { computed } from 'vue'\n\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useMessages } from '../../i18n/state'\n\nimport { hueOf } from './color'\nimport type {\n CalendarEvent,\n CalendarEventId,\n CalendarEventLayout,\n CalendarEventSlotProps,\n} from './types'\n\nexport interface CalendarEventProps<T> {\n /** The event this card stands for. */\n event: T\n /**\n * Which shape to take: a block, which fills the box the calendar gives it and can show a\n * second line, or a chip, which is one line high and sits in a row of others.\n */\n layout?: CalendarEventLayout\n /** The event's times, already written out for the reader by the calendar. */\n timeText?: string\n /** Whether the event carries on past the start or the end of what is on show. */\n continuesBefore?: boolean\n continuesAfter?: boolean\n /** Shows the strip along the bottom edge that the event's end is dragged by. */\n resizable?: boolean\n /** Whether the card is being dragged with a pointer right now. */\n dragging?: boolean\n /**\n * Whether letting go now would write nothing: the pointer has left the calendar, and the\n * event is about to return to where the faded echo shows it started.\n */\n rejected?: boolean\n /** Whether the card has been taken hold of with the keyboard. */\n grabbed?: boolean\n /** How the card says it can be moved, read from a node the calendar shares between them. */\n hintId?: string\n /**\n * Marks this card as the faded echo left behind where a dragged event STARTED, and names the\n * event it echoes.\n */\n ghostOf?: CalendarEventId\n /** Whether the whole calendar is disabled, which makes the card a real disabled button. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<CalendarEventProps<E>>(), {\n layout: 'block',\n timeText: '',\n continuesBefore: false,\n continuesAfter: false,\n resizable: false,\n dragging: false,\n rejected: false,\n grabbed: false,\n hintId: undefined,\n ghostOf: undefined,\n disabled: false,\n})\n\ndefineSlots<{\n /** The whole content of the card, replacing the title and the times. */\n default?(props: CalendarEventSlotProps<E>): unknown\n}>()\n\nconst m = useMessages()\n\n/*\n * A colour given by the consumer is used as it stands; otherwise a hue is derived from the\n * event's id and the token layer supplies the lightness and the chroma that go with it. The two\n * are kept apart by an attribute rather than by a fallback chain, because the custom case needs\n * a DIFFERENT recipe and not merely a different value; see the stylesheet below.\n */\nconst hue = computed(() => hueOf(props.ghostOf ?? props.event.id))\n\nconst style = computed(() =>\n props.event.color\n ? { '--calendar-event-color': props.event.color }\n : { '--vectis-calendar-event-hue': String(hue.value) },\n)\n\n/** What a screen reader hears: the title, then when it happens. */\nconst accessibleName = computed(() =>\n props.timeText ? `${props.event.title}, ${props.timeText}` : props.event.title,\n)\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"v-calendar-event\"\n :data-event-id=\"String(event.id)\"\n :data-layout=\"layout\"\n :data-custom=\"event.color ? '' : undefined\"\n :data-continues-before=\"continuesBefore ? '' : undefined\"\n :data-continues-after=\"continuesAfter ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n :data-rejected=\"rejected ? '' : undefined\"\n :data-grabbed=\"grabbed ? '' : undefined\"\n :data-ghost=\"ghostOf !== undefined ? '' : undefined\"\n :style=\"style\"\n :aria-label=\"accessibleName\"\n :aria-roledescription=\"m.calendar.eventRoleDescription\"\n :aria-describedby=\"hintId\"\n :disabled=\"disabled || undefined\"\n :inert=\"ghostOf !== undefined ? true : undefined\"\n >\n <!--\n The content sits in a box of its own because the CARD is the container the stylesheet\n queries, and an element cannot be styled by its own container query. The layout that has\n to change when a card gets short; a column of two lines becoming one row; must therefore\n live on a descendant.\n -->\n <span class=\"v-calendar-event-body\">\n <slot\n :event=\"event\"\n :layout=\"layout\"\n :time-text=\"timeText\"\n :continues-before=\"continuesBefore\"\n :continues-after=\"continuesAfter\"\n :dragging=\"dragging\"\n :grabbed=\"grabbed\"\n >\n <span class=\"v-calendar-event-title\">{{ event.title }}</span>\n <span v-if=\"layout === 'block' && timeText\" class=\"v-calendar-event-time\">\n {{ timeText }}\n </span>\n <VTypography\n v-if=\"layout === 'block' && event.description\"\n as=\"span\"\n variant=\"caption\"\n class=\"v-calendar-event-description\"\n >\n {{ event.description }}\n </VTypography>\n </slot>\n </span>\n\n <!--\n It is a pointer affordance and nothing else, and its keyboard equivalent lives on the card\n itself as Shift with the arrow keys; which is why hiding it costs a reader nothing.\n -->\n <span\n v-if=\"resizable && layout === 'block'\"\n class=\"v-calendar-event-handle\"\n data-calendar-handle\n aria-hidden=\"true\"\n />\n </button>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-event {\n /*\n * The three colours of a card, named by what they paint rather than by where they come\n * from; which lets the custom block below swap the source of all three without touching a\n * single rule that consumes them.\n */\n /*\n * The hue is turned here, on the card, and never in the tokens. Relative colour syntax\n * keeps the token's lightness and chroma, which are what hold the title's contrast, and\n * takes the hue the card sets inline, or the token's own (`h`) when none is set.\n */\n --calendar-event-face: oklch(\n from var(--vectis-color-event-surface) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-edge: oklch(\n from var(--vectis-color-event-border) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-ink: oklch(\n from var(--vectis-color-event-text) l c var(--vectis-calendar-event-hue, h)\n );\n\n position: relative;\n display: flex;\n overflow: hidden;\n /*\n * It is safe because a card's two dimensions are both set outright by `.v-calendar-block`;\n * size containment therefore removes an influence nothing was exercising. Asking in minutes\n * instead would have meant calibrating against `--vectis-control-size-calendar-hour`, and\n * being silently wrong for anyone who overrode it.\n */\n container-type: size;\n border: 1px solid var(--calendar-event-edge);\n /* The leading edge is what carries the colour at a glance, so it is drawn thicker. It\n is a border and not a background stripe: under Windows forced-colors a background is\n forced to Canvas and vanishes, where a border keeps a colour of its own. */\n border-inline-start: var(--vectis-control-size-calendar-event-edge) solid\n var(--calendar-event-edge);\n /*\n * A browser scales down any radius it cannot fit, so a chip already paints half a lane\n * under a large --vectis-radius-interactive; min() applies that same reduction to a timed\n * block, whose height is the event's DURATION. Written bare, a pill theme paints half of a\n * three-hour block instead: 96px corners on one card and 12px on the chip beside it.\n */\n border-radius: min(\n var(--vectis-radius-interactive),\n calc(var(--vectis-control-size-calendar-allday-lane) / 2)\n );\n background: var(--calendar-event-face);\n color: var(--calendar-event-ink);\n font-family: var(--vectis-text-family);\n text-align: start;\n cursor: pointer;\n transition:\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default),\n filter var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * A colour the consumer chose is an arbitrary value, so the card is built so that NOTHING is\n * ever written on top of it: it paints the edge, and the face is a faint wash of it over the\n * page's own surface; which also makes it follow the theme with no second setting. The text\n * stays the page's text colour, whose contrast against that surface is already guaranteed.\n */\n .v-calendar-event[data-custom] {\n --calendar-event-edge: var(--calendar-event-color);\n --calendar-event-face: color-mix(\n in oklab,\n var(--calendar-event-color) 14%,\n var(--vectis-color-surface)\n );\n --calendar-event-ink: var(--vectis-color-text);\n }\n\n .v-calendar-event-body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 1px;\n /* Without this a flex item refuses to shrink past its content, and a card too short for\n its own text would push its title out of the clip instead of cropping it. */\n min-block-size: 0;\n min-inline-size: 0;\n overflow: hidden;\n padding: var(--vectis-space-1) var(--vectis-space-2);\n }\n\n /*\n * Give the time a larger weighted flex-shrink so it disappears before truncating the event\n * title.\n */\n @container (max-block-size: 3rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-title {\n flex: 0 1 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n flex: 0 1000 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-description {\n display: none;\n }\n }\n\n /*\n * The shortest card there is: one slot, which at the default hour height is sixteen pixels,\n * leaving fourteen once the border is taken. A line of the title at its normal leading is\n * eighteen; so the leading is what gives, down to the glyphs themselves.\n */\n @container (max-block-size: 1.5rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-title,\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n line-height: 1;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-handle {\n block-size: calc(var(--vectis-control-size-calendar-handle) / 2);\n }\n }\n\n .v-calendar-event:hover {\n filter: brightness(0.97);\n }\n\n /*\n * `pointer-events: none` matters as much: the pointer is captured by the grid, and a card\n * under the cursor would otherwise take the hover of every cell it passed over.\n */\n .v-calendar-event[data-dragging] {\n opacity: 0.75;\n box-shadow: var(--vectis-shadow-md);\n pointer-events: none;\n z-index: 3;\n }\n\n /*\n * This rule must stay BELOW `[data-dragging]`. Both are (0,2,0) and a refused card is always\n * also a dragged one, so the later rule is the whole of the arbitration.\n */\n .v-calendar-event[data-rejected] {\n --calendar-event-face: var(--vectis-color-danger-surface);\n --calendar-event-edge: var(--vectis-color-danger-border);\n --calendar-event-ink: var(--vectis-color-danger-text);\n\n border-style: dotted;\n box-shadow: none;\n }\n\n /*\n * The echo left where a dragged event started, so the reader can see what they are moving it\n * FROM; without it a long drag ends with no idea what has just been given up. Faded rather\n * than outlined, and dashed rather than solid, so that it reads as a memory and not as a\n * second event: at a glance the only card that looks real is the one under the pointer.\n */\n .v-calendar-event[data-ghost] {\n opacity: 0.4;\n border-style: dashed;\n z-index: 0;\n }\n\n /* Held by the keyboard: the same lift, but marked with the focus ring's own colour, since\n there is no pointer to show where it is going. */\n .v-calendar-event[data-grabbed] {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n box-shadow: var(--vectis-shadow-md);\n z-index: 3;\n }\n\n .v-calendar-event-handle {\n position: absolute;\n inset-block-end: 0;\n inset-inline: 0;\n block-size: var(--vectis-control-size-calendar-handle);\n /* Dragging here IS how the end is set, so it must do nothing else: no scrolling under a\n finger, and no selecting the text it sits over. */\n touch-action: none;\n cursor: ns-resize;\n }\n\n /* The grip appears on hover and while the card is being resized, never permanently: a\n short card is mostly handle, and a line across every event all the time reads as a\n border nobody asked for. */\n .v-calendar-event-handle::after {\n content: '';\n position: absolute;\n inset-block-end: var(--vectis-control-size-calendar-grip-thickness);\n inset-inline-start: 50%;\n inline-size: var(--vectis-control-size-calendar-grip);\n block-size: var(--vectis-control-size-calendar-grip-thickness);\n translate: -50% 0;\n border-radius: var(--vectis-radius-pill);\n background: var(--calendar-event-ink);\n opacity: 0;\n transition: opacity var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-event:hover .v-calendar-event-handle::after,\n .v-calendar-event[data-dragging] .v-calendar-event-handle::after {\n opacity: 0.6;\n }\n\n .v-calendar-event:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n /* An event running past what is on show loses the corner on that side, so the card reads\n as cut off rather than as merely small. */\n .v-calendar-event[data-continues-before] {\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n border-block-start-style: dashed;\n }\n\n .v-calendar-event[data-continues-after] {\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n border-block-end-style: dashed;\n }\n\n /*\n * The height goes through `--calendar-chip-height`, which `.v-calendar-month-chip` sets,\n * rather than that rule setting `block-size` itself. This selector is (0,2,0) and that one is\n * (0,1,0) in ANOTHER SHEET: matching specificity would hand the winner to whichever order the\n * consumer's bundler emits, and beating it would need a three-class compound.\n */\n .v-calendar-event[data-layout='chip'] {\n block-size: var(--calendar-chip-height, 100%);\n }\n\n .v-calendar-event[data-layout='chip'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event-title {\n overflow: hidden;\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-font-weight-medium);\n line-height: var(--vectis-text-body-sm-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-event-time {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n /*\n * The times are secondary to the title, but the card's colour is already doing the quiet\n * work; a muted token here would fight it, so the same ink at less weight.\n */\n opacity: 0.85;\n }\n\n .v-calendar-event-description {\n overflow: hidden;\n /* The card's height is the event's length, so a description shows only where there is\n genuinely room for it: it takes whatever is left and disappears when that is nothing. */\n min-block-size: 0;\n color: inherit;\n text-overflow: ellipsis;\n opacity: 0.85;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-event,\n .v-calendar-event-handle::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .v-calendar-event-handle::after {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VCalendarEvent.js","names":["_sfc_main","VCalendarEvent_vue_vue_type_script_setup_true_lang_default","VCalendarEvent_default"],"sources":["../../../src/components/VCalendar/VCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * Share the native event button across calendar views so accessible naming and event-slot\n * rendering remain consistent.\n */\nimport { computed } from 'vue'\n\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useMessages } from '../../i18n/state'\n\nimport { hueOf } from './color'\nimport type {\n CalendarEvent,\n CalendarEventId,\n CalendarEventLayout,\n CalendarEventSlotProps,\n} from './types'\n\nexport interface CalendarEventProps<T> {\n /** The event this card stands for. */\n event: T\n /**\n * Which shape to take: a block, which fills the box the calendar gives it and can show a\n * second line, or a chip, which is one line high and sits in a row of others.\n */\n layout?: CalendarEventLayout\n /** The event's times, already written out for the reader by the calendar. */\n timeText?: string\n /** Whether the event carries on past the start or the end of what is on show. */\n continuesBefore?: boolean\n continuesAfter?: boolean\n /** Shows the strip along the bottom edge that the event's end is dragged by. */\n resizable?: boolean\n /** Whether the card is being dragged with a pointer right now. */\n dragging?: boolean\n /**\n * Whether letting go now would write nothing: the pointer has left the calendar, and the\n * event is about to return to where the faded echo shows it started.\n */\n rejected?: boolean\n /** Whether the card has been taken hold of with the keyboard. */\n grabbed?: boolean\n /** How the card says it can be moved, read from a node the calendar shares between them. */\n hintId?: string\n /**\n * Marks this card as the faded echo left behind where a dragged event STARTED, and names the\n * event it echoes.\n */\n ghostOf?: CalendarEventId\n /** Whether the whole calendar is disabled, which makes the card a real disabled button. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<CalendarEventProps<E>>(), {\n layout: 'block',\n timeText: '',\n continuesBefore: false,\n continuesAfter: false,\n resizable: false,\n dragging: false,\n rejected: false,\n grabbed: false,\n hintId: undefined,\n ghostOf: undefined,\n disabled: false,\n})\n\ndefineSlots<{\n /** The whole content of the card, replacing the title and the times. */\n default?(props: CalendarEventSlotProps<E>): unknown\n}>()\n\nconst m = useMessages()\n\n/*\n * A colour given by the consumer is used as it stands; otherwise a hue is derived from the\n * event's id and the token layer supplies the lightness and the chroma that go with it. The two\n * are kept apart by an attribute rather than by a fallback chain, because the custom case needs\n * a DIFFERENT recipe and not merely a different value; see the stylesheet below.\n */\nconst hue = computed(() => hueOf(props.ghostOf ?? props.event.id))\n\nconst style = computed(() =>\n props.event.color\n ? { '--calendar-event-color': props.event.color }\n : { '--vectis-calendar-event-hue': String(hue.value) },\n)\n\n/** What a screen reader hears: the title, then when it happens. */\nconst accessibleName = computed(() =>\n props.timeText ? `${props.event.title}, ${props.timeText}` : props.event.title,\n)\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"v-calendar-event\"\n :data-event-id=\"String(event.id)\"\n :data-layout=\"layout\"\n :data-custom=\"event.color ? '' : undefined\"\n :data-continues-before=\"continuesBefore ? '' : undefined\"\n :data-continues-after=\"continuesAfter ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n :data-rejected=\"rejected ? '' : undefined\"\n :data-grabbed=\"grabbed ? '' : undefined\"\n :data-ghost=\"ghostOf !== undefined ? '' : undefined\"\n :style=\"style\"\n :aria-label=\"accessibleName\"\n :aria-roledescription=\"m.calendar.eventRoleDescription\"\n :aria-describedby=\"hintId\"\n :disabled=\"disabled || undefined\"\n :inert=\"ghostOf !== undefined ? true : undefined\"\n >\n <!--\n The content sits in a box of its own because the CARD is the container the stylesheet\n queries, and an element cannot be styled by its own container query. The layout that has\n to change when a card gets short; a column of two lines becoming one row; must therefore\n live on a descendant.\n -->\n <span class=\"v-calendar-event-body\">\n <slot\n :event=\"event\"\n :layout=\"layout\"\n :time-text=\"timeText\"\n :continues-before=\"continuesBefore\"\n :continues-after=\"continuesAfter\"\n :dragging=\"dragging\"\n :grabbed=\"grabbed\"\n >\n <span class=\"v-calendar-event-title\">{{ event.title }}</span>\n <span v-if=\"layout === 'block' && timeText\" class=\"v-calendar-event-time\">\n {{ timeText }}\n </span>\n <VTypography\n v-if=\"layout === 'block' && event.description\"\n as=\"span\"\n variant=\"caption\"\n class=\"v-calendar-event-description\"\n >\n {{ event.description }}\n </VTypography>\n </slot>\n </span>\n\n <!--\n It is a pointer affordance and nothing else, and its keyboard equivalent lives on the card\n itself as Shift with the arrow keys; which is why hiding it costs a reader nothing.\n -->\n <span\n v-if=\"resizable && layout === 'block'\"\n class=\"v-calendar-event-handle\"\n data-calendar-handle\n aria-hidden=\"true\"\n />\n </button>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-event {\n /*\n * The three colours of a card, named by what they paint rather than by where they come\n * from; which lets the custom block below swap the source of all three without touching a\n * single rule that consumes them.\n */\n /*\n * The hue is turned here, on the card, and never in the tokens. Relative colour syntax\n * keeps the token's lightness and chroma, which are what hold the title's contrast, and\n * takes the hue the card sets inline, or the token's own (`h`) when none is set.\n */\n --calendar-event-face: oklch(\n from var(--vectis-color-event-surface) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-edge: oklch(\n from var(--vectis-color-event-border) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-ink: oklch(\n from var(--vectis-color-event-text) l c var(--vectis-calendar-event-hue, h)\n );\n\n position: relative;\n display: flex;\n overflow: hidden;\n /*\n * It is safe because a card's two dimensions are both set outright by `.v-calendar-block`;\n * size containment therefore removes an influence nothing was exercising. Asking in minutes\n * instead would have meant calibrating against `--vectis-control-size-calendar-hour`, and\n * being silently wrong for anyone who overrode it.\n */\n container-type: size;\n border: 1px solid var(--calendar-event-edge);\n /* The leading edge is what carries the colour at a glance, so it is drawn thicker. It\n is a border and not a background stripe: under Windows forced-colors a background is\n forced to Canvas and vanishes, where a border keeps a colour of its own. */\n border-inline-start: var(--vectis-control-size-calendar-event-edge) solid\n var(--calendar-event-edge);\n /*\n * A browser scales down any radius it cannot fit, so a chip already paints half a lane\n * under a large --vectis-radius-interactive; min() applies that same reduction to a timed\n * block, whose height is the event's DURATION. Written bare, a pill theme paints half of a\n * three-hour block instead: 96px corners on one card and 12px on the chip beside it.\n */\n border-radius: min(\n var(--vectis-radius-interactive),\n calc(var(--vectis-control-size-calendar-allday-lane) / 2)\n );\n background: var(--calendar-event-face);\n color: var(--calendar-event-ink);\n font-family: var(--vectis-text-family);\n text-align: start;\n cursor: pointer;\n transition:\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default),\n filter var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * A colour the consumer chose is an arbitrary value, so the card is built so that NOTHING is\n * ever written on top of it: it paints the edge, and the face is a faint wash of it over the\n * page's own surface; which also makes it follow the theme with no second setting. The text\n * stays the page's text colour, whose contrast against that surface is already guaranteed.\n */\n .v-calendar-event[data-custom] {\n --calendar-event-edge: var(--calendar-event-color);\n --calendar-event-face: color-mix(\n in oklab,\n var(--calendar-event-color) 14%,\n var(--vectis-color-surface)\n );\n --calendar-event-ink: var(--vectis-color-text);\n }\n\n .v-calendar-event-body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 1px;\n /* Without this a flex item refuses to shrink past its content, and a card too short for\n its own text would push its title out of the clip instead of cropping it. */\n min-block-size: 0;\n min-inline-size: 0;\n overflow: hidden;\n padding: var(--vectis-space-1) var(--vectis-space-2);\n }\n\n /*\n * Give the time a larger weighted flex-shrink so it disappears before truncating the event\n * title.\n */\n @container (max-block-size: 3rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-title {\n flex: 0 1 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n flex: 0 1000 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-description {\n display: none;\n }\n }\n\n /*\n * The shortest card there is: one slot, which at the default hour height is sixteen pixels,\n * leaving fourteen once the border is taken. A line of the title at its normal leading is\n * eighteen; so the leading is what gives, down to the glyphs themselves.\n */\n @container (max-block-size: 1.5rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-title,\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n line-height: 1;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-handle {\n block-size: calc(var(--vectis-control-size-calendar-handle) / 2);\n }\n }\n\n .v-calendar-event:hover {\n filter: brightness(0.97);\n }\n\n /*\n * `pointer-events: none` matters as much: the pointer is captured by the grid, and a card\n * under the cursor would otherwise take the hover of every cell it passed over.\n */\n .v-calendar-event[data-dragging] {\n opacity: 0.75;\n box-shadow: var(--vectis-shadow-md);\n pointer-events: none;\n z-index: 3;\n }\n\n /*\n * This rule must stay BELOW `[data-dragging]`. Both are (0,2,0) and a refused card is always\n * also a dragged one, so the later rule is the whole of the arbitration.\n */\n .v-calendar-event[data-rejected] {\n --calendar-event-face: var(--vectis-color-danger-surface);\n --calendar-event-edge: var(--vectis-color-danger-border);\n --calendar-event-ink: var(--vectis-color-danger-text);\n\n border-style: dotted;\n box-shadow: none;\n }\n\n /*\n * The echo left where a dragged event started, so the reader can see what they are moving it\n * FROM; without it a long drag ends with no idea what has just been given up. Faded rather\n * than outlined, and dashed rather than solid, so that it reads as a memory and not as a\n * second event: at a glance the only card that looks real is the one under the pointer.\n */\n .v-calendar-event[data-ghost] {\n opacity: 0.4;\n border-style: dashed;\n z-index: 0;\n }\n\n /* Held by the keyboard: the same lift, but marked with the focus ring's own colour, since\n there is no pointer to show where it is going. */\n .v-calendar-event[data-grabbed] {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n box-shadow: var(--vectis-shadow-md);\n z-index: 3;\n }\n\n .v-calendar-event-handle {\n position: absolute;\n inset-block-end: 0;\n inset-inline: 0;\n block-size: var(--vectis-control-size-calendar-handle);\n /* Dragging here IS how the end is set, so it must do nothing else: no scrolling under a\n finger, and no selecting the text it sits over. */\n touch-action: none;\n cursor: ns-resize;\n }\n\n /* The grip appears on hover and while the card is being resized, never permanently: a\n short card is mostly handle, and a line across every event all the time reads as a\n border nobody asked for. */\n .v-calendar-event-handle::after {\n content: '';\n position: absolute;\n inset-block-end: var(--vectis-control-size-calendar-grip-thickness);\n inset-inline-start: 50%;\n inline-size: var(--vectis-control-size-calendar-grip);\n block-size: var(--vectis-control-size-calendar-grip-thickness);\n translate: -50% 0;\n border-radius: var(--vectis-radius-pill);\n background: var(--calendar-event-ink);\n opacity: 0;\n transition: opacity var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-event:hover .v-calendar-event-handle::after,\n .v-calendar-event[data-dragging] .v-calendar-event-handle::after {\n opacity: 0.6;\n }\n\n .v-calendar-event:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n /* An event running past what is on show loses the corner on that side, so the card reads\n as cut off rather than as merely small. */\n .v-calendar-event[data-continues-before] {\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n border-block-start-style: dashed;\n }\n\n .v-calendar-event[data-continues-after] {\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n border-block-end-style: dashed;\n }\n\n /*\n * The height goes through `--calendar-chip-height`, which `.v-calendar-month-chip` sets,\n * rather than that rule setting `block-size` itself. This selector is (0,2,0) and that one is\n * (0,1,0) in ANOTHER SHEET: matching specificity would hand the winner to whichever order the\n * consumer's bundler emits, and beating it would need a three-class compound.\n */\n .v-calendar-event[data-layout='chip'] {\n block-size: var(--calendar-chip-height, 100%);\n }\n\n .v-calendar-event[data-layout='chip'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event-title {\n overflow: hidden;\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-font-weight-medium);\n line-height: var(--vectis-text-body-sm-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-event-time {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n /*\n * The times are secondary to the title, but the card's colour is already doing the quiet\n * work; a muted token here would fight it, so the same ink at less weight.\n */\n opacity: 0.85;\n }\n\n .v-calendar-event-description {\n overflow: hidden;\n /* The card's height is the event's length, so a description shows only where there is\n genuinely room for it: it takes whatever is left and disappears when that is nothing. */\n min-block-size: 0;\n color: inherit;\n text-overflow: ellipsis;\n opacity: 0.85;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-event,\n .v-calendar-event-handle::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .v-calendar-event-handle::after {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VCalendarEvent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * Share the native event button across calendar views so accessible naming and event-slot\n * rendering remain consistent.\n */\nimport { computed } from 'vue'\n\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useMessages } from '../../i18n/state'\n\nimport { hueOf } from './color'\nimport type {\n CalendarEvent,\n CalendarEventId,\n CalendarEventLayout,\n CalendarEventSlotProps,\n} from './types'\n\nexport interface CalendarEventProps<T> {\n /** The event this card stands for. */\n event: T\n /**\n * Which shape to take: a block, which fills the box the calendar gives it and can show a\n * second line, or a chip, which is one line high and sits in a row of others.\n */\n layout?: CalendarEventLayout\n /** The event's times, already written out for the reader by the calendar. */\n timeText?: string\n /** Whether the event carries on past the start or the end of what is on show. */\n continuesBefore?: boolean\n continuesAfter?: boolean\n /** Shows the strip along the bottom edge that the event's end is dragged by. */\n resizable?: boolean\n /** Whether the card is being dragged with a pointer right now. */\n dragging?: boolean\n /**\n * Whether letting go now would write nothing: the pointer has left the calendar, and the\n * event is about to return to where the faded echo shows it started.\n */\n rejected?: boolean\n /** Whether the card has been taken hold of with the keyboard. */\n grabbed?: boolean\n /** How the card says it can be moved, read from a node the calendar shares between them. */\n hintId?: string\n /**\n * Marks this card as the faded echo left behind where a dragged event STARTED, and names the\n * event it echoes.\n */\n ghostOf?: CalendarEventId\n /** Whether the whole calendar is disabled, which makes the card a real disabled button. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<CalendarEventProps<E>>(), {\n layout: 'block',\n timeText: '',\n continuesBefore: false,\n continuesAfter: false,\n resizable: false,\n dragging: false,\n rejected: false,\n grabbed: false,\n hintId: undefined,\n ghostOf: undefined,\n disabled: false,\n})\n\ndefineSlots<{\n /** The whole content of the card, replacing the title and the times. */\n default?(props: CalendarEventSlotProps<E>): unknown\n}>()\n\nconst m = useMessages()\n\n/*\n * A colour given by the consumer is used as it stands; otherwise a hue is derived from the\n * event's id and the token layer supplies the lightness and the chroma that go with it. The two\n * are kept apart by an attribute rather than by a fallback chain, because the custom case needs\n * a DIFFERENT recipe and not merely a different value; see the stylesheet below.\n */\nconst hue = computed(() => hueOf(props.ghostOf ?? props.event.id))\n\nconst style = computed(() =>\n props.event.color\n ? { '--calendar-event-color': props.event.color }\n : { '--vectis-calendar-event-hue': String(hue.value) },\n)\n\n/** What a screen reader hears: the title, then when it happens. */\nconst accessibleName = computed(() =>\n props.timeText ? `${props.event.title}, ${props.timeText}` : props.event.title,\n)\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"v-calendar-event\"\n :data-event-id=\"String(event.id)\"\n :data-layout=\"layout\"\n :data-custom=\"event.color ? '' : undefined\"\n :data-continues-before=\"continuesBefore ? '' : undefined\"\n :data-continues-after=\"continuesAfter ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n :data-rejected=\"rejected ? '' : undefined\"\n :data-grabbed=\"grabbed ? '' : undefined\"\n :data-ghost=\"ghostOf !== undefined ? '' : undefined\"\n :style=\"style\"\n :aria-label=\"accessibleName\"\n :aria-roledescription=\"m.calendar.eventRoleDescription\"\n :aria-describedby=\"hintId\"\n :disabled=\"disabled || undefined\"\n :inert=\"ghostOf !== undefined ? true : undefined\"\n >\n <!--\n The content sits in a box of its own because the CARD is the container the stylesheet\n queries, and an element cannot be styled by its own container query. The layout that has\n to change when a card gets short; a column of two lines becoming one row; must therefore\n live on a descendant.\n -->\n <span class=\"v-calendar-event-body\">\n <slot\n :event=\"event\"\n :layout=\"layout\"\n :time-text=\"timeText\"\n :continues-before=\"continuesBefore\"\n :continues-after=\"continuesAfter\"\n :dragging=\"dragging\"\n :grabbed=\"grabbed\"\n >\n <span class=\"v-calendar-event-title\">{{ event.title }}</span>\n <span v-if=\"layout === 'block' && timeText\" class=\"v-calendar-event-time\">\n {{ timeText }}\n </span>\n <VTypography\n v-if=\"layout === 'block' && event.description\"\n as=\"span\"\n variant=\"caption\"\n class=\"v-calendar-event-description\"\n >\n {{ event.description }}\n </VTypography>\n </slot>\n </span>\n\n <!--\n It is a pointer affordance and nothing else, and its keyboard equivalent lives on the card\n itself as Shift with the arrow keys; which is why hiding it costs a reader nothing.\n -->\n <span\n v-if=\"resizable && layout === 'block'\"\n class=\"v-calendar-event-handle\"\n data-calendar-handle\n aria-hidden=\"true\"\n />\n </button>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-event {\n /*\n * The three colours of a card, named by what they paint rather than by where they come\n * from; which lets the custom block below swap the source of all three without touching a\n * single rule that consumes them.\n */\n /*\n * The hue is turned here, on the card, and never in the tokens. Relative colour syntax\n * keeps the token's lightness and chroma, which are what hold the title's contrast, and\n * takes the hue the card sets inline, or the token's own (`h`) when none is set.\n */\n --calendar-event-face: oklch(\n from var(--vectis-color-event-surface) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-edge: oklch(\n from var(--vectis-color-event-border) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-ink: oklch(\n from var(--vectis-color-event-text) l c var(--vectis-calendar-event-hue, h)\n );\n\n position: relative;\n display: flex;\n overflow: hidden;\n /*\n * It is safe because a card's two dimensions are both set outright by `.v-calendar-block`;\n * size containment therefore removes an influence nothing was exercising. Asking in minutes\n * instead would have meant calibrating against `--vectis-control-size-calendar-hour`, and\n * being silently wrong for anyone who overrode it.\n */\n container-type: size;\n border: 1px solid var(--calendar-event-edge);\n /* The leading edge is what carries the colour at a glance, so it is drawn thicker. It\n is a border and not a background stripe: under Windows forced-colors a background is\n forced to Canvas and vanishes, where a border keeps a colour of its own. */\n border-inline-start: var(--vectis-control-size-calendar-event-edge) solid\n var(--calendar-event-edge);\n /*\n * A browser scales down any radius it cannot fit, so a chip already paints half a lane\n * under a large --vectis-radius-interactive; min() applies that same reduction to a timed\n * block, whose height is the event's DURATION. Written bare, a pill theme paints half of a\n * three-hour block instead: 96px corners on one card and 12px on the chip beside it.\n */\n border-radius: min(\n var(--vectis-radius-interactive),\n calc(var(--vectis-control-size-calendar-allday-lane) / 2)\n );\n background: var(--calendar-event-face);\n color: var(--calendar-event-ink);\n font-family: var(--vectis-text-family);\n text-align: start;\n cursor: pointer;\n transition:\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default),\n filter var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * A colour the consumer chose is an arbitrary value, so the card is built so that NOTHING is\n * ever written on top of it: it paints the edge, and the face is a faint wash of it over the\n * page's own surface; which also makes it follow the theme with no second setting. The text\n * stays the page's text colour, whose contrast against that surface is already guaranteed.\n */\n .v-calendar-event[data-custom] {\n --calendar-event-edge: var(--calendar-event-color);\n --calendar-event-face: color-mix(\n in oklab,\n var(--calendar-event-color) 14%,\n var(--vectis-color-surface)\n );\n --calendar-event-ink: var(--vectis-color-text);\n }\n\n .v-calendar-event-body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 1px;\n /* Without this a flex item refuses to shrink past its content, and a card too short for\n its own text would push its title out of the clip instead of cropping it. */\n min-block-size: 0;\n min-inline-size: 0;\n overflow: hidden;\n padding: var(--vectis-space-1) var(--vectis-space-2);\n }\n\n /*\n * Give the time a larger weighted flex-shrink so it disappears before truncating the event\n * title.\n */\n @container (max-block-size: 3rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-title {\n flex: 0 1 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n flex: 0 1000 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-description {\n display: none;\n }\n }\n\n /*\n * The shortest card there is: one slot, which at the default hour height is sixteen pixels,\n * leaving fourteen once the border is taken. A line of the title at its normal leading is\n * eighteen; so the leading is what gives, down to the glyphs themselves.\n */\n @container (max-block-size: 1.5rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-title,\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n line-height: 1;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-handle {\n block-size: calc(var(--vectis-control-size-calendar-handle) / 2);\n }\n }\n\n .v-calendar-event:hover {\n filter: brightness(0.97);\n }\n\n /*\n * `pointer-events: none` matters as much: the pointer is captured by the grid, and a card\n * under the cursor would otherwise take the hover of every cell it passed over.\n */\n .v-calendar-event[data-dragging] {\n opacity: 0.75;\n box-shadow: var(--vectis-shadow-md);\n pointer-events: none;\n z-index: 3;\n }\n\n /*\n * This rule must stay BELOW `[data-dragging]`. Both are (0,2,0) and a refused card is always\n * also a dragged one, so the later rule is the whole of the arbitration.\n */\n .v-calendar-event[data-rejected] {\n --calendar-event-face: var(--vectis-color-danger-surface);\n --calendar-event-edge: var(--vectis-color-danger-border);\n --calendar-event-ink: var(--vectis-color-danger-text);\n\n border-style: dotted;\n box-shadow: none;\n }\n\n /*\n * The echo left where a dragged event started, so the reader can see what they are moving it\n * FROM; without it a long drag ends with no idea what has just been given up. Faded rather\n * than outlined, and dashed rather than solid, so that it reads as a memory and not as a\n * second event: at a glance the only card that looks real is the one under the pointer.\n */\n .v-calendar-event[data-ghost] {\n opacity: 0.4;\n border-style: dashed;\n z-index: 0;\n }\n\n /* Held by the keyboard: the same lift, but marked with the focus ring's own colour, since\n there is no pointer to show where it is going. */\n .v-calendar-event[data-grabbed] {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n box-shadow: var(--vectis-shadow-md);\n z-index: 3;\n }\n\n .v-calendar-event-handle {\n position: absolute;\n inset-block-end: 0;\n inset-inline: 0;\n block-size: var(--vectis-control-size-calendar-handle);\n /* Dragging here IS how the end is set, so it must do nothing else: no scrolling under a\n finger, and no selecting the text it sits over. */\n touch-action: none;\n cursor: ns-resize;\n }\n\n /* The grip appears on hover and while the card is being resized, never permanently: a\n short card is mostly handle, and a line across every event all the time reads as a\n border nobody asked for. */\n .v-calendar-event-handle::after {\n content: '';\n position: absolute;\n inset-block-end: var(--vectis-control-size-calendar-grip-thickness);\n inset-inline-start: 50%;\n inline-size: var(--vectis-control-size-calendar-grip);\n block-size: var(--vectis-control-size-calendar-grip-thickness);\n translate: -50% 0;\n border-radius: var(--vectis-radius-pill);\n background: var(--calendar-event-ink);\n opacity: 0;\n transition: opacity var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-event:hover .v-calendar-event-handle::after,\n .v-calendar-event[data-dragging] .v-calendar-event-handle::after {\n opacity: 0.6;\n }\n\n .v-calendar-event:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n /* An event running past what is on show loses the corner on that side, so the card reads\n as cut off rather than as merely small. */\n .v-calendar-event[data-continues-before] {\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n border-block-start-style: dashed;\n }\n\n .v-calendar-event[data-continues-after] {\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n border-block-end-style: dashed;\n }\n\n /*\n * The height goes through `--calendar-chip-height`, which `.v-calendar-month-chip` sets,\n * rather than that rule setting `block-size` itself. This selector is (0,2,0) and that one is\n * (0,1,0) in ANOTHER SHEET: matching specificity would hand the winner to whichever order the\n * consumer's bundler emits, and beating it would need a three-class compound.\n */\n .v-calendar-event[data-layout='chip'] {\n block-size: var(--calendar-chip-height, 100%);\n }\n\n .v-calendar-event[data-layout='chip'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event-title {\n overflow: hidden;\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-font-weight-medium);\n line-height: var(--vectis-text-body-sm-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-event-time {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n /*\n * The times are secondary to the title, but the card's colour is already doing the quiet\n * work; a muted token here would fight it, so the same ink at less weight.\n */\n opacity: 0.85;\n }\n\n .v-calendar-event-description {\n overflow: hidden;\n /* The card's height is the event's length, so a description shows only where there is\n genuinely room for it: it takes whatever is left and disappears when that is nothing. */\n min-block-size: 0;\n color: inherit;\n text-overflow: ellipsis;\n opacity: 0.85;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-event,\n .v-calendar-event-handle::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .v-calendar-event-handle::after {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDA,IAAM,IAAQ,GAmBR,IAAI,EAAY,GAQhB,IAAM,QAAe,EAAM,EAAM,WAAW,EAAM,MAAM,EAAE,CAAC,GAE3D,IAAQ,QACZ,EAAM,MAAM,QACR,EAAE,0BAA0B,EAAM,MAAM,MAAM,IAC9C,EAAE,+BAA+B,OAAO,EAAI,KAAK,EAAE,CACzD,GAGM,IAAiB,QACrB,EAAM,WAAW,GAAG,EAAM,MAAM,MAAM,IAAI,EAAM,aAAa,EAAM,MAAM,KAC3E;yBAIE,EA4DS,UAAA;GA3DP,MAAK;GACL,OAAM;GACL,iBAAe,OAAO,EAAA,MAAM,EAAE;GAC9B,eAAa,EAAA;GACb,eAAa,EAAA,MAAM,QAAK,KAAQ,KAAA;GAChC,yBAAuB,EAAA,kBAAe,KAAQ,KAAA;GAC9C,wBAAsB,EAAA,iBAAc,KAAQ,KAAA;GAC5C,iBAAe,EAAA,WAAQ,KAAQ,KAAA;GAC/B,iBAAe,EAAA,WAAQ,KAAQ,KAAA;GAC/B,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,cAAY,EAAA,YAAY,KAAA,IAAiB,KAAA,IAAR;GACjC,OAAK,EAAE,EAAA,KAAK;GACZ,cAAY,EAAA;GACZ,wBAAsB,EAAA,CAAA,CAAC,CAAC,SAAS;GACjC,oBAAkB,EAAA;GAClB,UAAU,EAAA,YAAY,KAAA;GACtB,OAAO,EAAA,YAAY,KAAA,KAAmB,KAAA;MAQvC,EAuBO,QAvBP,GAuBO,CAtBL,EAqBO,EAAA,QAAA,WAAA;GApBJ,OAAO,EAAA;GACP,QAAQ,EAAA;GACR,UAAW,EAAA;GACX,iBAAkB,EAAA;GAClB,gBAAiB,EAAA;GACjB,UAAU,EAAA;GACV,SAAS,EAAA;WAcL;GAZL,EAA6D,QAA7D,GAA6D,EAArB,EAAA,MAAM,KAAK,GAAA,CAAA;GACvC,EAAA,WAAM,WAAgB,EAAA,YAAA,EAAA,GAAlC,EAEO,QAFP,GAEO,EADF,EAAA,QAAQ,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GAGL,EAAA,WAAM,WAAgB,EAAA,MAAM,eAAA,EAAA,GADpC,EAOc,GAAA;;IALZ,IAAG;IACH,SAAQ;IACR,OAAM;;qBAEiB,CAAA,EAAA,EAApB,EAAA,MAAM,WAAW,GAAA,CAAA,CAAA,CAAA;;;QAUlB,EAAA,aAAa,EAAA,WAAM,WAAA,EAAA,GAD3B,EAKE,QALF,CAKE,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,IAAA,CAAA"}
1
+ {"version":3,"file":"VCalendarEvent.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeStyle","_unref","_createElementVNode","_renderSlot","_toDisplayString","_createCommentVNode","_createBlock","VTypography","_withCtx","_createTextVNode","VTypography_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","VCalendarEvent_vue_vue_type_script_setup_true_lang_default","props","__props","m","useMessages","hue","computed","hueOf","style","accessibleName","openBlock","createElementBlock","normalizeStyle","unref","createElementVNode","renderSlot","_ctx","toDisplayString","createCommentVNode","createBlock","withCtx","createTextVNode"],"sources":["../../../src/components/VCalendar/VCalendarEvent.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * Share the native event button across calendar views so accessible naming and event-slot\n * rendering remain consistent.\n */\nimport { computed } from 'vue'\n\nimport VTypography from '../VTypography/VTypography.vue'\n\nimport { useMessages } from '../../i18n/state'\n\nimport { hueOf } from './color'\nimport type {\n CalendarEvent,\n CalendarEventId,\n CalendarEventLayout,\n CalendarEventSlotProps,\n} from './types'\n\nexport interface CalendarEventProps<T> {\n /** The event this card stands for. */\n event: T\n /**\n * Which shape to take: a block, which fills the box the calendar gives it and can show a\n * second line, or a chip, which is one line high and sits in a row of others.\n */\n layout?: CalendarEventLayout\n /** The event's times, already written out for the reader by the calendar. */\n timeText?: string\n /** Whether the event carries on past the start or the end of what is on show. */\n continuesBefore?: boolean\n continuesAfter?: boolean\n /** Shows the strip along the bottom edge that the event's end is dragged by. */\n resizable?: boolean\n /** Whether the card is being dragged with a pointer right now. */\n dragging?: boolean\n /**\n * Whether letting go now would write nothing: the pointer has left the calendar, and the\n * event is about to return to where the faded echo shows it started.\n */\n rejected?: boolean\n /** Whether the card has been taken hold of with the keyboard. */\n grabbed?: boolean\n /** How the card says it can be moved, read from a node the calendar shares between them. */\n hintId?: string\n /**\n * Marks this card as the faded echo left behind where a dragged event STARTED, and names the\n * event it echoes.\n */\n ghostOf?: CalendarEventId\n /** Whether the whole calendar is disabled, which makes the card a real disabled button. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<CalendarEventProps<E>>(), {\n layout: 'block',\n timeText: '',\n continuesBefore: false,\n continuesAfter: false,\n resizable: false,\n dragging: false,\n rejected: false,\n grabbed: false,\n hintId: undefined,\n ghostOf: undefined,\n disabled: false,\n})\n\ndefineSlots<{\n /** The whole content of the card, replacing the title and the times. */\n default?(props: CalendarEventSlotProps<E>): unknown\n}>()\n\nconst m = useMessages()\n\n/*\n * A colour given by the consumer is used as it stands; otherwise a hue is derived from the\n * event's id and the token layer supplies the lightness and the chroma that go with it. The two\n * are kept apart by an attribute rather than by a fallback chain, because the custom case needs\n * a DIFFERENT recipe and not merely a different value; see the stylesheet below.\n */\nconst hue = computed(() => hueOf(props.ghostOf ?? props.event.id))\n\nconst style = computed(() =>\n props.event.color\n ? { '--calendar-event-color': props.event.color }\n : { '--vectis-calendar-event-hue': String(hue.value) },\n)\n\n/** What a screen reader hears: the title, then when it happens. */\nconst accessibleName = computed(() =>\n props.timeText ? `${props.event.title}, ${props.timeText}` : props.event.title,\n)\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"v-calendar-event\"\n :data-event-id=\"String(event.id)\"\n :data-layout=\"layout\"\n :data-custom=\"event.color ? '' : undefined\"\n :data-continues-before=\"continuesBefore ? '' : undefined\"\n :data-continues-after=\"continuesAfter ? '' : undefined\"\n :data-dragging=\"dragging ? '' : undefined\"\n :data-rejected=\"rejected ? '' : undefined\"\n :data-grabbed=\"grabbed ? '' : undefined\"\n :data-ghost=\"ghostOf !== undefined ? '' : undefined\"\n :style=\"style\"\n :aria-label=\"accessibleName\"\n :aria-roledescription=\"m.calendar.eventRoleDescription\"\n :aria-describedby=\"hintId\"\n :disabled=\"disabled || undefined\"\n :inert=\"ghostOf !== undefined ? true : undefined\"\n >\n <!--\n The content sits in a box of its own because the CARD is the container the stylesheet\n queries, and an element cannot be styled by its own container query. The layout that has\n to change when a card gets short; a column of two lines becoming one row; must therefore\n live on a descendant.\n -->\n <span class=\"v-calendar-event-body\">\n <slot\n :event=\"event\"\n :layout=\"layout\"\n :time-text=\"timeText\"\n :continues-before=\"continuesBefore\"\n :continues-after=\"continuesAfter\"\n :dragging=\"dragging\"\n :grabbed=\"grabbed\"\n >\n <span class=\"v-calendar-event-title\">{{ event.title }}</span>\n <span v-if=\"layout === 'block' && timeText\" class=\"v-calendar-event-time\">\n {{ timeText }}\n </span>\n <VTypography\n v-if=\"layout === 'block' && event.description\"\n as=\"span\"\n variant=\"caption\"\n class=\"v-calendar-event-description\"\n >\n {{ event.description }}\n </VTypography>\n </slot>\n </span>\n\n <!--\n It is a pointer affordance and nothing else, and its keyboard equivalent lives on the card\n itself as Shift with the arrow keys; which is why hiding it costs a reader nothing.\n -->\n <span\n v-if=\"resizable && layout === 'block'\"\n class=\"v-calendar-event-handle\"\n data-calendar-handle\n aria-hidden=\"true\"\n />\n </button>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-event {\n /*\n * The three colours of a card, named by what they paint rather than by where they come\n * from; which lets the custom block below swap the source of all three without touching a\n * single rule that consumes them.\n */\n /*\n * The hue is turned here, on the card, and never in the tokens. Relative colour syntax\n * keeps the token's lightness and chroma, which are what hold the title's contrast, and\n * takes the hue the card sets inline, or the token's own (`h`) when none is set.\n */\n --calendar-event-face: oklch(\n from var(--vectis-color-event-surface) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-edge: oklch(\n from var(--vectis-color-event-border) l c var(--vectis-calendar-event-hue, h)\n );\n --calendar-event-ink: oklch(\n from var(--vectis-color-event-text) l c var(--vectis-calendar-event-hue, h)\n );\n\n position: relative;\n display: flex;\n overflow: hidden;\n /*\n * It is safe because a card's two dimensions are both set outright by `.v-calendar-block`;\n * size containment therefore removes an influence nothing was exercising. Asking in minutes\n * instead would have meant calibrating against `--vectis-control-size-calendar-hour`, and\n * being silently wrong for anyone who overrode it.\n */\n container-type: size;\n border: 1px solid var(--calendar-event-edge);\n /* The leading edge is what carries the colour at a glance, so it is drawn thicker. It\n is a border and not a background stripe: under Windows forced-colors a background is\n forced to Canvas and vanishes, where a border keeps a colour of its own. */\n border-inline-start: var(--vectis-control-size-calendar-event-edge) solid\n var(--calendar-event-edge);\n /*\n * A browser scales down any radius it cannot fit, so a chip already paints half a lane\n * under a large --vectis-radius-interactive; min() applies that same reduction to a timed\n * block, whose height is the event's DURATION. Written bare, a pill theme paints half of a\n * three-hour block instead: 96px corners on one card and 12px on the chip beside it.\n */\n border-radius: min(\n var(--vectis-radius-interactive),\n calc(var(--vectis-control-size-calendar-allday-lane) / 2)\n );\n background: var(--calendar-event-face);\n color: var(--calendar-event-ink);\n font-family: var(--vectis-text-family);\n text-align: start;\n cursor: pointer;\n transition:\n box-shadow var(--vectis-duration-fast) var(--vectis-ease-default),\n filter var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * A colour the consumer chose is an arbitrary value, so the card is built so that NOTHING is\n * ever written on top of it: it paints the edge, and the face is a faint wash of it over the\n * page's own surface; which also makes it follow the theme with no second setting. The text\n * stays the page's text colour, whose contrast against that surface is already guaranteed.\n */\n .v-calendar-event[data-custom] {\n --calendar-event-edge: var(--calendar-event-color);\n --calendar-event-face: color-mix(\n in oklab,\n var(--calendar-event-color) 14%,\n var(--vectis-color-surface)\n );\n --calendar-event-ink: var(--vectis-color-text);\n }\n\n .v-calendar-event-body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 1px;\n /* Without this a flex item refuses to shrink past its content, and a card too short for\n its own text would push its title out of the clip instead of cropping it. */\n min-block-size: 0;\n min-inline-size: 0;\n overflow: hidden;\n padding: var(--vectis-space-1) var(--vectis-space-2);\n }\n\n /*\n * Give the time a larger weighted flex-shrink so it disappears before truncating the event\n * title.\n */\n @container (max-block-size: 3rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-title {\n flex: 0 1 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n flex: 0 1000 auto;\n min-inline-size: 0;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-description {\n display: none;\n }\n }\n\n /*\n * The shortest card there is: one slot, which at the default hour height is sixteen pixels,\n * leaving fourteen once the border is taken. A line of the title at its normal leading is\n * eighteen; so the leading is what gives, down to the glyphs themselves.\n */\n @container (max-block-size: 1.5rem) {\n .v-calendar-event[data-layout='block'] .v-calendar-event-title,\n .v-calendar-event[data-layout='block'] .v-calendar-event-time {\n line-height: 1;\n }\n\n .v-calendar-event[data-layout='block'] .v-calendar-event-handle {\n block-size: calc(var(--vectis-control-size-calendar-handle) / 2);\n }\n }\n\n .v-calendar-event:hover {\n filter: brightness(0.97);\n }\n\n /*\n * `pointer-events: none` matters as much: the pointer is captured by the grid, and a card\n * under the cursor would otherwise take the hover of every cell it passed over.\n */\n .v-calendar-event[data-dragging] {\n opacity: 0.75;\n box-shadow: var(--vectis-shadow-md);\n pointer-events: none;\n z-index: 3;\n }\n\n /*\n * This rule must stay BELOW `[data-dragging]`. Both are (0,2,0) and a refused card is always\n * also a dragged one, so the later rule is the whole of the arbitration.\n */\n .v-calendar-event[data-rejected] {\n --calendar-event-face: var(--vectis-color-danger-surface);\n --calendar-event-edge: var(--vectis-color-danger-border);\n --calendar-event-ink: var(--vectis-color-danger-text);\n\n border-style: dotted;\n box-shadow: none;\n }\n\n /*\n * The echo left where a dragged event started, so the reader can see what they are moving it\n * FROM; without it a long drag ends with no idea what has just been given up. Faded rather\n * than outlined, and dashed rather than solid, so that it reads as a memory and not as a\n * second event: at a glance the only card that looks real is the one under the pointer.\n */\n .v-calendar-event[data-ghost] {\n opacity: 0.4;\n border-style: dashed;\n z-index: 0;\n }\n\n /* Held by the keyboard: the same lift, but marked with the focus ring's own colour, since\n there is no pointer to show where it is going. */\n .v-calendar-event[data-grabbed] {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n box-shadow: var(--vectis-shadow-md);\n z-index: 3;\n }\n\n .v-calendar-event-handle {\n position: absolute;\n inset-block-end: 0;\n inset-inline: 0;\n block-size: var(--vectis-control-size-calendar-handle);\n /* Dragging here IS how the end is set, so it must do nothing else: no scrolling under a\n finger, and no selecting the text it sits over. */\n touch-action: none;\n cursor: ns-resize;\n }\n\n /* The grip appears on hover and while the card is being resized, never permanently: a\n short card is mostly handle, and a line across every event all the time reads as a\n border nobody asked for. */\n .v-calendar-event-handle::after {\n content: '';\n position: absolute;\n inset-block-end: var(--vectis-control-size-calendar-grip-thickness);\n inset-inline-start: 50%;\n inline-size: var(--vectis-control-size-calendar-grip);\n block-size: var(--vectis-control-size-calendar-grip-thickness);\n translate: -50% 0;\n border-radius: var(--vectis-radius-pill);\n background: var(--calendar-event-ink);\n opacity: 0;\n transition: opacity var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-event:hover .v-calendar-event-handle::after,\n .v-calendar-event[data-dragging] .v-calendar-event-handle::after {\n opacity: 0.6;\n }\n\n .v-calendar-event:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n /* An event running past what is on show loses the corner on that side, so the card reads\n as cut off rather than as merely small. */\n .v-calendar-event[data-continues-before] {\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n border-block-start-style: dashed;\n }\n\n .v-calendar-event[data-continues-after] {\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n border-block-end-style: dashed;\n }\n\n /*\n * The height goes through `--calendar-chip-height`, which `.v-calendar-month-chip` sets,\n * rather than that rule setting `block-size` itself. This selector is (0,2,0) and that one is\n * (0,1,0) in ANOTHER SHEET: matching specificity would hand the winner to whichever order the\n * consumer's bundler emits, and beating it would need a three-class compound.\n */\n .v-calendar-event[data-layout='chip'] {\n block-size: var(--calendar-chip-height, 100%);\n }\n\n .v-calendar-event[data-layout='chip'] .v-calendar-event-body {\n flex-direction: row;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: 0;\n }\n\n .v-calendar-event-title {\n overflow: hidden;\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-font-weight-medium);\n line-height: var(--vectis-text-body-sm-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-calendar-event-time {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-overflow: ellipsis;\n white-space: nowrap;\n /*\n * The times are secondary to the title, but the card's colour is already doing the quiet\n * work; a muted token here would fight it, so the same ink at less weight.\n */\n opacity: 0.85;\n }\n\n .v-calendar-event-description {\n overflow: hidden;\n /* The card's height is the event's length, so a description shows only where there is\n genuinely room for it: it takes whatever is left and disappears when that is nothing. */\n min-block-size: 0;\n color: inherit;\n text-overflow: ellipsis;\n opacity: 0.85;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-event,\n .v-calendar-event-handle::after {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .v-calendar-event-handle::after {\n forced-color-adjust: none;\n background: CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDA,IAAMmB,IAAQC,GAmBRC,IAAIC,EAAY,GAQhBC,IAAMC,QAAeC,EAAMN,EAAM,WAAWA,EAAM,MAAM,EAAE,CAAC,GAE3DO,IAAQF,QACZL,EAAM,MAAM,QACR,EAAE,0BAA0BA,EAAM,MAAM,MAAM,IAC9C,EAAE,+BAA+B,OAAOI,EAAI,KAAK,EAAE,CACzD,GAGMI,IAAiBH,QACrBL,EAAM,WAAW,GAAGA,EAAM,MAAM,MAAM,IAAIA,EAAM,aAAaA,EAAM,MAAM,KAC3E;oBAIEnB,EAAA,GAAAC,EA4DS,UAAA;GA3DP,MAAK;GACL,OAAM;GACL,iBAAe,OAAOmB,EAAA,MAAM,EAAE;GAC9B,eAAaA,EAAA;GACb,eAAaA,EAAA,MAAM,QAAK,KAAQ,KAAA;GAChC,yBAAuBA,EAAA,kBAAe,KAAQ,KAAA;GAC9C,wBAAsBA,EAAA,iBAAc,KAAQ,KAAA;GAC5C,iBAAeA,EAAA,WAAQ,KAAQ,KAAA;GAC/B,iBAAeA,EAAA,WAAQ,KAAQ,KAAA;GAC/B,gBAAcA,EAAA,UAAO,KAAQ,KAAA;GAC7B,cAAYA,EAAA,YAAY,KAAA,IAAiB,KAAA,IAAR;GACjC,OAAKlB,EAAEwB,EAAA,KAAK;GACZ,cAAYC,EAAA;GACZ,wBAAsBxB,EAAAkB,CAAA,CAAC,CAAC,SAAS;GACjC,oBAAkBD,EAAA;GAClB,UAAUA,EAAA,YAAY,KAAA;GACtB,OAAOA,EAAA,YAAY,KAAA,KAAmB,KAAA;EAQvChB,GAAAA,CAAAA,EAuBO,QAvBPU,GAuBO,CAtBLT,EAqBO6B,EAAA,QAAA,WAAA;GApBJ,OAAOd,EAAA;GACP,QAAQA,EAAA;GACR,UAAWA,EAAA;GACX,iBAAkBA,EAAA;GAClB,gBAAiBA,EAAA;GACjB,UAAUA,EAAA;GACV,SAASA,EAAA;EAPZ,SAqBO;GAZLhB,EAA6D,QAA7DW,GAA6DT,EAArBc,EAAA,MAAM,KAAK,GAAA,CAAA;GACvCA,EAAA,WAAM,WAAgBA,EAAA,YAAlCpB,EAAA,GAAAC,EAEO,QAFPe,GAEOV,EADFc,EAAA,QAAQ,GAAA,CAAA,KAAAgB,EAAA,IAAA,EAAA;GAGLhB,EAAA,WAAM,WAAgBA,EAAA,MAAM,eADpCpB,EAAA,GAAAQ,EAOcC,GAAA;;IALZ,IAAG;IACH,SAAQ;IACR,OAAM;;IAEN,SAAAC,QAAuB,CAApBC,EAAAL,EAAAc,EAAA,MAAM,WAAW,GAAA,CAAA,CAAA,CAAA;;;EAUlB,CAAA,CAAA,CAAA,GAAAA,EAAA,aAAaA,EAAA,WAAM,WAD3BpB,EAAA,GAAAC,EAKE,QALFgB,CAKE,KAAAmB,EAAA,IAAA,EAAA,CAAA,GAAA,IAAAvB,CAAA"}