vectis-ui 0.14.0 → 0.16.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 (442) hide show
  1. package/dist/components/VAccordion/VAccordion.css +1 -1
  2. package/dist/components/VAccordion/VAccordion.d.ts +0 -6
  3. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  4. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -8
  5. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  7. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  8. package/dist/components/VAccordion/context.js.map +1 -1
  9. package/dist/components/VAlert/VAlert.js.map +1 -1
  10. package/dist/components/VAlert/VAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/VAvatar/VAvatar.d.ts +0 -3
  12. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  13. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +21 -27
  14. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/VAvatar/VAvatarGroup.d.ts +0 -6
  16. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  17. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +5 -19
  18. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VAvatar/context.d.ts +0 -1
  20. package/dist/components/VAvatar/context.js.map +1 -1
  21. package/dist/components/VBadge/VBadge.js.map +1 -1
  22. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  25. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/VButton/VButton.d.ts +0 -6
  27. package/dist/components/VButton/VButton.js.map +1 -1
  28. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +11 -17
  29. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/VButton/VButtonGroup.d.ts +0 -6
  31. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  32. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  33. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/VButton/context.d.ts +0 -2
  35. package/dist/components/VButton/context.js.map +1 -1
  36. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  37. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  39. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  41. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +5 -17
  42. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  44. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +19 -31
  45. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  47. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/VCalendar/color.js.map +1 -1
  49. package/dist/components/VCalendar/edgeStep.js +1 -5
  50. package/dist/components/VCalendar/edgeStep.js.map +1 -1
  51. package/dist/components/VCalendar/gesture.js +4 -12
  52. package/dist/components/VCalendar/gesture.js.map +1 -1
  53. package/dist/components/VCalendar/keyboard.js.map +1 -1
  54. package/dist/components/VCalendar/layout.js +8 -12
  55. package/dist/components/VCalendar/layout.js.map +1 -1
  56. package/dist/components/VCalendar/timeGrid.js +5 -5
  57. package/dist/components/VCalendar/timeGrid.js.map +1 -1
  58. package/dist/components/VCard/VCard.js.map +1 -1
  59. package/dist/components/VCard/VCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  60. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  61. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  63. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/VCarousel/context.js.map +1 -1
  65. package/dist/components/VCheckbox/VCheckMark.js.map +1 -1
  66. package/dist/components/VCheckbox/VCheckMark.vue_vue_type_script_setup_true_lang.js.map +1 -1
  67. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  68. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/VChip/VChip.d.ts +0 -3
  70. package/dist/components/VChip/VChip.js.map +1 -1
  71. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +0 -6
  72. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/VColorInput/VColorInput.d.ts +0 -3
  74. package/dist/components/VColorInput/VColorInput.js.map +1 -1
  75. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js +3 -9
  76. package/dist/components/VColorInput/VColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  77. package/dist/components/VColorPicker/VColorPicker.js.map +1 -1
  78. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js +1 -5
  79. package/dist/components/VColorPicker/VColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/VColorPicker/color.js.map +1 -1
  81. package/dist/components/VCombobox/VCombobox.d.ts +0 -3
  82. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  83. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +100 -119
  84. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/VCommandPalette/VCommandPalette.js.map +1 -1
  86. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js +0 -1
  87. package/dist/components/VCommandPalette/VCommandPalette.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/VCommandPalette/VCommandPaletteItem.js.map +1 -1
  89. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js +1 -5
  90. package/dist/components/VCommandPalette/VCommandPaletteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/VContextMenu/VContextMenu.d.ts +0 -3
  92. package/dist/components/VContextMenu/VContextMenu.js.map +1 -1
  93. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js +3 -11
  94. package/dist/components/VContextMenu/VContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/VDataTable/VDataTable.css +1 -1
  96. package/dist/components/VDataTable/VDataTable.d.ts +0 -2
  97. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  98. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +69 -88
  99. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/VDateInput/VDateInput.d.ts +0 -3
  101. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  102. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +5 -10
  103. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/VDateInput/mask.js.map +1 -1
  105. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  106. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +2 -1
  107. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/VDatePicker/keyboard.js.map +1 -1
  109. package/dist/components/VDatePicker/names.js.map +1 -1
  110. package/dist/components/VDialog/VDialog.js.map +1 -1
  111. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  113. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/VDrawer/VDrawer.js.map +1 -1
  115. package/dist/components/VDrawer/VDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/components/VEmptyState/VEmptyState.js.map +1 -1
  117. package/dist/components/VEmptyState/VEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/VField/VField.js.map +1 -1
  119. package/dist/components/VField/VField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/VField/VFieldAnnouncer.js.map +1 -1
  121. package/dist/components/VField/VFieldAnnouncer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VField/VFieldMessage.js.map +1 -1
  123. package/dist/components/VField/VFieldMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/VFieldset/VFieldset.js.map +1 -1
  125. package/dist/components/VFieldset/VFieldset.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/components/VFileInput/VFileInput.d.ts +0 -5
  127. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  128. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +54 -65
  129. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/VFileInput/truncate.js.map +1 -1
  131. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  132. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  133. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  134. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  135. package/dist/components/VHotkeys/VHotkeys.d.ts +0 -3
  136. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  137. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +0 -6
  138. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/VHotkeys/platform.js +1 -1
  140. package/dist/components/VHotkeys/platform.js.map +1 -1
  141. package/dist/components/VHoverCard/VHoverCard.js.map +1 -1
  142. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js +2 -12
  143. package/dist/components/VHoverCard/VHoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/VIcon/VIcon.js.map +1 -1
  145. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/VIcon/iconProps.js.map +1 -1
  147. package/dist/components/VIcon/icons/add.js.map +1 -1
  148. package/dist/components/VIcon/icons/arrow_downward.js.map +1 -1
  149. package/dist/components/VIcon/icons/arrow_downward_alt.js.map +1 -1
  150. package/dist/components/VIcon/icons/arrow_drop_down.js.map +1 -1
  151. package/dist/components/VIcon/icons/arrow_drop_up.js.map +1 -1
  152. package/dist/components/VIcon/icons/arrow_left_alt.js.map +1 -1
  153. package/dist/components/VIcon/icons/arrow_right_alt.js.map +1 -1
  154. package/dist/components/VIcon/icons/arrow_upward.js.map +1 -1
  155. package/dist/components/VIcon/icons/arrow_upward_alt.js.map +1 -1
  156. package/dist/components/VIcon/icons/attach_file.js.map +1 -1
  157. package/dist/components/VIcon/icons/audio_file.js.map +1 -1
  158. package/dist/components/VIcon/icons/calendar_today.js.map +1 -1
  159. package/dist/components/VIcon/icons/check.js.map +1 -1
  160. package/dist/components/VIcon/icons/check_circle.js.map +1 -1
  161. package/dist/components/VIcon/icons/chevron_left.js.map +1 -1
  162. package/dist/components/VIcon/icons/chevron_right.js.map +1 -1
  163. package/dist/components/VIcon/icons/close.js.map +1 -1
  164. package/dist/components/VIcon/icons/cloud_upload.js.map +1 -1
  165. package/dist/components/VIcon/icons/code.js.map +1 -1
  166. package/dist/components/VIcon/icons/colorize.js.map +1 -1
  167. package/dist/components/VIcon/icons/description.js.map +1 -1
  168. package/dist/components/VIcon/icons/error.js.map +1 -1
  169. package/dist/components/VIcon/icons/expand_less.js.map +1 -1
  170. package/dist/components/VIcon/icons/expand_more.js.map +1 -1
  171. package/dist/components/VIcon/icons/first_page.js.map +1 -1
  172. package/dist/components/VIcon/icons/folder_zip.js.map +1 -1
  173. package/dist/components/VIcon/icons/image.js.map +1 -1
  174. package/dist/components/VIcon/icons/inbox.js.map +1 -1
  175. package/dist/components/VIcon/icons/index.js.map +1 -1
  176. package/dist/components/VIcon/icons/info.js.map +1 -1
  177. package/dist/components/VIcon/icons/last_page.js.map +1 -1
  178. package/dist/components/VIcon/icons/more_horiz.js.map +1 -1
  179. package/dist/components/VIcon/icons/names.js.map +1 -1
  180. package/dist/components/VIcon/icons/notifications.js.map +1 -1
  181. package/dist/components/VIcon/icons/open_in_new.js.map +1 -1
  182. package/dist/components/VIcon/icons/picture_as_pdf.js.map +1 -1
  183. package/dist/components/VIcon/icons/priority_high.js.map +1 -1
  184. package/dist/components/VIcon/icons/remove.js.map +1 -1
  185. package/dist/components/VIcon/icons/schedule.js.map +1 -1
  186. package/dist/components/VIcon/icons/search.js.map +1 -1
  187. package/dist/components/VIcon/icons/search_off.js.map +1 -1
  188. package/dist/components/VIcon/icons/star.js.map +1 -1
  189. package/dist/components/VIcon/icons/swap_vert.js.map +1 -1
  190. package/dist/components/VIcon/icons/table_chart.js.map +1 -1
  191. package/dist/components/VIcon/icons/video_file.js.map +1 -1
  192. package/dist/components/VIcon/icons/viewBox.js.map +1 -1
  193. package/dist/components/VIcon/icons/warning.js.map +1 -1
  194. package/dist/components/VIcon/resolver.js.map +1 -1
  195. package/dist/components/VIconButton/VIconButton.d.ts +0 -3
  196. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  197. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +0 -6
  198. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  199. package/dist/components/VInput/VInput.css +1 -1
  200. package/dist/components/VInput/VInput.d.ts +0 -3
  201. package/dist/components/VInput/VInput.js.map +1 -1
  202. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +2 -8
  203. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  204. package/dist/components/VInput/VInputGroup.d.ts +0 -3
  205. package/dist/components/VInput/VInputGroup.js.map +1 -1
  206. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +0 -7
  207. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  208. package/dist/components/VInput/context.d.ts +0 -2
  209. package/dist/components/VInput/context.js.map +1 -1
  210. package/dist/components/VInputOTP/VInputOTP.d.ts +0 -3
  211. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  212. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +2 -14
  213. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/components/VLink/VLink.js.map +1 -1
  215. package/dist/components/VLink/VLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  216. package/dist/components/VListbox/VListboxChevron.js.map +1 -1
  217. package/dist/components/VListbox/VListboxChevron.vue_vue_type_script_setup_true_lang.js.map +1 -1
  218. package/dist/components/VListbox/VListboxGroup.js.map +1 -1
  219. package/dist/components/VListbox/VListboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/components/VListbox/VListboxOption.js.map +1 -1
  221. package/dist/components/VListbox/VListboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  222. package/dist/components/VListbox/VListboxPanel.d.ts +0 -3
  223. package/dist/components/VListbox/VListboxPanel.js.map +1 -1
  224. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js +0 -6
  225. package/dist/components/VListbox/VListboxPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  226. package/dist/components/VListbox/VListboxSeparator.js.map +1 -1
  227. package/dist/components/VListbox/VListboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  228. package/dist/components/VListbox/VListboxValues.js.map +1 -1
  229. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js +4 -14
  230. package/dist/components/VListbox/VListboxValues.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/components/VMenu/VMenu.d.ts +0 -3
  232. package/dist/components/VMenu/VMenu.js.map +1 -1
  233. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +0 -6
  234. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  235. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  236. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  237. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  238. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +6 -12
  239. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  240. package/dist/components/VMenu/VMenuPanel.d.ts +0 -3
  241. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  242. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +9 -16
  243. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/VMenu/VMenuSeparator.js.map +1 -1
  245. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  246. package/dist/components/VMenu/context.js.map +1 -1
  247. package/dist/components/VMeter/VMeter.js.map +1 -1
  248. package/dist/components/VMeter/VMeter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  249. package/dist/components/VNumberInput/VNumberInput.d.ts +0 -3
  250. package/dist/components/VNumberInput/VNumberInput.js.map +1 -1
  251. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js +85 -90
  252. package/dist/components/VNumberInput/VNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  253. package/dist/components/VNumberInput/number.js.map +1 -1
  254. package/dist/components/VPagination/VPagination.d.ts +0 -3
  255. package/dist/components/VPagination/VPagination.js.map +1 -1
  256. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +0 -6
  257. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  258. package/dist/components/VPopover/VPopover.js.map +1 -1
  259. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  260. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  261. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  262. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  263. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  264. package/dist/components/VRadio/VRadio.js.map +1 -1
  265. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  266. package/dist/components/VRating/VRating.js.map +1 -1
  267. package/dist/components/VRating/VRating.vue_vue_type_script_setup_true_lang.js.map +1 -1
  268. package/dist/components/VResizable/VResizable.js.map +1 -1
  269. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js +8 -6
  270. package/dist/components/VResizable/VResizable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  271. package/dist/components/VResizable/VResizablePanel.js.map +1 -1
  272. package/dist/components/VResizable/VResizablePanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  273. package/dist/components/VResizable/context.js.map +1 -1
  274. package/dist/components/VResizable/layout.js.map +1 -1
  275. package/dist/components/VSelect/VSelect.d.ts +0 -3
  276. package/dist/components/VSelect/VSelect.js.map +1 -1
  277. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js +80 -90
  278. package/dist/components/VSelect/VSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  279. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  280. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  281. package/dist/components/VSideNavigation/VSideNavigation.d.ts +0 -6
  282. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  283. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +2 -11
  284. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  285. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  286. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  287. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  288. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +1 -5
  289. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  290. package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -1
  291. package/dist/components/VSideNavigation/context.js.map +1 -1
  292. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +0 -3
  293. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  294. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +0 -6
  295. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  296. package/dist/components/VSlider/VSlider.js.map +1 -1
  297. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +107 -112
  298. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  299. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  300. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  301. package/dist/components/VSnackbar/state.js.map +1 -1
  302. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  303. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  304. package/dist/components/VSplitButton/VSplitButton.d.ts +0 -3
  305. package/dist/components/VSplitButton/VSplitButton.js.map +1 -1
  306. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js +0 -6
  307. package/dist/components/VSplitButton/VSplitButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  308. package/dist/components/VStepper/VStepper.js.map +1 -1
  309. package/dist/components/VStepper/VStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  310. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  311. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  312. package/dist/components/VTabs/VTab.js.map +1 -1
  313. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +0 -2
  314. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  315. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  316. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  317. package/dist/components/VTabs/VTabs.css +1 -1
  318. package/dist/components/VTabs/VTabs.d.ts +0 -3
  319. package/dist/components/VTabs/VTabs.js.map +1 -1
  320. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +2 -15
  321. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  322. package/dist/components/VTabs/context.d.ts +0 -2
  323. package/dist/components/VTabs/context.js.map +1 -1
  324. package/dist/components/VTextarea/VTextarea.d.ts +0 -6
  325. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  326. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +0 -6
  327. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  328. package/dist/components/VTimeInput/VTimeInput.d.ts +0 -3
  329. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  330. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +197 -204
  331. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  332. package/dist/components/VTimeInput/search.js.map +1 -1
  333. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  334. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +9 -9
  335. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  336. package/dist/components/VTimePicker/limits.js.map +1 -1
  337. package/dist/components/VTimeline/VTimeline.js.map +1 -1
  338. package/dist/components/VTimeline/VTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -1
  339. package/dist/components/VTimeline/VTimelineItem.js.map +1 -1
  340. package/dist/components/VTimeline/VTimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  341. package/dist/components/VTimeline/context.js.map +1 -1
  342. package/dist/components/VTimeline/datetime.js.map +1 -1
  343. package/dist/components/VToast/VToast.js.map +1 -1
  344. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  345. package/dist/components/VToast/VToaster.js.map +1 -1
  346. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +1 -1
  347. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  348. package/dist/components/VToast/state.js.map +1 -1
  349. package/dist/components/VToggle/VToggle.d.ts +0 -3
  350. package/dist/components/VToggle/VToggle.js.map +1 -1
  351. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +1 -13
  352. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  353. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  354. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  355. package/dist/components/VToggle/context.js.map +1 -1
  356. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  357. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  358. package/dist/components/VTreeView/VTreeView.js.map +1 -1
  359. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js +1 -5
  360. package/dist/components/VTreeView/VTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  361. package/dist/components/VTypography/VTypography.js.map +1 -1
  362. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  363. package/dist/components/VVirtualList/VVirtualList.js.map +1 -1
  364. package/dist/components/VVirtualList/VVirtualList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  365. package/dist/composables/useAriaLabel.js.map +1 -1
  366. package/dist/composables/useChoice.js.map +1 -1
  367. package/dist/composables/useClearable.js.map +1 -1
  368. package/dist/composables/useControlShape.d.ts +1 -5
  369. package/dist/composables/useControlShape.js +0 -1
  370. package/dist/composables/useControlShape.js.map +1 -1
  371. package/dist/composables/useDebouncedSearch.js.map +1 -1
  372. package/dist/composables/useDetailsOpen.js.map +1 -1
  373. package/dist/composables/useEscapeDismiss.js.map +1 -1
  374. package/dist/composables/useFieldIds.js.map +1 -1
  375. package/dist/composables/useFieldPanel.js +3 -7
  376. package/dist/composables/useFieldPanel.js.map +1 -1
  377. package/dist/composables/useFileDrop.js.map +1 -1
  378. package/dist/composables/useFileField.js +2 -2
  379. package/dist/composables/useFileField.js.map +1 -1
  380. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  381. package/dist/composables/useHotkeyListener.js.map +1 -1
  382. package/dist/composables/useIconClickHandlers.js.map +1 -1
  383. package/dist/composables/useInertLink.js.map +1 -1
  384. package/dist/composables/useInfiniteScroll.js +2 -2
  385. package/dist/composables/useInfiniteScroll.js.map +1 -1
  386. package/dist/composables/useListbox.d.ts +0 -1
  387. package/dist/composables/useListbox.js +4 -10
  388. package/dist/composables/useListbox.js.map +1 -1
  389. package/dist/composables/useLiveAnnouncer.js.map +1 -1
  390. package/dist/composables/useMaskedField.js +28 -48
  391. package/dist/composables/useMaskedField.js.map +1 -1
  392. package/dist/composables/useModalDialog.js +1 -1
  393. package/dist/composables/useModalDialog.js.map +1 -1
  394. package/dist/composables/usePopover.js +1 -1
  395. package/dist/composables/usePopover.js.map +1 -1
  396. package/dist/composables/useProgressValue.js.map +1 -1
  397. package/dist/composables/useRootAttrs.js.map +1 -1
  398. package/dist/composables/useSlotNodes.js.map +1 -1
  399. package/dist/composables/useTextLimit.js.map +1 -1
  400. package/dist/composables/useTimer.js.map +1 -1
  401. package/dist/composables/useTypeahead.js.map +1 -1
  402. package/dist/composables/useVirtualList.js.map +1 -1
  403. package/dist/i18n/en.js.map +1 -1
  404. package/dist/i18n/fr.js.map +1 -1
  405. package/dist/i18n/state.js.map +1 -1
  406. package/dist/styles.css +1 -1
  407. package/dist/tokens/css.js.map +1 -1
  408. package/dist/tokens/index.d.ts +3 -0
  409. package/dist/tokens/index.js.map +1 -1
  410. package/dist/tokens/primitives.js.map +1 -1
  411. package/dist/tokens/semantic.d.ts +3 -0
  412. package/dist/tokens/semantic.js +6 -5
  413. package/dist/tokens/semantic.js.map +1 -1
  414. package/dist/tokens/themes/dark.js.map +1 -1
  415. package/dist/tokens/types.js.map +1 -1
  416. package/dist/tokens.json +12 -5
  417. package/dist/types.d.ts +0 -2
  418. package/dist/utils/array.js.map +1 -1
  419. package/dist/utils/arrowNav.js.map +1 -1
  420. package/dist/utils/attrs.js.map +1 -1
  421. package/dist/utils/chip.d.ts +4 -6
  422. package/dist/utils/chip.js +8 -5
  423. package/dist/utils/chip.js.map +1 -1
  424. package/dist/utils/clock.js +3 -1
  425. package/dist/utils/clock.js.map +1 -1
  426. package/dist/utils/css.js +1 -1
  427. package/dist/utils/css.js.map +1 -1
  428. package/dist/utils/date.js.map +1 -1
  429. package/dist/utils/direction.js.map +1 -1
  430. package/dist/utils/env.js.map +1 -1
  431. package/dist/utils/file.js +13 -31
  432. package/dist/utils/file.js.map +1 -1
  433. package/dist/utils/focus.js.map +1 -1
  434. package/dist/utils/hostWarns.js.map +1 -1
  435. package/dist/utils/ids.js.map +1 -1
  436. package/dist/utils/matcher.js.map +1 -1
  437. package/dist/utils/memo.js.map +1 -1
  438. package/dist/utils/number.js.map +1 -1
  439. package/dist/utils/text.js.map +1 -1
  440. package/dist/utils/time.js.map +1 -1
  441. package/dist/utils/vnode.js.map +1 -1
  442. package/package.json +19 -19
@@ -1 +1 @@
1
- {"version":3,"file":"VTimePicker.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VTimePicker/VTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @a11y @core\n/**\n * CSS places clock numerals and the hand. JavaScript maps pointer angles and keyboard steps to\n * a time because HTML has no interactive clock-face primitive.\n */\n\nimport { computed, inject, ref, watchEffect } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VToggle from '../VToggle/VToggle.vue'\nimport type { ToggleModelValue } from '../VToggle/VToggle.vue'\nimport VToggleItem from '../VToggle/VToggleItem.vue'\nimport { formatTime, hourCycleFor, parseTime } from '../../utils/time'\nimport {\n DIAL_DEAD_ZONE,\n DIAL_INNER_THRESHOLD,\n angleToIndex,\n dialIndexToHour24,\n distanceFraction,\n hour24ToDial,\n hourWithMeridiem,\n snapMinute,\n to12h,\n to24h,\n} from '../../utils/clock'\nimport type { HourFormat, Meridiem } from '../../utils/time'\nimport {\n allowedMinutesFor,\n firstAllowed,\n isHourAllowed,\n isTimeAllowed,\n limitsProblem,\n minuteGrid,\n minuteInterval,\n nearestAllowedMinute,\n resolveLimits,\n} from './limits'\nimport type { TimePickerAllowed } from './limits'\nimport { pad2 } from '../../utils/text'\nimport { isDev } from '../../utils/env'\nimport { hostWarnsKey } from '../../utils/hostWarns'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\n/** Whether the face shows a 12- or a 24-hour clock. */\nexport type TimePickerFormat = HourFormat\n\n/** Which of the two halves of a time is being adjusted. */\ntype TimePickerStep = 'hour' | 'minute'\n\ninterface TimePickerProps {\n /**\n * Whether the face shows a 12- or a 24-hour clock. Left out, the reader's language\n * decides, which is almost always what one wants.\n */\n format?: TimePickerFormat\n /**\n * A BCP 47 locale, which decides the clock. It TAKES PRECEDENCE over the design\n * system's global locale and falls back to it, which is why it has no literal default:\n * `undefined` has to stay recognizable for the global locale to have its chance.\n */\n locale?: string\n /**\n * The interval the minutes snap to, both when dragging and with the arrow keys. The face\n * prints only the minutes it can reach, so a step of a quarter of an hour marks four.\n */\n minuteStep?: number\n /** The earliest time that can be chosen, inclusive, as a canonical 24-hour `'HH:mm'`. */\n min?: string\n /** The latest time that can be chosen, inclusive, written like `min`. */\n max?: string\n /** Which hours can be chosen: the list of them, or a rule answering for one. */\n allowedHours?: TimePickerAllowed\n /**\n * Which minutes can be chosen: the list of them, or a rule answering for one. The\n * minutes it leaves out are not printed.\n */\n allowedMinutes?: TimePickerAllowed\n /**\n * Makes the whole clock unusable: the hand cannot be moved, the half-day cannot be\n * changed, and everything greys out through the colour tokens.\n */\n disabled?: boolean\n /** Shows the time without letting it be changed. */\n readonly?: boolean\n /**\n * The accessible name of the whole clock, its two numerals and its face together. It falls\n * back to the dictionary, and a consumer `aria-label` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<TimePickerProps>(), {\n format: undefined,\n locale: undefined,\n minuteStep: 1,\n min: undefined,\n max: undefined,\n allowedHours: undefined,\n allowedMinutes: undefined,\n disabled: false,\n readonly: false,\n label: undefined,\n})\n\n/** The time, always as a 24-hour \"HH:mm\" string whatever clock is displayed. */\nconst model = defineModel<string | null>({ default: null })\n\nconst emit = defineEmits<{\n /**\n * The reader has FINISHED, carrying the time as it stands: the minutes were settled from the\n * keyboard.\n */\n confirm: [value: string | null]\n}>()\n\ndefineSlots<{\n /** A strip at the foot of the clock, the place for actions such as Cancel and OK. */\n footer?(): unknown\n}>()\n\nconst m = useMessages()\n// @a11y\n// A roleless box cannot carry an accessible name (axe: aria-prohibited-attr),\n// so the root is a named group: the VCarousel viewport arrangement.\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.timePicker.label)\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed<TimePickerFormat>(\n () => props.format ?? hourCycleFor(resolvedLocale.value),\n)\n\n/** The restrictions, resolved once for the whole render. */\nconst limits = computed(() => resolveLimits(props))\n\n/** The hours the restrictions still leave something in, worked out once per set of restrictions. */\nconst availableHours = computed(() => {\n const hours = new Set<number>()\n for (let candidate = 0; candidate < 24; candidate += 1)\n if (isHourAllowed(candidate, limits.value)) hours.add(candidate)\n return hours\n})\n\n/** Whether an hour is one the restrictions still leave something in. */\nconst isAvailableHour = (candidate: number) => availableHours.value.has(candidate)\n\n// @devwarn\nif (isDev && !inject(hostWarnsKey, false)) {\n watchEffect(() => {\n if (!Number.isInteger(props.minuteStep) || props.minuteStep < 1 || 60 % props.minuteStep !== 0)\n console.warn(`[VTimePicker] minuteStep ${props.minuteStep} — a divisor of 60 is expected.`)\n const problem = limitsProblem(limits.value)\n if (problem) console.warn(`[VTimePicker] ${problem}`)\n })\n}\n\n/** Which of the two is being adjusted. It starts on the hour and moves on by itself. */\nconst step = ref<TimePickerStep>('hour')\n\n// With no value the clock shows the first hour of the half of the day chosen so far, which\n// is midnight until PM is picked. It is also the hour a time started from the MINUTES is\n// written with, so that choice is not lost when the reader begins there.\nconst parts = computed(\n () =>\n parseTime(model.value) ?? {\n hour: resolvedFormat.value === '12h' ? to24h(12, pendingMeridiem.value) : 0,\n minute: 0,\n },\n)\nconst hour = computed(() => parts.value.hour)\nconst minute = computed(() => parts.value.minute)\n\n/*\n * The two writers are the SINGLE cut-off point for the restrictions: the pointer, the six\n * keys and the AM/PM control all write through them and through nothing else, so not one\n * handler carries a guard of its own.\n */\n\n/**\n * Writing the hour. An hour with nothing left in it has no minute to fall back on, which\n * refuses it; one that is only PARTLY available pulls the minutes to what it does allow, since\n * `min: '09:30'` must not be left holding 09:00.\n */\nfunction setHour(value: number | null) {\n // Changing which face is shown stays allowed under `readonly`: reading the minutes is not\n // changing them.\n if (props.disabled || props.readonly) return\n if (value === null) return\n const minutes = isTimeAllowed(value, minute.value, limits.value)\n ? minute.value\n : nearestAllowedMinute(value, minute.value, limits.value)\n if (minutes === null) return\n model.value = formatTime(value, minutes)\n}\n\n/** Writing the minutes. Null is \"there was nowhere to go\", which every key can produce. */\nfunction setMinute(value: number | null) {\n if (props.disabled || props.readonly) return\n if (value === null || !isTimeAllowed(hour.value, value, limits.value)) return\n model.value = formatTime(hour.value, value)\n}\n\n// @a11y\n/*\n * Which step the clock is on is otherwise carried by the face's own name alone, and a change of\n * name is not reliably announced. A politely announced region says it a second time.\n */\nconst liveMessage = ref('')\n\nfunction setStep(next: TimePickerStep) {\n step.value = next\n liveMessage.value =\n next === 'minute' ? m.value.timePicker.choosingMinutes : m.value.timePicker.choosingHour\n}\n\n/** One numeral on the face. */\ninterface DialCell {\n key: string\n /** What is printed. */\n label: string\n /** Where it sits, as a fraction of a full turn from twelve o'clock. */\n turn: number\n /** Which of the two circles it belongs to, a 24-hour face having an inner one. */\n ring: 'outer' | 'inner'\n /** Whether it is the value currently being pointed at. */\n selected: boolean\n}\n\n/** The hour a position on the face stands for. */\nfunction hourAt(index: number, ring: 'outer' | 'inner'): number {\n return resolvedFormat.value === '24h'\n ? dialIndexToHour24(index, ring)\n : to24h(index === 0 ? 12 : index, currentMeridiem.value)\n}\n\n/** The minutes the face prints. */\nconst minuteMarks = computed(() => {\n const interval = minuteInterval(props.minuteStep)\n const spacing = 60 / interval <= 12 ? interval : 5\n const marks: number[] = []\n for (let minutes = 0; minutes < 60; minutes += spacing)\n if (minutes % interval === 0 && isTimeAllowed(hour.value, minutes, limits.value))\n marks.push(minutes)\n return marks\n})\n\n/*\n * A numeral that is only there to be refused says nothing the missing numeral does not say\n * better, and it says it in grey text a screen reader has no way to reach: the markers are\n * `aria-hidden`, so what the restrictions leave is spoken by the face's own value and by\n * nothing else.\n */\nconst cells = computed<DialCell[]>(() => {\n if (step.value === 'minute') {\n return minuteMarks.value.map((minutes) => ({\n key: `m-${minutes}`,\n label: pad2(minutes),\n turn: minutes / 60,\n ring: 'outer' as const,\n selected: minute.value === minutes,\n }))\n }\n // Each position's hour is worked out once, since on a 12-hour face that takes the half of the\n // day in force. The selection there still compares numerals and not hours: an empty clock\n // holding a PM choice sits on midnight, and its hand points at the 12 all the same.\n const twelve = resolvedFormat.value === '12h'\n const shown12 = to12h(hour.value).hour\n const rings: DialCell['ring'][] = twelve ? ['outer'] : ['outer', 'inner']\n const out: DialCell[] = []\n for (const ring of rings)\n for (let i = 0; i < 12; i += 1) {\n const target = hourAt(i, ring)\n if (!isAvailableHour(target)) continue\n const numeral = i === 0 ? 12 : i\n out.push({\n key: `${ring === 'outer' ? 'o' : 'i'}-${i}`,\n label: ring === 'inner' ? pad2(target) : String(numeral),\n turn: i / 12,\n ring,\n selected: twelve ? shown12 === numeral : hour.value === target,\n })\n }\n return out\n})\n\nconst handTurn = computed(() => {\n if (step.value === 'minute') return minute.value / 60\n const index =\n resolvedFormat.value === '24h' ? hour24ToDial(hour.value).index : to12h(hour.value).hour % 12\n return index / 12\n})\n\nconst handRing = computed(() =>\n step.value === 'hour' && resolvedFormat.value === '24h' ? hour24ToDial(hour.value).ring : 'outer',\n)\n\n/**\n * Whether the hand points at a minute that has no marker of its own. The tip is then\n * drawn small: at full size it would cover the two neighbouring markers and read as\n * pointing at neither.\n */\nconst handMinor = computed(\n () => step.value === 'minute' && !minuteMarks.value.includes(minute.value),\n)\n\n/** The hour as the two large numerals show it, on whichever clock is displayed. */\nconst displayHourText = computed(() =>\n pad2(resolvedFormat.value === '12h' ? to12h(hour.value).hour : hour.value),\n)\n\n/** Which half of the day is chosen while no time is set at all. */\nconst pendingMeridiem = ref<Meridiem>('AM')\n\n/**\n * The half of the day in force: the value's own once there is one, the remembered choice until\n * then.\n */\nconst currentMeridiem = computed<Meridiem>(() =>\n model.value ? to12h(hour.value).meridiem : pendingMeridiem.value,\n)\n\nconst meridiemModel = computed<ToggleModelValue>({\n get: () => currentMeridiem.value,\n set: (value) => {\n const meridiem: Meridiem = value === 'PM' ? 'PM' : 'AM'\n pendingMeridiem.value = meridiem\n // With no time set there is nothing to convert, so the choice is simply REMEMBERED\n // and applies to the first time chosen.\n if (!model.value) return\n // What is being chosen here is the HALF OF THE DAY, so the hour gives way to it: kept\n // when the new half allows it, and otherwise the first hour of that half that does.\n // Refusing the write instead would leave the control snapping straight back, since it\n // reads the half of the day off the value.\n const wanted = hourWithMeridiem(hour.value, meridiem)\n setHour(\n isAvailableHour(wanted)\n ? wanted\n : firstAllowed(12, (i) => to24h(i, meridiem), isAvailableHour),\n )\n },\n})\n\n/**\n * Whether each half of the day still holds an hour one could choose. An empty one takes its\n * button with it: a control that can only ever be refused is worse than no control.\n */\nconst meridiemAvailable = computed<Record<Meridiem, boolean>>(() => ({\n AM: firstAllowed(12, (i) => to24h(i, 'AM'), isAvailableHour) !== null,\n PM: firstAllowed(12, (i) => to24h(i, 'PM'), isAvailableHour) !== null,\n}))\n\n// @a11y\n// The entire spoken value of the face. The numerals are hidden from screen readers, so these\n// four attributes are the only thing assistive technology has: what the value is, what its\n// bounds are, and how to say it.\nconst ariaValueNow = computed(() => {\n if (step.value === 'minute') return minute.value\n return resolvedFormat.value === '12h' ? to12h(hour.value).hour : hour.value\n})\nconst ariaValueMin = computed(() =>\n step.value === 'minute' ? 0 : resolvedFormat.value === '12h' ? 1 : 0,\n)\nconst ariaValueMax = computed(() =>\n step.value === 'minute' ? 59 : resolvedFormat.value === '12h' ? 12 : 23,\n)\n// On a 12-hour face the half of the day is spoken with the hour: the AM/PM control is not\n// on the slider's way, and \"9 o'clock\" alone is two different times.\nconst ariaValueText = computed(() => {\n const m_ = m.value.timePicker\n if (step.value === 'minute') return m_.minutesValue(minute.value)\n const spoken = m_.hourValue(ariaValueNow.value)\n if (resolvedFormat.value === '24h') return spoken\n return `${spoken} ${currentMeridiem.value === 'PM' ? m_.pm : m_.am}`\n})\n\n/**\n * A step has been settled: after the hour come the minutes, and after the minutes the whole\n * thing is confirmed; but by KEYBOARD only, for the reason given on the emit.\n */\nfunction settleStep(via: 'pointer' | 'keyboard') {\n if (step.value === 'hour') setStep('minute')\n else if (via === 'keyboard') emit('confirm', model.value)\n}\n\nconst faceEl = ref<HTMLElement | null>(null)\nconst dragging = ref(false)\n/** Whether anything in the gesture under way landed on a numeral. */\nlet landed = false\n\n/**\n * Where a point on the face lands, and whether there was anything there at all. The write\n * itself still goes through `setHour`/ `setMinute` and their own guards, which is why\n * `readonly` is refused THERE and not here: a frozen clock is still one whose numerals are\n * real, and a tap on one moves the step on as it always did.\n */\nfunction applyPoint(event: PointerEvent): boolean {\n const face = faceEl.value\n // A disabled clock aims at nothing, so no step is moved on either: its header buttons\n // are disabled for the same reason.\n if (!face || props.disabled) return false\n // Measuring the face is safe here: this runs from a handler, hence in a browser, never\n // during a render.\n const rect = face.getBoundingClientRect()\n const dx = event.clientX - (rect.left + rect.width / 2)\n const dy = event.clientY - (rect.top + rect.height / 2)\n if (Math.hypot(dx, dy) <= DIAL_DEAD_ZONE * (rect.width / 2)) return false\n if (step.value === 'minute') {\n // The step's own snapping stands: a point between two markers has always been pulled\n // to the one it is nearest. What it is pulled to still has to BE on the face.\n const minutes = snapMinute(angleToIndex(dx, dy, 60), props.minuteStep)\n if (!isTimeAllowed(hour.value, minutes, limits.value)) return false\n setMinute(minutes)\n return true\n }\n const index = angleToIndex(dx, dy, 12)\n const ring =\n resolvedFormat.value === '24h' &&\n distanceFraction(dx, dy, rect.width / 2) < DIAL_INNER_THRESHOLD\n ? 'inner'\n : 'outer'\n const target = hourAt(index, ring)\n if (!isAvailableHour(target)) return false\n setHour(target)\n return true\n}\n\nfunction onPointerdown(event: PointerEvent) {\n // @fallback\n // Capture keeps dragging active outside the clock face; synthetic events may not reference a\n // capturable pointer.\n try {\n faceEl.value?.setPointerCapture(event.pointerId)\n } catch {\n /* Synthetic pointers cannot be captured. */\n }\n dragging.value = true\n landed = applyPoint(event)\n}\n\nfunction onPointermove(event: PointerEvent) {\n if (dragging.value && applyPoint(event)) landed = true\n}\n\nfunction onPointerup() {\n if (!dragging.value) return\n dragging.value = false\n // A gesture that never landed on a numeral has chosen nothing, so there is nothing to\n // move on FROM: the reader is left on the face they aimed at, looking at what they missed.\n if (landed) settleStep('pointer')\n}\n\nfunction onPointercancel() {\n dragging.value = false\n}\n\n// @keyboard @a11y\n// The keyboard a slider is expected to have.\n/*\n * Every key below walks until it finds something it MAY land on, rather than stopping at the\n * first thing it may not: with scattered hours a key that stopped would die at the first hole\n * and never reach what lies past it. Against a bound there is nothing past the hole, so the\n * same walk comes back empty and the key holds still, which a bound means.\n */\nfunction moveHour(delta: number) {\n if (resolvedFormat.value === '24h') {\n setHour(firstAllowed(23, (i) => (hour.value + delta * i + 24) % 24, isAvailableHour))\n return\n }\n // On a 12-hour face the hours cycle from 1 to 12 WITHIN the current half of the day:\n // passing midday is done on the AM/PM control, not by walking the hand past twelve.\n const hour12 = to12h(hour.value).hour\n setHour(\n firstAllowed(\n 11,\n (i) => to24h(((hour12 - 1 + delta * i + 12) % 12) + 1, currentMeridiem.value),\n isAvailableHour,\n ),\n )\n}\n\n/** The first or the last hour the face allows, on whichever clock it is showing. */\nfunction edgeHour(edge: 'first' | 'last'): number | null {\n if (resolvedFormat.value === '24h')\n return firstAllowed(24, (i) => (edge === 'first' ? i - 1 : 24 - i), isAvailableHour)\n return firstAllowed(\n 12,\n (i) => to24h(edge === 'first' ? i : 13 - i, currentMeridiem.value),\n isAvailableHour,\n )\n}\n\n/**\n * The minute a key lands on: the first step of the grid at least `distance` minutes away, that\n * way round, and then the next one the hour allows.\n */\nfunction minuteToward(direction: 1 | -1, distance: number): number | null {\n const grid = minuteGrid(props.minuteStep)\n const target = (((minute.value + direction * distance) % 60) + 60) % 60\n const n = grid.length\n let start = direction > 0 ? 0 : n - 1\n for (let k = 0; k < n; k += 1) {\n const i = direction > 0 ? k : n - 1 - k\n if (direction > 0 ? grid[i]! >= target : grid[i]! <= target) {\n start = i\n break\n }\n }\n return firstAllowed(\n n,\n (i) => grid[(((start + direction * (i - 1)) % n) + n) % n]!,\n (candidate) => isTimeAllowed(hour.value, candidate, limits.value),\n )\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n // The face of a disabled clock is out of the tab order, but `focus()` can still put the\n // focus there: nothing it is sent may move the step on or confirm.\n if (props.disabled) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n settleStep('keyboard')\n return\n }\n // The arrows are not flipped in a right-to-left page: a clock face is never mirrored;\n // clockwise means the same thing everywhere; so forward stays forward.\n const delta =\n event.key === 'ArrowUp' || event.key === 'ArrowRight'\n ? 1\n : event.key === 'ArrowDown' || event.key === 'ArrowLeft'\n ? -1\n : 0\n if (step.value === 'hour') {\n if (delta) moveHour(delta)\n else if (event.key === 'Home') setHour(edgeHour('first'))\n else if (event.key === 'End') setHour(edgeHour('last'))\n else return\n event.preventDefault()\n return\n }\n if (delta) setMinute(minuteToward(delta, 1))\n else if (event.key === 'PageUp') setMinute(minuteToward(1, 5))\n else if (event.key === 'PageDown') setMinute(minuteToward(-1, 5))\n // The list is built in these two branches alone: the arrows walk to a neighbour and never\n // need the whole of it.\n else if (event.key === 'Home') setMinute(allowedMinutesFor(hour.value, limits.value)[0] ?? null)\n else if (event.key === 'End')\n setMinute(allowedMinutesFor(hour.value, limits.value).at(-1) ?? null)\n else return\n event.preventDefault()\n}\n\ndefineExpose({\n /** Moves the focus onto the clock face, which the arrow keys drive. */\n focus: (options?: FocusOptions) => faceEl.value?.focus(options),\n /**\n * Puts the clock back on the hour and clears the announcement, WITHOUT announcing anything\n * itself.\n */\n reset: () => {\n step.value = 'hour'\n liveMessage.value = ''\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-time-picker\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :data-step=\"step\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n >\n <!--\n The two large numerals switch between adjusting the hour and the minutes. The one being\n adjusted takes the accent tone, which on a quiet button shows as the colour of the numeral\n rather than as a filled background.\n -->\n <div class=\"v-time-picker-header\">\n <div class=\"v-time-picker-time\">\n <VButton\n class=\"v-time-picker-cell\"\n variant=\"ghost\"\n size=\"lg\"\n :tone=\"step === 'hour' ? 'accent' : 'neutral'\"\n :aria-pressed=\"step === 'hour' ? 'true' : 'false'\"\n :aria-label=\"`${displayHourText}, ${m.timePicker.selectHour}`\"\n :disabled=\"disabled\"\n @click=\"setStep('hour')\"\n >\n {{ displayHourText }}\n </VButton>\n <span class=\"v-time-picker-sep\" aria-hidden=\"true\">:</span>\n <VButton\n class=\"v-time-picker-cell\"\n variant=\"ghost\"\n size=\"lg\"\n :tone=\"step === 'minute' ? 'accent' : 'neutral'\"\n :aria-pressed=\"step === 'minute' ? 'true' : 'false'\"\n :aria-label=\"`${pad2(minute)}, ${m.timePicker.selectMinutes}`\"\n :disabled=\"disabled\"\n @click=\"setStep('minute')\"\n >\n {{ pad2(minute) }}\n </VButton>\n </div>\n\n <VToggle\n v-if=\"resolvedFormat === '12h'\"\n v-model=\"meridiemModel\"\n class=\"v-time-picker-meridiem\"\n mandatory\n item-variant=\"outline\"\n selected-variant=\"soft\"\n orientation=\"vertical\"\n size=\"sm\"\n :label=\"m.timePicker.meridiem\"\n :disabled=\"disabled || readonly\"\n >\n <VToggleItem value=\"AM\" :label=\"m.timePicker.am\" :disabled=\"!meridiemAvailable.AM\" />\n <VToggleItem value=\"PM\" :label=\"m.timePicker.pm\" :disabled=\"!meridiemAvailable.PM\" />\n </VToggle>\n </div>\n\n <div\n ref=\"faceEl\"\n role=\"slider\"\n :tabindex=\"disabled ? -1 : 0\"\n class=\"v-time-picker-face\"\n :aria-label=\"step === 'hour' ? m.timePicker.hour : m.timePicker.minutes\"\n :aria-valuemin=\"ariaValueMin\"\n :aria-valuemax=\"ariaValueMax\"\n :aria-valuenow=\"ariaValueNow\"\n :aria-valuetext=\"ariaValueText\"\n :data-dragging=\"dragging ? '' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-readonly=\"readonly ? 'true' : undefined\"\n @pointerdown=\"onPointerdown\"\n @pointermove=\"onPointermove\"\n @pointerup=\"onPointerup\"\n @pointercancel=\"onPointercancel\"\n @keydown=\"onKeydown\"\n >\n <div\n class=\"v-time-picker-hand\"\n aria-hidden=\"true\"\n :data-ring=\"handRing\"\n :data-minor=\"handMinor ? '' : undefined\"\n :style=\"{ '--dial-turn': String(handTurn) }\"\n />\n <span class=\"v-time-picker-center\" aria-hidden=\"true\" />\n <span\n v-for=\"cell in cells\"\n :key=\"cell.key\"\n class=\"v-time-picker-number\"\n aria-hidden=\"true\"\n :data-ring=\"cell.ring\"\n :data-selected=\"cell.selected ? '' : undefined\"\n :style=\"{ '--dial-turn': String(cell.turn) }\"\n >{{ cell.label }}</span\n >\n </div>\n\n <div class=\"v-visually-hidden\" aria-live=\"polite\">{{ liveMessage }}</div>\n\n <div v-if=\"$slots.footer\" class=\"v-time-picker-footer\"><slot name=\"footer\" /></div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /* The same root as VDatePicker's: an inline column that sizes to its content and pads\n itself, so the clock reads the same on a page as in VTimeInput's panel, which adds no\n padding of its own. The gap is the clock's, its parts being larger. */\n .v-time-picker {\n display: inline-flex;\n flex-direction: column;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n /*\n * The numerals and the choice of half-day on one row, the second beside the first. The gap is\n * logical, so the control follows the reading direction; the numerals inside it stay in a\n * group of their own, which keeps the direction they force off it.\n */\n .v-time-picker-header {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--vectis-space-3);\n }\n\n /* A time written in figures always reads hours then minutes, in every language. Forcing\n the direction here is what stops bidirectional reordering from swapping the two in a\n right-to-left page. */\n .v-time-picker-time {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--vectis-space-2);\n direction: ltr;\n }\n\n /*\n * What is overridden here is the \"large numeral\" look alone; the width and the type; the\n * height, the states, the focus ring and the transitions all come from the button itself. The\n * type is the `heading-1` recipe taken whole, and the colon the `heading-2` one: read in\n * halves, a consumer repointing `--vectis-text-heading-1-weight` would move every heading but\n * these two numerals.\n */\n .v-time-picker-cell[data-size] {\n width: var(--control-height);\n font-size: var(--vectis-text-heading-1-size);\n font-weight: var(--vectis-text-heading-1-weight);\n line-height: var(--vectis-text-heading-1-leading);\n letter-spacing: var(--vectis-text-heading-1-tracking);\n /* Figures of equal width, so that going from \"11\" to \"00\" does not shift the cell. */\n font-variant-numeric: tabular-nums;\n }\n\n .v-time-picker-sep {\n font-size: var(--vectis-text-heading-2-size);\n font-weight: var(--vectis-text-heading-2-weight);\n line-height: var(--vectis-text-heading-2-leading);\n color: var(--vectis-color-text);\n user-select: none;\n }\n\n .v-time-picker-meridiem {\n flex: none;\n }\n\n .v-time-picker-face {\n position: relative;\n /*\n * The row above is wider than the face as soon as the half-day control is rendered, and the\n * column is only as wide as its widest child: without this the clock would hang at the\n * start edge of that row instead of under the middle of it. The face itself stays physical;\n * a clock is never mirrored.\n */\n align-self: center;\n inline-size: var(--vectis-control-size-time-picker-dial);\n block-size: var(--vectis-control-size-time-picker-dial);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-surface-muted);\n /* Dragging across the face IS how one chooses, so it must do nothing else: no\n scrolling under a finger, and no selecting the numerals as text. */\n touch-action: none;\n user-select: none;\n cursor: pointer;\n /*\n * This is coupled to the threshold that decides which of the two circles a point belongs\n * to, in `utils/clock`. Changing one without the other makes the face answer with the wrong\n * ring, and no test can catch it: the unit tests measure nothing.\n */\n --dial-radius: calc(\n var(--vectis-control-size-time-picker-dial) / 2 -\n var(--vectis-control-size-time-picker-number) / 2\n );\n }\n\n .v-time-picker-face: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 * The properties used are PHYSICAL on purpose, where the rest of the design system prefers\n * logical ones: a clock face is never mirrored, clockwise meaning the same thing in every\n * language.\n */\n .v-time-picker-number {\n position: absolute;\n left: calc(50% + var(--dial-radius) * sin(var(--dial-turn) * 1turn));\n top: calc(50% - var(--dial-radius) * cos(var(--dial-turn) * 1turn));\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-number);\n block-size: var(--vectis-control-size-time-picker-number);\n display: grid;\n place-items: center;\n border-radius: var(--vectis-radius-pill);\n /* The outer circle is set at the large body size: these numerals are read at arm's\n length on a phone, not scanned like a label. */\n font-size: var(--vectis-text-body-lg-size);\n color: var(--vectis-color-text);\n /*\n * Above the hand, so that the numeral being pointed at reads on its dot rather than being\n * covered by it.\n */\n z-index: 1;\n pointer-events: none;\n }\n\n .v-time-picker-number[data-ring='inner'],\n .v-time-picker-hand[data-ring='inner'] {\n --dial-radius: calc(\n var(--vectis-control-size-time-picker-dial) / 2 -\n var(--vectis-control-size-time-picker-number) * 1.5\n );\n }\n\n .v-time-picker-number[data-ring='inner'] {\n font-size: var(--vectis-text-body-md-size);\n color: var(--vectis-color-text-muted);\n }\n\n .v-time-picker-number[data-selected] {\n color: var(--vectis-color-text-on-accent);\n }\n\n /*\n * The rotation is deliberately not animated. Going from 55 minutes to 0 takes the angle from\n * nearly a full turn back to none, and an interpolation would sweep the hand all the way\n * round anticlockwise.\n */\n .v-time-picker-hand {\n position: absolute;\n left: calc(50% - var(--vectis-control-size-time-picker-hand) / 2);\n bottom: 50%;\n inline-size: var(--vectis-control-size-time-picker-hand);\n block-size: var(--dial-radius);\n background: var(--vectis-color-accent);\n transform-origin: 50% 100%;\n rotate: calc(var(--dial-turn) * 1turn);\n }\n\n /*\n * The dot at the tip of the hand. It is exactly the size of a numeral's cell, so it covers\n * the one being pointed at; whose text turns to the colour that reads on it.\n */\n .v-time-picker-hand::before {\n content: '';\n position: absolute;\n top: 0;\n left: 50%;\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-number);\n block-size: var(--vectis-control-size-time-picker-number);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent);\n /* The ONE thing animated on the hand: the dot changing size between its two forms. It\n interpolates between two bounded values and can therefore never take a wrong path,\n unlike the rotation above. */\n transition:\n inline-size var(--vectis-duration-fast) var(--vectis-ease-default),\n block-size var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * Only the DOT's own size changes. Redefining the numeral size variable here would also move\n * the radius derived from it, and with it the hand's length and the position of both circles.\n */\n .v-time-picker-hand[data-minor]::before {\n inline-size: var(--vectis-control-size-time-picker-hand-minor);\n block-size: var(--vectis-control-size-time-picker-hand-minor);\n }\n\n .v-time-picker-center {\n position: absolute;\n left: 50%;\n top: 50%;\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-center);\n block-size: var(--vectis-control-size-time-picker-center);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent);\n }\n\n /* Neither state is a pointer target. A read-only clock is still read, so it keeps the\n ordinary cursor; a disabled one refuses. */\n .v-time-picker[data-readonly] .v-time-picker-face {\n cursor: default;\n }\n\n .v-time-picker[data-disabled] .v-time-picker-face {\n cursor: not-allowed;\n }\n\n /*\n * The whole block sits after the rules it overrides, every one of them at the same\n * specificity: this is one sheet, so its own order is what settles them.\n */\n .v-time-picker[data-disabled] .v-time-picker-hand,\n .v-time-picker[data-disabled] .v-time-picker-hand::before,\n .v-time-picker[data-disabled] .v-time-picker-center {\n background: var(--vectis-color-border-strong);\n }\n\n .v-time-picker[data-disabled] .v-time-picker-sep,\n .v-time-picker[data-disabled] .v-time-picker-number,\n .v-time-picker[data-disabled] .v-time-picker-number[data-selected] {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-time-picker-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--vectis-space-2);\n padding-block-start: var(--vectis-space-2);\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-time-picker-hand::before {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VTimePicker.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_openBlock","_createElementBlock","_unref","_createElementVNode","_createVNode","VButton","_withCtx","_createTextVNode","_toDisplayString","_createBlock","VToggle","VToggleItem","_createCommentVNode","_normalizeStyle","_Fragment","_renderList","_renderSlot","VButton_default","VToggle_default","VToggleItem_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","VTimePicker_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__expose","__emit","props","__props","model","useModel","emit","m","useMessages","ariaLabel","useAriaLabel","resolvedLocale","useResolvedLocale","resolvedFormat","computed","hourCycleFor","limits","resolveLimits","availableHours","hours","candidate","isHourAllowed","isAvailableHour","isDev","inject","hostWarnsKey","watchEffect","problem","limitsProblem","step","ref","parts","parseTime","to24h","pendingMeridiem","hour","minute","setHour","value","minutes","isTimeAllowed","nearestAllowedMinute","formatTime","setMinute","liveMessage","setStep","next","hourAt","dialIndexToHour24","index","ring","currentMeridiem","minuteMarks","interval","minuteInterval","spacing","marks","cells","pad2","twelve","shown12","to12h","rings","out","i","target","numeral","handTurn","hour24ToDial","handRing","handMinor","displayHourText","meridiemModel","meridiem","wanted","hourWithMeridiem","firstAllowed","meridiemAvailable","ariaValueNow","ariaValueMin","ariaValueMax","ariaValueText","m_","spoken","settleStep","via","faceEl","dragging","landed","applyPoint","face","rect","dx","event","dy","snapMinute","angleToIndex","distanceFraction","onPointerdown","onPointermove","onPointerup","onPointercancel","moveHour","delta","hour12","edgeHour","edge","minuteToward","grid","minuteGrid","direction","distance","n","start","k","onKeydown","allowedMinutesFor","options","openBlock","createElementBlock","unref","createElementVNode","createVNode","_cache","withCtx","createTextVNode","toDisplayString","createBlock","$event","createCommentVNode","normalizeStyle","Fragment","renderList","cell","_ctx","renderSlot"],"sources":["../../../src/components/VTimePicker/VTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @keyboard @a11y @core\n/**\n * CSS places clock numerals and the hand. JavaScript maps pointer angles and keyboard steps to\n * a time because HTML has no interactive clock-face primitive.\n */\n\nimport { computed, inject, ref, watchEffect } from 'vue'\n\nimport VButton from '../VButton/VButton.vue'\nimport VToggle from '../VToggle/VToggle.vue'\nimport type { ToggleModelValue } from '../VToggle/VToggle.vue'\nimport VToggleItem from '../VToggle/VToggleItem.vue'\nimport { formatTime, hourCycleFor, parseTime } from '../../utils/time'\nimport {\n DIAL_DEAD_ZONE,\n DIAL_INNER_THRESHOLD,\n angleToIndex,\n dialIndexToHour24,\n distanceFraction,\n hour24ToDial,\n hourWithMeridiem,\n snapMinute,\n to12h,\n to24h,\n} from '../../utils/clock'\nimport type { HourFormat, Meridiem } from '../../utils/time'\nimport {\n allowedMinutesFor,\n firstAllowed,\n isHourAllowed,\n isTimeAllowed,\n limitsProblem,\n minuteGrid,\n minuteInterval,\n nearestAllowedMinute,\n resolveLimits,\n} from './limits'\nimport type { TimePickerAllowed } from './limits'\nimport { pad2 } from '../../utils/text'\nimport { isDev } from '../../utils/env'\nimport { hostWarnsKey } from '../../utils/hostWarns'\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\n/** Whether the face shows a 12- or a 24-hour clock. */\nexport type TimePickerFormat = HourFormat\n\n/** Which of the two halves of a time is being adjusted. */\ntype TimePickerStep = 'hour' | 'minute'\n\ninterface TimePickerProps {\n /**\n * Whether the face shows a 12- or a 24-hour clock. Left out, the reader's language\n * decides, which is almost always what one wants.\n */\n format?: TimePickerFormat\n /**\n * A BCP 47 locale, which decides the clock. It TAKES PRECEDENCE over the design\n * system's global locale and falls back to it, which is why it has no literal default:\n * `undefined` has to stay recognizable for the global locale to have its chance.\n */\n locale?: string\n /**\n * The interval the minutes snap to, both when dragging and with the arrow keys. The face\n * prints only the minutes it can reach, so a step of a quarter of an hour marks four.\n */\n minuteStep?: number\n /** The earliest time that can be chosen, inclusive, as a canonical 24-hour `'HH:mm'`. */\n min?: string\n /** The latest time that can be chosen, inclusive, written like `min`. */\n max?: string\n /** Which hours can be chosen: the list of them, or a rule answering for one. */\n allowedHours?: TimePickerAllowed\n /**\n * Which minutes can be chosen: the list of them, or a rule answering for one. The\n * minutes it leaves out are not printed.\n */\n allowedMinutes?: TimePickerAllowed\n /**\n * Makes the whole clock unusable: the hand cannot be moved, the half-day cannot be\n * changed, and everything greys out through the colour tokens.\n */\n disabled?: boolean\n /** Shows the time without letting it be changed. */\n readonly?: boolean\n /**\n * The accessible name of the whole clock, its two numerals and its face together. It falls\n * back to the dictionary, and a consumer `aria-label` wins over it.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<TimePickerProps>(), {\n format: undefined,\n locale: undefined,\n minuteStep: 1,\n min: undefined,\n max: undefined,\n allowedHours: undefined,\n allowedMinutes: undefined,\n disabled: false,\n readonly: false,\n label: undefined,\n})\n\n/** The time, always as a 24-hour \"HH:mm\" string whatever clock is displayed. */\nconst model = defineModel<string | null>({ default: null })\n\nconst emit = defineEmits<{\n /**\n * The reader has FINISHED, carrying the time as it stands: the minutes were settled from the\n * keyboard.\n */\n confirm: [value: string | null]\n}>()\n\ndefineSlots<{\n /** A strip at the foot of the clock, the place for actions such as Cancel and OK. */\n footer?(): unknown\n}>()\n\nconst m = useMessages()\n// @a11y\n// A roleless box cannot carry an accessible name (axe: aria-prohibited-attr),\n// so the root is a named group: the VCarousel viewport arrangement.\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.timePicker.label)\nconst resolvedLocale = useResolvedLocale(() => props.locale)\nconst resolvedFormat = computed<TimePickerFormat>(\n () => props.format ?? hourCycleFor(resolvedLocale.value),\n)\n\n/** The restrictions, resolved once for the whole render. */\nconst limits = computed(() => resolveLimits(props))\n\n/** The hours the restrictions still leave something in, worked out once per set of restrictions. */\nconst availableHours = computed(() => {\n const hours = new Set<number>()\n for (let candidate = 0; candidate < 24; candidate += 1)\n if (isHourAllowed(candidate, limits.value)) hours.add(candidate)\n return hours\n})\n\n/** Whether an hour is one the restrictions still leave something in. */\nconst isAvailableHour = (candidate: number) => availableHours.value.has(candidate)\n\n// @devwarn\nif (isDev && !inject(hostWarnsKey, false)) {\n watchEffect(() => {\n if (!Number.isInteger(props.minuteStep) || props.minuteStep < 1 || 60 % props.minuteStep !== 0)\n console.warn(`[VTimePicker] minuteStep ${props.minuteStep} — a divisor of 60 is expected.`)\n const problem = limitsProblem(limits.value)\n if (problem) console.warn(`[VTimePicker] ${problem}`)\n })\n}\n\n/** Which of the two is being adjusted. It starts on the hour and moves on by itself. */\nconst step = ref<TimePickerStep>('hour')\n\n// With no value the clock shows the first hour of the half of the day chosen so far, which\n// is midnight until PM is picked. It is also the hour a time started from the MINUTES is\n// written with, so that choice is not lost when the reader begins there.\nconst parts = computed(\n () =>\n parseTime(model.value) ?? {\n hour: resolvedFormat.value === '12h' ? to24h(12, pendingMeridiem.value) : 0,\n minute: 0,\n },\n)\nconst hour = computed(() => parts.value.hour)\nconst minute = computed(() => parts.value.minute)\n\n/*\n * The two writers are the SINGLE cut-off point for the restrictions: the pointer, the six\n * keys and the AM/PM control all write through them and through nothing else, so not one\n * handler carries a guard of its own.\n */\n\n/**\n * Writing the hour. An hour with nothing left in it has no minute to fall back on, which\n * refuses it; one that is only PARTLY available pulls the minutes to what it does allow, since\n * `min: '09:30'` must not be left holding 09:00.\n */\nfunction setHour(value: number | null) {\n // Changing which face is shown stays allowed under `readonly`: reading the minutes is not\n // changing them.\n if (props.disabled || props.readonly) return\n if (value === null) return\n const minutes = isTimeAllowed(value, minute.value, limits.value)\n ? minute.value\n : nearestAllowedMinute(value, minute.value, limits.value)\n if (minutes === null) return\n model.value = formatTime(value, minutes)\n}\n\n/** Writing the minutes. Null is \"there was nowhere to go\", which every key can produce. */\nfunction setMinute(value: number | null) {\n if (props.disabled || props.readonly) return\n if (value === null || !isTimeAllowed(hour.value, value, limits.value)) return\n model.value = formatTime(hour.value, value)\n}\n\n// @a11y\n/*\n * Which step the clock is on is otherwise carried by the face's own name alone, and a change of\n * name is not reliably announced. A politely announced region says it a second time.\n */\nconst liveMessage = ref('')\n\nfunction setStep(next: TimePickerStep) {\n step.value = next\n liveMessage.value =\n next === 'minute' ? m.value.timePicker.choosingMinutes : m.value.timePicker.choosingHour\n}\n\n/** One numeral on the face. */\ninterface DialCell {\n key: string\n /** What is printed. */\n label: string\n /** Where it sits, as a fraction of a full turn from twelve o'clock. */\n turn: number\n /** Which of the two circles it belongs to, a 24-hour face having an inner one. */\n ring: 'outer' | 'inner'\n /** Whether it is the value currently being pointed at. */\n selected: boolean\n}\n\n/** The hour a position on the face stands for. */\nfunction hourAt(index: number, ring: 'outer' | 'inner'): number {\n return resolvedFormat.value === '24h'\n ? dialIndexToHour24(index, ring)\n : to24h(index === 0 ? 12 : index, currentMeridiem.value)\n}\n\n/** The minutes the face prints. */\nconst minuteMarks = computed(() => {\n const interval = minuteInterval(props.minuteStep)\n const spacing = 60 / interval <= 12 ? interval : 5\n const marks: number[] = []\n for (let minutes = 0; minutes < 60; minutes += spacing)\n if (minutes % interval === 0 && isTimeAllowed(hour.value, minutes, limits.value))\n marks.push(minutes)\n return marks\n})\n\n/*\n * A numeral that is only there to be refused says nothing the missing numeral does not say\n * better, and it says it in grey text a screen reader has no way to reach: the markers are\n * `aria-hidden`, so what the restrictions leave is spoken by the face's own value and by\n * nothing else.\n */\nconst cells = computed<DialCell[]>(() => {\n if (step.value === 'minute') {\n return minuteMarks.value.map((minutes) => ({\n key: `m-${minutes}`,\n label: pad2(minutes),\n turn: minutes / 60,\n ring: 'outer' as const,\n selected: minute.value === minutes,\n }))\n }\n // Each position's hour is worked out once, since on a 12-hour face that takes the half of the\n // day in force. The selection there still compares numerals and not hours: an empty clock\n // holding a PM choice sits on midnight, and its hand points at the 12 all the same.\n const twelve = resolvedFormat.value === '12h'\n const shown12 = to12h(hour.value).hour\n const rings: DialCell['ring'][] = twelve ? ['outer'] : ['outer', 'inner']\n const out: DialCell[] = []\n for (const ring of rings)\n for (let i = 0; i < 12; i += 1) {\n const target = hourAt(i, ring)\n if (!isAvailableHour(target)) continue\n const numeral = i === 0 ? 12 : i\n out.push({\n key: `${ring === 'outer' ? 'o' : 'i'}-${i}`,\n label: ring === 'inner' ? pad2(target) : String(numeral),\n turn: i / 12,\n ring,\n selected: twelve ? shown12 === numeral : hour.value === target,\n })\n }\n return out\n})\n\nconst handTurn = computed(() => {\n if (step.value === 'minute') return minute.value / 60\n const index =\n resolvedFormat.value === '24h' ? hour24ToDial(hour.value).index : to12h(hour.value).hour % 12\n return index / 12\n})\n\nconst handRing = computed(() =>\n step.value === 'hour' && resolvedFormat.value === '24h' ? hour24ToDial(hour.value).ring : 'outer',\n)\n\n/**\n * Whether the hand points at a minute that has no marker of its own. The tip is then\n * drawn small: at full size it would cover the two neighbouring markers and read as\n * pointing at neither.\n */\nconst handMinor = computed(\n () => step.value === 'minute' && !minuteMarks.value.includes(minute.value),\n)\n\n/** The hour as the two large numerals show it, on whichever clock is displayed. */\nconst displayHourText = computed(() =>\n pad2(resolvedFormat.value === '12h' ? to12h(hour.value).hour : hour.value),\n)\n\n/** Which half of the day is chosen while no time is set at all. */\nconst pendingMeridiem = ref<Meridiem>('AM')\n\n/**\n * The half of the day in force: the value's own once there is one, the remembered choice until\n * then.\n */\nconst currentMeridiem = computed<Meridiem>(() =>\n model.value ? to12h(hour.value).meridiem : pendingMeridiem.value,\n)\n\nconst meridiemModel = computed<ToggleModelValue>({\n get: () => currentMeridiem.value,\n set: (value) => {\n const meridiem: Meridiem = value === 'PM' ? 'PM' : 'AM'\n pendingMeridiem.value = meridiem\n // With no time set there is nothing to convert, so the choice is simply REMEMBERED\n // and applies to the first time chosen.\n if (!model.value) return\n // What is being chosen here is the HALF OF THE DAY, so the hour gives way to it: kept\n // when the new half allows it, and otherwise the first hour of that half that does.\n // Refusing the write instead would leave the control snapping straight back, since it\n // reads the half of the day off the value.\n const wanted = hourWithMeridiem(hour.value, meridiem)\n setHour(\n isAvailableHour(wanted)\n ? wanted\n : firstAllowed(12, (i) => to24h(i, meridiem), isAvailableHour),\n )\n },\n})\n\n/**\n * Whether each half of the day still holds an hour one could choose. An empty one takes its\n * button with it: a control that can only ever be refused is worse than no control.\n */\nconst meridiemAvailable = computed<Record<Meridiem, boolean>>(() => ({\n AM: firstAllowed(12, (i) => to24h(i, 'AM'), isAvailableHour) !== null,\n PM: firstAllowed(12, (i) => to24h(i, 'PM'), isAvailableHour) !== null,\n}))\n\n// @a11y\n// The entire spoken value of the face. The numerals are hidden from screen readers, so these\n// four attributes are the only thing assistive technology has: what the value is, what its\n// bounds are, and how to say it.\nconst ariaValueNow = computed(() => {\n if (step.value === 'minute') return minute.value\n return resolvedFormat.value === '12h' ? to12h(hour.value).hour : hour.value\n})\nconst ariaValueMin = computed(() =>\n step.value === 'minute' ? 0 : resolvedFormat.value === '12h' ? 1 : 0,\n)\nconst ariaValueMax = computed(() =>\n step.value === 'minute' ? 59 : resolvedFormat.value === '12h' ? 12 : 23,\n)\n// On a 12-hour face the half of the day is spoken with the hour: the AM/PM control is not\n// on the slider's way, and \"9 o'clock\" alone is two different times.\nconst ariaValueText = computed(() => {\n const m_ = m.value.timePicker\n if (step.value === 'minute') return m_.minutesValue(minute.value)\n const spoken = m_.hourValue(ariaValueNow.value)\n if (resolvedFormat.value === '24h') return spoken\n return `${spoken} ${currentMeridiem.value === 'PM' ? m_.pm : m_.am}`\n})\n\n/**\n * A step has been settled: after the hour come the minutes, and after the minutes the whole\n * thing is confirmed; but by KEYBOARD only, for the reason given on the emit.\n */\nfunction settleStep(via: 'pointer' | 'keyboard') {\n if (step.value === 'hour') setStep('minute')\n else if (via === 'keyboard') emit('confirm', model.value)\n}\n\nconst faceEl = ref<HTMLElement | null>(null)\nconst dragging = ref(false)\n/** Whether anything in the gesture under way landed on a numeral. */\nlet landed = false\n\n/**\n * Where a point on the face lands, and whether there was anything there at all. The write\n * itself still goes through `setHour`/ `setMinute` and their own guards, which is why\n * `readonly` is refused THERE and not here: a frozen clock is still one whose numerals are\n * real, and a tap on one moves the step on as it always did.\n */\nfunction applyPoint(event: PointerEvent): boolean {\n const face = faceEl.value\n // A disabled clock aims at nothing, so no step is moved on either: its header buttons\n // are disabled for the same reason.\n if (!face || props.disabled) return false\n // Measuring the face is safe here: this runs from a handler, hence in a browser, never\n // during a render.\n const rect = face.getBoundingClientRect()\n const dx = event.clientX - (rect.left + rect.width / 2)\n const dy = event.clientY - (rect.top + rect.height / 2)\n if (Math.hypot(dx, dy) <= DIAL_DEAD_ZONE * (rect.width / 2)) return false\n if (step.value === 'minute') {\n // The step's own snapping stands: a point between two markers has always been pulled\n // to the one it is nearest. What it is pulled to still has to BE on the face.\n const minutes = snapMinute(angleToIndex(dx, dy, 60), props.minuteStep)\n if (!isTimeAllowed(hour.value, minutes, limits.value)) return false\n setMinute(minutes)\n return true\n }\n const index = angleToIndex(dx, dy, 12)\n const ring =\n resolvedFormat.value === '24h' &&\n distanceFraction(dx, dy, rect.width / 2) < DIAL_INNER_THRESHOLD\n ? 'inner'\n : 'outer'\n const target = hourAt(index, ring)\n if (!isAvailableHour(target)) return false\n setHour(target)\n return true\n}\n\nfunction onPointerdown(event: PointerEvent) {\n // @fallback\n // Capture keeps dragging active outside the clock face; synthetic events may not reference a\n // capturable pointer.\n try {\n faceEl.value?.setPointerCapture(event.pointerId)\n } catch {\n /* Synthetic pointers cannot be captured. */\n }\n dragging.value = true\n landed = applyPoint(event)\n}\n\nfunction onPointermove(event: PointerEvent) {\n if (dragging.value && applyPoint(event)) landed = true\n}\n\nfunction onPointerup() {\n if (!dragging.value) return\n dragging.value = false\n // A gesture that never landed on a numeral has chosen nothing, so there is nothing to\n // move on FROM: the reader is left on the face they aimed at, looking at what they missed.\n if (landed) settleStep('pointer')\n}\n\nfunction onPointercancel() {\n dragging.value = false\n}\n\n// @keyboard @a11y\n// The keyboard a slider is expected to have.\n/*\n * Every key below walks until it finds something it MAY land on, rather than stopping at the\n * first thing it may not: with scattered hours a key that stopped would die at the first hole\n * and never reach what lies past it. Against a bound there is nothing past the hole, so the\n * same walk comes back empty and the key holds still, which a bound means.\n */\nfunction moveHour(delta: number) {\n if (resolvedFormat.value === '24h') {\n setHour(firstAllowed(23, (i) => (hour.value + delta * i + 24) % 24, isAvailableHour))\n return\n }\n // On a 12-hour face the hours cycle from 1 to 12 WITHIN the current half of the day:\n // passing midday is done on the AM/PM control, not by walking the hand past twelve.\n const hour12 = to12h(hour.value).hour\n setHour(\n firstAllowed(\n 11,\n (i) => to24h(((hour12 - 1 + delta * i + 12) % 12) + 1, currentMeridiem.value),\n isAvailableHour,\n ),\n )\n}\n\n/** The first or the last hour the face allows, on whichever clock it is showing. */\nfunction edgeHour(edge: 'first' | 'last'): number | null {\n if (resolvedFormat.value === '24h')\n return firstAllowed(24, (i) => (edge === 'first' ? i - 1 : 24 - i), isAvailableHour)\n return firstAllowed(\n 12,\n (i) => to24h(edge === 'first' ? i : 13 - i, currentMeridiem.value),\n isAvailableHour,\n )\n}\n\n/**\n * The minute a key lands on: the first step of the grid at least `distance` minutes away, that\n * way round, and then the next one the hour allows.\n */\nfunction minuteToward(direction: 1 | -1, distance: number): number | null {\n const grid = minuteGrid(props.minuteStep)\n const target = (((minute.value + direction * distance) % 60) + 60) % 60\n const n = grid.length\n let start = direction > 0 ? 0 : n - 1\n for (let k = 0; k < n; k += 1) {\n const i = direction > 0 ? k : n - 1 - k\n if (direction > 0 ? grid[i]! >= target : grid[i]! <= target) {\n start = i\n break\n }\n }\n return firstAllowed(\n n,\n (i) => grid[(((start + direction * (i - 1)) % n) + n) % n]!,\n (candidate) => isTimeAllowed(hour.value, candidate, limits.value),\n )\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n // The face of a disabled clock is out of the tab order, but `focus()` can still put the\n // focus there: nothing it is sent may move the step on or confirm.\n if (props.disabled) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n settleStep('keyboard')\n return\n }\n // The arrows are not flipped in a right-to-left page: a clock face is never mirrored;\n // clockwise means the same thing everywhere; so forward stays forward.\n const delta =\n event.key === 'ArrowUp' || event.key === 'ArrowRight'\n ? 1\n : event.key === 'ArrowDown' || event.key === 'ArrowLeft'\n ? -1\n : 0\n if (step.value === 'hour') {\n if (delta) moveHour(delta)\n else if (event.key === 'Home') setHour(edgeHour('first'))\n else if (event.key === 'End') setHour(edgeHour('last'))\n else return\n event.preventDefault()\n return\n }\n if (delta) setMinute(minuteToward(delta, 1))\n else if (event.key === 'PageUp') setMinute(minuteToward(1, 5))\n else if (event.key === 'PageDown') setMinute(minuteToward(-1, 5))\n // The list is built in these two branches alone: the arrows walk to a neighbour and never\n // need the whole of it.\n else if (event.key === 'Home') setMinute(allowedMinutesFor(hour.value, limits.value)[0] ?? null)\n else if (event.key === 'End')\n setMinute(allowedMinutesFor(hour.value, limits.value).at(-1) ?? null)\n else return\n event.preventDefault()\n}\n\ndefineExpose({\n /** Moves the focus onto the clock face, which the arrow keys drive. */\n focus: (options?: FocusOptions) => faceEl.value?.focus(options),\n /**\n * Puts the clock back on the hour and clears the announcement, WITHOUT announcing anything\n * itself.\n */\n reset: () => {\n step.value = 'hour'\n liveMessage.value = ''\n },\n})\n</script>\n\n<template>\n <div\n class=\"v-time-picker\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :data-step=\"step\"\n :data-disabled=\"disabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n >\n <!--\n The two large numerals switch between adjusting the hour and the minutes. The one being\n adjusted takes the accent tone, which on a quiet button shows as the colour of the numeral\n rather than as a filled background.\n -->\n <div class=\"v-time-picker-header\">\n <div class=\"v-time-picker-time\">\n <VButton\n class=\"v-time-picker-cell\"\n variant=\"ghost\"\n size=\"lg\"\n :tone=\"step === 'hour' ? 'accent' : 'neutral'\"\n :aria-pressed=\"step === 'hour' ? 'true' : 'false'\"\n :aria-label=\"`${displayHourText}, ${m.timePicker.selectHour}`\"\n :disabled=\"disabled\"\n @click=\"setStep('hour')\"\n >\n {{ displayHourText }}\n </VButton>\n <span class=\"v-time-picker-sep\" aria-hidden=\"true\">:</span>\n <VButton\n class=\"v-time-picker-cell\"\n variant=\"ghost\"\n size=\"lg\"\n :tone=\"step === 'minute' ? 'accent' : 'neutral'\"\n :aria-pressed=\"step === 'minute' ? 'true' : 'false'\"\n :aria-label=\"`${pad2(minute)}, ${m.timePicker.selectMinutes}`\"\n :disabled=\"disabled\"\n @click=\"setStep('minute')\"\n >\n {{ pad2(minute) }}\n </VButton>\n </div>\n\n <VToggle\n v-if=\"resolvedFormat === '12h'\"\n v-model=\"meridiemModel\"\n class=\"v-time-picker-meridiem\"\n mandatory\n item-variant=\"outline\"\n selected-variant=\"soft\"\n orientation=\"vertical\"\n size=\"sm\"\n :label=\"m.timePicker.meridiem\"\n :disabled=\"disabled || readonly\"\n >\n <VToggleItem value=\"AM\" :label=\"m.timePicker.am\" :disabled=\"!meridiemAvailable.AM\" />\n <VToggleItem value=\"PM\" :label=\"m.timePicker.pm\" :disabled=\"!meridiemAvailable.PM\" />\n </VToggle>\n </div>\n\n <div\n ref=\"faceEl\"\n role=\"slider\"\n :tabindex=\"disabled ? -1 : 0\"\n class=\"v-time-picker-face\"\n :aria-label=\"step === 'hour' ? m.timePicker.hour : m.timePicker.minutes\"\n :aria-valuemin=\"ariaValueMin\"\n :aria-valuemax=\"ariaValueMax\"\n :aria-valuenow=\"ariaValueNow\"\n :aria-valuetext=\"ariaValueText\"\n :data-dragging=\"dragging ? '' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-readonly=\"readonly ? 'true' : undefined\"\n @pointerdown=\"onPointerdown\"\n @pointermove=\"onPointermove\"\n @pointerup=\"onPointerup\"\n @pointercancel=\"onPointercancel\"\n @keydown=\"onKeydown\"\n >\n <div\n class=\"v-time-picker-hand\"\n aria-hidden=\"true\"\n :data-ring=\"handRing\"\n :data-minor=\"handMinor ? '' : undefined\"\n :style=\"{ '--dial-turn': String(handTurn) }\"\n />\n <span class=\"v-time-picker-center\" aria-hidden=\"true\" />\n <span\n v-for=\"cell in cells\"\n :key=\"cell.key\"\n class=\"v-time-picker-number\"\n aria-hidden=\"true\"\n :data-ring=\"cell.ring\"\n :data-selected=\"cell.selected ? '' : undefined\"\n :style=\"{ '--dial-turn': String(cell.turn) }\"\n >{{ cell.label }}</span\n >\n </div>\n\n <div class=\"v-visually-hidden\" aria-live=\"polite\">{{ liveMessage }}</div>\n\n <div v-if=\"$slots.footer\" class=\"v-time-picker-footer\"><slot name=\"footer\" /></div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /* The same root as VDatePicker's: an inline column that sizes to its content and pads\n itself, so the clock reads the same on a page as in VTimeInput's panel, which adds no\n padding of its own. The gap is the clock's, its parts being larger. */\n .v-time-picker {\n display: inline-flex;\n flex-direction: column;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n /*\n * The numerals and the choice of half-day on one row, the second beside the first. The gap is\n * logical, so the control follows the reading direction; the numerals inside it stay in a\n * group of their own, which keeps the direction they force off it.\n */\n .v-time-picker-header {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--vectis-space-3);\n }\n\n /* A time written in figures always reads hours then minutes, in every language. Forcing\n the direction here is what stops bidirectional reordering from swapping the two in a\n right-to-left page. */\n .v-time-picker-time {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--vectis-space-2);\n direction: ltr;\n }\n\n /*\n * What is overridden here is the \"large numeral\" look alone; the width and the type; the\n * height, the states, the focus ring and the transitions all come from the button itself. The\n * type is the `heading-1` recipe taken whole, and the colon the `heading-2` one: read in\n * halves, a consumer repointing `--vectis-text-heading-1-weight` would move every heading but\n * these two numerals.\n */\n .v-time-picker-cell[data-size] {\n width: var(--control-height);\n font-size: var(--vectis-text-heading-1-size);\n font-weight: var(--vectis-text-heading-1-weight);\n line-height: var(--vectis-text-heading-1-leading);\n letter-spacing: var(--vectis-text-heading-1-tracking);\n /* Figures of equal width, so that going from \"11\" to \"00\" does not shift the cell. */\n font-variant-numeric: tabular-nums;\n }\n\n .v-time-picker-sep {\n font-size: var(--vectis-text-heading-2-size);\n font-weight: var(--vectis-text-heading-2-weight);\n line-height: var(--vectis-text-heading-2-leading);\n color: var(--vectis-color-text);\n user-select: none;\n }\n\n .v-time-picker-meridiem {\n flex: none;\n }\n\n .v-time-picker-face {\n position: relative;\n /*\n * The row above is wider than the face as soon as the half-day control is rendered, and the\n * column is only as wide as its widest child: without this the clock would hang at the\n * start edge of that row instead of under the middle of it. The face itself stays physical;\n * a clock is never mirrored.\n */\n align-self: center;\n inline-size: var(--vectis-control-size-time-picker-dial);\n block-size: var(--vectis-control-size-time-picker-dial);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-surface-muted);\n /* Dragging across the face IS how one chooses, so it must do nothing else: no\n scrolling under a finger, and no selecting the numerals as text. */\n touch-action: none;\n user-select: none;\n cursor: pointer;\n /*\n * This is coupled to the threshold that decides which of the two circles a point belongs\n * to, in `utils/clock`. Changing one without the other makes the face answer with the wrong\n * ring, and no test can catch it: the unit tests measure nothing.\n */\n --dial-radius: calc(\n var(--vectis-control-size-time-picker-dial) / 2 -\n var(--vectis-control-size-time-picker-number) / 2\n );\n }\n\n .v-time-picker-face: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 * The properties used are PHYSICAL on purpose, where the rest of the design system prefers\n * logical ones: a clock face is never mirrored, clockwise meaning the same thing in every\n * language.\n */\n .v-time-picker-number {\n position: absolute;\n left: calc(50% + var(--dial-radius) * sin(var(--dial-turn) * 1turn));\n top: calc(50% - var(--dial-radius) * cos(var(--dial-turn) * 1turn));\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-number);\n block-size: var(--vectis-control-size-time-picker-number);\n display: grid;\n place-items: center;\n border-radius: var(--vectis-radius-pill);\n /* The outer circle is set at the large body size: these numerals are read at arm's\n length on a phone, not scanned like a label. */\n font-size: var(--vectis-text-body-lg-size);\n color: var(--vectis-color-text);\n /*\n * Above the hand, so that the numeral being pointed at reads on its dot rather than being\n * covered by it.\n */\n z-index: 1;\n pointer-events: none;\n }\n\n .v-time-picker-number[data-ring='inner'],\n .v-time-picker-hand[data-ring='inner'] {\n --dial-radius: calc(\n var(--vectis-control-size-time-picker-dial) / 2 -\n var(--vectis-control-size-time-picker-number) * 1.5\n );\n }\n\n .v-time-picker-number[data-ring='inner'] {\n font-size: var(--vectis-text-body-md-size);\n color: var(--vectis-color-text-muted);\n }\n\n .v-time-picker-number[data-selected] {\n color: var(--vectis-color-text-on-accent);\n }\n\n /*\n * The rotation is deliberately not animated. Going from 55 minutes to 0 takes the angle from\n * nearly a full turn back to none, and an interpolation would sweep the hand all the way\n * round anticlockwise.\n */\n .v-time-picker-hand {\n position: absolute;\n left: calc(50% - var(--vectis-control-size-time-picker-hand) / 2);\n bottom: 50%;\n inline-size: var(--vectis-control-size-time-picker-hand);\n block-size: var(--dial-radius);\n background: var(--vectis-color-accent);\n transform-origin: 50% 100%;\n rotate: calc(var(--dial-turn) * 1turn);\n }\n\n /*\n * The dot at the tip of the hand. It is exactly the size of a numeral's cell, so it covers\n * the one being pointed at; whose text turns to the colour that reads on it.\n */\n .v-time-picker-hand::before {\n content: '';\n position: absolute;\n top: 0;\n left: 50%;\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-number);\n block-size: var(--vectis-control-size-time-picker-number);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent);\n /* The ONE thing animated on the hand: the dot changing size between its two forms. It\n interpolates between two bounded values and can therefore never take a wrong path,\n unlike the rotation above. */\n transition:\n inline-size var(--vectis-duration-fast) var(--vectis-ease-default),\n block-size var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n /*\n * Only the DOT's own size changes. Redefining the numeral size variable here would also move\n * the radius derived from it, and with it the hand's length and the position of both circles.\n */\n .v-time-picker-hand[data-minor]::before {\n inline-size: var(--vectis-control-size-time-picker-hand-minor);\n block-size: var(--vectis-control-size-time-picker-hand-minor);\n }\n\n .v-time-picker-center {\n position: absolute;\n left: 50%;\n top: 50%;\n translate: -50% -50%;\n inline-size: var(--vectis-control-size-time-picker-center);\n block-size: var(--vectis-control-size-time-picker-center);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent);\n }\n\n /* Neither state is a pointer target. A read-only clock is still read, so it keeps the\n ordinary cursor; a disabled one refuses. */\n .v-time-picker[data-readonly] .v-time-picker-face {\n cursor: default;\n }\n\n .v-time-picker[data-disabled] .v-time-picker-face {\n cursor: not-allowed;\n }\n\n /*\n * The whole block sits after the rules it overrides, every one of them at the same\n * specificity: this is one sheet, so its own order is what settles them.\n */\n .v-time-picker[data-disabled] .v-time-picker-hand,\n .v-time-picker[data-disabled] .v-time-picker-hand::before,\n .v-time-picker[data-disabled] .v-time-picker-center {\n background: var(--vectis-color-border-strong);\n }\n\n .v-time-picker[data-disabled] .v-time-picker-sep,\n .v-time-picker[data-disabled] .v-time-picker-number,\n .v-time-picker[data-disabled] .v-time-picker-number[data-selected] {\n color: var(--vectis-color-text-subtle);\n }\n\n .v-time-picker-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--vectis-space-2);\n padding-block-start: var(--vectis-space-2);\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-time-picker-hand::before {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","names":[],"sources":["../../../src/components/VTimePicker/limits.ts"],"sourcesContent":["// @core\n/**\n * Pure, which makes any of it testable: jsdom lays no dial out, so what the face decides has to\n * be decidable from numbers alone.\n */\nimport { resolveMatcher } from '../../utils/matcher'\nimport { memo } from '../../utils/memo'\nimport { formatTime } from '../../utils/time'\n\n/** Which values are ALLOWED: the list of them, or a rule answering for one. */\nexport type TimePickerAllowed = number[] | ((value: number) => boolean)\n\n/**\n * The restrictions in force, resolved once: the matchers already turned into functions, and the\n * interval the minutes are reachable on carried alongside them, since whether an hour has\n * anything left in it depends on that too.\n */\nexport interface TimeLimits {\n /** The earliest time allowed, inclusive, as a canonical 24-hour `'HH:mm'`. */\n min?: string\n /** The latest time allowed, inclusive, in the same form. */\n max?: string\n /** Whether an hour, always the 24-hour one, is allowed. */\n hour: (hour: number) => boolean\n /** Whether a minute is allowed. */\n minute: (minute: number) => boolean\n /** The interval the minutes snap to, which makes one reachable at all. */\n step: number\n}\n\n/** The props both components declare, which is all this needs to resolve them. */\nexport interface TimeLimitProps {\n min?: string\n max?: string\n allowedHours?: TimePickerAllowed\n allowedMinutes?: TimePickerAllowed\n minuteStep: number\n}\n\n/** Allowing everything, which a restriction nobody wrote has to mean. */\nconst allowEverything = () => true\n\n/** The props as the resolved form. */\nexport function resolveLimits(props: TimeLimitProps): TimeLimits {\n return {\n min: props.min,\n max: props.max,\n hour: props.allowedHours ? resolveMatcher(props.allowedHours) : allowEverything,\n minute: props.allowedMinutes ? resolveMatcher(props.allowedMinutes) : allowEverything,\n step: props.minuteStep,\n }\n}\n\n/**\n * The interval a `minuteStep` actually walks by. A step at or below one minute is every minute,\n * which `snapMinute` reads it as.\n */\nexport function minuteInterval(step: number): number {\n const size = Math.round(step)\n return size > 1 ? size : 1\n}\n\nconst minuteGrids = new Map<number, readonly number[]>()\n\n/**\n * The minutes an interval leaves reachable inside an hour, built once per step. The list is\n * shared: read-only.\n */\nexport function minuteGrid(step: number): readonly number[] {\n return memo(minuteGrids, step, () => {\n const interval = minuteInterval(step)\n const grid: number[] = []\n for (let minute = 0; minute < 60; minute += interval) grid.push(minute)\n return grid\n })\n}\n\n/**\n * The bounds are compared as STRINGS. That works only because a canonical time is zero-padded\n * and fixed-width, which makes '09:30' < '17:00' order the way the clock does; hand it a value\n * that never went through `formatTime` and the comparison is quietly wrong.\n */\nexport function isTimeAllowed(hour: number, minute: number, limits: TimeLimits): boolean {\n if (!limits.hour(hour) || !limits.minute(minute)) return false\n // Without a bound there is nothing to compare, and no string worth formatting.\n if (!limits.min && !limits.max) return true\n const time = formatTime(hour, minute)\n return (!limits.min || time >= limits.min) && (!limits.max || time <= limits.max)\n}\n\n/** The minutes of one hour that can be chosen, in order. */\nexport function allowedMinutesFor(hour: number, limits: TimeLimits): number[] {\n return minuteGrid(limits.step).filter((minute) => isTimeAllowed(hour, minute, limits))\n}\n\n/**\n * Whether an hour still holds a minute one could choose. An hour is closed only when\n * nothing at all is left in it: `min: '09:30'` leaves nine o'clock open and takes the\n * first half of it away from the minutes instead.\n */\nexport function isHourAllowed(hour: number, limits: TimeLimits): boolean {\n if (!limits.hour(hour)) return false\n return minuteGrid(limits.step).some((minute) => isTimeAllowed(hour, minute, limits))\n}\n\n/** The minute nearest the one asked for that the hour allows, `null` when it allows none. */\nexport function nearestAllowedMinute(\n hour: number,\n minute: number,\n limits: TimeLimits,\n): number | null {\n let best: number | null = null\n let bestDistance = Number.POSITIVE_INFINITY\n for (const candidate of minuteGrid(limits.step)) {\n if (!isTimeAllowed(hour, candidate, limits)) continue\n const distance = Math.abs(candidate - minute)\n if (distance < bestDistance) {\n best = candidate\n bestDistance = distance\n }\n }\n return best\n}\n\n/**\n * The allowed time nearest the one asked for, as a canonical string, `null` when the\n * restrictions allow nothing at all.\n */\nexport function nearestAllowedTime(\n hour: number,\n minute: number,\n limits: TimeLimits,\n): string | null {\n const target = hour * 60 + minute\n let best: string | null = null\n let bestDistance = Number.POSITIVE_INFINITY\n for (let candidate = 0; candidate < 24; candidate += 1) {\n if (!limits.hour(candidate)) continue\n for (const each of allowedMinutesFor(candidate, limits)) {\n const distance = Math.abs(candidate * 60 + each - target)\n if (distance < bestDistance) {\n best = formatTime(candidate, each)\n bestDistance = distance\n }\n }\n }\n return best\n}\n\n/**\n * Walking a cycle until a value is allowed: `at` produces the candidate `i` steps away,\n * counting from one, and `allowed` answers for it. It gives up after a full turn instead of\n * looping for ever, which a set of restrictions allowing nothing would do.\n */\nexport function firstAllowed(\n turn: number,\n at: (i: number) => number,\n allowed: (value: number) => boolean,\n): number | null {\n for (let i = 1; i <= turn; i += 1) {\n const value = at(i)\n if (allowed(value)) return value\n }\n return null\n}\n\n/** What is wrong with a set of restrictions, in a sentence, or nothing at all. */\nexport function limitsProblem(limits: TimeLimits): string | null {\n if (limits.min && limits.max && limits.min > limits.max)\n return `min \"${limits.min}\" falls after max \"${limits.max}\", so no time can be chosen.`\n for (let hour = 0; hour < 24; hour += 1) if (isHourAllowed(hour, limits)) return null\n return 'min, max, allowedHours and allowedMinutes together leave no time that can be chosen.'\n}\n"],"mappings":";;;;AAwCA,IAAM,UAAwB;AAG9B,SAAgB,EAAc,GAAmC;CAC/D,OAAO;EACL,KAAK,EAAM;EACX,KAAK,EAAM;EACX,MAAM,EAAM,eAAe,EAAe,EAAM,YAAY,IAAI;EAChE,QAAQ,EAAM,iBAAiB,EAAe,EAAM,cAAc,IAAI;EACtE,MAAM,EAAM;CACd;AACF;AAMA,SAAgB,EAAe,GAAsB;CACnD,IAAM,IAAO,KAAK,MAAM,CAAI;CAC5B,OAAO,IAAO,IAAI,IAAO;AAC3B;AAEA,IAAM,oBAAc,IAAI,IAA+B;AAMvD,SAAgB,EAAW,GAAiC;CAC1D,OAAO,EAAK,GAAa,SAAY;EACnC,IAAM,IAAW,EAAe,CAAI,GAC9B,IAAiB,CAAC;EACxB,KAAK,IAAI,IAAS,GAAG,IAAS,IAAI,KAAU,GAAU,EAAK,KAAK,CAAM;EACtE,OAAO;CACT,CAAC;AACH;AAOA,SAAgB,EAAc,GAAc,GAAgB,GAA6B;CACvF,IAAI,CAAC,EAAO,KAAK,CAAI,KAAK,CAAC,EAAO,OAAO,CAAM,GAAG,OAAO;CAEzD,IAAI,CAAC,EAAO,OAAO,CAAC,EAAO,KAAK,OAAO;CACvC,IAAM,IAAO,EAAW,GAAM,CAAM;CACpC,QAAQ,CAAC,EAAO,OAAO,KAAQ,EAAO,SAAS,CAAC,EAAO,OAAO,KAAQ,EAAO;AAC/E;AAGA,SAAgB,EAAkB,GAAc,GAA8B;CAC5E,OAAO,EAAW,EAAO,IAAI,CAAC,CAAC,QAAQ,MAAW,EAAc,GAAM,GAAQ,CAAM,CAAC;AACvF;AAOA,SAAgB,EAAc,GAAc,GAA6B;CAEvE,OADK,EAAO,KAAK,CAAI,IACd,EAAW,EAAO,IAAI,CAAC,CAAC,MAAM,MAAW,EAAc,GAAM,GAAQ,CAAM,CAAC,IADpD;AAEjC;AAGA,SAAgB,EACd,GACA,GACA,GACe;CACf,IAAI,IAAsB,MACtB,IAAe;CACnB,KAAK,IAAM,KAAa,EAAW,EAAO,IAAI,GAAG;EAC/C,IAAI,CAAC,EAAc,GAAM,GAAW,CAAM,GAAG;EAC7C,IAAM,IAAW,KAAK,IAAI,IAAY,CAAM;EAC5C,AAAI,IAAW,MACb,IAAO,GACP,IAAe;CAEnB;CACA,OAAO;AACT;AAMA,SAAgB,EACd,GACA,GACA,GACe;CACf,IAAM,IAAS,IAAO,KAAK,GACvB,IAAsB,MACtB,IAAe;CACnB,KAAK,IAAI,IAAY,GAAG,IAAY,IAAI,KAAa,GAC9C,MAAO,KAAK,CAAS,GAC1B,KAAK,IAAM,KAAQ,EAAkB,GAAW,CAAM,GAAG;EACvD,IAAM,IAAW,KAAK,IAAI,IAAY,KAAK,IAAO,CAAM;EACxD,AAAI,IAAW,MACb,IAAO,EAAW,GAAW,CAAI,GACjC,IAAe;CAEnB;CAEF,OAAO;AACT;AAOA,SAAgB,EACd,GACA,GACA,GACe;CACf,KAAK,IAAI,IAAI,GAAG,KAAK,GAAM,KAAK,GAAG;EACjC,IAAM,IAAQ,EAAG,CAAC;EAClB,IAAI,EAAQ,CAAK,GAAG,OAAO;CAC7B;CACA,OAAO;AACT;AAGA,SAAgB,EAAc,GAAmC;CAC/D,IAAI,EAAO,OAAO,EAAO,OAAO,EAAO,MAAM,EAAO,KAClD,OAAO,QAAQ,EAAO,IAAI,qBAAqB,EAAO,IAAI;CAC5D,KAAK,IAAI,IAAO,GAAG,IAAO,IAAI,KAAQ,GAAG,IAAI,EAAc,GAAM,CAAM,GAAG,OAAO;CACjF,OAAO;AACT"}
1
+ {"version":3,"file":"limits.js","names":["allowEverything","resolveLimits","props","resolveMatcher","minuteInterval","size","step","minuteGrids","minuteGrid","memo","interval","grid","minute","isTimeAllowed","limits","hour","time","formatTime","allowedMinutesFor","isHourAllowed","nearestAllowedMinute","best","bestDistance","candidate","distance","nearestAllowedTime","target","each","firstAllowed","i","turn","value","at","allowed","limitsProblem"],"sources":["../../../src/components/VTimePicker/limits.ts"],"sourcesContent":["// @core\n/**\n * Pure, which makes any of it testable: jsdom lays no dial out, so what the face decides has to\n * be decidable from numbers alone.\n */\nimport { resolveMatcher } from '../../utils/matcher'\nimport { memo } from '../../utils/memo'\nimport { formatTime } from '../../utils/time'\n\n/** Which values are ALLOWED: the list of them, or a rule answering for one. */\nexport type TimePickerAllowed = number[] | ((value: number) => boolean)\n\n/**\n * The restrictions in force, resolved once: the matchers already turned into functions, and the\n * interval the minutes are reachable on carried alongside them, since whether an hour has\n * anything left in it depends on that too.\n */\nexport interface TimeLimits {\n /** The earliest time allowed, inclusive, as a canonical 24-hour `'HH:mm'`. */\n min?: string\n /** The latest time allowed, inclusive, in the same form. */\n max?: string\n /** Whether an hour, always the 24-hour one, is allowed. */\n hour: (hour: number) => boolean\n /** Whether a minute is allowed. */\n minute: (minute: number) => boolean\n /** The interval the minutes snap to, which makes one reachable at all. */\n step: number\n}\n\n/** The props both components declare, which is all this needs to resolve them. */\nexport interface TimeLimitProps {\n min?: string\n max?: string\n allowedHours?: TimePickerAllowed\n allowedMinutes?: TimePickerAllowed\n minuteStep: number\n}\n\n/** Allowing everything, which a restriction nobody wrote has to mean. */\nconst allowEverything = () => true\n\n/** The props as the resolved form. */\nexport function resolveLimits(props: TimeLimitProps): TimeLimits {\n return {\n min: props.min,\n max: props.max,\n hour: props.allowedHours ? resolveMatcher(props.allowedHours) : allowEverything,\n minute: props.allowedMinutes ? resolveMatcher(props.allowedMinutes) : allowEverything,\n step: props.minuteStep,\n }\n}\n\n/**\n * The interval a `minuteStep` actually walks by. A step at or below one minute is every minute,\n * which `snapMinute` reads it as.\n */\nexport function minuteInterval(step: number): number {\n const size = Math.round(step)\n return size > 1 ? size : 1\n}\n\nconst minuteGrids = new Map<number, readonly number[]>()\n\n/**\n * The minutes an interval leaves reachable inside an hour, built once per step. The list is\n * shared: read-only.\n */\nexport function minuteGrid(step: number): readonly number[] {\n return memo(minuteGrids, step, () => {\n const interval = minuteInterval(step)\n const grid: number[] = []\n for (let minute = 0; minute < 60; minute += interval) grid.push(minute)\n return grid\n })\n}\n\n/**\n * The bounds are compared as STRINGS. That works only because a canonical time is zero-padded\n * and fixed-width, which makes '09:30' < '17:00' order the way the clock does; hand it a value\n * that never went through `formatTime` and the comparison is quietly wrong.\n */\nexport function isTimeAllowed(hour: number, minute: number, limits: TimeLimits): boolean {\n if (!limits.hour(hour) || !limits.minute(minute)) return false\n // Without a bound there is nothing to compare, and no string worth formatting.\n if (!limits.min && !limits.max) return true\n const time = formatTime(hour, minute)\n return (!limits.min || time >= limits.min) && (!limits.max || time <= limits.max)\n}\n\n/** The minutes of one hour that can be chosen, in order. */\nexport function allowedMinutesFor(hour: number, limits: TimeLimits): number[] {\n return minuteGrid(limits.step).filter((minute) => isTimeAllowed(hour, minute, limits))\n}\n\n/**\n * Whether an hour still holds a minute one could choose. An hour is closed only when\n * nothing at all is left in it: `min: '09:30'` leaves nine o'clock open and takes the\n * first half of it away from the minutes instead.\n */\nexport function isHourAllowed(hour: number, limits: TimeLimits): boolean {\n if (!limits.hour(hour)) return false\n return minuteGrid(limits.step).some((minute) => isTimeAllowed(hour, minute, limits))\n}\n\n/** The minute nearest the one asked for that the hour allows, `null` when it allows none. */\nexport function nearestAllowedMinute(\n hour: number,\n minute: number,\n limits: TimeLimits,\n): number | null {\n let best: number | null = null\n let bestDistance = Number.POSITIVE_INFINITY\n for (const candidate of minuteGrid(limits.step)) {\n if (!isTimeAllowed(hour, candidate, limits)) continue\n const distance = Math.abs(candidate - minute)\n if (distance < bestDistance) {\n best = candidate\n bestDistance = distance\n }\n }\n return best\n}\n\n/**\n * The allowed time nearest the one asked for, as a canonical string, `null` when the\n * restrictions allow nothing at all.\n */\nexport function nearestAllowedTime(\n hour: number,\n minute: number,\n limits: TimeLimits,\n): string | null {\n const target = hour * 60 + minute\n let best: string | null = null\n let bestDistance = Number.POSITIVE_INFINITY\n for (let candidate = 0; candidate < 24; candidate += 1) {\n if (!limits.hour(candidate)) continue\n for (const each of allowedMinutesFor(candidate, limits)) {\n const distance = Math.abs(candidate * 60 + each - target)\n if (distance < bestDistance) {\n best = formatTime(candidate, each)\n bestDistance = distance\n }\n }\n }\n return best\n}\n\n/**\n * Walking a cycle until a value is allowed: `at` produces the candidate `i` steps away,\n * counting from one, and `allowed` answers for it. It gives up after a full turn instead of\n * looping for ever, which a set of restrictions allowing nothing would do.\n */\nexport function firstAllowed(\n turn: number,\n at: (i: number) => number,\n allowed: (value: number) => boolean,\n): number | null {\n for (let i = 1; i <= turn; i += 1) {\n const value = at(i)\n if (allowed(value)) return value\n }\n return null\n}\n\n/** What is wrong with a set of restrictions, in a sentence, or nothing at all. */\nexport function limitsProblem(limits: TimeLimits): string | null {\n if (limits.min && limits.max && limits.min > limits.max)\n return `min \"${limits.min}\" falls after max \"${limits.max}\", so no time can be chosen.`\n for (let hour = 0; hour < 24; hour += 1) if (isHourAllowed(hour, limits)) return null\n return 'min, max, allowedHours and allowedMinutes together leave no time that can be chosen.'\n}\n"],"mappings":";;;;AAwCA,IAAMA,UAAwB;AAG9B,SAAgBC,EAAc,GAAmC;CAC/D,OAAO;EACL,KAAKC,EAAM;EACX,KAAKA,EAAM;EACX,MAAMA,EAAM,eAAeC,EAAeD,EAAM,YAAY,IAAIF;EAChE,QAAQE,EAAM,iBAAiBC,EAAeD,EAAM,cAAc,IAAIF;EACtE,MAAME,EAAM;CACd;AACF;AAMA,SAAgBE,EAAe,GAAsB;CACnD,IAAMC,IAAO,KAAK,MAAMC,CAAI;CAC5B,OAAOD,IAAO,IAAIA,IAAO;AAC3B;AAEA,IAAME,oBAAc,IAAI,IAA+B;AAMvD,SAAgBC,EAAW,GAAiC;CAC1D,OAAOC,EAAKF,GAAaD,SAAY;EACnC,IAAMI,IAAWN,EAAeE,CAAI,GAC9BK,IAAiB,CAAC;EACxB,KAAK,IAAIC,IAAS,GAAGA,IAAS,IAAI,KAAUF,GAAU,EAAK,KAAKE,CAAM;EACtE,OAAOD;CACT,CAAC;AACH;AAOA,SAAgBE,EAAc,GAAc,GAAgB,GAA6B;CACvF,IAAI,CAACC,EAAO,KAAKC,CAAI,KAAK,CAACD,EAAO,OAAOF,CAAM,GAAG,OAAO;CAEzD,IAAI,CAACE,EAAO,OAAO,CAACA,EAAO,KAAK,OAAO;CACvC,IAAME,IAAOC,EAAWF,GAAMH,CAAM;CACpC,QAAQ,CAACE,EAAO,OAAOE,KAAQF,EAAO,SAAS,CAACA,EAAO,OAAOE,KAAQF,EAAO;AAC/E;AAGA,SAAgBI,EAAkB,GAAc,GAA8B;CAC5E,OAAOV,EAAWM,EAAO,IAAI,CAAC,CAAC,QAAQ,MAAWD,EAAcE,GAAMH,GAAQE,CAAM,CAAC;AACvF;AAOA,SAAgBK,EAAc,GAAc,GAA6B;CAEvE,OADKL,EAAO,KAAKC,CAAI,IACdP,EAAWM,EAAO,IAAI,CAAC,CAAC,MAAM,MAAWD,EAAcE,GAAMH,GAAQE,CAAM,CAAC,IADpD;AAEjC;AAGA,SAAgBM,EACd,GACA,GACA,GACe;CACf,IAAIC,IAAsB,MACtBC,IAAe;CACnB,KAAK,IAAMC,KAAaf,EAAWM,EAAO,IAAI,GAAG;EAC/C,IAAI,CAACD,EAAcE,GAAMQ,GAAWT,CAAM,GAAG;EAC7C,IAAMU,IAAW,KAAK,IAAID,IAAYX,CAAM;EAC5C,AAAIY,IAAWF,MACb,IAAOC,GACP,IAAeC;CAEnB;CACA,OAAOH;AACT;AAMA,SAAgBI,EACd,GACA,GACA,GACe;CACf,IAAMC,IAASX,IAAO,KAAKH,GACvBS,IAAsB,MACtBC,IAAe;CACnB,KAAK,IAAIC,IAAY,GAAGA,IAAY,IAAI,KAAa,GACnD,IAAKT,EAAO,KAAKS,CAAS,GAC1B,KAAK,IAAMI,KAAQT,EAAkBK,GAAWT,CAAM,GAAG;EACvD,IAAMU,IAAW,KAAK,IAAID,IAAY,KAAKI,IAAOD,CAAM;EACxD,AAAIF,IAAWF,MACb,IAAOL,EAAWM,GAAWI,CAAI,GACjC,IAAeH;CAEnB;CAEF,OAAOH;AACT;AAOA,SAAgBO,EACd,GACA,GACA,GACe;CACf,KAAK,IAAIC,IAAI,GAAGA,KAAKC,GAAM,KAAK,GAAG;EACjC,IAAMC,IAAQC,EAAGH,CAAC;EAClB,IAAII,EAAQF,CAAK,GAAG,OAAOA;CAC7B;CACA,OAAO;AACT;AAGA,SAAgBG,EAAc,GAAmC;CAC/D,IAAIpB,EAAO,OAAOA,EAAO,OAAOA,EAAO,MAAMA,EAAO,KAClD,OAAO,QAAQA,EAAO,IAAI,qBAAqBA,EAAO,IAAI;CAC5D,KAAK,IAAIC,IAAO,GAAGA,IAAO,IAAI,KAAQ,GAAG,IAAII,EAAcJ,GAAMD,CAAM,GAAG,OAAO;CACjF,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"VTimeline.js","names":[],"sources":["../../../src/components/VTimeline/VTimeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * An ordered list of dated events, each a VTimelineItem: a marker on a line, a date, a title and\n * content of its own. The root is a wrapper, the size container of the side-by-side layouts;\n * attributes other than `class` and `style` go to the list.\n */\nimport { provide } from 'vue'\n\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { timelineKey, type TimelineHeadingLevel } from './context'\n\ndefineOptions({ inheritAttrs: false })\n\n/** Whether the events run down the page or across it. */\nexport type TimelineOrientation = 'vertical' | 'horizontal'\n\n/**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column of its own\n * across the line (`split`), or across the line from content that alternates sides\n * (`alternate`).\n */\nexport type TimelineLayout = 'stacked' | 'split' | 'alternate'\n\n/** The density of the timeline. */\nexport type TimelineSize = 'sm' | 'md'\n\ninterface TimelineProps {\n /**\n * Whether the events run down the page (`vertical`) or across it (`horizontal`). A horizontal\n * timeline scrolls when its events no longer fit.\n */\n orientation?: TimelineOrientation\n /**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column across the\n * line (`split`), or across the line from content that alternates sides (`alternate`). The\n * last two fall back to `stacked` in a narrow space.\n */\n layout?: TimelineLayout\n /** The density: `sm` tightens the spacing, the markers and the content text. */\n size?: TimelineSize\n /**\n * Renders the titles of the events as headings of this level, without changing how they look.\n * Left out, they are paragraphs.\n */\n headingLevel?: TimelineHeadingLevel\n /** The locale the dates are written in. Left out, the design system locale applies. */\n locale?: string\n /**\n * How a day or a moment is written, as `Intl.DateTimeFormat` options. Years and months keep\n * their own format. Set `timeZone` when the page is rendered on a server and a date carries an\n * offset, or the server's time zone would be the one shown.\n */\n formatOptions?: Intl.DateTimeFormatOptions\n}\n\nconst props = withDefaults(defineProps<TimelineProps>(), {\n orientation: 'vertical',\n layout: 'stacked',\n size: 'md',\n headingLevel: undefined,\n locale: undefined,\n formatOptions: undefined,\n})\n\ndefineSlots<{\n /** The `<VTimelineItem>`s, oldest or newest first as the story reads best. */\n default?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nprovide(timelineKey, {\n get orientation() {\n return props.orientation\n },\n get layout() {\n return props.layout\n },\n get headingLevel() {\n return props.headingLevel\n },\n get locale() {\n return props.locale\n },\n get formatOptions() {\n return props.formatOptions\n },\n})\n</script>\n\n<template>\n <div\n :class=\"['v-timeline', rootClass]\"\n :style=\"rootStyle\"\n :data-orientation=\"orientation\"\n :data-layout=\"orientation === 'vertical' ? layout : undefined\"\n :data-size=\"size\"\n >\n <!--\n A horizontal list scrolls, and its events may hold nothing focusable: the list itself is\n the tab stop that lets a keyboard scroll it.\n -->\n <ol\n class=\"v-timeline-list\"\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n v-bind=\"forwardedAttrs\"\n >\n <slot />\n </ol>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-timeline {\n --timeline-dot: var(--vectis-control-size-timeline-dot-md);\n --timeline-icon: var(--vectis-control-size-timeline-icon-md);\n --timeline-gutter: var(--vectis-space-3);\n --timeline-gap: var(--vectis-space-6);\n\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-timeline[data-size='sm'] {\n --timeline-dot: var(--vectis-control-size-timeline-dot-sm);\n --timeline-icon: var(--vectis-control-size-timeline-icon-sm);\n --timeline-gutter: var(--vectis-space-2);\n --timeline-gap: var(--vectis-space-4);\n }\n\n /*\n * The side-by-side layouts make the wrapper a size container, which is what lets them fall back\n * to `stacked` below a width. It therefore takes its width from its parent, never from its\n * events: in a row, give it a `flex` basis of its own.\n */\n .v-timeline[data-layout='split'],\n .v-timeline[data-layout='alternate'] {\n container: v-timeline / inline-size;\n }\n\n .v-timeline-list {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /*\n * The events are subgrids of the list: the marker column is as wide as the widest marker, so\n * the line runs straight through dots and badges alike.\n */\n .v-timeline[data-orientation='vertical'] > .v-timeline-list {\n grid-template-columns: [marker-start] auto [marker-end main-start] minmax(0, 1fr) [main-end];\n column-gap: var(--timeline-gutter);\n }\n\n /*\n * Across the page, the rows are shared instead: markers, dates, titles and contents line up\n * from one event to the next.\n */\n .v-timeline[data-orientation='horizontal'] > .v-timeline-list {\n grid-auto-flow: column;\n grid-auto-columns: minmax(var(--vectis-control-size-timeline-item-min), 1fr);\n grid-template-rows: repeat(4, auto);\n overflow-x: auto;\n border-radius: var(--vectis-radius-interactive);\n }\n\n .v-timeline-list: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 * The thresholds are literals, a container query accepting no variables. The date column of\n * `split` takes what its longest date needs, up to a third of the width.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline[data-layout='split'] > .v-timeline-list {\n grid-template-columns:\n [time-start] fit-content(33%) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n\n /* VTimelineItem repeats both thresholds: keep them in step. */\n @container v-timeline (width > 36rem) {\n .v-timeline[data-layout='alternate'] > .v-timeline-list {\n grid-template-columns:\n [time-start] minmax(0, 1fr) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VTimeline.js","names":["_sfc_main","VTimeline_vue_vue_type_script_setup_true_lang_default","VTimeline_default"],"sources":["../../../src/components/VTimeline/VTimeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * An ordered list of dated events, each a VTimelineItem: a marker on a line, a date, a title and\n * content of its own. The root is a wrapper, the size container of the side-by-side layouts;\n * attributes other than `class` and `style` go to the list.\n */\nimport { provide } from 'vue'\n\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { timelineKey, type TimelineHeadingLevel } from './context'\n\ndefineOptions({ inheritAttrs: false })\n\n/** Whether the events run down the page or across it. */\nexport type TimelineOrientation = 'vertical' | 'horizontal'\n\n/**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column of its own\n * across the line (`split`), or across the line from content that alternates sides\n * (`alternate`).\n */\nexport type TimelineLayout = 'stacked' | 'split' | 'alternate'\n\n/** The density of the timeline. */\nexport type TimelineSize = 'sm' | 'md'\n\ninterface TimelineProps {\n /**\n * Whether the events run down the page (`vertical`) or across it (`horizontal`). A horizontal\n * timeline scrolls when its events no longer fit.\n */\n orientation?: TimelineOrientation\n /**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column across the\n * line (`split`), or across the line from content that alternates sides (`alternate`). The\n * last two fall back to `stacked` in a narrow space.\n */\n layout?: TimelineLayout\n /** The density: `sm` tightens the spacing, the markers and the content text. */\n size?: TimelineSize\n /**\n * Renders the titles of the events as headings of this level, without changing how they look.\n * Left out, they are paragraphs.\n */\n headingLevel?: TimelineHeadingLevel\n /** The locale the dates are written in. Left out, the design system locale applies. */\n locale?: string\n /**\n * How a day or a moment is written, as `Intl.DateTimeFormat` options. Years and months keep\n * their own format. Set `timeZone` when the page is rendered on a server and a date carries an\n * offset, or the server's time zone would be the one shown.\n */\n formatOptions?: Intl.DateTimeFormatOptions\n}\n\nconst props = withDefaults(defineProps<TimelineProps>(), {\n orientation: 'vertical',\n layout: 'stacked',\n size: 'md',\n headingLevel: undefined,\n locale: undefined,\n formatOptions: undefined,\n})\n\ndefineSlots<{\n /** The `<VTimelineItem>`s, oldest or newest first as the story reads best. */\n default?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nprovide(timelineKey, {\n get orientation() {\n return props.orientation\n },\n get layout() {\n return props.layout\n },\n get headingLevel() {\n return props.headingLevel\n },\n get locale() {\n return props.locale\n },\n get formatOptions() {\n return props.formatOptions\n },\n})\n</script>\n\n<template>\n <div\n :class=\"['v-timeline', rootClass]\"\n :style=\"rootStyle\"\n :data-orientation=\"orientation\"\n :data-layout=\"orientation === 'vertical' ? layout : undefined\"\n :data-size=\"size\"\n >\n <!--\n A horizontal list scrolls, and its events may hold nothing focusable: the list itself is\n the tab stop that lets a keyboard scroll it.\n -->\n <ol\n class=\"v-timeline-list\"\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n v-bind=\"forwardedAttrs\"\n >\n <slot />\n </ol>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-timeline {\n --timeline-dot: var(--vectis-control-size-timeline-dot-md);\n --timeline-icon: var(--vectis-control-size-timeline-icon-md);\n --timeline-gutter: var(--vectis-space-3);\n --timeline-gap: var(--vectis-space-6);\n\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-timeline[data-size='sm'] {\n --timeline-dot: var(--vectis-control-size-timeline-dot-sm);\n --timeline-icon: var(--vectis-control-size-timeline-icon-sm);\n --timeline-gutter: var(--vectis-space-2);\n --timeline-gap: var(--vectis-space-4);\n }\n\n /*\n * The side-by-side layouts make the wrapper a size container, which is what lets them fall back\n * to `stacked` below a width. It therefore takes its width from its parent, never from its\n * events: in a row, give it a `flex` basis of its own.\n */\n .v-timeline[data-layout='split'],\n .v-timeline[data-layout='alternate'] {\n container: v-timeline / inline-size;\n }\n\n .v-timeline-list {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /*\n * The events are subgrids of the list: the marker column is as wide as the widest marker, so\n * the line runs straight through dots and badges alike.\n */\n .v-timeline[data-orientation='vertical'] > .v-timeline-list {\n grid-template-columns: [marker-start] auto [marker-end main-start] minmax(0, 1fr) [main-end];\n column-gap: var(--timeline-gutter);\n }\n\n /*\n * Across the page, the rows are shared instead: markers, dates, titles and contents line up\n * from one event to the next.\n */\n .v-timeline[data-orientation='horizontal'] > .v-timeline-list {\n grid-auto-flow: column;\n grid-auto-columns: minmax(var(--vectis-control-size-timeline-item-min), 1fr);\n grid-template-rows: repeat(4, auto);\n overflow-x: auto;\n border-radius: var(--vectis-radius-interactive);\n }\n\n .v-timeline-list: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 * The thresholds are literals, a container query accepting no variables. The date column of\n * `split` takes what its longest date needs, up to a third of the width.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline[data-layout='split'] > .v-timeline-list {\n grid-template-columns:\n [time-start] fit-content(33%) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n\n /* VTimelineItem repeats both thresholds: keep them in step. */\n @container v-timeline (width > 36rem) {\n .v-timeline[data-layout='alternate'] > .v-timeline-list {\n grid-template-columns:\n [time-start] minmax(0, 1fr) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VTimeline.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VTimeline/VTimeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * An ordered list of dated events, each a VTimelineItem: a marker on a line, a date, a title and\n * content of its own. The root is a wrapper, the size container of the side-by-side layouts;\n * attributes other than `class` and `style` go to the list.\n */\nimport { provide } from 'vue'\n\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { timelineKey, type TimelineHeadingLevel } from './context'\n\ndefineOptions({ inheritAttrs: false })\n\n/** Whether the events run down the page or across it. */\nexport type TimelineOrientation = 'vertical' | 'horizontal'\n\n/**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column of its own\n * across the line (`split`), or across the line from content that alternates sides\n * (`alternate`).\n */\nexport type TimelineLayout = 'stacked' | 'split' | 'alternate'\n\n/** The density of the timeline. */\nexport type TimelineSize = 'sm' | 'md'\n\ninterface TimelineProps {\n /**\n * Whether the events run down the page (`vertical`) or across it (`horizontal`). A horizontal\n * timeline scrolls when its events no longer fit.\n */\n orientation?: TimelineOrientation\n /**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column across the\n * line (`split`), or across the line from content that alternates sides (`alternate`). The\n * last two fall back to `stacked` in a narrow space.\n */\n layout?: TimelineLayout\n /** The density: `sm` tightens the spacing, the markers and the content text. */\n size?: TimelineSize\n /**\n * Renders the titles of the events as headings of this level, without changing how they look.\n * Left out, they are paragraphs.\n */\n headingLevel?: TimelineHeadingLevel\n /** The locale the dates are written in. Left out, the design system locale applies. */\n locale?: string\n /**\n * How a day or a moment is written, as `Intl.DateTimeFormat` options. Years and months keep\n * their own format. Set `timeZone` when the page is rendered on a server and a date carries an\n * offset, or the server's time zone would be the one shown.\n */\n formatOptions?: Intl.DateTimeFormatOptions\n}\n\nconst props = withDefaults(defineProps<TimelineProps>(), {\n orientation: 'vertical',\n layout: 'stacked',\n size: 'md',\n headingLevel: undefined,\n locale: undefined,\n formatOptions: undefined,\n})\n\ndefineSlots<{\n /** The `<VTimelineItem>`s, oldest or newest first as the story reads best. */\n default?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nprovide(timelineKey, {\n get orientation() {\n return props.orientation\n },\n get layout() {\n return props.layout\n },\n get headingLevel() {\n return props.headingLevel\n },\n get locale() {\n return props.locale\n },\n get formatOptions() {\n return props.formatOptions\n },\n})\n</script>\n\n<template>\n <div\n :class=\"['v-timeline', rootClass]\"\n :style=\"rootStyle\"\n :data-orientation=\"orientation\"\n :data-layout=\"orientation === 'vertical' ? layout : undefined\"\n :data-size=\"size\"\n >\n <!--\n A horizontal list scrolls, and its events may hold nothing focusable: the list itself is\n the tab stop that lets a keyboard scroll it.\n -->\n <ol\n class=\"v-timeline-list\"\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n v-bind=\"forwardedAttrs\"\n >\n <slot />\n </ol>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-timeline {\n --timeline-dot: var(--vectis-control-size-timeline-dot-md);\n --timeline-icon: var(--vectis-control-size-timeline-icon-md);\n --timeline-gutter: var(--vectis-space-3);\n --timeline-gap: var(--vectis-space-6);\n\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-timeline[data-size='sm'] {\n --timeline-dot: var(--vectis-control-size-timeline-dot-sm);\n --timeline-icon: var(--vectis-control-size-timeline-icon-sm);\n --timeline-gutter: var(--vectis-space-2);\n --timeline-gap: var(--vectis-space-4);\n }\n\n /*\n * The side-by-side layouts make the wrapper a size container, which is what lets them fall back\n * to `stacked` below a width. It therefore takes its width from its parent, never from its\n * events: in a row, give it a `flex` basis of its own.\n */\n .v-timeline[data-layout='split'],\n .v-timeline[data-layout='alternate'] {\n container: v-timeline / inline-size;\n }\n\n .v-timeline-list {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /*\n * The events are subgrids of the list: the marker column is as wide as the widest marker, so\n * the line runs straight through dots and badges alike.\n */\n .v-timeline[data-orientation='vertical'] > .v-timeline-list {\n grid-template-columns: [marker-start] auto [marker-end main-start] minmax(0, 1fr) [main-end];\n column-gap: var(--timeline-gutter);\n }\n\n /*\n * Across the page, the rows are shared instead: markers, dates, titles and contents line up\n * from one event to the next.\n */\n .v-timeline[data-orientation='horizontal'] > .v-timeline-list {\n grid-auto-flow: column;\n grid-auto-columns: minmax(var(--vectis-control-size-timeline-item-min), 1fr);\n grid-template-rows: repeat(4, auto);\n overflow-x: auto;\n border-radius: var(--vectis-radius-interactive);\n }\n\n .v-timeline-list: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 * The thresholds are literals, a container query accepting no variables. The date column of\n * `split` takes what its longest date needs, up to a third of the width.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline[data-layout='split'] > .v-timeline-list {\n grid-template-columns:\n [time-start] fit-content(33%) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n\n /* VTimelineItem repeats both thresholds: keep them in step. */\n @container v-timeline (width > 36rem) {\n .v-timeline[data-layout='alternate'] > .v-timeline-list {\n grid-template-columns:\n [time-start] minmax(0, 1fr) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAwDA,IAAM,IAAQ,GAcR,EAAE,cAAW,cAAW,sBAAmB,EAAa;SAE9D,EAAQ,GAAa;GACnB,IAAI,cAAc;IAChB,OAAO,EAAM;GACf;GACA,IAAI,SAAS;IACX,OAAO,EAAM;GACf;GACA,IAAI,eAAe;IACjB,OAAO,EAAM;GACf;GACA,IAAI,SAAS;IACX,OAAO,EAAM;GACf;GACA,IAAI,gBAAgB;IAClB,OAAO,EAAM;GACf;EACF,CAAC,mBAIC,EAkBM,OAAA;GAjBH,OAAK,EAAA,CAAA,cAAiB,EAAA,CAAA,CAAS,CAAA;GAC/B,OAAK,EAAE,EAAA,CAAA,CAAS;GAChB,oBAAkB,EAAA;GAClB,eAAa,EAAA,gBAAW,aAAkB,EAAA,SAAS,KAAA;GACnD,aAAW,EAAA;MAMZ,EAMK,MANL,EAMK;GALH,OAAM;GACL,UAAU,EAAA,gBAAW,eAAA,IAAwB,KAAA;KACtC,EAAA,CAAA,CAAc,GAAA,CAEtB,EAAQ,EAAA,QAAA,SAAA,CAAA,GAAA,IAAA,CAAA,CAAA,GAAA,IAAA,CAAA"}
1
+ {"version":3,"file":"VTimeline.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_createElementVNode","_mergeProps","_renderSlot","_hoisted_1","_hoisted_2","VTimeline_vue_vue_type_script_setup_true_lang_default","props","__props","useRootAttrs","provide","timelineKey","openBlock","createElementBlock","normalizeClass","unref","rootClass","normalizeStyle","rootStyle","createElementVNode","mergeProps","forwardedAttrs","renderSlot","_ctx"],"sources":["../../../src/components/VTimeline/VTimeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * An ordered list of dated events, each a VTimelineItem: a marker on a line, a date, a title and\n * content of its own. The root is a wrapper, the size container of the side-by-side layouts;\n * attributes other than `class` and `style` go to the list.\n */\nimport { provide } from 'vue'\n\nimport { useRootAttrs } from '../../composables/useRootAttrs'\nimport { timelineKey, type TimelineHeadingLevel } from './context'\n\ndefineOptions({ inheritAttrs: false })\n\n/** Whether the events run down the page or across it. */\nexport type TimelineOrientation = 'vertical' | 'horizontal'\n\n/**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column of its own\n * across the line (`split`), or across the line from content that alternates sides\n * (`alternate`).\n */\nexport type TimelineLayout = 'stacked' | 'split' | 'alternate'\n\n/** The density of the timeline. */\nexport type TimelineSize = 'sm' | 'md'\n\ninterface TimelineProps {\n /**\n * Whether the events run down the page (`vertical`) or across it (`horizontal`). A horizontal\n * timeline scrolls when its events no longer fit.\n */\n orientation?: TimelineOrientation\n /**\n * Where a vertical timeline puts the date: above the title (`stacked`), in a column across the\n * line (`split`), or across the line from content that alternates sides (`alternate`). The\n * last two fall back to `stacked` in a narrow space.\n */\n layout?: TimelineLayout\n /** The density: `sm` tightens the spacing, the markers and the content text. */\n size?: TimelineSize\n /**\n * Renders the titles of the events as headings of this level, without changing how they look.\n * Left out, they are paragraphs.\n */\n headingLevel?: TimelineHeadingLevel\n /** The locale the dates are written in. Left out, the design system locale applies. */\n locale?: string\n /**\n * How a day or a moment is written, as `Intl.DateTimeFormat` options. Years and months keep\n * their own format. Set `timeZone` when the page is rendered on a server and a date carries an\n * offset, or the server's time zone would be the one shown.\n */\n formatOptions?: Intl.DateTimeFormatOptions\n}\n\nconst props = withDefaults(defineProps<TimelineProps>(), {\n orientation: 'vertical',\n layout: 'stacked',\n size: 'md',\n headingLevel: undefined,\n locale: undefined,\n formatOptions: undefined,\n})\n\ndefineSlots<{\n /** The `<VTimelineItem>`s, oldest or newest first as the story reads best. */\n default?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nprovide(timelineKey, {\n get orientation() {\n return props.orientation\n },\n get layout() {\n return props.layout\n },\n get headingLevel() {\n return props.headingLevel\n },\n get locale() {\n return props.locale\n },\n get formatOptions() {\n return props.formatOptions\n },\n})\n</script>\n\n<template>\n <div\n :class=\"['v-timeline', rootClass]\"\n :style=\"rootStyle\"\n :data-orientation=\"orientation\"\n :data-layout=\"orientation === 'vertical' ? layout : undefined\"\n :data-size=\"size\"\n >\n <!--\n A horizontal list scrolls, and its events may hold nothing focusable: the list itself is\n the tab stop that lets a keyboard scroll it.\n -->\n <ol\n class=\"v-timeline-list\"\n :tabindex=\"orientation === 'horizontal' ? 0 : undefined\"\n v-bind=\"forwardedAttrs\"\n >\n <slot />\n </ol>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-timeline {\n --timeline-dot: var(--vectis-control-size-timeline-dot-md);\n --timeline-icon: var(--vectis-control-size-timeline-icon-md);\n --timeline-gutter: var(--vectis-space-3);\n --timeline-gap: var(--vectis-space-6);\n\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-timeline[data-size='sm'] {\n --timeline-dot: var(--vectis-control-size-timeline-dot-sm);\n --timeline-icon: var(--vectis-control-size-timeline-icon-sm);\n --timeline-gutter: var(--vectis-space-2);\n --timeline-gap: var(--vectis-space-4);\n }\n\n /*\n * The side-by-side layouts make the wrapper a size container, which is what lets them fall back\n * to `stacked` below a width. It therefore takes its width from its parent, never from its\n * events: in a row, give it a `flex` basis of its own.\n */\n .v-timeline[data-layout='split'],\n .v-timeline[data-layout='alternate'] {\n container: v-timeline / inline-size;\n }\n\n .v-timeline-list {\n display: grid;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n /*\n * The events are subgrids of the list: the marker column is as wide as the widest marker, so\n * the line runs straight through dots and badges alike.\n */\n .v-timeline[data-orientation='vertical'] > .v-timeline-list {\n grid-template-columns: [marker-start] auto [marker-end main-start] minmax(0, 1fr) [main-end];\n column-gap: var(--timeline-gutter);\n }\n\n /*\n * Across the page, the rows are shared instead: markers, dates, titles and contents line up\n * from one event to the next.\n */\n .v-timeline[data-orientation='horizontal'] > .v-timeline-list {\n grid-auto-flow: column;\n grid-auto-columns: minmax(var(--vectis-control-size-timeline-item-min), 1fr);\n grid-template-rows: repeat(4, auto);\n overflow-x: auto;\n border-radius: var(--vectis-radius-interactive);\n }\n\n .v-timeline-list: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 * The thresholds are literals, a container query accepting no variables. The date column of\n * `split` takes what its longest date needs, up to a third of the width.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline[data-layout='split'] > .v-timeline-list {\n grid-template-columns:\n [time-start] fit-content(33%) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n\n /* VTimelineItem repeats both thresholds: keep them in step. */\n @container v-timeline (width > 36rem) {\n .v-timeline[data-layout='alternate'] > .v-timeline-list {\n grid-template-columns:\n [time-start] minmax(0, 1fr) [time-end marker-start] auto [marker-end main-start]\n minmax(0, 1fr) [main-end];\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAwDA,IAAMW,IAAQC,GAcR,EAAE,cAAW,cAAW,sBAAmBC,EAAa;SAE9DC,EAAQC,GAAa;GACnB,IAAI,cAAc;IAChB,OAAOJ,EAAM;GACf;GACA,IAAI,SAAS;IACX,OAAOA,EAAM;GACf;GACA,IAAI,eAAe;IACjB,OAAOA,EAAM;GACf;GACA,IAAI,SAAS;IACX,OAAOA,EAAM;GACf;GACA,IAAI,gBAAgB;IAClB,OAAOA,EAAM;GACf;EACF,CAAC,cAICX,EAAA,GAAAC,EAkBM,OAAA;GAjBH,OAAKC,EAAA,CAAA,cAAiBC,EAAAiB,CAAA,CAAS,CAAA;GAC/B,OAAKhB,EAAED,EAAAmB,CAAA,CAAS;GAChB,oBAAkBV,EAAA;GAClB,eAAaA,EAAA,gBAAW,aAAkBA,EAAA,SAAS,KAAA;GACnD,aAAWA,EAAA;EAMZP,GAAAA,CAAAA,EAMK,MANLC,EAMK;GALH,OAAM;GACL,UAAUM,EAAA,gBAAW,eAAA,IAAwB,KAAA;EACtC,GAAAT,EAAAsB,CAAA,CAAc,GAAA,CAEtBlB,EAAQoB,EAAA,QAAA,SAAA,CAAA,GAAA,IAAAlB,CAAA,CAAA,GAAA,IAAAD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"VTimelineItem.js","names":[],"sources":["../../../src/components/VTimeline/VTimelineItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * One event of a VTimeline: a marker on the line, a date, a title and content. The marker is\n * decoration, hidden from assistive technology: what the tone means must also be said in words.\n */\nimport { computed, inject } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport { useResolvedLocale } from '../../i18n/state'\nimport { timelineKey } from './context'\nimport { formatTimelineDate } from './datetime'\n\n/** The colour of the marker. */\nexport type TimelineItemTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\ninterface TimelineItemProps {\n /**\n * When the event happened, as an ISO string: a year (`2019`), a month (`2026-10`), a day\n * (`2026-10-06`) or a moment (`2026-10-06T14:30`). It is written out in the locale, at that\n * precision, inside a `<time datetime>`.\n */\n datetime?: string\n /**\n * Visible text replacing the written-out date, such as \"2 hours ago\". The `<time>` keeps\n * `datetime` for machines.\n */\n timeText?: string\n /** What happened, in a few words. The `#title` slot replaces it. */\n title?: string\n /** The colour of the marker. */\n tone?: TimelineItemTone\n /**\n * An icon in a round badge on the line, in place of the dot: an icon name, or an explicit\n * render (the VIcon contract). The `#marker` slot replaces it.\n */\n icon?: IconSource\n}\n\nconst props = withDefaults(defineProps<TimelineItemProps>(), {\n datetime: undefined,\n timeText: undefined,\n title: undefined,\n tone: 'accent',\n icon: undefined,\n})\n\ndefineSlots<{\n /** The details of the event: text, links, buttons. */\n default?(): unknown\n /** Replaces the `title` prop with content of your own. */\n title?(): unknown\n /** Replaces the dot or the icon badge on the line, an avatar for instance. It is decoration. */\n marker?(): unknown\n}>()\n\nconst timeline = inject(timelineKey, undefined)\nconst locale = useResolvedLocale(() => timeline?.locale)\n\nconst titleTag = computed(() => (timeline?.headingLevel ? `h${timeline.headingLevel}` : 'p'))\n\nconst displayTime = computed(() => {\n if (props.timeText) return props.timeText\n if (!props.datetime) return ''\n return formatTimelineDate(props.datetime, locale.value, timeline?.formatOptions)\n})\n</script>\n\n<template>\n <li\n class=\"v-timeline-item v-tone\"\n :data-tone=\"tone\"\n :data-marker=\"$slots.marker ? 'custom' : icon ? 'icon' : 'dot'\"\n :data-orientation=\"timeline?.orientation ?? 'vertical'\"\n :data-layout=\"timeline?.layout ?? 'stacked'\"\n >\n <span class=\"v-timeline-marker\" aria-hidden=\"true\">\n <slot name=\"marker\">\n <span v-if=\"icon\" class=\"v-timeline-icon\"><VIcon v-bind=\"iconProps(icon)\" /></span>\n <span v-else class=\"v-timeline-dot\" />\n </slot>\n </span>\n <span class=\"v-timeline-connector\" aria-hidden=\"true\" />\n <component\n :is=\"datetime ? 'time' : 'span'\"\n v-if=\"displayTime\"\n class=\"v-timeline-time\"\n :datetime=\"datetime\"\n >\n {{ displayTime }}\n </component>\n <component :is=\"titleTag\" v-if=\"$slots.title || title\" class=\"v-timeline-title\">\n <slot name=\"title\">{{ title }}</slot>\n </component>\n <div v-if=\"$slots.default\" class=\"v-timeline-content\">\n <slot />\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The parts are placed on the grid of the list: the marker in the first row, the line under it\n * down to the end of the event, the texts beside it one row after another, and a last row for\n * the space before the next event, which the line runs through.\n */\n .v-timeline-item {\n --timeline-marker: var(--timeline-dot);\n /*\n * The first row is as tall as a title line, and the marker is centred on it. A badge taller\n * than the line reaches above and below it by `--timeline-overflow`, which the line and the\n * outer events make room for, so that the texts keep the same spacing beside a dot or a badge.\n */\n --timeline-line: calc(var(--vectis-text-label-size) * var(--vectis-text-label-leading));\n --timeline-overflow: max(0px, (var(--timeline-marker) - var(--timeline-line)) / 2);\n --timeline-dot-color: var(--tone-bg-solid);\n\n display: grid;\n min-inline-size: 0;\n }\n\n .v-timeline-item:last-child {\n --timeline-gap: 0px;\n }\n\n .v-timeline-item[data-orientation='vertical']:first-child {\n margin-block-start: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-orientation='vertical']:last-child {\n --timeline-gap: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-marker='icon'],\n .v-timeline-item[data-marker='custom'] {\n --timeline-marker: var(--timeline-icon);\n }\n\n .v-timeline-item[data-tone='neutral'] {\n --timeline-dot-color: var(--vectis-color-text-muted);\n }\n\n .v-timeline-item[data-orientation='vertical'] {\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n grid-template-rows: auto auto auto var(--timeline-gap);\n }\n\n /*\n * A flex line keeps the height of the marker, where a grid track would grow to fit a taller\n * badge; `unsafe` then centres the badge on that height rather than hanging it from its top.\n */\n .v-timeline-marker {\n display: flex;\n align-items: unsafe center;\n justify-content: center;\n min-inline-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-marker {\n grid-column: marker;\n grid-row: 1;\n block-size: var(--timeline-line);\n }\n\n /* A border rather than a fill draws the dot and the line, which forced colours keep. */\n .v-timeline-dot {\n box-sizing: border-box;\n inline-size: var(--timeline-dot);\n block-size: var(--timeline-dot);\n border: calc(var(--timeline-dot) / 2) solid var(--timeline-dot-color);\n border-radius: var(--vectis-radius-full);\n }\n\n .v-timeline-icon {\n --vectis-icon-size: calc(var(--timeline-icon) / 2);\n\n display: grid;\n place-items: center;\n box-sizing: border-box;\n inline-size: var(--timeline-icon);\n block-size: var(--timeline-icon);\n border: 1px solid var(--tone-border-soft);\n border-radius: var(--vectis-radius-full);\n background: var(--tone-bg-soft);\n color: var(--tone-text-tinted);\n }\n\n .v-timeline-connector {\n border-color: var(--vectis-color-border);\n border-style: solid;\n border-width: 0;\n }\n\n .v-timeline-item:last-child > .v-timeline-connector {\n display: none;\n }\n\n /* From under the marker down to the next one, stopping a little short of both. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector {\n grid-column: marker;\n grid-row: 2 / -1;\n justify-self: center;\n margin-block: calc(var(--vectis-space-1) + var(--timeline-overflow)) var(--vectis-space-1);\n border-inline-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='vertical']:has(\n + :is([data-marker='icon'], [data-marker='custom'])\n )\n > .v-timeline-connector {\n /* Halved term by term: cssnano's calc parser rejects a bracketed group inside max(). */\n margin-block-end: calc(\n var(--vectis-space-1) + max(0px, var(--timeline-icon) / 2 - var(--timeline-line) / 2)\n );\n }\n\n .v-timeline-item[data-orientation='vertical']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: main;\n }\n\n /* The first text beside the marker is at least a title line high, its first line centred. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-time {\n display: block;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n font-variant-numeric: tabular-nums;\n }\n\n .v-timeline-title {\n margin: 0;\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n .v-timeline-content {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-timeline-item > .v-timeline-title + .v-timeline-content {\n margin-block-start: var(--vectis-space-1);\n }\n\n .v-timeline[data-size='sm'] > .v-timeline-list > .v-timeline-item > .v-timeline-content {\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-text-body-sm-weight);\n line-height: var(--vectis-text-body-sm-leading);\n }\n\n /* Across the page: the marker and the line in the first row, the texts under them. */\n .v-timeline-item[data-orientation='horizontal'] {\n grid-row: 1 / -1;\n grid-template-rows: subgrid;\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-marker {\n grid-column: 1;\n grid-row: 1;\n align-self: center;\n block-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector {\n grid-column: 2;\n grid-row: 1;\n align-self: center;\n margin-inline: var(--vectis-space-1);\n border-block-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-time {\n grid-row: 2;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-title {\n grid-row: 3;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-content {\n grid-row: 4;\n }\n\n .v-timeline-item[data-orientation='horizontal']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: 1 / -1;\n padding-inline-end: var(--timeline-gap);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector + * {\n margin-block-start: var(--timeline-gutter);\n }\n\n /*\n * Across the line, the date sits in its own column and the title beside the marker takes the\n * row height too. The thresholds repeat those of VTimeline.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline-item[data-layout='split'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='split'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n }\n\n /* Every other event swaps sides: its date goes after the line, its texts before it. */\n @container v-timeline (width > 36rem) {\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even) > .v-timeline-time {\n grid-column: main;\n text-align: start;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even)\n > :is(.v-timeline-title, .v-timeline-content) {\n grid-column: time;\n text-align: end;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VTimelineItem.js","names":["_sfc_main","VTimelineItem_vue_vue_type_script_setup_true_lang_default","VTimelineItem_default"],"sources":["../../../src/components/VTimeline/VTimelineItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * One event of a VTimeline: a marker on the line, a date, a title and content. The marker is\n * decoration, hidden from assistive technology: what the tone means must also be said in words.\n */\nimport { computed, inject } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport { useResolvedLocale } from '../../i18n/state'\nimport { timelineKey } from './context'\nimport { formatTimelineDate } from './datetime'\n\n/** The colour of the marker. */\nexport type TimelineItemTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\ninterface TimelineItemProps {\n /**\n * When the event happened, as an ISO string: a year (`2019`), a month (`2026-10`), a day\n * (`2026-10-06`) or a moment (`2026-10-06T14:30`). It is written out in the locale, at that\n * precision, inside a `<time datetime>`.\n */\n datetime?: string\n /**\n * Visible text replacing the written-out date, such as \"2 hours ago\". The `<time>` keeps\n * `datetime` for machines.\n */\n timeText?: string\n /** What happened, in a few words. The `#title` slot replaces it. */\n title?: string\n /** The colour of the marker. */\n tone?: TimelineItemTone\n /**\n * An icon in a round badge on the line, in place of the dot: an icon name, or an explicit\n * render (the VIcon contract). The `#marker` slot replaces it.\n */\n icon?: IconSource\n}\n\nconst props = withDefaults(defineProps<TimelineItemProps>(), {\n datetime: undefined,\n timeText: undefined,\n title: undefined,\n tone: 'accent',\n icon: undefined,\n})\n\ndefineSlots<{\n /** The details of the event: text, links, buttons. */\n default?(): unknown\n /** Replaces the `title` prop with content of your own. */\n title?(): unknown\n /** Replaces the dot or the icon badge on the line, an avatar for instance. It is decoration. */\n marker?(): unknown\n}>()\n\nconst timeline = inject(timelineKey, undefined)\nconst locale = useResolvedLocale(() => timeline?.locale)\n\nconst titleTag = computed(() => (timeline?.headingLevel ? `h${timeline.headingLevel}` : 'p'))\n\nconst displayTime = computed(() => {\n if (props.timeText) return props.timeText\n if (!props.datetime) return ''\n return formatTimelineDate(props.datetime, locale.value, timeline?.formatOptions)\n})\n</script>\n\n<template>\n <li\n class=\"v-timeline-item v-tone\"\n :data-tone=\"tone\"\n :data-marker=\"$slots.marker ? 'custom' : icon ? 'icon' : 'dot'\"\n :data-orientation=\"timeline?.orientation ?? 'vertical'\"\n :data-layout=\"timeline?.layout ?? 'stacked'\"\n >\n <span class=\"v-timeline-marker\" aria-hidden=\"true\">\n <slot name=\"marker\">\n <span v-if=\"icon\" class=\"v-timeline-icon\"><VIcon v-bind=\"iconProps(icon)\" /></span>\n <span v-else class=\"v-timeline-dot\" />\n </slot>\n </span>\n <span class=\"v-timeline-connector\" aria-hidden=\"true\" />\n <component\n :is=\"datetime ? 'time' : 'span'\"\n v-if=\"displayTime\"\n class=\"v-timeline-time\"\n :datetime=\"datetime\"\n >\n {{ displayTime }}\n </component>\n <component :is=\"titleTag\" v-if=\"$slots.title || title\" class=\"v-timeline-title\">\n <slot name=\"title\">{{ title }}</slot>\n </component>\n <div v-if=\"$slots.default\" class=\"v-timeline-content\">\n <slot />\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The parts are placed on the grid of the list: the marker in the first row, the line under it\n * down to the end of the event, the texts beside it one row after another, and a last row for\n * the space before the next event, which the line runs through.\n */\n .v-timeline-item {\n --timeline-marker: var(--timeline-dot);\n /*\n * The first row is as tall as a title line, and the marker is centred on it. A badge taller\n * than the line reaches above and below it by `--timeline-overflow`, which the line and the\n * outer events make room for, so that the texts keep the same spacing beside a dot or a badge.\n */\n --timeline-line: calc(var(--vectis-text-label-size) * var(--vectis-text-label-leading));\n --timeline-overflow: max(0px, (var(--timeline-marker) - var(--timeline-line)) / 2);\n --timeline-dot-color: var(--tone-bg-solid);\n\n display: grid;\n min-inline-size: 0;\n }\n\n .v-timeline-item:last-child {\n --timeline-gap: 0px;\n }\n\n .v-timeline-item[data-orientation='vertical']:first-child {\n margin-block-start: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-orientation='vertical']:last-child {\n --timeline-gap: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-marker='icon'],\n .v-timeline-item[data-marker='custom'] {\n --timeline-marker: var(--timeline-icon);\n }\n\n .v-timeline-item[data-tone='neutral'] {\n --timeline-dot-color: var(--vectis-color-text-muted);\n }\n\n .v-timeline-item[data-orientation='vertical'] {\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n grid-template-rows: auto auto auto var(--timeline-gap);\n }\n\n /*\n * A flex line keeps the height of the marker, where a grid track would grow to fit a taller\n * badge; `unsafe` then centres the badge on that height rather than hanging it from its top.\n */\n .v-timeline-marker {\n display: flex;\n align-items: unsafe center;\n justify-content: center;\n min-inline-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-marker {\n grid-column: marker;\n grid-row: 1;\n block-size: var(--timeline-line);\n }\n\n /* A border rather than a fill draws the dot and the line, which forced colours keep. */\n .v-timeline-dot {\n box-sizing: border-box;\n inline-size: var(--timeline-dot);\n block-size: var(--timeline-dot);\n border: calc(var(--timeline-dot) / 2) solid var(--timeline-dot-color);\n border-radius: var(--vectis-radius-full);\n }\n\n .v-timeline-icon {\n --vectis-icon-size: calc(var(--timeline-icon) / 2);\n\n display: grid;\n place-items: center;\n box-sizing: border-box;\n inline-size: var(--timeline-icon);\n block-size: var(--timeline-icon);\n border: 1px solid var(--tone-border-soft);\n border-radius: var(--vectis-radius-full);\n background: var(--tone-bg-soft);\n color: var(--tone-text-tinted);\n }\n\n .v-timeline-connector {\n border-color: var(--vectis-color-border);\n border-style: solid;\n border-width: 0;\n }\n\n .v-timeline-item:last-child > .v-timeline-connector {\n display: none;\n }\n\n /* From under the marker down to the next one, stopping a little short of both. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector {\n grid-column: marker;\n grid-row: 2 / -1;\n justify-self: center;\n margin-block: calc(var(--vectis-space-1) + var(--timeline-overflow)) var(--vectis-space-1);\n border-inline-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='vertical']:has(\n + :is([data-marker='icon'], [data-marker='custom'])\n )\n > .v-timeline-connector {\n /* Halved term by term: cssnano's calc parser rejects a bracketed group inside max(). */\n margin-block-end: calc(\n var(--vectis-space-1) + max(0px, var(--timeline-icon) / 2 - var(--timeline-line) / 2)\n );\n }\n\n .v-timeline-item[data-orientation='vertical']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: main;\n }\n\n /* The first text beside the marker is at least a title line high, its first line centred. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-time {\n display: block;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n font-variant-numeric: tabular-nums;\n }\n\n .v-timeline-title {\n margin: 0;\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n .v-timeline-content {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-timeline-item > .v-timeline-title + .v-timeline-content {\n margin-block-start: var(--vectis-space-1);\n }\n\n .v-timeline[data-size='sm'] > .v-timeline-list > .v-timeline-item > .v-timeline-content {\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-text-body-sm-weight);\n line-height: var(--vectis-text-body-sm-leading);\n }\n\n /* Across the page: the marker and the line in the first row, the texts under them. */\n .v-timeline-item[data-orientation='horizontal'] {\n grid-row: 1 / -1;\n grid-template-rows: subgrid;\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-marker {\n grid-column: 1;\n grid-row: 1;\n align-self: center;\n block-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector {\n grid-column: 2;\n grid-row: 1;\n align-self: center;\n margin-inline: var(--vectis-space-1);\n border-block-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-time {\n grid-row: 2;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-title {\n grid-row: 3;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-content {\n grid-row: 4;\n }\n\n .v-timeline-item[data-orientation='horizontal']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: 1 / -1;\n padding-inline-end: var(--timeline-gap);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector + * {\n margin-block-start: var(--timeline-gutter);\n }\n\n /*\n * Across the line, the date sits in its own column and the title beside the marker takes the\n * row height too. The thresholds repeat those of VTimeline.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline-item[data-layout='split'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='split'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n }\n\n /* Every other event swaps sides: its date goes after the line, its texts before it. */\n @container v-timeline (width > 36rem) {\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even) > .v-timeline-time {\n grid-column: main;\n text-align: start;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even)\n > :is(.v-timeline-title, .v-timeline-content) {\n grid-column: time;\n text-align: end;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"VTimelineItem.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VTimeline/VTimelineItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * One event of a VTimeline: a marker on the line, a date, a title and content. The marker is\n * decoration, hidden from assistive technology: what the tone means must also be said in words.\n */\nimport { computed, inject } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport { useResolvedLocale } from '../../i18n/state'\nimport { timelineKey } from './context'\nimport { formatTimelineDate } from './datetime'\n\n/** The colour of the marker. */\nexport type TimelineItemTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\ninterface TimelineItemProps {\n /**\n * When the event happened, as an ISO string: a year (`2019`), a month (`2026-10`), a day\n * (`2026-10-06`) or a moment (`2026-10-06T14:30`). It is written out in the locale, at that\n * precision, inside a `<time datetime>`.\n */\n datetime?: string\n /**\n * Visible text replacing the written-out date, such as \"2 hours ago\". The `<time>` keeps\n * `datetime` for machines.\n */\n timeText?: string\n /** What happened, in a few words. The `#title` slot replaces it. */\n title?: string\n /** The colour of the marker. */\n tone?: TimelineItemTone\n /**\n * An icon in a round badge on the line, in place of the dot: an icon name, or an explicit\n * render (the VIcon contract). The `#marker` slot replaces it.\n */\n icon?: IconSource\n}\n\nconst props = withDefaults(defineProps<TimelineItemProps>(), {\n datetime: undefined,\n timeText: undefined,\n title: undefined,\n tone: 'accent',\n icon: undefined,\n})\n\ndefineSlots<{\n /** The details of the event: text, links, buttons. */\n default?(): unknown\n /** Replaces the `title` prop with content of your own. */\n title?(): unknown\n /** Replaces the dot or the icon badge on the line, an avatar for instance. It is decoration. */\n marker?(): unknown\n}>()\n\nconst timeline = inject(timelineKey, undefined)\nconst locale = useResolvedLocale(() => timeline?.locale)\n\nconst titleTag = computed(() => (timeline?.headingLevel ? `h${timeline.headingLevel}` : 'p'))\n\nconst displayTime = computed(() => {\n if (props.timeText) return props.timeText\n if (!props.datetime) return ''\n return formatTimelineDate(props.datetime, locale.value, timeline?.formatOptions)\n})\n</script>\n\n<template>\n <li\n class=\"v-timeline-item v-tone\"\n :data-tone=\"tone\"\n :data-marker=\"$slots.marker ? 'custom' : icon ? 'icon' : 'dot'\"\n :data-orientation=\"timeline?.orientation ?? 'vertical'\"\n :data-layout=\"timeline?.layout ?? 'stacked'\"\n >\n <span class=\"v-timeline-marker\" aria-hidden=\"true\">\n <slot name=\"marker\">\n <span v-if=\"icon\" class=\"v-timeline-icon\"><VIcon v-bind=\"iconProps(icon)\" /></span>\n <span v-else class=\"v-timeline-dot\" />\n </slot>\n </span>\n <span class=\"v-timeline-connector\" aria-hidden=\"true\" />\n <component\n :is=\"datetime ? 'time' : 'span'\"\n v-if=\"displayTime\"\n class=\"v-timeline-time\"\n :datetime=\"datetime\"\n >\n {{ displayTime }}\n </component>\n <component :is=\"titleTag\" v-if=\"$slots.title || title\" class=\"v-timeline-title\">\n <slot name=\"title\">{{ title }}</slot>\n </component>\n <div v-if=\"$slots.default\" class=\"v-timeline-content\">\n <slot />\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The parts are placed on the grid of the list: the marker in the first row, the line under it\n * down to the end of the event, the texts beside it one row after another, and a last row for\n * the space before the next event, which the line runs through.\n */\n .v-timeline-item {\n --timeline-marker: var(--timeline-dot);\n /*\n * The first row is as tall as a title line, and the marker is centred on it. A badge taller\n * than the line reaches above and below it by `--timeline-overflow`, which the line and the\n * outer events make room for, so that the texts keep the same spacing beside a dot or a badge.\n */\n --timeline-line: calc(var(--vectis-text-label-size) * var(--vectis-text-label-leading));\n --timeline-overflow: max(0px, (var(--timeline-marker) - var(--timeline-line)) / 2);\n --timeline-dot-color: var(--tone-bg-solid);\n\n display: grid;\n min-inline-size: 0;\n }\n\n .v-timeline-item:last-child {\n --timeline-gap: 0px;\n }\n\n .v-timeline-item[data-orientation='vertical']:first-child {\n margin-block-start: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-orientation='vertical']:last-child {\n --timeline-gap: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-marker='icon'],\n .v-timeline-item[data-marker='custom'] {\n --timeline-marker: var(--timeline-icon);\n }\n\n .v-timeline-item[data-tone='neutral'] {\n --timeline-dot-color: var(--vectis-color-text-muted);\n }\n\n .v-timeline-item[data-orientation='vertical'] {\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n grid-template-rows: auto auto auto var(--timeline-gap);\n }\n\n /*\n * A flex line keeps the height of the marker, where a grid track would grow to fit a taller\n * badge; `unsafe` then centres the badge on that height rather than hanging it from its top.\n */\n .v-timeline-marker {\n display: flex;\n align-items: unsafe center;\n justify-content: center;\n min-inline-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-marker {\n grid-column: marker;\n grid-row: 1;\n block-size: var(--timeline-line);\n }\n\n /* A border rather than a fill draws the dot and the line, which forced colours keep. */\n .v-timeline-dot {\n box-sizing: border-box;\n inline-size: var(--timeline-dot);\n block-size: var(--timeline-dot);\n border: calc(var(--timeline-dot) / 2) solid var(--timeline-dot-color);\n border-radius: var(--vectis-radius-full);\n }\n\n .v-timeline-icon {\n --vectis-icon-size: calc(var(--timeline-icon) / 2);\n\n display: grid;\n place-items: center;\n box-sizing: border-box;\n inline-size: var(--timeline-icon);\n block-size: var(--timeline-icon);\n border: 1px solid var(--tone-border-soft);\n border-radius: var(--vectis-radius-full);\n background: var(--tone-bg-soft);\n color: var(--tone-text-tinted);\n }\n\n .v-timeline-connector {\n border-color: var(--vectis-color-border);\n border-style: solid;\n border-width: 0;\n }\n\n .v-timeline-item:last-child > .v-timeline-connector {\n display: none;\n }\n\n /* From under the marker down to the next one, stopping a little short of both. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector {\n grid-column: marker;\n grid-row: 2 / -1;\n justify-self: center;\n margin-block: calc(var(--vectis-space-1) + var(--timeline-overflow)) var(--vectis-space-1);\n border-inline-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='vertical']:has(\n + :is([data-marker='icon'], [data-marker='custom'])\n )\n > .v-timeline-connector {\n /* Halved term by term: cssnano's calc parser rejects a bracketed group inside max(). */\n margin-block-end: calc(\n var(--vectis-space-1) + max(0px, var(--timeline-icon) / 2 - var(--timeline-line) / 2)\n );\n }\n\n .v-timeline-item[data-orientation='vertical']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: main;\n }\n\n /* The first text beside the marker is at least a title line high, its first line centred. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-time {\n display: block;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n font-variant-numeric: tabular-nums;\n }\n\n .v-timeline-title {\n margin: 0;\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n .v-timeline-content {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-timeline-item > .v-timeline-title + .v-timeline-content {\n margin-block-start: var(--vectis-space-1);\n }\n\n .v-timeline[data-size='sm'] > .v-timeline-list > .v-timeline-item > .v-timeline-content {\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-text-body-sm-weight);\n line-height: var(--vectis-text-body-sm-leading);\n }\n\n /* Across the page: the marker and the line in the first row, the texts under them. */\n .v-timeline-item[data-orientation='horizontal'] {\n grid-row: 1 / -1;\n grid-template-rows: subgrid;\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-marker {\n grid-column: 1;\n grid-row: 1;\n align-self: center;\n block-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector {\n grid-column: 2;\n grid-row: 1;\n align-self: center;\n margin-inline: var(--vectis-space-1);\n border-block-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-time {\n grid-row: 2;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-title {\n grid-row: 3;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-content {\n grid-row: 4;\n }\n\n .v-timeline-item[data-orientation='horizontal']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: 1 / -1;\n padding-inline-end: var(--timeline-gap);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector + * {\n margin-block-start: var(--timeline-gutter);\n }\n\n /*\n * Across the line, the date sits in its own column and the title beside the marker takes the\n * row height too. The thresholds repeat those of VTimeline.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline-item[data-layout='split'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='split'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n }\n\n /* Every other event swaps sides: its date goes after the line, its texts before it. */\n @container v-timeline (width > 36rem) {\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even) > .v-timeline-time {\n grid-column: main;\n text-align: start;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even)\n > :is(.v-timeline-title, .v-timeline-content) {\n grid-column: time;\n text-align: end;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCA,IAAM,IAAQ,GAiBR,IAAW,EAAO,GAAa,KAAA,CAAS,GACxC,IAAS,QAAwB,GAAU,MAAM,GAEjD,IAAW,QAAgB,GAAU,eAAe,IAAI,EAAS,iBAAiB,GAAI,GAEtF,IAAc,QACd,EAAM,WAAiB,EAAM,WAC5B,EAAM,WACJ,EAAmB,EAAM,UAAU,EAAO,OAAO,GAAU,aAAa,IADnD,EAE7B;yBAIC,EA4BK,MAAA;GA3BH,OAAM;GACL,aAAW,EAAA;GACX,eAAaA,EAAAA,OAAO,SAAM,WAAc,EAAA,OAAI,SAAA;GAC5C,oBAAkB,EAAA,CAAA,CAAQ,EAAE,eAAW;GACvC,eAAa,EAAA,CAAA,CAAQ,EAAE,UAAM;;GAE9B,EAKO,QALP,GAKO,CAJL,EAGO,EAAA,QAAA,UAAA,CAAA,SAAA,CAFO,EAAA,QAAA,EAAA,GAAZ,EAAmF,QAAnF,GAAmF,CAAzC,EAAkC,GAAA,EAAA,EAAnB,EAAA,CAAA,CAAS,CAAC,EAAA,IAAI,CAAA,CAAA,GAAA,MAAA,EAAA,CAAA,CAAA,MAAA,EAAA,GACvE,EAAsC,QAAtC,CAAsC,EAAA,CAAA,CAAA,CAAA;YAG1C,EAAwD,QAAA;IAAlD,OAAM;IAAuB,eAAY;;GAGvC,EAAA,SAAA,EAAA,GAFR,EAOY,EANL,EAAA,WAAQ,SAAA,MAAA,GAAA;;IAEb,OAAM;IACL,UAAU,EAAA;;qBAEM,CAAA,EAAA,EAAd,EAAA,KAAW,GAAA,CAAA,CAAA,CAAA;;;GAEgBA,EAAAA,OAAO,SAAS,EAAA,SAAA,EAAA,GAAhD,EAEY,EAFI,EAAA,KAAQ,GAAA;;IAA+B,OAAM;;qBACtB,CAArC,EAAqC,EAAA,QAAA,SAAA,CAAA,SAAA,CAAA,EAAA,EAAf,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;GAElBA,EAAAA,OAAO,WAAA,EAAA,GAAlB,EAEM,OAFN,GAEM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"VTimelineItem.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_unref","_createElementVNode","_renderSlot","_createVNode","VIcon","_normalizeProps","_guardReactiveProps","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","VIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","VTimelineItem_vue_vue_type_script_setup_true_lang_default","props","__props","timeline","inject","timelineKey","locale","useResolvedLocale","titleTag","computed","displayTime","formatTimelineDate","openBlock","createElementBlock","_ctx","unref","createElementVNode","renderSlot","createVNode","normalizeProps","guardReactiveProps","iconProps","_cache","createBlock","resolveDynamicComponent","withCtx","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/VTimeline/VTimelineItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * One event of a VTimeline: a marker on the line, a date, a title and content. The marker is\n * decoration, hidden from assistive technology: what the tone means must also be said in words.\n */\nimport { computed, inject } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport type { IconSource } from '../VIcon/types'\nimport { useResolvedLocale } from '../../i18n/state'\nimport { timelineKey } from './context'\nimport { formatTimelineDate } from './datetime'\n\n/** The colour of the marker. */\nexport type TimelineItemTone = 'neutral' | 'accent' | 'danger' | 'success' | 'warning'\n\ninterface TimelineItemProps {\n /**\n * When the event happened, as an ISO string: a year (`2019`), a month (`2026-10`), a day\n * (`2026-10-06`) or a moment (`2026-10-06T14:30`). It is written out in the locale, at that\n * precision, inside a `<time datetime>`.\n */\n datetime?: string\n /**\n * Visible text replacing the written-out date, such as \"2 hours ago\". The `<time>` keeps\n * `datetime` for machines.\n */\n timeText?: string\n /** What happened, in a few words. The `#title` slot replaces it. */\n title?: string\n /** The colour of the marker. */\n tone?: TimelineItemTone\n /**\n * An icon in a round badge on the line, in place of the dot: an icon name, or an explicit\n * render (the VIcon contract). The `#marker` slot replaces it.\n */\n icon?: IconSource\n}\n\nconst props = withDefaults(defineProps<TimelineItemProps>(), {\n datetime: undefined,\n timeText: undefined,\n title: undefined,\n tone: 'accent',\n icon: undefined,\n})\n\ndefineSlots<{\n /** The details of the event: text, links, buttons. */\n default?(): unknown\n /** Replaces the `title` prop with content of your own. */\n title?(): unknown\n /** Replaces the dot or the icon badge on the line, an avatar for instance. It is decoration. */\n marker?(): unknown\n}>()\n\nconst timeline = inject(timelineKey, undefined)\nconst locale = useResolvedLocale(() => timeline?.locale)\n\nconst titleTag = computed(() => (timeline?.headingLevel ? `h${timeline.headingLevel}` : 'p'))\n\nconst displayTime = computed(() => {\n if (props.timeText) return props.timeText\n if (!props.datetime) return ''\n return formatTimelineDate(props.datetime, locale.value, timeline?.formatOptions)\n})\n</script>\n\n<template>\n <li\n class=\"v-timeline-item v-tone\"\n :data-tone=\"tone\"\n :data-marker=\"$slots.marker ? 'custom' : icon ? 'icon' : 'dot'\"\n :data-orientation=\"timeline?.orientation ?? 'vertical'\"\n :data-layout=\"timeline?.layout ?? 'stacked'\"\n >\n <span class=\"v-timeline-marker\" aria-hidden=\"true\">\n <slot name=\"marker\">\n <span v-if=\"icon\" class=\"v-timeline-icon\"><VIcon v-bind=\"iconProps(icon)\" /></span>\n <span v-else class=\"v-timeline-dot\" />\n </slot>\n </span>\n <span class=\"v-timeline-connector\" aria-hidden=\"true\" />\n <component\n :is=\"datetime ? 'time' : 'span'\"\n v-if=\"displayTime\"\n class=\"v-timeline-time\"\n :datetime=\"datetime\"\n >\n {{ displayTime }}\n </component>\n <component :is=\"titleTag\" v-if=\"$slots.title || title\" class=\"v-timeline-title\">\n <slot name=\"title\">{{ title }}</slot>\n </component>\n <div v-if=\"$slots.default\" class=\"v-timeline-content\">\n <slot />\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The parts are placed on the grid of the list: the marker in the first row, the line under it\n * down to the end of the event, the texts beside it one row after another, and a last row for\n * the space before the next event, which the line runs through.\n */\n .v-timeline-item {\n --timeline-marker: var(--timeline-dot);\n /*\n * The first row is as tall as a title line, and the marker is centred on it. A badge taller\n * than the line reaches above and below it by `--timeline-overflow`, which the line and the\n * outer events make room for, so that the texts keep the same spacing beside a dot or a badge.\n */\n --timeline-line: calc(var(--vectis-text-label-size) * var(--vectis-text-label-leading));\n --timeline-overflow: max(0px, (var(--timeline-marker) - var(--timeline-line)) / 2);\n --timeline-dot-color: var(--tone-bg-solid);\n\n display: grid;\n min-inline-size: 0;\n }\n\n .v-timeline-item:last-child {\n --timeline-gap: 0px;\n }\n\n .v-timeline-item[data-orientation='vertical']:first-child {\n margin-block-start: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-orientation='vertical']:last-child {\n --timeline-gap: var(--timeline-overflow);\n }\n\n .v-timeline-item[data-marker='icon'],\n .v-timeline-item[data-marker='custom'] {\n --timeline-marker: var(--timeline-icon);\n }\n\n .v-timeline-item[data-tone='neutral'] {\n --timeline-dot-color: var(--vectis-color-text-muted);\n }\n\n .v-timeline-item[data-orientation='vertical'] {\n grid-column: 1 / -1;\n grid-template-columns: subgrid;\n grid-template-rows: auto auto auto var(--timeline-gap);\n }\n\n /*\n * A flex line keeps the height of the marker, where a grid track would grow to fit a taller\n * badge; `unsafe` then centres the badge on that height rather than hanging it from its top.\n */\n .v-timeline-marker {\n display: flex;\n align-items: unsafe center;\n justify-content: center;\n min-inline-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-marker {\n grid-column: marker;\n grid-row: 1;\n block-size: var(--timeline-line);\n }\n\n /* A border rather than a fill draws the dot and the line, which forced colours keep. */\n .v-timeline-dot {\n box-sizing: border-box;\n inline-size: var(--timeline-dot);\n block-size: var(--timeline-dot);\n border: calc(var(--timeline-dot) / 2) solid var(--timeline-dot-color);\n border-radius: var(--vectis-radius-full);\n }\n\n .v-timeline-icon {\n --vectis-icon-size: calc(var(--timeline-icon) / 2);\n\n display: grid;\n place-items: center;\n box-sizing: border-box;\n inline-size: var(--timeline-icon);\n block-size: var(--timeline-icon);\n border: 1px solid var(--tone-border-soft);\n border-radius: var(--vectis-radius-full);\n background: var(--tone-bg-soft);\n color: var(--tone-text-tinted);\n }\n\n .v-timeline-connector {\n border-color: var(--vectis-color-border);\n border-style: solid;\n border-width: 0;\n }\n\n .v-timeline-item:last-child > .v-timeline-connector {\n display: none;\n }\n\n /* From under the marker down to the next one, stopping a little short of both. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector {\n grid-column: marker;\n grid-row: 2 / -1;\n justify-self: center;\n margin-block: calc(var(--vectis-space-1) + var(--timeline-overflow)) var(--vectis-space-1);\n border-inline-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='vertical']:has(\n + :is([data-marker='icon'], [data-marker='custom'])\n )\n > .v-timeline-connector {\n /* Halved term by term: cssnano's calc parser rejects a bracketed group inside max(). */\n margin-block-end: calc(\n var(--vectis-space-1) + max(0px, var(--timeline-icon) / 2 - var(--timeline-line) / 2)\n );\n }\n\n .v-timeline-item[data-orientation='vertical']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: main;\n }\n\n /* The first text beside the marker is at least a title line high, its first line centred. */\n .v-timeline-item[data-orientation='vertical'] > .v-timeline-connector + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-time {\n display: block;\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-text-caption-weight);\n line-height: var(--vectis-text-caption-leading);\n font-variant-numeric: tabular-nums;\n }\n\n .v-timeline-title {\n margin: 0;\n color: var(--vectis-color-text);\n font-size: var(--vectis-text-label-size);\n font-weight: var(--vectis-text-label-weight);\n line-height: var(--vectis-text-label-leading);\n }\n\n .v-timeline-content {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-body-md-size);\n font-weight: var(--vectis-text-body-md-weight);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-timeline-item > .v-timeline-title + .v-timeline-content {\n margin-block-start: var(--vectis-space-1);\n }\n\n .v-timeline[data-size='sm'] > .v-timeline-list > .v-timeline-item > .v-timeline-content {\n font-size: var(--vectis-text-body-sm-size);\n font-weight: var(--vectis-text-body-sm-weight);\n line-height: var(--vectis-text-body-sm-leading);\n }\n\n /* Across the page: the marker and the line in the first row, the texts under them. */\n .v-timeline-item[data-orientation='horizontal'] {\n grid-row: 1 / -1;\n grid-template-rows: subgrid;\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-marker {\n grid-column: 1;\n grid-row: 1;\n align-self: center;\n block-size: var(--timeline-marker);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector {\n grid-column: 2;\n grid-row: 1;\n align-self: center;\n margin-inline: var(--vectis-space-1);\n border-block-start-width: 1px;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-time {\n grid-row: 2;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-title {\n grid-row: 3;\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-content {\n grid-row: 4;\n }\n\n .v-timeline-item[data-orientation='horizontal']\n > :is(.v-timeline-time, .v-timeline-title, .v-timeline-content) {\n grid-column: 1 / -1;\n padding-inline-end: var(--timeline-gap);\n }\n\n .v-timeline-item[data-orientation='horizontal'] > .v-timeline-connector + * {\n margin-block-start: var(--timeline-gutter);\n }\n\n /*\n * Across the line, the date sits in its own column and the title beside the marker takes the\n * row height too. The thresholds repeat those of VTimeline.\n */\n @container v-timeline (width > 30rem) {\n .v-timeline-item[data-layout='split'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='split'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n }\n\n /* Every other event swaps sides: its date goes after the line, its texts before it. */\n @container v-timeline (width > 36rem) {\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time {\n grid-column: time;\n grid-row: 1;\n text-align: end;\n }\n\n .v-timeline-item[data-layout='alternate'] > .v-timeline-time + * {\n min-block-size: var(--timeline-line);\n align-content: center;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even) > .v-timeline-time {\n grid-column: main;\n text-align: start;\n }\n\n .v-timeline-item[data-layout='alternate']:nth-child(even)\n > :is(.v-timeline-title, .v-timeline-content) {\n grid-column: time;\n text-align: end;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCA,IAAMuB,IAAQC,GAiBRC,IAAWC,EAAOC,GAAa,KAAA,CAAS,GACxCC,IAASC,QAAwBJ,GAAU,MAAM,GAEjDK,IAAWC,QAAgBN,GAAU,eAAe,IAAIA,EAAS,iBAAiB,GAAI,GAEtFO,IAAcD,QACdR,EAAM,WAAiBA,EAAM,WAC5BA,EAAM,WACJU,EAAmBV,EAAM,UAAUK,EAAO,OAAOH,GAAU,aAAa,IADnD,EAE7B;oBAICxB,EAAA,GAAAC,EA4BK,MAAA;GA3BH,OAAM;GACL,aAAWsB,EAAA;GACX,eAAaxB,EAAAA,OAAO,SAAM,WAAcwB,EAAA,OAAI,SAAA;GAC5C,oBAAkBrB,EAAAsB,CAAA,CAAQ,EAAE,eAAW;GACvC,eAAatB,EAAAsB,CAAA,CAAQ,EAAE,UAAM;;GAE9BrB,EAKO,QALPc,GAKO,CAJLb,EAGO+B,EAAA,QAAA,UAAA,CAAA,SAAA,CAFOZ,EAAA,QAAZvB,EAAA,GAAAC,EAAmF,QAAnFiB,GAAmF,CAAzCb,EAAkCC,GAAAC,EAAAC,EAAnBN,EAAAwC,CAAA,CAAS,CAACnB,EAAA,IAAI,CAAA,CAAA,GAAA,MAAA,EAAA,CAAA,CAAA,MACvEvB,EAAA,GAAAC,EAAsC,QAAtCkB,CAAsC,EAAA,CAAA,CAAA,CAAA;GAG1C,AAAAwB,EAAA,OAAAxC,EAAwD,QAAA;IAAlD,OAAM;IAAuB,eAAY;;GAGvC4B,EAAA,SAFR/B,EAAA,GAAAS,EAOYC,EANLa,EAAA,WAAQ,SAAA,MAAA,GAAA;;IAEb,OAAM;IACL,UAAUA,EAAA;;IAEX,SAAAZ,QAAiB,CAAdC,EAAAC,EAAAkB,EAAA,KAAW,GAAA,CAAA,CAAA,CAAA;;;GAEgBhC,EAAAA,OAAO,SAASwB,EAAA,SAAhDvB,EAAA,GAAAS,EAEYC,EAFImB,EAAA,KAAQ,GAAA;;IAA+B,OAAM;;IAC3D,SAAAlB,QAAqC,CAArCP,EAAqC+B,EAAA,QAAA,SAAA,CAAA,SAAA,CAAfvB,EAAAC,EAAAU,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;GAElBxB,EAAAA,OAAO,WAAlBC,EAAA,GAAAC,EAEM,OAFNmB,GAEM,CADJhB,EAAQ+B,EAAA,QAAA,SAAA,CAAA,CAAA,KAAAc,EAAA,IAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/components/VTimeline/context.ts"],"sourcesContent":["/**\n * What a VTimeline shares with its events: how they are laid out, which an event marks on itself\n * so that a timeline nested in its content keeps its own layout, and how titles and dates are\n * written.\n */\n\nimport type { InjectionKey } from 'vue'\n\n/** The heading level the titles of the events are rendered at. */\nexport type TimelineHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6\n\nexport interface TimelineContext {\n orientation: 'vertical' | 'horizontal'\n layout: 'stacked' | 'split' | 'alternate'\n headingLevel: TimelineHeadingLevel | undefined\n locale: string | undefined\n formatOptions: Intl.DateTimeFormatOptions | undefined\n}\n\nexport const timelineKey: InjectionKey<TimelineContext> = Symbol('v-timeline')\n"],"mappings":";AAmBA,IAAa,IAA6C,OAAO,YAAY"}
1
+ {"version":3,"file":"context.js","names":["timelineKey"],"sources":["../../../src/components/VTimeline/context.ts"],"sourcesContent":["/**\n * What a VTimeline shares with its events: how they are laid out, which an event marks on itself\n * so that a timeline nested in its content keeps its own layout, and how titles and dates are\n * written.\n */\n\nimport type { InjectionKey } from 'vue'\n\n/** The heading level the titles of the events are rendered at. */\nexport type TimelineHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6\n\nexport interface TimelineContext {\n orientation: 'vertical' | 'horizontal'\n layout: 'stacked' | 'split' | 'alternate'\n headingLevel: TimelineHeadingLevel | undefined\n locale: string | undefined\n formatOptions: Intl.DateTimeFormatOptions | undefined\n}\n\nexport const timelineKey: InjectionKey<TimelineContext> = Symbol('v-timeline')\n"],"mappings":";AAmBA,IAAaA,IAA6C,OAAO,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"datetime.js","names":[],"sources":["../../../src/components/VTimeline/datetime.ts"],"sourcesContent":["// @ssr\n/** Writes out the moment of a timeline event at the precision its ISO string gives. */\n\nimport { parseISO } from '../../utils/date'\nimport { memo } from '../../utils/memo'\n\nconst YEAR_RE = /^(\\d{4})$/\nconst MONTH_RE = /^(\\d{4})-(\\d{2})$/\nconst DAY_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\nconst YEAR_FORMAT: Intl.DateTimeFormatOptions = { year: 'numeric' }\nconst MONTH_FORMAT: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' }\nconst DAY_FORMAT: Intl.DateTimeFormatOptions = { dateStyle: 'medium' }\nconst DATETIME_FORMAT: Intl.DateTimeFormatOptions = { dateStyle: 'medium', timeStyle: 'short' }\n\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/** A year or a month read at local time, like a calendar date. */\nfunction localMonth(year: number, month0: number): Date {\n const date = new Date(2000, month0, 1)\n date.setFullYear(year, month0, 1)\n return date\n}\n\n/**\n * The text shown for `datetime`. A year (`2019`) is written as a year and a month (`2026-10`) as\n * a month; `options` replaces the format of a day (`2026-10-06`) or of a moment\n * (`2026-10-06T14:30`), which are `dateStyle: 'medium'`, plus `timeStyle: 'short'` for a moment.\n * A value the browser cannot read is shown as it is.\n */\nexport function formatTimelineDate(\n datetime: string,\n locale: string,\n options?: Intl.DateTimeFormatOptions,\n): string {\n const year = YEAR_RE.exec(datetime)\n if (year) return formatterFor(locale, YEAR_FORMAT).format(localMonth(Number(year[1]), 0))\n\n const month = MONTH_RE.exec(datetime)\n if (month) {\n const month0 = Number(month[2]) - 1\n if (month0 < 0 || month0 > 11) return datetime\n return formatterFor(locale, MONTH_FORMAT).format(localMonth(Number(month[1]), month0))\n }\n\n if (DAY_RE.test(datetime)) {\n const day = parseISO(datetime)\n return day ? formatterFor(locale, options ?? DAY_FORMAT).format(day) : datetime\n }\n\n // A moment without an offset is read at local time, one with an offset (`Z`, `+02:00`) as the\n // instant it names, shown in the time zone the code runs in unless `options` sets one.\n const moment = new Date(datetime)\n if (Number.isNaN(moment.getTime())) return datetime\n return formatterFor(locale, options ?? DATETIME_FORMAT).format(moment)\n}\n"],"mappings":";;;AAMA,IAAM,IAAU,aACV,IAAW,qBACX,IAAS,uBAET,IAA0C,EAAE,MAAM,UAAU,GAC5D,IAA2C;CAAE,MAAM;CAAW,OAAO;AAAO,GAC5E,IAAyC,EAAE,WAAW,SAAS,GAC/D,IAA8C;CAAE,WAAW;CAAU,WAAW;AAAQ,GAExF,oBAAa,IAAI,IAAiC;AAExD,SAAS,EAAa,GAAgB,GAA0D;CAC9F,OAAO,EACL,GACA,GAAG,EAAO,GAAG,KAAK,UAAU,CAAO,WAC7B,IAAI,KAAK,eAAe,GAAQ,CAAO,CAC/C;AACF;AAGA,SAAS,EAAW,GAAc,GAAsB;CACtD,IAAM,IAAO,IAAI,KAAK,KAAM,GAAQ,CAAC;CAErC,OADA,EAAK,YAAY,GAAM,GAAQ,CAAC,GACzB;AACT;AAQA,SAAgB,EACd,GACA,GACA,GACQ;CACR,IAAM,IAAO,EAAQ,KAAK,CAAQ;CAClC,IAAI,GAAM,OAAO,EAAa,GAAQ,CAAW,CAAC,CAAC,OAAO,EAAW,OAAO,EAAK,EAAE,GAAG,CAAC,CAAC;CAExF,IAAM,IAAQ,EAAS,KAAK,CAAQ;CACpC,IAAI,GAAO;EACT,IAAM,IAAS,OAAO,EAAM,EAAE,IAAI;EAElC,OADI,IAAS,KAAK,IAAS,KAAW,IAC/B,EAAa,GAAQ,CAAY,CAAC,CAAC,OAAO,EAAW,OAAO,EAAM,EAAE,GAAG,CAAM,CAAC;CACvF;CAEA,IAAI,EAAO,KAAK,CAAQ,GAAG;EACzB,IAAM,IAAM,EAAS,CAAQ;EAC7B,OAAO,IAAM,EAAa,GAAQ,KAAW,CAAU,CAAC,CAAC,OAAO,CAAG,IAAI;CACzE;CAIA,IAAM,IAAS,IAAI,KAAK,CAAQ;CAEhC,OADI,OAAO,MAAM,EAAO,QAAQ,CAAC,IAAU,IACpC,EAAa,GAAQ,KAAW,CAAe,CAAC,CAAC,OAAO,CAAM;AACvE"}
1
+ {"version":3,"file":"datetime.js","names":["YEAR_RE","MONTH_RE","DAY_RE","YEAR_FORMAT","MONTH_FORMAT","DAY_FORMAT","DATETIME_FORMAT","formatters","formatterFor","memo","locale","options","localMonth","date","month0","year","formatTimelineDate","datetime","month","day","parseISO","moment"],"sources":["../../../src/components/VTimeline/datetime.ts"],"sourcesContent":["// @ssr\n/** Writes out the moment of a timeline event at the precision its ISO string gives. */\n\nimport { parseISO } from '../../utils/date'\nimport { memo } from '../../utils/memo'\n\nconst YEAR_RE = /^(\\d{4})$/\nconst MONTH_RE = /^(\\d{4})-(\\d{2})$/\nconst DAY_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\nconst YEAR_FORMAT: Intl.DateTimeFormatOptions = { year: 'numeric' }\nconst MONTH_FORMAT: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' }\nconst DAY_FORMAT: Intl.DateTimeFormatOptions = { dateStyle: 'medium' }\nconst DATETIME_FORMAT: Intl.DateTimeFormatOptions = { dateStyle: 'medium', timeStyle: 'short' }\n\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/** A year or a month read at local time, like a calendar date. */\nfunction localMonth(year: number, month0: number): Date {\n const date = new Date(2000, month0, 1)\n date.setFullYear(year, month0, 1)\n return date\n}\n\n/**\n * The text shown for `datetime`. A year (`2019`) is written as a year and a month (`2026-10`) as\n * a month; `options` replaces the format of a day (`2026-10-06`) or of a moment\n * (`2026-10-06T14:30`), which are `dateStyle: 'medium'`, plus `timeStyle: 'short'` for a moment.\n * A value the browser cannot read is shown as it is.\n */\nexport function formatTimelineDate(\n datetime: string,\n locale: string,\n options?: Intl.DateTimeFormatOptions,\n): string {\n const year = YEAR_RE.exec(datetime)\n if (year) return formatterFor(locale, YEAR_FORMAT).format(localMonth(Number(year[1]), 0))\n\n const month = MONTH_RE.exec(datetime)\n if (month) {\n const month0 = Number(month[2]) - 1\n if (month0 < 0 || month0 > 11) return datetime\n return formatterFor(locale, MONTH_FORMAT).format(localMonth(Number(month[1]), month0))\n }\n\n if (DAY_RE.test(datetime)) {\n const day = parseISO(datetime)\n return day ? formatterFor(locale, options ?? DAY_FORMAT).format(day) : datetime\n }\n\n // A moment without an offset is read at local time, one with an offset (`Z`, `+02:00`) as the\n // instant it names, shown in the time zone the code runs in unless `options` sets one.\n const moment = new Date(datetime)\n if (Number.isNaN(moment.getTime())) return datetime\n return formatterFor(locale, options ?? DATETIME_FORMAT).format(moment)\n}\n"],"mappings":";;;AAMA,IAAMA,IAAU,aACVC,IAAW,qBACXC,IAAS,uBAETC,IAA0C,EAAE,MAAM,UAAU,GAC5DC,IAA2C;CAAE,MAAM;CAAW,OAAO;AAAO,GAC5EC,IAAyC,EAAE,WAAW,SAAS,GAC/DC,IAA8C;CAAE,WAAW;CAAU,WAAW;AAAQ,GAExFC,oBAAa,IAAI,IAAiC;AAExD,SAASC,EAAa,GAAgB,GAA0D;CAC9F,OAAOC,EACLF,GACA,GAAGG,EAAO,GAAG,KAAK,UAAUC,CAAO,WAC7B,IAAI,KAAK,eAAeD,GAAQC,CAAO,CAC/C;AACF;AAGA,SAASC,EAAW,GAAc,GAAsB;CACtD,IAAMC,IAAO,IAAI,KAAK,KAAMC,GAAQ,CAAC;CAErC,OADAD,EAAK,YAAYE,GAAMD,GAAQ,CAAC,GACzBD;AACT;AAQA,SAAgBG,EACd,GACA,GACA,GACQ;CACR,IAAMD,IAAOf,EAAQ,KAAKiB,CAAQ;CAClC,IAAIF,GAAM,OAAOP,EAAaE,GAAQP,CAAW,CAAC,CAAC,OAAOS,EAAW,OAAOG,EAAK,EAAE,GAAG,CAAC,CAAC;CAExF,IAAMG,IAAQjB,EAAS,KAAKgB,CAAQ;CACpC,IAAIC,GAAO;EACT,IAAMJ,IAAS,OAAOI,EAAM,EAAE,IAAI;EAElC,OADIJ,IAAS,KAAKA,IAAS,KAAWG,IAC/BT,EAAaE,GAAQN,CAAY,CAAC,CAAC,OAAOQ,EAAW,OAAOM,EAAM,EAAE,GAAGJ,CAAM,CAAC;CACvF;CAEA,IAAIZ,EAAO,KAAKe,CAAQ,GAAG;EACzB,IAAME,IAAMC,EAASH,CAAQ;EAC7B,OAAOE,IAAMX,EAAaE,GAAQC,KAAWN,CAAU,CAAC,CAAC,OAAOc,CAAG,IAAIF;CACzE;CAIA,IAAMI,IAAS,IAAI,KAAKJ,CAAQ;CAEhC,OADI,OAAO,MAAMI,EAAO,QAAQ,CAAC,IAAUJ,IACpCT,EAAaE,GAAQC,KAAWL,CAAe,CAAC,CAAC,OAAOe,CAAM;AACvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"VToast.js","names":[],"sources":["../../../src/components/VToast/VToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * Presentation-only notification card; VToaster owns queue state and polite/assertive\n * announcements to avoid duplicate status messages.\n */\n\nimport { computed } from 'vue'\n\nimport { cssSize } from '../../utils/css'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { check_circle as checkCircleIcon } from '../VIcon/icons/check_circle'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport { error as errorIcon } from '../VIcon/icons/error'\nimport { info as infoIcon } from '../VIcon/icons/info'\nimport { notifications as notificationsIcon } from '../VIcon/icons/notifications'\nimport { warning as warningIcon } from '../VIcon/icons/warning'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport type { ToastItem, ToastTone } from './state'\n\nconst props = defineProps<{\n /** The notification to draw, with all its options already resolved. */\n item: ToastItem\n /** What the close cross does, in words. */\n closeLabel: string\n}>()\n\nconst emit = defineEmits<{\n /**\n * The reader asked for this notification to go. The card removes nothing itself;\n * the queue belongs to the VToaster.\n */\n close: [id: number]\n}>()\n\nconst DEFAULT_ICONS: Record<ToastTone, IconSource> = {\n neutral: notificationsIcon,\n accent: infoIcon,\n success: checkCircleIcon,\n danger: errorIcon,\n warning: warningIcon,\n}\n\n/**\n * The icon to draw: the one the notification asked for, or failing that the one its\n * tone brings. Asking for `false` means no icon at all.\n */\nconst icon = computed(() =>\n props.item.icon === false\n ? undefined\n : iconProps(props.item.icon ?? DEFAULT_ICONS[props.item.tone]),\n)\n</script>\n\n<template>\n <div\n class=\"v-banner v-toast v-tone\"\n :data-tone=\"item.tone\"\n :data-variant=\"item.variant\"\n :style=\"item.width !== undefined ? { '--toast-width': cssSize(item.width) } : undefined\"\n >\n <VIcon v-if=\"icon\" class=\"v-toast-icon\" v-bind=\"icon\" />\n <div class=\"v-banner-text v-toast-body\">\n <p v-if=\"item.title\" class=\"v-toast-title\">{{ item.title }}</p>\n <p class=\"v-toast-message\">{{ item.message }}</p>\n </div>\n <VIconButton\n v-if=\"!item.hideClose\"\n class=\"v-banner-control v-toast-close\"\n :label=\"closeLabel\"\n size=\"sm\"\n @click=\"emit('close', item.id)\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * Shared banner chrome supplies decoration and motion; toast owns alignment, dimensions and\n * tone painting.\n */\n .v-toast {\n /*\n * The `--banner-line` margins are what make that identical to centring on a single line.\n * (VSnackbar centres instead; one short sentence, and a control that would sit in a corner\n * otherwise.)\n */\n align-items: flex-start;\n padding: var(--vectis-space-3) var(--vectis-space-4);\n inline-size: var(--toast-width, var(--vectis-control-size-toast-width));\n /* On a narrow screen the card is never wider than the viewport, the stack's own\n margins deducted. */\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n }\n\n /*\n * The tone table itself lives in styles/tones.css, in a layer below the components, and is\n * shared with VButton and VChip. The rules below read that shared contract directly rather\n * than restating any of its colours.\n */\n .v-toast {\n --toast-accent: var(--tone-text-tinted);\n }\n\n /*\n * The neutral tone is overridden here, and for the soft variant only. A notification floats\n * above the page rather than sitting in it, so it takes the overlay background and the plain\n * border that goes with it, where the shared table assumes a surface within the page.\n */\n .v-toast[data-tone='neutral'] {\n --tone-bg-soft: var(--vectis-color-surface-overlay);\n --tone-border-soft: var(--vectis-color-border);\n --toast-accent: var(--vectis-color-text);\n }\n\n .v-toast[data-variant='soft'] {\n background: var(--tone-bg-soft);\n border: 1px solid var(--tone-border-soft);\n color: var(--vectis-color-text);\n }\n\n .v-toast[data-variant='soft'] .v-toast-icon,\n .v-toast[data-variant='soft'] .v-toast-title {\n color: var(--toast-accent);\n }\n\n .v-toast[data-variant='soft'] .v-toast-message {\n color: var(--vectis-color-text-muted);\n }\n\n .v-toast[data-variant='solid'] {\n background: var(--tone-bg-solid);\n color: var(--tone-text-solid);\n }\n\n /*\n * (0,4,0) is load-bearing: the shared rebind is (0,3,0) in the same layer and ships in\n * another sheet, so at equal specificity the winner would be whichever sheet the consumer's\n * bundler put last.\n */\n .v-toast[data-variant='soft'] .v-toast-close[data-tone] {\n --tone-text-tinted: var(--toast-accent);\n --tone-bg-soft: color-mix(in oklab, var(--toast-accent), transparent 88%);\n }\n\n .v-toast-icon {\n --vectis-icon-size: var(--vectis-icon-size-md);\n margin-block: calc((var(--banner-line) - var(--vectis-icon-size-md)) / 2);\n }\n\n .v-toast-title {\n margin-block-end: var(--vectis-space-1);\n /*\n * The heavier weight marks the title against its own message, which is emphasis rather than\n * a typographic role; hence a font token read directly.\n */\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /* An outline draws one without moving the layout. */\n @media (forced-colors: active) {\n .v-toast[data-variant='solid'] {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VToast.js","names":["_sfc_main","VToast_vue_vue_type_script_setup_true_lang_default","VToast_default"],"sources":["../../../src/components/VToast/VToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y\n/**\n * Presentation-only notification card; VToaster owns queue state and polite/assertive\n * announcements to avoid duplicate status messages.\n */\n\nimport { computed } from 'vue'\n\nimport { cssSize } from '../../utils/css'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { check_circle as checkCircleIcon } from '../VIcon/icons/check_circle'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport { error as errorIcon } from '../VIcon/icons/error'\nimport { info as infoIcon } from '../VIcon/icons/info'\nimport { notifications as notificationsIcon } from '../VIcon/icons/notifications'\nimport { warning as warningIcon } from '../VIcon/icons/warning'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport type { ToastItem, ToastTone } from './state'\n\nconst props = defineProps<{\n /** The notification to draw, with all its options already resolved. */\n item: ToastItem\n /** What the close cross does, in words. */\n closeLabel: string\n}>()\n\nconst emit = defineEmits<{\n /**\n * The reader asked for this notification to go. The card removes nothing itself;\n * the queue belongs to the VToaster.\n */\n close: [id: number]\n}>()\n\nconst DEFAULT_ICONS: Record<ToastTone, IconSource> = {\n neutral: notificationsIcon,\n accent: infoIcon,\n success: checkCircleIcon,\n danger: errorIcon,\n warning: warningIcon,\n}\n\n/**\n * The icon to draw: the one the notification asked for, or failing that the one its\n * tone brings. Asking for `false` means no icon at all.\n */\nconst icon = computed(() =>\n props.item.icon === false\n ? undefined\n : iconProps(props.item.icon ?? DEFAULT_ICONS[props.item.tone]),\n)\n</script>\n\n<template>\n <div\n class=\"v-banner v-toast v-tone\"\n :data-tone=\"item.tone\"\n :data-variant=\"item.variant\"\n :style=\"item.width !== undefined ? { '--toast-width': cssSize(item.width) } : undefined\"\n >\n <VIcon v-if=\"icon\" class=\"v-toast-icon\" v-bind=\"icon\" />\n <div class=\"v-banner-text v-toast-body\">\n <p v-if=\"item.title\" class=\"v-toast-title\">{{ item.title }}</p>\n <p class=\"v-toast-message\">{{ item.message }}</p>\n </div>\n <VIconButton\n v-if=\"!item.hideClose\"\n class=\"v-banner-control v-toast-close\"\n :label=\"closeLabel\"\n size=\"sm\"\n @click=\"emit('close', item.id)\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * Shared banner chrome supplies decoration and motion; toast owns alignment, dimensions and\n * tone painting.\n */\n .v-toast {\n /*\n * The `--banner-line` margins are what make that identical to centring on a single line.\n * (VSnackbar centres instead; one short sentence, and a control that would sit in a corner\n * otherwise.)\n */\n align-items: flex-start;\n padding: var(--vectis-space-3) var(--vectis-space-4);\n inline-size: var(--toast-width, var(--vectis-control-size-toast-width));\n /* On a narrow screen the card is never wider than the viewport, the stack's own\n margins deducted. */\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n }\n\n /*\n * The tone table itself lives in styles/tones.css, in a layer below the components, and is\n * shared with VButton and VChip. The rules below read that shared contract directly rather\n * than restating any of its colours.\n */\n .v-toast {\n --toast-accent: var(--tone-text-tinted);\n }\n\n /*\n * The neutral tone is overridden here, and for the soft variant only. A notification floats\n * above the page rather than sitting in it, so it takes the overlay background and the plain\n * border that goes with it, where the shared table assumes a surface within the page.\n */\n .v-toast[data-tone='neutral'] {\n --tone-bg-soft: var(--vectis-color-surface-overlay);\n --tone-border-soft: var(--vectis-color-border);\n --toast-accent: var(--vectis-color-text);\n }\n\n .v-toast[data-variant='soft'] {\n background: var(--tone-bg-soft);\n border: 1px solid var(--tone-border-soft);\n color: var(--vectis-color-text);\n }\n\n .v-toast[data-variant='soft'] .v-toast-icon,\n .v-toast[data-variant='soft'] .v-toast-title {\n color: var(--toast-accent);\n }\n\n .v-toast[data-variant='soft'] .v-toast-message {\n color: var(--vectis-color-text-muted);\n }\n\n .v-toast[data-variant='solid'] {\n background: var(--tone-bg-solid);\n color: var(--tone-text-solid);\n }\n\n /*\n * (0,4,0) is load-bearing: the shared rebind is (0,3,0) in the same layer and ships in\n * another sheet, so at equal specificity the winner would be whichever sheet the consumer's\n * bundler put last.\n */\n .v-toast[data-variant='soft'] .v-toast-close[data-tone] {\n --tone-text-tinted: var(--toast-accent);\n --tone-bg-soft: color-mix(in oklab, var(--toast-accent), transparent 88%);\n }\n\n .v-toast-icon {\n --vectis-icon-size: var(--vectis-icon-size-md);\n margin-block: calc((var(--banner-line) - var(--vectis-icon-size-md)) / 2);\n }\n\n .v-toast-title {\n margin-block-end: var(--vectis-space-1);\n /*\n * The heavier weight marks the title against its own message, which is emphasis rather than\n * a typographic role; hence a font token read directly.\n */\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n /* An outline draws one without moving the layout. */\n @media (forced-colors: active) {\n .v-toast[data-variant='solid'] {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}