vectis-ui 0.10.1 → 0.10.2

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 (330) hide show
  1. package/dist/components/VAccordion/VAccordion.js.map +1 -1
  2. package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/VAccordion/VAccordionItem.d.ts +6 -21
  4. package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
  5. package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/VAccordion/context.js.map +1 -1
  7. package/dist/components/VAvatar/VAvatar.d.ts +2 -12
  8. package/dist/components/VAvatar/VAvatar.js.map +1 -1
  9. package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/VAvatar/VAvatarGroup.d.ts +2 -2
  11. package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
  12. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +6 -6
  13. package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/VAvatar/context.d.ts +1 -5
  15. package/dist/components/VAvatar/context.js.map +1 -1
  16. package/dist/components/VBadge/VBadge.d.ts +13 -27
  17. package/dist/components/VBadge/VBadge.js.map +1 -1
  18. package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +3 -9
  20. package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
  21. package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/VButton/VButton.d.ts +10 -17
  23. package/dist/components/VButton/VButton.js.map +1 -1
  24. package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/VButton/VButtonGroup.d.ts +6 -15
  26. package/dist/components/VButton/VButtonGroup.js.map +1 -1
  27. package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/VButton/context.d.ts +1 -9
  29. package/dist/components/VButton/context.js.map +1 -1
  30. package/dist/components/VCalendar/VCalendar.d.ts +9 -24
  31. package/dist/components/VCalendar/VCalendar.js.map +1 -1
  32. package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/VCalendar/VCalendarEvent.d.ts +4 -13
  34. package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
  35. package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
  37. package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +1 -5
  39. package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
  40. package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
  42. package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/components/VCalendar/color.d.ts +1 -7
  44. package/dist/components/VCalendar/color.js.map +1 -1
  45. package/dist/components/VCalendar/edgeStep.d.ts +5 -15
  46. package/dist/components/VCalendar/edgeStep.js.map +1 -1
  47. package/dist/components/VCalendar/gesture.d.ts +12 -36
  48. package/dist/components/VCalendar/gesture.js.map +1 -1
  49. package/dist/components/VCalendar/keyboard.d.ts +5 -42
  50. package/dist/components/VCalendar/keyboard.js.map +1 -1
  51. package/dist/components/VCalendar/layout.d.ts +38 -199
  52. package/dist/components/VCalendar/layout.js.map +1 -1
  53. package/dist/components/VCalendar/timeGrid.d.ts +3 -25
  54. package/dist/components/VCalendar/timeGrid.js.map +1 -1
  55. package/dist/components/VCalendar/types.d.ts +6 -23
  56. package/dist/components/VCarousel/VCarousel.d.ts +25 -96
  57. package/dist/components/VCarousel/VCarousel.js.map +1 -1
  58. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +6 -6
  59. package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  60. package/dist/components/VCarousel/VCarouselItem.d.ts +1 -6
  61. package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
  62. package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/VCarousel/context.js.map +1 -1
  64. package/dist/components/VCheckbox/VCheckbox.d.ts +1 -5
  65. package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
  66. package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  67. package/dist/components/VChip/VChip.d.ts +2 -8
  68. package/dist/components/VChip/VChip.js.map +1 -1
  69. package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/VCombobox/VCombobox.d.ts +21 -59
  71. package/dist/components/VCombobox/VCombobox.js.map +1 -1
  72. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +117 -119
  73. package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
  75. package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/VCombobox/VComboboxOption.js.map +1 -1
  77. package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -1
  79. package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/VCombobox/infiniteScroll.d.ts +4 -10
  81. package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
  82. package/dist/components/VDataTable/VDataTable.d.ts +11 -36
  83. package/dist/components/VDataTable/VDataTable.js.map +1 -1
  84. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +23 -20
  85. package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  86. package/dist/components/VDateInput/VDateInput.d.ts +12 -21
  87. package/dist/components/VDateInput/VDateInput.js.map +1 -1
  88. package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  89. package/dist/components/VDateInput/mask.d.ts +14 -59
  90. package/dist/components/VDateInput/mask.js.map +1 -1
  91. package/dist/components/VDatePicker/VDatePicker.d.ts +6 -12
  92. package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
  93. package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  94. package/dist/components/VDatePicker/keyboard.d.ts +10 -42
  95. package/dist/components/VDatePicker/keyboard.js.map +1 -1
  96. package/dist/components/VDatePicker/names.d.ts +8 -22
  97. package/dist/components/VDatePicker/names.js.map +1 -1
  98. package/dist/components/VDialog/VDialog.d.ts +5 -10
  99. package/dist/components/VDialog/VDialog.js.map +1 -1
  100. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +51 -53
  101. package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  102. package/dist/components/VDialog/VDialogAlert.d.ts +2 -3
  103. package/dist/components/VDialog/VDialogAlert.js.map +1 -1
  104. package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/VFileInput/VFileInput.d.ts +11 -37
  106. package/dist/components/VFileInput/VFileInput.js.map +1 -1
  107. package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/VFileInput/truncate.d.ts +3 -23
  109. package/dist/components/VFileInput/truncate.js.map +1 -1
  110. package/dist/components/VFilePicker/VFilePicker.d.ts +15 -65
  111. package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
  112. package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  113. package/dist/components/VFilePicker/fileKind.js.map +1 -1
  114. package/dist/components/VHotkeys/VHotkeys.d.ts +6 -15
  115. package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
  116. package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  117. package/dist/components/VHotkeys/platform.d.ts +10 -49
  118. package/dist/components/VHotkeys/platform.js.map +1 -1
  119. package/dist/components/VIcon/VIcon.d.ts +7 -19
  120. package/dist/components/VIcon/VIcon.js.map +1 -1
  121. package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/VIcon/iconProps.d.ts +5 -19
  123. package/dist/components/VIcon/iconProps.js.map +1 -1
  124. package/dist/components/VIcon/resolver.d.ts +15 -43
  125. package/dist/components/VIcon/resolver.js.map +1 -1
  126. package/dist/components/VIcon/types.d.ts +7 -34
  127. package/dist/components/VIconButton/VIconButton.d.ts +2 -3
  128. package/dist/components/VIconButton/VIconButton.js.map +1 -1
  129. package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/VInput/VInput.d.ts +14 -29
  131. package/dist/components/VInput/VInput.js.map +1 -1
  132. package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/VInput/VInputGroup.js.map +1 -1
  134. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +34 -50
  135. package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/VInput/context.js.map +1 -1
  137. package/dist/components/VInputOTP/VInputOTP.d.ts +8 -16
  138. package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
  139. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +55 -63
  140. package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/VMenu/VMenu.js.map +1 -1
  142. package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/VMenu/VMenuGroup.d.ts +1 -6
  144. package/dist/components/VMenu/VMenuGroup.js.map +1 -1
  145. package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/VMenu/VMenuItem.d.ts +0 -5
  147. package/dist/components/VMenu/VMenuItem.js.map +1 -1
  148. package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/VMenu/VMenuPanel.d.ts +1 -6
  150. package/dist/components/VMenu/VMenuPanel.js.map +1 -1
  151. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  152. package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  153. package/dist/components/VMenu/VMenuSeparator.js.map +1 -1
  154. package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/VMenu/context.d.ts +3 -11
  156. package/dist/components/VMenu/context.js.map +1 -1
  157. package/dist/components/VPagination/VPagination.d.ts +9 -20
  158. package/dist/components/VPagination/VPagination.js.map +1 -1
  159. package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  160. package/dist/components/VPopover/VPopover.d.ts +7 -18
  161. package/dist/components/VPopover/VPopover.js.map +1 -1
  162. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +23 -27
  163. package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/components/VProgressCircular/VProgressCircular.d.ts +2 -6
  165. package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
  166. package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
  167. package/dist/components/VProgressLinear/VProgressLinear.d.ts +4 -15
  168. package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
  169. package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
  170. package/dist/components/VRadio/VRadio.d.ts +1 -5
  171. package/dist/components/VRadio/VRadio.js.map +1 -1
  172. package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  173. package/dist/components/VSeparator/VSeparator.d.ts +2 -15
  174. package/dist/components/VSeparator/VSeparator.js.map +1 -1
  175. package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
  176. package/dist/components/VSideNavigation/VSideNavigation.d.ts +1 -1
  177. package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
  178. package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +1 -5
  180. package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
  181. package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  182. package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +1 -5
  183. package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
  184. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +80 -75
  185. package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  186. package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -1
  187. package/dist/components/VSideNavigation/context.js.map +1 -1
  188. package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +6 -19
  189. package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  190. package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/components/VSlider/VSlider.d.ts +5 -13
  192. package/dist/components/VSlider/VSlider.js.map +1 -1
  193. package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  194. package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
  195. package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  196. package/dist/components/VSnackbar/state.d.ts +4 -17
  197. package/dist/components/VSnackbar/state.js.map +1 -1
  198. package/dist/components/VSpinner/VSpinner.d.ts +3 -5
  199. package/dist/components/VSpinner/VSpinner.js.map +1 -1
  200. package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  201. package/dist/components/VSwitch/VSwitch.js.map +1 -1
  202. package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/components/VTabs/VTab.d.ts +1 -5
  204. package/dist/components/VTabs/VTab.js.map +1 -1
  205. package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  206. package/dist/components/VTabs/VTabPanel.js.map +1 -1
  207. package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  208. package/dist/components/VTabs/VTabs.d.ts +5 -17
  209. package/dist/components/VTabs/VTabs.js.map +1 -1
  210. package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/components/VTabs/context.js.map +1 -1
  212. package/dist/components/VTextarea/VTextarea.d.ts +13 -20
  213. package/dist/components/VTextarea/VTextarea.js.map +1 -1
  214. package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  215. package/dist/components/VTimeInput/VTimeInput.d.ts +8 -21
  216. package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
  217. package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  218. package/dist/components/VTimeInput/search.d.ts +3 -34
  219. package/dist/components/VTimeInput/search.js.map +1 -1
  220. package/dist/components/VTimePicker/VTimePicker.d.ts +9 -31
  221. package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
  222. package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/components/VTimePicker/limits.d.ts +18 -45
  224. package/dist/components/VTimePicker/limits.js.map +1 -1
  225. package/dist/components/VToast/VToast.js.map +1 -1
  226. package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  227. package/dist/components/VToast/VToaster.js.map +1 -1
  228. package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  229. package/dist/components/VToast/state.d.ts +2 -7
  230. package/dist/components/VToast/state.js.map +1 -1
  231. package/dist/components/VToggle/VToggle.d.ts +5 -9
  232. package/dist/components/VToggle/VToggle.js.map +1 -1
  233. package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  234. package/dist/components/VToggle/VToggleItem.d.ts +1 -9
  235. package/dist/components/VToggle/VToggleItem.js.map +1 -1
  236. package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  237. package/dist/components/VToggle/context.js.map +1 -1
  238. package/dist/components/VTooltip/VTooltip.d.ts +3 -16
  239. package/dist/components/VTooltip/VTooltip.js.map +1 -1
  240. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +2 -2
  241. package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  242. package/dist/components/VTypography/VTypography.d.ts +4 -8
  243. package/dist/components/VTypography/VTypography.js.map +1 -1
  244. package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
  245. package/dist/composables/useAriaLabel.js.map +1 -1
  246. package/dist/composables/useClearable.d.ts +2 -8
  247. package/dist/composables/useClearable.js.map +1 -1
  248. package/dist/composables/useControlShape.js.map +1 -1
  249. package/dist/composables/useDetailsOpen.d.ts +2 -10
  250. package/dist/composables/useDetailsOpen.js.map +1 -1
  251. package/dist/composables/useFieldIds.js.map +1 -1
  252. package/dist/composables/useFieldPanel.d.ts +4 -17
  253. package/dist/composables/useFieldPanel.js.map +1 -1
  254. package/dist/composables/useFileDrop.js.map +1 -1
  255. package/dist/composables/useFileField.d.ts +1 -5
  256. package/dist/composables/useFileField.js.map +1 -1
  257. package/dist/composables/useFocusoutDismiss.js.map +1 -1
  258. package/dist/composables/useIconClickHandlers.d.ts +4 -19
  259. package/dist/composables/useIconClickHandlers.js.map +1 -1
  260. package/dist/composables/useInertLink.d.ts +1 -1
  261. package/dist/composables/useInertLink.js.map +1 -1
  262. package/dist/composables/useLiveAnnouncer.js.map +1 -1
  263. package/dist/composables/useMaskedField.d.ts +12 -27
  264. package/dist/composables/useMaskedField.js.map +1 -1
  265. package/dist/composables/usePopover.d.ts +3 -11
  266. package/dist/composables/usePopover.js.map +1 -1
  267. package/dist/composables/useProgressValue.js.map +1 -1
  268. package/dist/composables/useRootAttrs.d.ts +0 -9
  269. package/dist/composables/useRootAttrs.js +11 -4
  270. package/dist/composables/useRootAttrs.js.map +1 -1
  271. package/dist/composables/useSlotNodes.d.ts +3 -14
  272. package/dist/composables/useSlotNodes.js.map +1 -1
  273. package/dist/composables/useTextLimit.d.ts +4 -16
  274. package/dist/composables/useTextLimit.js.map +1 -1
  275. package/dist/composables/useTimer.d.ts +2 -15
  276. package/dist/composables/useTimer.js.map +1 -1
  277. package/dist/i18n/en.js.map +1 -1
  278. package/dist/i18n/fr.js.map +1 -1
  279. package/dist/i18n/state.d.ts +9 -38
  280. package/dist/i18n/state.js.map +1 -1
  281. package/dist/i18n/types.d.ts +19 -81
  282. package/dist/icons.d.ts +2 -12
  283. package/dist/tokens/css.d.ts +3 -16
  284. package/dist/tokens/css.js.map +1 -1
  285. package/dist/tokens/index.js.map +1 -1
  286. package/dist/tokens/primitives.js.map +1 -1
  287. package/dist/tokens/semantic.d.ts +1 -23
  288. package/dist/tokens/semantic.js.map +1 -1
  289. package/dist/tokens/themes/dark.js.map +1 -1
  290. package/dist/tokens/types.d.ts +2 -12
  291. package/dist/tokens/types.js.map +1 -1
  292. package/dist/types.d.ts +3 -21
  293. package/dist/utils/array.d.ts +2 -4
  294. package/dist/utils/array.js.map +1 -1
  295. package/dist/utils/arrowNav.d.ts +2 -26
  296. package/dist/utils/arrowNav.js.map +1 -1
  297. package/dist/utils/chip.d.ts +1 -8
  298. package/dist/utils/chip.js.map +1 -1
  299. package/dist/utils/clock.d.ts +16 -39
  300. package/dist/utils/clock.js.map +1 -1
  301. package/dist/utils/css.d.ts +5 -16
  302. package/dist/utils/css.js.map +1 -1
  303. package/dist/utils/date.d.ts +17 -60
  304. package/dist/utils/date.js.map +1 -1
  305. package/dist/utils/direction.d.ts +2 -9
  306. package/dist/utils/direction.js.map +1 -1
  307. package/dist/utils/env.d.ts +2 -15
  308. package/dist/utils/env.js.map +1 -1
  309. package/dist/utils/file.d.ts +8 -46
  310. package/dist/utils/file.js.map +1 -1
  311. package/dist/utils/focus.d.ts +1 -14
  312. package/dist/utils/focus.js +1 -6
  313. package/dist/utils/focus.js.map +1 -1
  314. package/dist/utils/hostWarns.d.ts +3 -8
  315. package/dist/utils/hostWarns.js.map +1 -1
  316. package/dist/utils/ids.d.ts +2 -7
  317. package/dist/utils/ids.js.map +1 -1
  318. package/dist/utils/matcher.d.ts +1 -8
  319. package/dist/utils/matcher.js.map +1 -1
  320. package/dist/utils/memo.d.ts +1 -11
  321. package/dist/utils/memo.js.map +1 -1
  322. package/dist/utils/number.d.ts +1 -7
  323. package/dist/utils/number.js.map +1 -1
  324. package/dist/utils/text.d.ts +4 -23
  325. package/dist/utils/text.js.map +1 -1
  326. package/dist/utils/time.d.ts +4 -12
  327. package/dist/utils/time.js.map +1 -1
  328. package/dist/utils/vnode.d.ts +0 -10
  329. package/dist/utils/vnode.js.map +1 -1
  330. package/package.json +1 -1
@@ -1,56 +1,24 @@
1
1
  /**
2
- * The pure half of VDatePicker's keyboard: it answers the single question "how far
3
- * does this key move?", and does nothing else. Actually moving the focus, calling
4
- * `preventDefault` and keeping the result inside the `min`/`max` bounds all stay in
5
- * the component, where the reactive state lives.
6
- *
7
- * It sits in VDatePicker's own folder rather than in `utils/` because it has exactly
8
- * one consumer, which fails the admission rule for shared code, and because
9
- * VDatePicker owns the contract (the same reasoning as `VHotkeys/platform.ts` and
10
- * `VCombobox/infiniteScroll.ts`). Being pure is also what makes this logic testable
11
- * without mounting anything: the handlers in the component only ever move DOM focus,
12
- * and jsdom lays nothing out to observe.
13
- *
14
- * One number has to be shared rather than repeated: `PICKER_COLUMNS` both cuts the
15
- * months and years grid into rows and defines what a vertical arrow steps over. Were
16
- * those two written as separate literals, widening the picker to four columns would
17
- * leave the arrows moving three cells, with no error anywhere to point at it.
18
- */
19
- /**
20
- * How many columns the months and years pickers are laid out in. It drives BOTH the
21
- * cutting of those grids into rows and the distance a vertical arrow travels: these
22
- * are the same number, and have to stay so.
2
+ * Decode date-navigation keys without side effects; the picker applies bounds, focus and model
3
+ * updates.
23
4
  */
5
+ /** How many columns the months and years pickers are laid out in. */
24
6
  export declare const PICKER_COLUMNS = 3;
25
- /**
26
- * How far a key moves in the days view. It comes in two units because a month is not
27
- * a fixed number of days: `utils/date` provides one helper for each, and the caller
28
- * picks by looking at which shape it was handed.
29
- */
7
+ /** How far a key moves in the days view. */
30
8
  export type DayStep = {
31
9
  days: number;
32
10
  } | {
33
11
  months: number;
34
12
  };
35
13
  /**
36
- * The step a key produces in the days view, given the key itself, whether Shift is
37
- * held, and how far the focused date sits from the start of its week: the last
38
- * being what Home and End need in order to land on the right day. Returning
39
- * `undefined` means the key is none of this table's business, and the event must be
40
- * left alone.
41
- *
42
- * `weekdayOffset` is passed in rather than worked out here, because it depends on
43
- * which day the week starts on in the current locale, and resolving that belongs to
44
- * `utils/date`, not to a keyboard table.
14
+ * The step a key produces in the days view, given the key itself, whether Shift is held, and
15
+ * how far the focused date sits from the start of its week: the last being what Home and End
16
+ * need to land on the right day.
45
17
  */
46
18
  export declare function dayStep(key: string, shiftKey: boolean, weekdayOffset: number): DayStep | undefined;
47
19
  /**
48
- * The step a key produces in the months and years views, expressed as a movement of
49
- * a flat index over a grid `PICKER_COLUMNS` wide. `undefined` again means the key is
50
- * not this table's business.
51
- *
52
- * Home and End are deliberately absent: both views are bounded: twelve months, a
53
- * year range fixed by `min` and `max`, and the component clamps whatever comes out,
54
- * so there is no wrapping behaviour left to define.
20
+ * The step a key produces in the months and years views, expressed as a movement of a flat
21
+ * index over a grid `PICKER_COLUMNS` wide. `undefined` again means the key is not this table's
22
+ * business.
55
23
  */
56
24
  export declare function gridDelta(key: string): number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard.js","names":[],"sources":["../../../src/components/VDatePicker/keyboard.ts"],"sourcesContent":["// @keyboard @core\n/**\n * The pure half of VDatePicker's keyboard: it answers the single question \"how far\n * does this key move?\", and does nothing else. Actually moving the focus, calling\n * `preventDefault` and keeping the result inside the `min`/`max` bounds all stay in\n * the component, where the reactive state lives.\n *\n * It sits in VDatePicker's own folder rather than in `utils/` because it has exactly\n * one consumer, which fails the admission rule for shared code, and because\n * VDatePicker owns the contract (the same reasoning as `VHotkeys/platform.ts` and\n * `VCombobox/infiniteScroll.ts`). Being pure is also what makes this logic testable\n * without mounting anything: the handlers in the component only ever move DOM focus,\n * and jsdom lays nothing out to observe.\n *\n * One number has to be shared rather than repeated: `PICKER_COLUMNS` both cuts the\n * months and years grid into rows and defines what a vertical arrow steps over. Were\n * those two written as separate literals, widening the picker to four columns would\n * leave the arrows moving three cells, with no error anywhere to point at it.\n */\n\n/**\n * How many columns the months and years pickers are laid out in. It drives BOTH the\n * cutting of those grids into rows and the distance a vertical arrow travels: these\n * are the same number, and have to stay so.\n */\nexport const PICKER_COLUMNS = 3\n\nconst DAYS_PER_WEEK = 7\n\n/**\n * How far a key moves in the days view. It comes in two units because a month is not\n * a fixed number of days: `utils/date` provides one helper for each, and the caller\n * picks by looking at which shape it was handed.\n */\nexport type DayStep = { days: number } | { months: number }\n\n/**\n * The step a key produces in the days view, given the key itself, whether Shift is\n * held, and how far the focused date sits from the start of its week: the last\n * being what Home and End need in order to land on the right day. Returning\n * `undefined` means the key is none of this table's business, and the event must be\n * left alone.\n *\n * `weekdayOffset` is passed in rather than worked out here, because it depends on\n * which day the week starts on in the current locale, and resolving that belongs to\n * `utils/date`, not to a keyboard table.\n */\nexport function dayStep(\n key: string,\n shiftKey: boolean,\n weekdayOffset: number,\n): DayStep | undefined {\n switch (key) {\n case 'ArrowRight':\n return { days: 1 }\n case 'ArrowLeft':\n return { days: -1 }\n case 'ArrowDown':\n return { days: DAYS_PER_WEEK }\n case 'ArrowUp':\n return { days: -DAYS_PER_WEEK }\n case 'Home':\n // Negating an offset of zero yields `-0`, and the `|| 0` normalizes it back.\n // `addDays` would not care either way, but a pure function should not hand out\n // a value that `Object.is` reports as different from the zero every caller\n // means.\n return { days: -weekdayOffset || 0 }\n case 'End':\n return { days: DAYS_PER_WEEK - 1 - weekdayOffset }\n case 'PageUp':\n return { months: shiftKey ? -12 : -1 }\n case 'PageDown':\n return { months: shiftKey ? 12 : 1 }\n default:\n return undefined\n }\n}\n\n/**\n * The step a key produces in the months and years views, expressed as a movement of\n * a flat index over a grid `PICKER_COLUMNS` wide. `undefined` again means the key is\n * not this table's business.\n *\n * Home and End are deliberately absent: both views are bounded: twelve months, a\n * year range fixed by `min` and `max`, and the component clamps whatever comes out,\n * so there is no wrapping behaviour left to define.\n */\nexport function gridDelta(key: string): number | undefined {\n switch (key) {\n case 'ArrowRight':\n return 1\n case 'ArrowLeft':\n return -1\n case 'ArrowDown':\n return PICKER_COLUMNS\n case 'ArrowUp':\n return -PICKER_COLUMNS\n default:\n return undefined\n }\n}\n"],"mappings":"AA+CA,SAAgB,EACd,GACA,GACA,GACqB;CACrB,QAAQ,GAAR;EACE,KAAK,cACH,OAAO,EAAE,MAAM,EAAE;EACnB,KAAK,aACH,OAAO,EAAE,MAAM,GAAG;EACpB,KAAK,aACH,OAAO,EAAE,MAAM,EAAc;EAC/B,KAAK,WACH,OAAO,EAAE,MAAM,GAAe;EAChC,KAAK,QAKH,OAAO,EAAE,MAAM,CAAC,KAAiB,EAAE;EACrC,KAAK,OACH,OAAO,EAAE,MAAM,IAAoB,EAAc;EACnD,KAAK,UACH,OAAO,EAAE,QAAQ,IAAW,MAAM,GAAG;EACvC,KAAK,YACH,OAAO,EAAE,QAAQ,IAAW,KAAK,EAAE;EACrC,SACE;CACJ;AACF;AAWA,SAAgB,EAAU,GAAiC;CACzD,QAAQ,GAAR;EACE,KAAK,cACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,aACH,OAAA;EACF,KAAK,WACH,OAAO;EACT,SACE;CACJ;AACF"}
1
+ {"version":3,"file":"keyboard.js","names":[],"sources":["../../../src/components/VDatePicker/keyboard.ts"],"sourcesContent":["// @keyboard @core\n/**\n * Decode date-navigation keys without side effects; the picker applies bounds, focus and model\n * updates.\n */\n\n/** How many columns the months and years pickers are laid out in. */\nexport const PICKER_COLUMNS = 3\n\nconst DAYS_PER_WEEK = 7\n\n/** How far a key moves in the days view. */\nexport type DayStep = { days: number } | { months: number }\n\n/**\n * The step a key produces in the days view, given the key itself, whether Shift is held, and\n * how far the focused date sits from the start of its week: the last being what Home and End\n * need to land on the right day.\n */\nexport function dayStep(\n key: string,\n shiftKey: boolean,\n weekdayOffset: number,\n): DayStep | undefined {\n switch (key) {\n case 'ArrowRight':\n return { days: 1 }\n case 'ArrowLeft':\n return { days: -1 }\n case 'ArrowDown':\n return { days: DAYS_PER_WEEK }\n case 'ArrowUp':\n return { days: -DAYS_PER_WEEK }\n case 'Home':\n // Negating an offset of zero yields `-0`, and the `|| 0` normalizes it back.\n // `addDays` would not care either way, but a pure function should not hand out\n // a value that `Object.is` reports as different from the zero every caller\n // means.\n return { days: -weekdayOffset || 0 }\n case 'End':\n return { days: DAYS_PER_WEEK - 1 - weekdayOffset }\n case 'PageUp':\n return { months: shiftKey ? -12 : -1 }\n case 'PageDown':\n return { months: shiftKey ? 12 : 1 }\n default:\n return undefined\n }\n}\n\n/**\n * The step a key produces in the months and years views, expressed as a movement of a flat\n * index over a grid `PICKER_COLUMNS` wide. `undefined` again means the key is not this table's\n * business.\n */\nexport function gridDelta(key: string): number | undefined {\n switch (key) {\n case 'ArrowRight':\n return 1\n case 'ArrowLeft':\n return -1\n case 'ArrowDown':\n return PICKER_COLUMNS\n case 'ArrowUp':\n return -PICKER_COLUMNS\n default:\n return undefined\n }\n}\n"],"mappings":"AAmBA,SAAgB,EACd,GACA,GACA,GACqB;CACrB,QAAQ,GAAR;EACE,KAAK,cACH,OAAO,EAAE,MAAM,EAAE;EACnB,KAAK,aACH,OAAO,EAAE,MAAM,GAAG;EACpB,KAAK,aACH,OAAO,EAAE,MAAM,EAAc;EAC/B,KAAK,WACH,OAAO,EAAE,MAAM,GAAe;EAChC,KAAK,QAKH,OAAO,EAAE,MAAM,CAAC,KAAiB,EAAE;EACrC,KAAK,OACH,OAAO,EAAE,MAAM,IAAoB,EAAc;EACnD,KAAK,UACH,OAAO,EAAE,QAAQ,IAAW,MAAM,GAAG;EACvC,KAAK,YACH,OAAO,EAAE,QAAQ,IAAW,KAAK,EAAE;EACrC,SACE;CACJ;AACF;AAOA,SAAgB,EAAU,GAAiC;CACzD,QAAQ,GAAR;EACE,KAAK,cACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,KAAK,aACH,OAAA;EACF,KAAK,WACH,OAAO;EACT,SACE;CACJ;AACF"}
@@ -1,34 +1,20 @@
1
1
  /**
2
- * The names of the months, as VDatePicker writes them in its header, its months view and
3
- * the title of its grid.
4
- *
5
- * It sits in the component's folder rather than in `utils/date.ts`: there is one consumer,
6
- * and `utils/date.ts` is in the import closure of every VCalendar component, which would
7
- * pay for rules only the picker needs, the `VTimeInput/search.ts` argument.
8
- *
9
- * Every name is read on a REFERENCE date pinned to `timeZone: 'UTC'`, so a label never
10
- * depends on the rendering machine's zone and the server agrees with the browser.
2
+ * Format reference dates in UTC so month and weekday names do not vary with the rendering
3
+ * machine's time zone.
11
4
  */
12
5
  /** The full names of the twelve months, in January-to-December order. */
13
6
  export declare function monthNames(locale: string): string[];
14
7
  /**
15
- * Month names shortened for the picker's narrow cells: a name of four characters or
16
- * fewer is kept whole ("May", "June", "July"), a longer one is cut to three
17
- * characters followed by a dot ("January" becomes "Jan."). The name is spread with
18
- * `[...n]` rather than indexed, so that an accented or non-Latin character counts as
19
- * one character and is never cut in half.
20
- *
21
- * TRAP: the cut is not safe everywhere. Vietnamese writes every month "Tháng N", so all
22
- * twelve come out "Thá.", and Estonian, Czech, Lithuanian or Greek lose a pair; the months
23
- * view then shows identical cells. When the cut repeats itself, the language's own short
24
- * names are used instead, which CLDR keeps distinct.
8
+ * The cut is not safe everywhere. Vietnamese writes every month "Tháng N", so all twelve come
9
+ * out "Thá.", and Estonian, Czech, Lithuanian or Greek lose a pair; the months view then shows
10
+ * identical cells.
25
11
  */
26
12
  export declare function monthNamesCompact(locale: string): string[];
27
13
  /** The full name of one month, 0 being January. */
28
14
  export declare function monthName(locale: string, month0: number): string;
29
15
  /**
30
- * A month and its year written the way the language writes them together: "June 2026",
31
- * "juin 2026", but "2026年6月" in Japanese and "2026. június" in Hungarian, where gluing the
32
- * two with a space gets the order wrong. The digits are Latin, as on the year button.
16
+ * A month and its year written the way the language writes them together: "June 2026", "juin
17
+ * 2026", but "2026年6月" in Japanese and "2026. június" in Hungarian, where gluing the two with a
18
+ * space gets the order wrong.
33
19
  */
34
20
  export declare function monthYearName(locale: string, year: number, month0: number): string;
@@ -1 +1 @@
1
- {"version":3,"file":"names.js","names":[],"sources":["../../../src/components/VDatePicker/names.ts"],"sourcesContent":["// @core\n/**\n * The names of the months, as VDatePicker writes them in its header, its months view and\n * the title of its grid.\n *\n * It sits in the component's folder rather than in `utils/date.ts`: there is one consumer,\n * and `utils/date.ts` is in the import closure of every VCalendar component, which would\n * pay for rules only the picker needs, the `VTimeInput/search.ts` argument.\n *\n * Every name is read on a REFERENCE date pinned to `timeZone: 'UTC'`, so a label never\n * depends on the rendering machine's zone and the server agrees with the browser.\n */\n\nimport { memo } from '../../utils/memo'\n\n/** The full names of the twelve months, in January-to-December order. */\nexport function monthNames(locale: string): string[] {\n const fmt = new Intl.DateTimeFormat(locale, MONTH_LONG)\n return Array.from({ length: 12 }, (_, i) => fmt.format(Date.UTC(2021, i, 1)))\n}\n\n/**\n * The options every month name is read with. `calendar: 'gregory'` is not optional: the\n * grid is Gregorian, and a locale whose default calendar is another one (fa-IR, or any tag\n * carrying `-u-ca-islamic`) would otherwise title a January grid with the month of ITS\n * calendar that happens to hold the 1st, \"Dey\" in Persian.\n */\nconst MONTH_LONG = { month: 'long', calendar: 'gregory', timeZone: 'UTC' } as const\n\n/**\n * Month names shortened for the picker's narrow cells: a name of four characters or\n * fewer is kept whole (\"May\", \"June\", \"July\"), a longer one is cut to three\n * characters followed by a dot (\"January\" becomes \"Jan.\"). The name is spread with\n * `[...n]` rather than indexed, so that an accented or non-Latin character counts as\n * one character and is never cut in half.\n *\n * TRAP: the cut is not safe everywhere. Vietnamese writes every month \"Tháng N\", so all\n * twelve come out \"Thá.\", and Estonian, Czech, Lithuanian or Greek lose a pair; the months\n * view then shows identical cells. When the cut repeats itself, the language's own short\n * names are used instead, which CLDR keeps distinct.\n */\nexport function monthNamesCompact(locale: string): string[] {\n const cut = monthNames(locale).map((n) => {\n const chars = [...n]\n return chars.length <= 4 ? n : chars.slice(0, 3).join('') + '.'\n })\n if (new Set(cut).size === 12) return cut\n const fmt = new Intl.DateTimeFormat(locale, { ...MONTH_LONG, month: 'short' })\n return Array.from({ length: 12 }, (_, i) => fmt.format(Date.UTC(2021, i, 1)))\n}\n\n/**\n * One formatter kept per locale and set of options, for the lifetime of the module: the\n * two functions below are asked one month at a time, and building an `Intl` formatter\n * costs far more than using one.\n */\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/** The full name of one month, 0 being January. */\nexport function monthName(locale: string, month0: number): string {\n return formatterFor(locale, MONTH_LONG).format(Date.UTC(2021, month0, 1))\n}\n\n/**\n * A month and its year written the way the language writes them together: \"June 2026\",\n * \"juin 2026\", but \"2026年6月\" in Japanese and \"2026. június\" in Hungarian, where gluing the\n * two with a space gets the order wrong. The digits are Latin, as on the year button.\n */\nexport function monthYearName(locale: string, year: number, month0: number): string {\n const at = new Date(Date.UTC(2021, month0, 1))\n at.setUTCFullYear(year)\n return formatterFor(locale, {\n ...MONTH_LONG,\n year: 'numeric',\n numberingSystem: 'latn',\n }).format(at)\n}\n"],"mappings":";;AAgBA,SAAgB,EAAW,GAA0B;CACnD,IAAM,IAAM,IAAI,KAAK,eAAe,GAAQ,CAAU;CACtD,OAAO,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,EAAI,OAAO,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E;AAQA,IAAM,IAAa;CAAE,OAAO;CAAQ,UAAU;CAAW,UAAU;AAAM;AAczE,SAAgB,EAAkB,GAA0B;CAC1D,IAAM,IAAM,EAAW,CAAM,CAAC,CAAC,KAAK,MAAM;EACxC,IAAM,IAAQ,CAAC,GAAG,CAAC;EACnB,OAAO,EAAM,UAAU,IAAI,IAAI,EAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI;CAC9D,CAAC;CACD,IAAI,IAAI,IAAI,CAAG,CAAC,CAAC,SAAS,IAAI,OAAO;CACrC,IAAM,IAAM,IAAI,KAAK,eAAe,GAAQ;EAAE,GAAG;EAAY,OAAO;CAAQ,CAAC;CAC7E,OAAO,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,EAAI,OAAO,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E;AAOA,IAAM,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,SAAgB,EAAU,GAAgB,GAAwB;CAChE,OAAO,EAAa,GAAQ,CAAU,CAAC,CAAC,OAAO,KAAK,IAAI,MAAM,GAAQ,CAAC,CAAC;AAC1E;AAOA,SAAgB,EAAc,GAAgB,GAAc,GAAwB;CAClF,IAAM,IAAK,IAAI,KAAK,KAAK,IAAI,MAAM,GAAQ,CAAC,CAAC;CAE7C,OADA,EAAG,eAAe,CAAI,GACf,EAAa,GAAQ;EAC1B,GAAG;EACH,MAAM;EACN,iBAAiB;CACnB,CAAC,CAAC,CAAC,OAAO,CAAE;AACd"}
1
+ {"version":3,"file":"names.js","names":[],"sources":["../../../src/components/VDatePicker/names.ts"],"sourcesContent":["// @core\n/**\n * Format reference dates in UTC so month and weekday names do not vary with the rendering\n * machine's time zone.\n */\n\nimport { memo } from '../../utils/memo'\n\n/** The full names of the twelve months, in January-to-December order. */\nexport function monthNames(locale: string): string[] {\n const fmt = new Intl.DateTimeFormat(locale, MONTH_LONG)\n return Array.from({ length: 12 }, (_, i) => fmt.format(Date.UTC(2021, i, 1)))\n}\n\n/**\n * The options every month name is read with. `calendar: 'gregory'` is not optional: the\n * grid is Gregorian, and a locale whose default calendar is another one (fa-IR, or any tag\n * carrying `-u-ca-islamic`) would otherwise title a January grid with the month of ITS\n * calendar that happens to hold the 1st, \"Dey\" in Persian.\n */\nconst MONTH_LONG = { month: 'long', calendar: 'gregory', timeZone: 'UTC' } as const\n\n/**\n * The cut is not safe everywhere. Vietnamese writes every month \"Tháng N\", so all twelve come\n * out \"Thá.\", and Estonian, Czech, Lithuanian or Greek lose a pair; the months view then shows\n * identical cells.\n */\nexport function monthNamesCompact(locale: string): string[] {\n const cut = monthNames(locale).map((n) => {\n const chars = [...n]\n return chars.length <= 4 ? n : chars.slice(0, 3).join('') + '.'\n })\n if (new Set(cut).size === 12) return cut\n const fmt = new Intl.DateTimeFormat(locale, { ...MONTH_LONG, month: 'short' })\n return Array.from({ length: 12 }, (_, i) => fmt.format(Date.UTC(2021, i, 1)))\n}\n\n/**\n * One formatter kept per locale and set of options, for the lifetime of the module: the\n * two functions below are asked one month at a time, and building an `Intl` formatter\n * costs far more than using one.\n */\nconst formatters = new Map<string, Intl.DateTimeFormat>()\n\nfunction formatterFor(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {\n return memo(\n formatters,\n `${locale}|${JSON.stringify(options)}`,\n () => new Intl.DateTimeFormat(locale, options),\n )\n}\n\n/** The full name of one month, 0 being January. */\nexport function monthName(locale: string, month0: number): string {\n return formatterFor(locale, MONTH_LONG).format(Date.UTC(2021, month0, 1))\n}\n\n/**\n * A month and its year written the way the language writes them together: \"June 2026\", \"juin\n * 2026\", but \"2026年6月\" in Japanese and \"2026. június\" in Hungarian, where gluing the two with a\n * space gets the order wrong.\n */\nexport function monthYearName(locale: string, year: number, month0: number): string {\n const at = new Date(Date.UTC(2021, month0, 1))\n at.setUTCFullYear(year)\n return formatterFor(locale, {\n ...MONTH_LONG,\n year: 'numeric',\n numberingSystem: 'latn',\n }).format(at)\n}\n"],"mappings":";;AASA,SAAgB,EAAW,GAA0B;CACnD,IAAM,IAAM,IAAI,KAAK,eAAe,GAAQ,CAAU;CACtD,OAAO,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,EAAI,OAAO,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E;AAQA,IAAM,IAAa;CAAE,OAAO;CAAQ,UAAU;CAAW,UAAU;AAAM;AAOzE,SAAgB,EAAkB,GAA0B;CAC1D,IAAM,IAAM,EAAW,CAAM,CAAC,CAAC,KAAK,MAAM;EACxC,IAAM,IAAQ,CAAC,GAAG,CAAC;EACnB,OAAO,EAAM,UAAU,IAAI,IAAI,EAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI;CAC9D,CAAC;CACD,IAAI,IAAI,IAAI,CAAG,CAAC,CAAC,SAAS,IAAI,OAAO;CACrC,IAAM,IAAM,IAAI,KAAK,eAAe,GAAQ;EAAE,GAAG;EAAY,OAAO;CAAQ,CAAC;CAC7E,OAAO,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,EAAI,OAAO,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E;AAOA,IAAM,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,SAAgB,EAAU,GAAgB,GAAwB;CAChE,OAAO,EAAa,GAAQ,CAAU,CAAC,CAAC,OAAO,KAAK,IAAI,MAAM,GAAQ,CAAC,CAAC;AAC1E;AAOA,SAAgB,EAAc,GAAgB,GAAc,GAAwB;CAClF,IAAM,IAAK,IAAI,KAAK,KAAK,IAAI,MAAM,GAAQ,CAAC,CAAC;CAE7C,OADA,EAAG,eAAe,CAAI,GACf,EAAa,GAAQ;EAC1B,GAAG;EACH,MAAM;EACN,iBAAiB;CACnB,CAAC,CAAC,CAAC,OAAO,CAAE;AACd"}
@@ -9,9 +9,8 @@ interface DialogProps {
9
9
  /** A line under the title, explaining what the dialog is asking. */
10
10
  subtitle?: string;
11
11
  /**
12
- * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left
13
- * out, it takes the `--vectis-control-size-dialog-width` token, 400px by default. It is
14
- * never allowed to exceed the width of the viewport.
12
+ * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left out,
13
+ * it takes the `--vectis-control-size-dialog-width` token, 400px by default.
15
14
  */
16
15
  width?: number | string;
17
16
  /**
@@ -52,8 +51,8 @@ type __VLS_Slots = {
52
51
  /** The buttons at the foot of the dialog. */
53
52
  footer?(): unknown;
54
53
  /**
55
- * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It
56
- * stays rendered at all times, unlike the dialog itself.
54
+ * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It stays
55
+ * rendered always, unlike the dialog itself.
57
56
  */
58
57
  trigger?(props: {
59
58
  triggerProps: DialogTriggerProps;
@@ -62,11 +61,7 @@ type __VLS_Slots = {
62
61
  declare function show(): Promise<void>;
63
62
  declare function requestClose(): void;
64
63
  type __VLS_ModelProps = {
65
- /**
66
- * Whether the dialog is showing. It starts closed, and it is BIDIRECTIONAL: the browser
67
- * writes back to it whenever the dialog closes on its own, through Escape or the backdrop,
68
- * so a consumer never has to reset it by hand.
69
- */
64
+ /** Whether the dialog is showing. */
70
65
  'open'?: boolean;
71
66
  };
72
67
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
@@ -1 +1 @@
1
- {"version":3,"file":"VDialog.js","names":[],"sources":["../../../src/components/VDialog/VDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * A modal dialog: it takes over the page until the reader answers it.\n *\n * Almost everything that makes a modal correct comes free with the native `<dialog>`\n * element opened as a modal — it is drawn above the whole page, the background is\n * dimmed and made unusable, the focus is trapped inside it and handed back to the\n * trigger on closing, and whether a click outside or Escape dismisses it is declared\n * with an attribute rather than coded.\n *\n * The ONLY behavioural JavaScript is the bridge between `v-model:open` and the two\n * methods the platform offers no declarative equivalent for: opening as a modal, and\n * closing.\n */\n\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, useAttrs, useId, watch } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VTypography from '../VTypography/VTypography.vue'\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\n/** How assistive technology announces the dialog. */\nexport type DialogRole = 'dialog' | 'alertdialog'\n\ninterface DialogProps {\n /**\n * The title of the dialog, which also names it for assistive technology. It is\n * ignored when the `#header` slot replaces the whole header.\n */\n title?: string\n /** A line under the title, explaining what the dialog is asking. */\n subtitle?: string\n /**\n * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left\n * out, it takes the `--vectis-control-size-dialog-width` token, 400px by default. It is\n * never allowed to exceed the width of the viewport.\n */\n width?: number | string\n /**\n * What kind of dialog this is. `alertdialog` is for one that must be answered\n * explicitly, and it makes screen readers announce it more insistently. VDialogAlert is\n * exactly that.\n */\n role?: DialogRole\n /**\n * Takes the close cross out of the header, leaving the reader with Escape, the\n * backdrop and whatever the footer offers.\n */\n hideClose?: boolean\n /** Stops a click outside the dialog from closing it. */\n persistentBackdrop?: boolean\n /**\n * Stops the Escape key from closing the dialog. Note that refusing Escape while the\n * backdrop still closes cannot be expressed natively, so both routes are then\n * allowed.\n */\n persistentEscape?: boolean\n /** What the close cross does, in words. It falls back to the design system dictionary. */\n closeLabel?: string\n}\n\nconst props = withDefaults(defineProps<DialogProps>(), {\n title: undefined,\n subtitle: undefined,\n width: undefined,\n role: 'dialog',\n hideClose: false,\n persistentBackdrop: false,\n persistentEscape: false,\n closeLabel: undefined,\n})\n\nconst m = useMessages()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? m.value.common.close)\n\n/**\n * Whether the dialog is showing. It starts closed, and it is BIDIRECTIONAL: the browser\n * writes back to it whenever the dialog closes on its own, through Escape or the backdrop,\n * so a consumer never has to reset it by hand.\n */\nconst open = defineModel<boolean>('open', { default: false })\n\n/** What the trigger has to carry: the click that opens the dialog, and the fact that it does. */\nexport type DialogTriggerProps = {\n onClick: () => void\n 'aria-haspopup': 'dialog'\n}\n\ndefineSlots<{\n /** The body of the dialog. This is the part that scrolls when there is too much of it. */\n default(): unknown\n /** Replaces the title and subtitle block with content of your own. */\n header?(): unknown\n /** Extra controls in the header, placed before the close cross: a menu, a full-screen toggle. */\n 'header-actions'?(): unknown\n /** The buttons at the foot of the dialog. */\n footer?(): unknown\n /**\n * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It\n * stays rendered at all times, unlike the dialog itself.\n */\n trigger?(props: { triggerProps: DialogTriggerProps }): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst dialogEl = ref<HTMLDialogElement | null>(null)\nconst titleId = useId()\nconst subtitleId = useId()\n\n/**\n * Which dismissals the browser itself accepts, declared as an attribute rather than\n * handled in code: everything, Escape alone, or nothing.\n *\n * One combination cannot be expressed that way — a click outside allowed while Escape\n * is not — and it falls back to allowing both. Nothing in the design system asks for\n * it, and it would be a strange thing to want.\n */\nconst closedby = computed(() =>\n props.persistentBackdrop ? (props.persistentEscape ? 'none' : 'closerequest') : 'any',\n)\n\n// @fallback\n// The `closedby` attribute is newer than the type definitions shipped with\n// TypeScript, so writing it directly in the template would be reported as an unknown\n// attribute. Passing it inside a bound object goes through the same path as any\n// forwarded attribute, which is not checked element by element. Vue still merges the\n// `class` and `style` it may contain with the static ones below.\nconst rootAttrs = computed(() => ({ ...attrs, closedby: closedby.value }))\n\n// The dialog and its content only exist while it is open, which also spares the page\n// whatever heavy thing it contains. Every opening therefore builds a BRAND NEW\n// element, so it is always opened as a modal from a clean slate, and closing removes\n// it entirely — nothing is left behind to swallow clicks, and reopening cannot race\n// with a closing that is still finishing. The trigger, by contrast, stays rendered at\n// all times.\nconst rendered = ref(open.value)\n\n/**\n * Settles once the dialog opened by the latest change of `open` is actually showing. The\n * opening waits for the element to be rendered, so it is always a tick behind the model.\n */\nlet opening: Promise<void> = Promise.resolve()\n\nfunction show(): Promise<void> {\n open.value = true\n // The watcher below only runs when the scheduler flushes, so `opening` is read from a\n // tick later: read at once, it would still be the promise of the previous opening.\n return nextTick(() => opening)\n}\n\nfunction requestClose() {\n // Closing the element is enough: the browser then fires its own close event, which\n // is what puts the model back in step below.\n dialogEl.value?.close()\n}\n\nconst triggerProps = computed<DialogTriggerProps>(() => ({\n onClick: show,\n 'aria-haspopup': 'dialog',\n}))\n\n// The `<dialog>` element is asymmetric in a way that shapes this whole bridge: it\n// announces every closing with an event, but announces nothing at all when it opens —\n// where a popover reports both. So the two directions are not written the same way:\n//\n// - opening: render the element, then, once Vue has actually put it in the document,\n// open it as a modal;\n// - closing: whatever closed it — the cross, our own call, Escape, a click outside —\n// the browser's close event is what puts the model back in step, and only then is\n// the element removed.\nwatch(open, (value) => {\n if (value) {\n rendered.value = true\n // the brand new <dialog> has to exist before it can be opened\n opening = nextTick(() => dialogEl.value?.showModal())\n } else {\n dialogEl.value?.close()\n rendered.value = false\n }\n})\n\n// @ssr\nonMounted(() => {\n // A watcher does not run during the server render, so a dialog asked to be open from\n // the start would never be opened. The element is already there — the flag above was\n // initialized from the model — it just has to be told to show itself.\n if (open.value) dialogEl.value?.showModal()\n})\n\n// The browser's own close event, whatever caused it, is what brings the model back in\n// step with reality.\n//\n// TRAP — only the element on screen may do it. A close event is queued as a TASK, so the\n// one fired by the element a quick close-and-reopen has just replaced arrives after the new\n// element exists, and without the check it closed the dialog that had just opened.\nfunction onClose(event: Event) {\n if (event.target !== dialogEl.value) return\n open.value = false\n}\n\n// @core\n// An open dialog removed with its parent (a `v-if`, a route change) runs no close steps,\n// so no close event would come: the model is handed back closed here, or it stayed `true`\n// and the dialog reopened by itself the next time its parent was shown.\nonBeforeUnmount(() => {\n if (open.value) open.value = false\n})\n\n// @fallback\n/*\n * `closedby` is what applies `persistentBackdrop` and `persistentEscape`, and Safari does\n * not implement it: there Escape always closes and the backdrop never does. The two halves\n * are rebuilt below, and ONLY where the attribute is unknown, so a browser that has it is\n * never second-guessed. The support is asked at event time: there is no DOM during setup.\n */\nconst closedbyUnsupported = () => !('closedBy' in HTMLDialogElement.prototype)\n\nfunction onCancel(event: Event) {\n if (closedbyUnsupported() && closedby.value === 'none') event.preventDefault()\n}\n\n/**\n * Whether a point lies outside the dialog's box, which is where the backdrop is: a click on\n * the `::backdrop` is dispatched to the dialog element itself.\n */\nfunction outsideBox(event: MouseEvent) {\n const box = dialogEl.value?.getBoundingClientRect()\n if (!box) return false\n return (\n event.clientX < box.left ||\n event.clientX > box.right ||\n event.clientY < box.top ||\n event.clientY > box.bottom\n )\n}\n\n// A press that STARTED inside and ended on the backdrop (a text selection dragged past the\n// edge) is not a click on the backdrop, so the press is remembered, not only the release.\nlet pressedOnBackdrop = false\nfunction onPointerdown(event: PointerEvent) {\n pressedOnBackdrop = event.target === dialogEl.value && outsideBox(event)\n}\nfunction onBackdropClick(event: MouseEvent) {\n const onBackdrop = pressedOnBackdrop && event.target === dialogEl.value && outsideBox(event)\n pressedOnBackdrop = false\n if (onBackdrop && closedbyUnsupported() && closedby.value === 'any') requestClose()\n}\n\ndefineExpose({\n /**\n * Opens the dialog, exactly as setting `open` does. The opening lands on the next tick,\n * once the element has been rendered: `el` is still null right after the call, and the\n * promise returned settles once the dialog is showing.\n */\n show,\n /**\n * Closes the dialog. It closes unconditionally, `persistentEscape` and\n * `persistentBackdrop` governing only the two routes the reader can take.\n */\n close: requestClose,\n /** The `<dialog>` element. It is null while closed: each opening builds a fresh one. */\n el: dialogEl,\n})\n</script>\n\n<template>\n <slot name=\"trigger\" :trigger-props=\"triggerProps\" />\n <dialog\n v-if=\"rendered\"\n ref=\"dialogEl\"\n :aria-labelledby=\"title ? titleId : undefined\"\n :aria-describedby=\"subtitle ? subtitleId : undefined\"\n v-bind=\"rootAttrs\"\n class=\"v-dialog\"\n :style=\"{ '--dialog-width': cssSize(width) }\"\n :role=\"role === 'alertdialog' ? 'alertdialog' : undefined\"\n @close=\"onClose\"\n @cancel=\"onCancel\"\n @pointerdown=\"onPointerdown\"\n @click=\"onBackdropClick\"\n >\n <!--\n The header and the footer stay put while only the body scrolls, so the scrollbar\n is confined to the body and never runs along them.\n\n The lines that appear under the header and above the footer once the body is\n scrolled are drawn by two sentinels stuck INSIDE the scrolling area, and not by\n the header and footer themselves: a container query can only style what is inside\n the container it asks about, never a sibling of it.\n -->\n <header class=\"v-dialog-header\">\n <slot name=\"header\">\n <div class=\"v-dialog-titles\">\n <VTypography\n v-if=\"title\"\n :id=\"titleId\"\n as=\"h2\"\n variant=\"heading-3\"\n class=\"v-dialog-title\"\n >\n {{ title }}\n </VTypography>\n <VTypography\n v-if=\"subtitle\"\n :id=\"subtitleId\"\n variant=\"subtitle\"\n tone=\"muted\"\n class=\"v-dialog-subtitle\"\n >\n {{ subtitle }}\n </VTypography>\n </div>\n </slot>\n <div v-if=\"!hideClose || $slots['header-actions']\" class=\"v-dialog-header-actions\">\n <slot name=\"header-actions\" />\n <VIconButton\n v-if=\"!hideClose\"\n class=\"v-dialog-close\"\n :label=\"resolvedCloseLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n @click=\"requestClose\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n </header>\n <div class=\"v-dialog-scroll\">\n <span class=\"v-dialog-edge v-dialog-edge--top\" aria-hidden=\"true\" />\n <div class=\"v-dialog-body\">\n <slot />\n </div>\n <span class=\"v-dialog-edge v-dialog-edge--bottom\" aria-hidden=\"true\" />\n </div>\n <footer v-if=\"$slots.footer\" class=\"v-dialog-footer\">\n <slot name=\"footer\" />\n </footer>\n </dialog>\n</template>\n\n<style>\n@layer vectis.components {\n .v-dialog {\n /* The width comes from the prop, set inline, or from the token when there is none.\n Whatever it asks for, the dialog is never allowed past the viewport, margins included.\n\n TRAP — the token is declared ON the element rather than written as a `var()` fallback.\n A custom property inherits, and a dialog opened from inside another one is its DOM\n descendant: with a fallback, an alert confirming something in an 800px dialog would\n read that dialog's inline width and open 800px wide itself, with no error anywhere. */\n --dialog-width: var(--vectis-control-size-dialog-width);\n inline-size: var(--dialog-width);\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n max-block-size: calc(100dvb - 2 * var(--vectis-space-4));\n /* This puts the dialog back in the middle of the screen. The browser centres a\n modal with an automatic margin, which the design system's own reset — where\n every element loses its margins — had removed; restoring it here works because\n the component layer is stronger than the reset one. */\n margin: auto;\n /* The header and footer stay put while only the body scrolls, and hiding the\n overflow is what keeps the content inside the rounded corners. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 0;\n border: none;\n border-radius: var(--vectis-radius-overlay);\n background: var(--vectis-color-surface-overlay);\n color: var(--vectis-color-text);\n box-shadow: var(--vectis-shadow-xl);\n font-family: var(--vectis-text-family);\n }\n\n /*\n * An indispensable guard. The browser hides a closed dialog with a rule of its own,\n * but any display we declare above beats it — so without this, a closed dialog would\n * sit in the page at the top left, swallowing clicks.\n *\n * It also covers the two moments where the element exists without being open yet: the\n * frame between rendering it and opening it, and the server-rendered markup. The\n * popovers have the very same guard.\n */\n .v-dialog:not([open]) {\n display: none;\n }\n\n /* Opening a modal puts the focus on the dialog itself. No ring is drawn around the\n whole thing for that: the focus a reader needs to see is the one on the controls\n inside. */\n .v-dialog:focus-visible {\n outline: none;\n }\n\n .v-dialog-scroll {\n /* The ONLY part that scrolls. It takes whatever room is left between the header\n and the footer, which is what keeps the scrollbar confined to it. The zero\n minimum is load-bearing: without it a flex item refuses to shrink below its\n content, and nothing would ever scroll. */\n flex: 1 1 auto;\n min-block-size: 0;\n overflow-y: auto;\n /* A wheel reaching the end of the content stops there rather than scrolling the page\n behind the modal. */\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n /* This makes the box something its descendants can ask questions about — namely\n whether there is content hidden above or below. It adds no containment of size. */\n container-type: scroll-state;\n }\n\n /*\n * The two sentinels: hairlines stuck to the top and the bottom of the scrolling\n * area, and descendants of it, which is what allows them to ask about its scroll\n * state. Their negative margins mean they occupy no space at all. They are\n * transparent until the rules further down reveal them.\n */\n .v-dialog-edge {\n flex: none;\n block-size: 1px;\n position: sticky;\n background: transparent;\n }\n\n .v-dialog-edge--top {\n inset-block-start: 0;\n margin-block-end: -1px;\n }\n\n .v-dialog-edge--bottom {\n inset-block-end: 0;\n margin-block-start: -1px;\n }\n\n .v-dialog-header {\n flex: none; /* stays at the top, outside whatever scrolls */\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-6) var(--vectis-space-6) var(--vectis-space-3);\n }\n\n .v-dialog-titles {\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n }\n\n /* The title and the subtitle are rendered by VTypography, which carries their type.\n Their classes remain as hooks, for a consumer's overrides and for the tests. */\n\n .v-dialog-header-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n /* The cross is a button, so it carries invisible padding of its own; pulling the\n row back by that amount is what makes the glyph line up with the header's edge\n rather than floating inside it. */\n margin-block-start: calc(-1 * var(--vectis-space-1));\n margin-inline-end: calc(-1 * var(--vectis-space-2));\n }\n\n .v-dialog-body {\n /* Short content is stretched to fill the space, so the footer stays at the bottom\n of the dialog rather than floating halfway up; long content keeps its natural\n height, overflows, and is what scrolls. */\n flex: 1 0 auto;\n padding: var(--vectis-space-1) var(--vectis-space-6) var(--vectis-space-3);\n font-size: var(--vectis-text-body-md-size);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-dialog-footer {\n flex: none; /* stays at the bottom, outside whatever scrolls */\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-wrap: wrap;\n gap: var(--vectis-space-3);\n padding: var(--vectis-space-3) var(--vectis-space-6) var(--vectis-space-6);\n }\n\n /*\n * The lines only appear when they mean something. Asking the scrolling area whether\n * it can still be scrolled upwards tells us content is hidden ABOVE, so the line\n * under the header is shown; the same question downwards reveals the one above the\n * footer. In other words each line is drawn exactly when content is passing behind\n * the edge it marks.\n *\n * This kind of query is Chrome 133 and later for now. Where it is missing the\n * sentinels simply stay transparent, which is the intended fallback.\n */\n @container scroll-state(scrollable: top) {\n .v-dialog-edge--top {\n background: var(--vectis-color-border);\n }\n }\n\n @container scroll-state(scrollable: bottom) {\n .v-dialog-edge--bottom {\n background: var(--vectis-color-border);\n }\n }\n\n /*\n * The dialog animates on the way IN and not on the way out. Since it is removed from\n * the page the moment it closes, there is nothing left to animate out — that is the\n * price of the clean slate the lazy rendering buys, and it also spares the extra\n * declarations an exit animation would need.\n *\n * The starting values below are where a freshly rendered dialog begins, before\n * settling into its open state.\n */\n .v-dialog {\n transition:\n opacity var(--vectis-duration-base) var(--vectis-ease-default),\n transform var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open] {\n opacity: 0;\n transform: scale(0.97);\n }\n }\n\n .v-dialog::backdrop {\n background: var(--vectis-color-backdrop);\n transition: opacity var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open]::backdrop {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-dialog,\n .v-dialog::backdrop {\n transition: none;\n }\n }\n\n /* Windows forced colors flattens the dialog's background to Canvas and drops its shadow,\n which were its only edge: it would float over the page with no boundary at all. An\n outline draws one without moving the layout by a pixel. */\n @media (forced-colors: active) {\n .v-dialog {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"VDialog.js","names":[],"sources":["../../../src/components/VDialog/VDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native showModal supplies top-layer placement and modal focus. JavaScript bridges v-model to\n * imperative open/close and provides guarded dismissal where closedBy is absent.\n */\n\nimport { computed, nextTick, onBeforeUnmount, ref, useAttrs, useId, watch } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VTypography from '../VTypography/VTypography.vue'\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\n/** How assistive technology announces the dialog. */\nexport type DialogRole = 'dialog' | 'alertdialog'\n\ninterface DialogProps {\n /**\n * The title of the dialog, which also names it for assistive technology. It is\n * ignored when the `#header` slot replaces the whole header.\n */\n title?: string\n /** A line under the title, explaining what the dialog is asking. */\n subtitle?: string\n /**\n * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left out,\n * it takes the `--vectis-control-size-dialog-width` token, 400px by default.\n */\n width?: number | string\n /**\n * What kind of dialog this is. `alertdialog` is for one that must be answered\n * explicitly, and it makes screen readers announce it more insistently. VDialogAlert is\n * exactly that.\n */\n role?: DialogRole\n /**\n * Takes the close cross out of the header, leaving the reader with Escape, the\n * backdrop and whatever the footer offers.\n */\n hideClose?: boolean\n /** Stops a click outside the dialog from closing it. */\n persistentBackdrop?: boolean\n /**\n * Stops the Escape key from closing the dialog. Note that refusing Escape while the\n * backdrop still closes cannot be expressed natively, so both routes are then\n * allowed.\n */\n persistentEscape?: boolean\n /** What the close cross does, in words. It falls back to the design system dictionary. */\n closeLabel?: string\n}\n\nconst props = withDefaults(defineProps<DialogProps>(), {\n title: undefined,\n subtitle: undefined,\n width: undefined,\n role: 'dialog',\n hideClose: false,\n persistentBackdrop: false,\n persistentEscape: false,\n closeLabel: undefined,\n})\n\nconst m = useMessages()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? m.value.common.close)\n\n/** Whether the dialog is showing. */\nconst open = defineModel<boolean>('open', { default: false })\n\n/** What the trigger has to carry: the click that opens the dialog, and the fact that it does. */\nexport type DialogTriggerProps = {\n onClick: () => void\n 'aria-haspopup': 'dialog'\n}\n\ndefineSlots<{\n /** The body of the dialog. This is the part that scrolls when there is too much of it. */\n default(): unknown\n /** Replaces the title and subtitle block with content of your own. */\n header?(): unknown\n /** Extra controls in the header, placed before the close cross: a menu, a full-screen toggle. */\n 'header-actions'?(): unknown\n /** The buttons at the foot of the dialog. */\n footer?(): unknown\n /**\n * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It stays\n * rendered always, unlike the dialog itself.\n */\n trigger?(props: { triggerProps: DialogTriggerProps }): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst dialogEl = ref<HTMLDialogElement | null>(null)\nconst titleId = useId()\nconst subtitleId = useId()\n\n/**\n * Which dismissals the browser itself accepts, declared as an attribute rather than handled in\n * code: everything, Escape alone, or nothing. One combination cannot be expressed that way; a\n * click outside allowed while Escape is not; and it falls back to allowing both.\n */\nconst closedby = computed(() =>\n props.persistentBackdrop ? (props.persistentEscape ? 'none' : 'closerequest') : 'any',\n)\n\n// @fallback\n// The `closedby` attribute is newer than the type definitions shipped with TypeScript, so\n// writing it directly in the template would be reported as an unknown attribute. Passing it\n// inside a bound object goes through the same path as any forwarded attribute, which is not\n// checked element by element.\nconst rootAttrs = computed(() => ({ ...attrs, closedby: closedby.value }))\n\nfunction show(): Promise<void> {\n open.value = true\n return nextTick()\n}\n\nfunction requestClose() {\n // Closing the element is enough: the browser then fires its own close event, which puts the\n // model back in step below.\n dialogEl.value?.close()\n}\n\nconst triggerProps = computed<DialogTriggerProps>(() => ({\n onClick: show,\n 'aria-haspopup': 'dialog',\n}))\n\n// Close before v-if removes the element so the browser restores the invoker's focus.\nwatch(open, (value) => {\n if (!value) dialogEl.value?.close()\n})\n\n// @ssr\n// Template refs become available after mounting, including when hydrating an open dialog.\nwatch(dialogEl, (dialog) => dialog?.showModal(), { flush: 'post' })\n\n// Ignore close events from replaced elements: the queued event from a quick close-and-reopen\n// must not close the new dialog.\nfunction onClose(event: Event) {\n if (event.target !== dialogEl.value) return\n open.value = false\n}\n\n// @core\n// An open dialog removed with its parent (a `v-if`, a route change) runs no close steps,\n// so no close event would come: the model is handed back closed here, or it stayed `true`\n// and the dialog reopened by itself the next time its parent was shown.\nonBeforeUnmount(() => {\n if (open.value) open.value = false\n})\n\n// @fallback\n/*\n * `closedby` is what applies `persistentBackdrop` and `persistentEscape`, and Safari does not\n * implement it: there Escape always closes and the backdrop never does. The two halves are\n * rebuilt below, and only where the attribute is unknown, so a browser that has it is never\n * second-guessed.\n */\nconst closedbyUnsupported = () => !('closedBy' in HTMLDialogElement.prototype)\n\nfunction onCancel(event: Event) {\n if (closedbyUnsupported() && closedby.value === 'none') event.preventDefault()\n}\n\n/**\n * Whether a point lies outside the dialog's box, which is where the backdrop is: a click on\n * the `::backdrop` is dispatched to the dialog element itself.\n */\nfunction outsideBox(event: MouseEvent) {\n const box = dialogEl.value?.getBoundingClientRect()\n if (!box) return false\n return (\n event.clientX < box.left ||\n event.clientX > box.right ||\n event.clientY < box.top ||\n event.clientY > box.bottom\n )\n}\n\n// A press that STARTED inside and ended on the backdrop (a text selection dragged past the\n// edge) is not a click on the backdrop, so the press is remembered, not only the release.\nlet pressedOnBackdrop = false\nfunction onPointerdown(event: PointerEvent) {\n pressedOnBackdrop = closedbyUnsupported() && event.target === dialogEl.value && outsideBox(event)\n}\nfunction onBackdropClick(event: MouseEvent) {\n const onBackdrop = pressedOnBackdrop && event.target === dialogEl.value && outsideBox(event)\n pressedOnBackdrop = false\n if (onBackdrop && closedbyUnsupported() && closedby.value === 'any') requestClose()\n}\n\ndefineExpose({\n /**\n * Opens the dialog, exactly as setting `open` does. The opening lands on the next tick,\n * once the element has been rendered: `el` is still null right after the call, and the\n * promise returned settles once the dialog is showing.\n */\n show,\n /**\n * Closes the dialog. It closes unconditionally, `persistentEscape` and\n * `persistentBackdrop` governing only the two routes the reader can take.\n */\n close: requestClose,\n /** The `<dialog>` element. It is null while closed: each opening builds a fresh one. */\n el: dialogEl,\n})\n</script>\n\n<template>\n <slot name=\"trigger\" :trigger-props=\"triggerProps\" />\n <dialog\n v-if=\"open\"\n ref=\"dialogEl\"\n :aria-labelledby=\"title ? titleId : undefined\"\n :aria-describedby=\"subtitle ? subtitleId : undefined\"\n v-bind=\"rootAttrs\"\n class=\"v-dialog\"\n :style=\"{ '--dialog-width': cssSize(width) }\"\n :role=\"role === 'alertdialog' ? 'alertdialog' : undefined\"\n @close=\"onClose\"\n @cancel=\"onCancel\"\n @pointerdown=\"onPointerdown\"\n @click=\"onBackdropClick\"\n >\n <!--\n The header and the footer stay put while only the body scrolls, so the scrollbar\n is confined to the body and never runs along them.\n\n The lines that appear under the header and above the footer once the body is\n scrolled are drawn by two sentinels stuck INSIDE the scrolling area, and not by\n the header and footer themselves: a container query can only style what is inside\n the container it asks about, never a sibling of it.\n -->\n <header class=\"v-dialog-header\">\n <slot name=\"header\">\n <div class=\"v-dialog-titles\">\n <VTypography\n v-if=\"title\"\n :id=\"titleId\"\n as=\"h2\"\n variant=\"heading-3\"\n class=\"v-dialog-title\"\n >\n {{ title }}\n </VTypography>\n <VTypography\n v-if=\"subtitle\"\n :id=\"subtitleId\"\n variant=\"subtitle\"\n tone=\"muted\"\n class=\"v-dialog-subtitle\"\n >\n {{ subtitle }}\n </VTypography>\n </div>\n </slot>\n <div v-if=\"!hideClose || $slots['header-actions']\" class=\"v-dialog-header-actions\">\n <slot name=\"header-actions\" />\n <VIconButton\n v-if=\"!hideClose\"\n class=\"v-dialog-close\"\n :label=\"resolvedCloseLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n @click=\"requestClose\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n </header>\n <div class=\"v-dialog-scroll\">\n <span class=\"v-dialog-edge v-dialog-edge--top\" aria-hidden=\"true\" />\n <div class=\"v-dialog-body\">\n <slot />\n </div>\n <span class=\"v-dialog-edge v-dialog-edge--bottom\" aria-hidden=\"true\" />\n </div>\n <footer v-if=\"$slots.footer\" class=\"v-dialog-footer\">\n <slot name=\"footer\" />\n </footer>\n </dialog>\n</template>\n\n<style>\n@layer vectis.components {\n .v-dialog {\n /*\n * The token is declared on the element rather than written as a `var()` fallback. A custom\n * property inherits, and a dialog opened from inside another one is its DOM descendant:\n * with a fallback, an alert confirming something in an 800px dialog would read that\n * dialog's inline width and open 800px wide itself, with no error anywhere.\n */\n --dialog-width: var(--vectis-control-size-dialog-width);\n inline-size: var(--dialog-width);\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n max-block-size: calc(100dvb - 2 * var(--vectis-space-4));\n /*\n * Restore the modal's automatic margins in the component layer because the reset removes\n * native dialog centring.\n */\n margin: auto;\n /* The header and footer stay put while only the body scrolls, and hiding the\n overflow is what keeps the content inside the rounded corners. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 0;\n border: none;\n border-radius: var(--vectis-radius-overlay);\n background: var(--vectis-color-surface-overlay);\n color: var(--vectis-color-text);\n box-shadow: var(--vectis-shadow-xl);\n font-family: var(--vectis-text-family);\n }\n\n /*\n * An indispensable guard. The browser hides a closed dialog with a rule of its own, but any\n * display we declare above beats it; so without this, a closed dialog would sit in the page\n * at the top left, swallowing clicks.\n */\n .v-dialog:not([open]) {\n display: none;\n }\n\n /* Opening a modal puts the focus on the dialog itself. No ring is drawn around the\n whole thing for that: the focus a reader needs to see is the one on the controls\n inside. */\n .v-dialog:focus-visible {\n outline: none;\n }\n\n .v-dialog-scroll {\n /*\n * The zero minimum is load-bearing: without it a flex item refuses to shrink below its\n * content, and nothing would ever scroll.\n */\n flex: 1 1 auto;\n min-block-size: 0;\n overflow-y: auto;\n /* A wheel reaching the end of the content stops there rather than scrolling the page\n behind the modal. */\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n /*\n * This makes the box something its descendants can ask questions about; namely whether\n * there is content hidden above or below. It adds no containment of size.\n */\n container-type: scroll-state;\n }\n\n /*\n * The two sentinels: hairlines stuck to the top and the bottom of the scrolling area, and\n * descendants of it, which allows them to ask about its scroll state. Their negative margins\n * mean they occupy no space at all.\n */\n .v-dialog-edge {\n flex: none;\n block-size: 1px;\n position: sticky;\n background: transparent;\n }\n\n .v-dialog-edge--top {\n inset-block-start: 0;\n margin-block-end: -1px;\n }\n\n .v-dialog-edge--bottom {\n inset-block-end: 0;\n margin-block-start: -1px;\n }\n\n .v-dialog-header {\n flex: none;\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-6) var(--vectis-space-6) var(--vectis-space-3);\n }\n\n .v-dialog-titles {\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n }\n\n /* The title and the subtitle are rendered by VTypography, which carries their type.\n Their classes remain as hooks, for a consumer's overrides and for the tests. */\n\n .v-dialog-header-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n /* The cross is a button, so it carries invisible padding of its own; pulling the\n row back by that amount is what makes the glyph line up with the header's edge\n rather than floating inside it. */\n margin-block-start: calc(-1 * var(--vectis-space-1));\n margin-inline-end: calc(-1 * var(--vectis-space-2));\n }\n\n .v-dialog-body {\n /* Short content is stretched to fill the space, so the footer stays at the bottom\n of the dialog rather than floating halfway up; long content keeps its natural\n height, overflows, and is what scrolls. */\n flex: 1 0 auto;\n padding: var(--vectis-space-1) var(--vectis-space-6) var(--vectis-space-3);\n font-size: var(--vectis-text-body-md-size);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-dialog-footer {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-wrap: wrap;\n gap: var(--vectis-space-3);\n padding: var(--vectis-space-3) var(--vectis-space-6) var(--vectis-space-6);\n }\n\n /* Where it is missing the sentinels simply stay transparent, which is the intended fallback. */\n @container scroll-state(scrollable: top) {\n .v-dialog-edge--top {\n background: var(--vectis-color-border);\n }\n }\n\n @container scroll-state(scrollable: bottom) {\n .v-dialog-edge--bottom {\n background: var(--vectis-color-border);\n }\n }\n\n /*\n * The dialog animates on the way in and not on the way out. Since it is removed from the page\n * the moment it closes, there is nothing left to animate out; that is the price of the clean\n * slate the lazy rendering buys, and it also spares the extra declarations an exit animation\n * would need.\n */\n .v-dialog {\n transition:\n opacity var(--vectis-duration-base) var(--vectis-ease-default),\n transform var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open] {\n opacity: 0;\n transform: scale(0.97);\n }\n }\n\n .v-dialog::backdrop {\n background: var(--vectis-color-backdrop);\n transition: opacity var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open]::backdrop {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-dialog,\n .v-dialog::backdrop {\n transition: none;\n }\n }\n\n /* An outline draws one without moving the layout by a pixel. */\n @media (forced-colors: active) {\n .v-dialog {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -4,19 +4,19 @@ import n from "../VIcon/VIcon.js";
4
4
  import r from "../VTypography/VTypography.js";
5
5
  import i from "../VIconButton/VIconButton.js";
6
6
  import { close as a } from "../VIcon/icons/close.js";
7
- import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, createVNode as p, defineComponent as m, mergeModels as h, mergeProps as g, nextTick as _, onBeforeUnmount as v, onMounted as ee, openBlock as y, ref as b, renderSlot as x, toDisplayString as S, unref as C, useAttrs as w, useId as T, useModel as E, watch as D, withCtx as O } from "vue";
7
+ import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, createVNode as p, defineComponent as m, mergeModels as h, mergeProps as g, nextTick as _, onBeforeUnmount as v, openBlock as y, ref as b, renderSlot as x, toDisplayString as S, unref as C, useAttrs as w, useId as T, useModel as E, watch as D, withCtx as O } from "vue";
8
8
  //#region src/components/VDialog/VDialog.vue?vue&type=script&setup=true&lang.ts
9
9
  var k = [
10
10
  "aria-labelledby",
11
11
  "aria-describedby",
12
12
  "role"
13
- ], te = { class: "v-dialog-header" }, A = { class: "v-dialog-titles" }, j = {
13
+ ], A = { class: "v-dialog-header" }, j = { class: "v-dialog-titles" }, M = {
14
14
  key: 0,
15
15
  class: "v-dialog-header-actions"
16
- }, M = { class: "v-dialog-scroll" }, N = { class: "v-dialog-body" }, P = {
16
+ }, N = { class: "v-dialog-scroll" }, P = { class: "v-dialog-body" }, F = {
17
17
  key: 0,
18
18
  class: "v-dialog-footer"
19
- }, F = /*@__PURE__*/ m({
19
+ }, I = /*@__PURE__*/ m({
20
20
  inheritAttrs: !1,
21
21
  __name: "VDialog",
22
22
  props: /*@__PURE__*/ h({
@@ -46,69 +46,67 @@ var k = [
46
46
  }),
47
47
  emits: ["update:open"],
48
48
  setup(m, { expose: h }) {
49
- let F = m, I = e(), L = s(() => F.closeLabel ?? I.value.common.close), R = E(m, "open"), z = w(), B = b(null), V = T(), H = T(), U = s(() => F.persistentBackdrop ? F.persistentEscape ? "none" : "closerequest" : "any"), W = s(() => ({
50
- ...z,
51
- closedby: U.value
52
- })), G = b(R.value), K = Promise.resolve();
53
- function q() {
54
- return R.value = !0, _(() => K);
49
+ let I = m, L = e(), R = s(() => I.closeLabel ?? L.value.common.close), z = E(m, "open"), B = w(), V = b(null), H = T(), U = T(), W = s(() => I.persistentBackdrop ? I.persistentEscape ? "none" : "closerequest" : "any"), G = s(() => ({
50
+ ...B,
51
+ closedby: W.value
52
+ }));
53
+ function K() {
54
+ return z.value = !0, _();
55
55
  }
56
- function J() {
57
- B.value?.close();
56
+ function q() {
57
+ V.value?.close();
58
58
  }
59
- let Y = s(() => ({
60
- onClick: q,
59
+ let J = s(() => ({
60
+ onClick: K,
61
61
  "aria-haspopup": "dialog"
62
62
  }));
63
- D(R, (e) => {
64
- e ? (G.value = !0, K = _(() => B.value?.showModal())) : (B.value?.close(), G.value = !1);
65
- }), ee(() => {
66
- R.value && B.value?.showModal();
67
- });
68
- function X(e) {
69
- e.target === B.value && (R.value = !1);
63
+ D(z, (e) => {
64
+ e || V.value?.close();
65
+ }), D(V, (e) => e?.showModal(), { flush: "post" });
66
+ function Y(e) {
67
+ e.target === V.value && (z.value = !1);
70
68
  }
71
69
  v(() => {
72
- R.value &&= !1;
70
+ z.value &&= !1;
73
71
  });
74
- let Z = () => !("closedBy" in HTMLDialogElement.prototype);
75
- function ne(e) {
76
- Z() && U.value === "none" && e.preventDefault();
72
+ let X = () => !("closedBy" in HTMLDialogElement.prototype);
73
+ function Z(e) {
74
+ X() && W.value === "none" && e.preventDefault();
77
75
  }
78
76
  function Q(e) {
79
- let t = B.value?.getBoundingClientRect();
77
+ let t = V.value?.getBoundingClientRect();
80
78
  return t ? e.clientX < t.left || e.clientX > t.right || e.clientY < t.top || e.clientY > t.bottom : !1;
81
79
  }
82
80
  let $ = !1;
83
- function re(e) {
84
- $ = e.target === B.value && Q(e);
81
+ function ee(e) {
82
+ $ = X() && e.target === V.value && Q(e);
85
83
  }
86
- function ie(e) {
87
- let t = $ && e.target === B.value && Q(e);
88
- $ = !1, t && Z() && U.value === "any" && J();
84
+ function te(e) {
85
+ let t = $ && e.target === V.value && Q(e);
86
+ $ = !1, t && X() && W.value === "any" && q();
89
87
  }
90
88
  return h({
91
- show: q,
92
- close: J,
93
- el: B
94
- }), (e, s) => (y(), u(o, null, [x(e.$slots, "trigger", { triggerProps: Y.value }), G.value ? (y(), u("dialog", g({
89
+ show: K,
90
+ close: q,
91
+ el: V
92
+ }), (e, s) => (y(), u(o, null, [x(e.$slots, "trigger", { triggerProps: J.value }), z.value ? (y(), u("dialog", g({
95
93
  key: 0,
96
94
  ref_key: "dialogEl",
97
- ref: B,
98
- "aria-labelledby": m.title ? C(V) : void 0,
99
- "aria-describedby": m.subtitle ? C(H) : void 0
100
- }, W.value, {
95
+ ref: V,
96
+ "aria-labelledby": m.title ? C(H) : void 0,
97
+ "aria-describedby": m.subtitle ? C(U) : void 0
98
+ }, G.value, {
101
99
  class: "v-dialog",
102
100
  style: { "--dialog-width": C(t)(m.width) },
103
101
  role: m.role === "alertdialog" ? "alertdialog" : void 0,
104
- onClose: X,
105
- onCancel: ne,
106
- onPointerdown: re,
107
- onClick: ie
102
+ onClose: Y,
103
+ onCancel: Z,
104
+ onPointerdown: ee,
105
+ onClick: te
108
106
  }), [
109
- d("header", te, [x(e.$slots, "header", {}, () => [d("div", A, [m.title ? (y(), c(r, {
107
+ d("header", A, [x(e.$slots, "header", {}, () => [d("div", j, [m.title ? (y(), c(r, {
110
108
  key: 0,
111
- id: C(V),
109
+ id: C(H),
112
110
  as: "h2",
113
111
  variant: "heading-3",
114
112
  class: "v-dialog-title"
@@ -117,41 +115,41 @@ var k = [
117
115
  _: 1
118
116
  }, 8, ["id"])) : l("", !0), m.subtitle ? (y(), c(r, {
119
117
  key: 1,
120
- id: C(H),
118
+ id: C(U),
121
119
  variant: "subtitle",
122
120
  tone: "muted",
123
121
  class: "v-dialog-subtitle"
124
122
  }, {
125
123
  default: O(() => [f(S(m.subtitle), 1)]),
126
124
  _: 1
127
- }, 8, ["id"])) : l("", !0)])]), !m.hideClose || e.$slots["header-actions"] ? (y(), u("div", j, [x(e.$slots, "header-actions"), m.hideClose ? l("", !0) : (y(), c(i, {
125
+ }, 8, ["id"])) : l("", !0)])]), !m.hideClose || e.$slots["header-actions"] ? (y(), u("div", M, [x(e.$slots, "header-actions"), m.hideClose ? l("", !0) : (y(), c(i, {
128
126
  key: 0,
129
127
  class: "v-dialog-close",
130
- label: L.value,
128
+ label: R.value,
131
129
  variant: "ghost",
132
130
  tone: "neutral",
133
131
  size: "sm",
134
- onClick: J
132
+ onClick: q
135
133
  }, {
136
134
  default: O(() => [p(n, { name: C(a) }, null, 8, ["name"])]),
137
135
  _: 1
138
136
  }, 8, ["label"]))])) : l("", !0)]),
139
- d("div", M, [
137
+ d("div", N, [
140
138
  s[0] ||= d("span", {
141
139
  class: "v-dialog-edge v-dialog-edge--top",
142
140
  "aria-hidden": "true"
143
141
  }, null, -1),
144
- d("div", N, [x(e.$slots, "default")]),
142
+ d("div", P, [x(e.$slots, "default")]),
145
143
  s[1] ||= d("span", {
146
144
  class: "v-dialog-edge v-dialog-edge--bottom",
147
145
  "aria-hidden": "true"
148
146
  }, null, -1)
149
147
  ]),
150
- e.$slots.footer ? (y(), u("footer", P, [x(e.$slots, "footer")])) : l("", !0)
148
+ e.$slots.footer ? (y(), u("footer", F, [x(e.$slots, "footer")])) : l("", !0)
151
149
  ], 16, k)) : l("", !0)], 64));
152
150
  }
153
151
  });
154
152
  //#endregion
155
- export { F as default };
153
+ export { I as default };
156
154
 
157
155
  //# sourceMappingURL=VDialog.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VDialog.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VDialog/VDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * A modal dialog: it takes over the page until the reader answers it.\n *\n * Almost everything that makes a modal correct comes free with the native `<dialog>`\n * element opened as a modal — it is drawn above the whole page, the background is\n * dimmed and made unusable, the focus is trapped inside it and handed back to the\n * trigger on closing, and whether a click outside or Escape dismisses it is declared\n * with an attribute rather than coded.\n *\n * The ONLY behavioural JavaScript is the bridge between `v-model:open` and the two\n * methods the platform offers no declarative equivalent for: opening as a modal, and\n * closing.\n */\n\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, useAttrs, useId, watch } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VTypography from '../VTypography/VTypography.vue'\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\n/** How assistive technology announces the dialog. */\nexport type DialogRole = 'dialog' | 'alertdialog'\n\ninterface DialogProps {\n /**\n * The title of the dialog, which also names it for assistive technology. It is\n * ignored when the `#header` slot replaces the whole header.\n */\n title?: string\n /** A line under the title, explaining what the dialog is asking. */\n subtitle?: string\n /**\n * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left\n * out, it takes the `--vectis-control-size-dialog-width` token, 400px by default. It is\n * never allowed to exceed the width of the viewport.\n */\n width?: number | string\n /**\n * What kind of dialog this is. `alertdialog` is for one that must be answered\n * explicitly, and it makes screen readers announce it more insistently. VDialogAlert is\n * exactly that.\n */\n role?: DialogRole\n /**\n * Takes the close cross out of the header, leaving the reader with Escape, the\n * backdrop and whatever the footer offers.\n */\n hideClose?: boolean\n /** Stops a click outside the dialog from closing it. */\n persistentBackdrop?: boolean\n /**\n * Stops the Escape key from closing the dialog. Note that refusing Escape while the\n * backdrop still closes cannot be expressed natively, so both routes are then\n * allowed.\n */\n persistentEscape?: boolean\n /** What the close cross does, in words. It falls back to the design system dictionary. */\n closeLabel?: string\n}\n\nconst props = withDefaults(defineProps<DialogProps>(), {\n title: undefined,\n subtitle: undefined,\n width: undefined,\n role: 'dialog',\n hideClose: false,\n persistentBackdrop: false,\n persistentEscape: false,\n closeLabel: undefined,\n})\n\nconst m = useMessages()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? m.value.common.close)\n\n/**\n * Whether the dialog is showing. It starts closed, and it is BIDIRECTIONAL: the browser\n * writes back to it whenever the dialog closes on its own, through Escape or the backdrop,\n * so a consumer never has to reset it by hand.\n */\nconst open = defineModel<boolean>('open', { default: false })\n\n/** What the trigger has to carry: the click that opens the dialog, and the fact that it does. */\nexport type DialogTriggerProps = {\n onClick: () => void\n 'aria-haspopup': 'dialog'\n}\n\ndefineSlots<{\n /** The body of the dialog. This is the part that scrolls when there is too much of it. */\n default(): unknown\n /** Replaces the title and subtitle block with content of your own. */\n header?(): unknown\n /** Extra controls in the header, placed before the close cross: a menu, a full-screen toggle. */\n 'header-actions'?(): unknown\n /** The buttons at the foot of the dialog. */\n footer?(): unknown\n /**\n * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It\n * stays rendered at all times, unlike the dialog itself.\n */\n trigger?(props: { triggerProps: DialogTriggerProps }): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst dialogEl = ref<HTMLDialogElement | null>(null)\nconst titleId = useId()\nconst subtitleId = useId()\n\n/**\n * Which dismissals the browser itself accepts, declared as an attribute rather than\n * handled in code: everything, Escape alone, or nothing.\n *\n * One combination cannot be expressed that way — a click outside allowed while Escape\n * is not — and it falls back to allowing both. Nothing in the design system asks for\n * it, and it would be a strange thing to want.\n */\nconst closedby = computed(() =>\n props.persistentBackdrop ? (props.persistentEscape ? 'none' : 'closerequest') : 'any',\n)\n\n// @fallback\n// The `closedby` attribute is newer than the type definitions shipped with\n// TypeScript, so writing it directly in the template would be reported as an unknown\n// attribute. Passing it inside a bound object goes through the same path as any\n// forwarded attribute, which is not checked element by element. Vue still merges the\n// `class` and `style` it may contain with the static ones below.\nconst rootAttrs = computed(() => ({ ...attrs, closedby: closedby.value }))\n\n// The dialog and its content only exist while it is open, which also spares the page\n// whatever heavy thing it contains. Every opening therefore builds a BRAND NEW\n// element, so it is always opened as a modal from a clean slate, and closing removes\n// it entirely — nothing is left behind to swallow clicks, and reopening cannot race\n// with a closing that is still finishing. The trigger, by contrast, stays rendered at\n// all times.\nconst rendered = ref(open.value)\n\n/**\n * Settles once the dialog opened by the latest change of `open` is actually showing. The\n * opening waits for the element to be rendered, so it is always a tick behind the model.\n */\nlet opening: Promise<void> = Promise.resolve()\n\nfunction show(): Promise<void> {\n open.value = true\n // The watcher below only runs when the scheduler flushes, so `opening` is read from a\n // tick later: read at once, it would still be the promise of the previous opening.\n return nextTick(() => opening)\n}\n\nfunction requestClose() {\n // Closing the element is enough: the browser then fires its own close event, which\n // is what puts the model back in step below.\n dialogEl.value?.close()\n}\n\nconst triggerProps = computed<DialogTriggerProps>(() => ({\n onClick: show,\n 'aria-haspopup': 'dialog',\n}))\n\n// The `<dialog>` element is asymmetric in a way that shapes this whole bridge: it\n// announces every closing with an event, but announces nothing at all when it opens —\n// where a popover reports both. So the two directions are not written the same way:\n//\n// - opening: render the element, then, once Vue has actually put it in the document,\n// open it as a modal;\n// - closing: whatever closed it — the cross, our own call, Escape, a click outside —\n// the browser's close event is what puts the model back in step, and only then is\n// the element removed.\nwatch(open, (value) => {\n if (value) {\n rendered.value = true\n // the brand new <dialog> has to exist before it can be opened\n opening = nextTick(() => dialogEl.value?.showModal())\n } else {\n dialogEl.value?.close()\n rendered.value = false\n }\n})\n\n// @ssr\nonMounted(() => {\n // A watcher does not run during the server render, so a dialog asked to be open from\n // the start would never be opened. The element is already there — the flag above was\n // initialized from the model — it just has to be told to show itself.\n if (open.value) dialogEl.value?.showModal()\n})\n\n// The browser's own close event, whatever caused it, is what brings the model back in\n// step with reality.\n//\n// TRAP — only the element on screen may do it. A close event is queued as a TASK, so the\n// one fired by the element a quick close-and-reopen has just replaced arrives after the new\n// element exists, and without the check it closed the dialog that had just opened.\nfunction onClose(event: Event) {\n if (event.target !== dialogEl.value) return\n open.value = false\n}\n\n// @core\n// An open dialog removed with its parent (a `v-if`, a route change) runs no close steps,\n// so no close event would come: the model is handed back closed here, or it stayed `true`\n// and the dialog reopened by itself the next time its parent was shown.\nonBeforeUnmount(() => {\n if (open.value) open.value = false\n})\n\n// @fallback\n/*\n * `closedby` is what applies `persistentBackdrop` and `persistentEscape`, and Safari does\n * not implement it: there Escape always closes and the backdrop never does. The two halves\n * are rebuilt below, and ONLY where the attribute is unknown, so a browser that has it is\n * never second-guessed. The support is asked at event time: there is no DOM during setup.\n */\nconst closedbyUnsupported = () => !('closedBy' in HTMLDialogElement.prototype)\n\nfunction onCancel(event: Event) {\n if (closedbyUnsupported() && closedby.value === 'none') event.preventDefault()\n}\n\n/**\n * Whether a point lies outside the dialog's box, which is where the backdrop is: a click on\n * the `::backdrop` is dispatched to the dialog element itself.\n */\nfunction outsideBox(event: MouseEvent) {\n const box = dialogEl.value?.getBoundingClientRect()\n if (!box) return false\n return (\n event.clientX < box.left ||\n event.clientX > box.right ||\n event.clientY < box.top ||\n event.clientY > box.bottom\n )\n}\n\n// A press that STARTED inside and ended on the backdrop (a text selection dragged past the\n// edge) is not a click on the backdrop, so the press is remembered, not only the release.\nlet pressedOnBackdrop = false\nfunction onPointerdown(event: PointerEvent) {\n pressedOnBackdrop = event.target === dialogEl.value && outsideBox(event)\n}\nfunction onBackdropClick(event: MouseEvent) {\n const onBackdrop = pressedOnBackdrop && event.target === dialogEl.value && outsideBox(event)\n pressedOnBackdrop = false\n if (onBackdrop && closedbyUnsupported() && closedby.value === 'any') requestClose()\n}\n\ndefineExpose({\n /**\n * Opens the dialog, exactly as setting `open` does. The opening lands on the next tick,\n * once the element has been rendered: `el` is still null right after the call, and the\n * promise returned settles once the dialog is showing.\n */\n show,\n /**\n * Closes the dialog. It closes unconditionally, `persistentEscape` and\n * `persistentBackdrop` governing only the two routes the reader can take.\n */\n close: requestClose,\n /** The `<dialog>` element. It is null while closed: each opening builds a fresh one. */\n el: dialogEl,\n})\n</script>\n\n<template>\n <slot name=\"trigger\" :trigger-props=\"triggerProps\" />\n <dialog\n v-if=\"rendered\"\n ref=\"dialogEl\"\n :aria-labelledby=\"title ? titleId : undefined\"\n :aria-describedby=\"subtitle ? subtitleId : undefined\"\n v-bind=\"rootAttrs\"\n class=\"v-dialog\"\n :style=\"{ '--dialog-width': cssSize(width) }\"\n :role=\"role === 'alertdialog' ? 'alertdialog' : undefined\"\n @close=\"onClose\"\n @cancel=\"onCancel\"\n @pointerdown=\"onPointerdown\"\n @click=\"onBackdropClick\"\n >\n <!--\n The header and the footer stay put while only the body scrolls, so the scrollbar\n is confined to the body and never runs along them.\n\n The lines that appear under the header and above the footer once the body is\n scrolled are drawn by two sentinels stuck INSIDE the scrolling area, and not by\n the header and footer themselves: a container query can only style what is inside\n the container it asks about, never a sibling of it.\n -->\n <header class=\"v-dialog-header\">\n <slot name=\"header\">\n <div class=\"v-dialog-titles\">\n <VTypography\n v-if=\"title\"\n :id=\"titleId\"\n as=\"h2\"\n variant=\"heading-3\"\n class=\"v-dialog-title\"\n >\n {{ title }}\n </VTypography>\n <VTypography\n v-if=\"subtitle\"\n :id=\"subtitleId\"\n variant=\"subtitle\"\n tone=\"muted\"\n class=\"v-dialog-subtitle\"\n >\n {{ subtitle }}\n </VTypography>\n </div>\n </slot>\n <div v-if=\"!hideClose || $slots['header-actions']\" class=\"v-dialog-header-actions\">\n <slot name=\"header-actions\" />\n <VIconButton\n v-if=\"!hideClose\"\n class=\"v-dialog-close\"\n :label=\"resolvedCloseLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n @click=\"requestClose\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n </header>\n <div class=\"v-dialog-scroll\">\n <span class=\"v-dialog-edge v-dialog-edge--top\" aria-hidden=\"true\" />\n <div class=\"v-dialog-body\">\n <slot />\n </div>\n <span class=\"v-dialog-edge v-dialog-edge--bottom\" aria-hidden=\"true\" />\n </div>\n <footer v-if=\"$slots.footer\" class=\"v-dialog-footer\">\n <slot name=\"footer\" />\n </footer>\n </dialog>\n</template>\n\n<style>\n@layer vectis.components {\n .v-dialog {\n /* The width comes from the prop, set inline, or from the token when there is none.\n Whatever it asks for, the dialog is never allowed past the viewport, margins included.\n\n TRAP — the token is declared ON the element rather than written as a `var()` fallback.\n A custom property inherits, and a dialog opened from inside another one is its DOM\n descendant: with a fallback, an alert confirming something in an 800px dialog would\n read that dialog's inline width and open 800px wide itself, with no error anywhere. */\n --dialog-width: var(--vectis-control-size-dialog-width);\n inline-size: var(--dialog-width);\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n max-block-size: calc(100dvb - 2 * var(--vectis-space-4));\n /* This puts the dialog back in the middle of the screen. The browser centres a\n modal with an automatic margin, which the design system's own reset — where\n every element loses its margins — had removed; restoring it here works because\n the component layer is stronger than the reset one. */\n margin: auto;\n /* The header and footer stay put while only the body scrolls, and hiding the\n overflow is what keeps the content inside the rounded corners. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 0;\n border: none;\n border-radius: var(--vectis-radius-overlay);\n background: var(--vectis-color-surface-overlay);\n color: var(--vectis-color-text);\n box-shadow: var(--vectis-shadow-xl);\n font-family: var(--vectis-text-family);\n }\n\n /*\n * An indispensable guard. The browser hides a closed dialog with a rule of its own,\n * but any display we declare above beats it — so without this, a closed dialog would\n * sit in the page at the top left, swallowing clicks.\n *\n * It also covers the two moments where the element exists without being open yet: the\n * frame between rendering it and opening it, and the server-rendered markup. The\n * popovers have the very same guard.\n */\n .v-dialog:not([open]) {\n display: none;\n }\n\n /* Opening a modal puts the focus on the dialog itself. No ring is drawn around the\n whole thing for that: the focus a reader needs to see is the one on the controls\n inside. */\n .v-dialog:focus-visible {\n outline: none;\n }\n\n .v-dialog-scroll {\n /* The ONLY part that scrolls. It takes whatever room is left between the header\n and the footer, which is what keeps the scrollbar confined to it. The zero\n minimum is load-bearing: without it a flex item refuses to shrink below its\n content, and nothing would ever scroll. */\n flex: 1 1 auto;\n min-block-size: 0;\n overflow-y: auto;\n /* A wheel reaching the end of the content stops there rather than scrolling the page\n behind the modal. */\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n /* This makes the box something its descendants can ask questions about — namely\n whether there is content hidden above or below. It adds no containment of size. */\n container-type: scroll-state;\n }\n\n /*\n * The two sentinels: hairlines stuck to the top and the bottom of the scrolling\n * area, and descendants of it, which is what allows them to ask about its scroll\n * state. Their negative margins mean they occupy no space at all. They are\n * transparent until the rules further down reveal them.\n */\n .v-dialog-edge {\n flex: none;\n block-size: 1px;\n position: sticky;\n background: transparent;\n }\n\n .v-dialog-edge--top {\n inset-block-start: 0;\n margin-block-end: -1px;\n }\n\n .v-dialog-edge--bottom {\n inset-block-end: 0;\n margin-block-start: -1px;\n }\n\n .v-dialog-header {\n flex: none; /* stays at the top, outside whatever scrolls */\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-6) var(--vectis-space-6) var(--vectis-space-3);\n }\n\n .v-dialog-titles {\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n }\n\n /* The title and the subtitle are rendered by VTypography, which carries their type.\n Their classes remain as hooks, for a consumer's overrides and for the tests. */\n\n .v-dialog-header-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n /* The cross is a button, so it carries invisible padding of its own; pulling the\n row back by that amount is what makes the glyph line up with the header's edge\n rather than floating inside it. */\n margin-block-start: calc(-1 * var(--vectis-space-1));\n margin-inline-end: calc(-1 * var(--vectis-space-2));\n }\n\n .v-dialog-body {\n /* Short content is stretched to fill the space, so the footer stays at the bottom\n of the dialog rather than floating halfway up; long content keeps its natural\n height, overflows, and is what scrolls. */\n flex: 1 0 auto;\n padding: var(--vectis-space-1) var(--vectis-space-6) var(--vectis-space-3);\n font-size: var(--vectis-text-body-md-size);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-dialog-footer {\n flex: none; /* stays at the bottom, outside whatever scrolls */\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-wrap: wrap;\n gap: var(--vectis-space-3);\n padding: var(--vectis-space-3) var(--vectis-space-6) var(--vectis-space-6);\n }\n\n /*\n * The lines only appear when they mean something. Asking the scrolling area whether\n * it can still be scrolled upwards tells us content is hidden ABOVE, so the line\n * under the header is shown; the same question downwards reveals the one above the\n * footer. In other words each line is drawn exactly when content is passing behind\n * the edge it marks.\n *\n * This kind of query is Chrome 133 and later for now. Where it is missing the\n * sentinels simply stay transparent, which is the intended fallback.\n */\n @container scroll-state(scrollable: top) {\n .v-dialog-edge--top {\n background: var(--vectis-color-border);\n }\n }\n\n @container scroll-state(scrollable: bottom) {\n .v-dialog-edge--bottom {\n background: var(--vectis-color-border);\n }\n }\n\n /*\n * The dialog animates on the way IN and not on the way out. Since it is removed from\n * the page the moment it closes, there is nothing left to animate out — that is the\n * price of the clean slate the lazy rendering buys, and it also spares the extra\n * declarations an exit animation would need.\n *\n * The starting values below are where a freshly rendered dialog begins, before\n * settling into its open state.\n */\n .v-dialog {\n transition:\n opacity var(--vectis-duration-base) var(--vectis-ease-default),\n transform var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open] {\n opacity: 0;\n transform: scale(0.97);\n }\n }\n\n .v-dialog::backdrop {\n background: var(--vectis-color-backdrop);\n transition: opacity var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open]::backdrop {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-dialog,\n .v-dialog::backdrop {\n transition: none;\n }\n }\n\n /* Windows forced colors flattens the dialog's background to Canvas and drops its shadow,\n which were its only edge: it would float over the page with no boundary at all. An\n outline draws one without moving the layout by a pixel. */\n @media (forced-colors: active) {\n .v-dialog {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEA,IAAM,IAAQ,GAWR,IAAI,EAAY,GAChB,IAAqB,QAAe,EAAM,cAAc,EAAE,MAAM,OAAO,KAAK,GAO5E,IAAO,EAAoB,GAAC,MAA0B,GA0BtD,IAAQ,EAAS,GACjB,IAAW,EAA8B,IAAI,GAC7C,IAAU,EAAM,GAChB,IAAa,EAAM,GAUnB,IAAW,QACf,EAAM,qBAAsB,EAAM,mBAAmB,SAAS,iBAAkB,KAClF,GAQM,IAAY,SAAgB;GAAE,GAAG;GAAO,UAAU,EAAS;EAAM,EAAE,GAQnE,IAAW,EAAI,EAAK,KAAK,GAM3B,IAAyB,QAAQ,QAAQ;EAE7C,SAAS,IAAsB;GAI7B,OAHA,EAAK,QAAQ,IAGN,QAAe,CAAO;EAC/B;EAEA,SAAS,IAAe;GAGtB,EAAS,OAAO,MAAM;EACxB;EAEA,IAAM,IAAe,SAAoC;GACvD,SAAS;GACT,iBAAiB;EACnB,EAAE;EAuBF,AAZA,EAAM,IAAO,MAAU;GACrB,AAAI,KACF,EAAS,QAAQ,IAEjB,IAAU,QAAe,EAAS,OAAO,UAAU,CAAC,MAEpD,EAAS,OAAO,MAAM,GACtB,EAAS,QAAQ;EAErB,CAAC,GAGD,SAAgB;GAId,AAAI,EAAK,SAAO,EAAS,OAAO,UAAU;EAC5C,CAAC;EAQD,SAAS,EAAQ,GAAc;GACzB,EAAM,WAAW,EAAS,UAC9B,EAAK,QAAQ;EACf;EAMA,QAAsB;GACpB,AAAgB,EAAK,UAAQ;EAC/B,CAAC;EASD,IAAM,UAA4B,EAAE,cAAc,kBAAkB;EAEpE,SAAS,GAAS,GAAc;GAC9B,AAAI,EAAoB,KAAK,EAAS,UAAU,UAAQ,EAAM,eAAe;EAC/E;EAMA,SAAS,EAAW,GAAmB;GACrC,IAAM,IAAM,EAAS,OAAO,sBAAsB;GAElD,OADK,IAEH,EAAM,UAAU,EAAI,QACpB,EAAM,UAAU,EAAI,SACpB,EAAM,UAAU,EAAI,OACpB,EAAM,UAAU,EAAI,SALL;EAOnB;EAIA,IAAI,IAAoB;EACxB,SAAS,GAAc,GAAqB;GAC1C,IAAoB,EAAM,WAAW,EAAS,SAAS,EAAW,CAAK;EACzE;EACA,SAAS,GAAgB,GAAmB;GAC1C,IAAM,IAAa,KAAqB,EAAM,WAAW,EAAS,SAAS,EAAW,CAAK;GAE3F,AADA,IAAoB,IAChB,KAAc,EAAoB,KAAK,EAAS,UAAU,SAAO,EAAa;EACpF;SAEA,EAAa;GAMX;GAKA,OAAO;GAEP,IAAI;EACN,CAAC,+BAIC,EAAqD,EAAA,QAAA,WAAA,EAA/B,cAAe,EAAA,MAAY,CAAA,GAEzC,EAAA,SAAA,EAAA,GADR,EAuES,UAvET,EAuES;;YArEH;GAAJ,KAAI;GACH,mBAAiB,EAAA,QAAQ,EAAA,CAAA,IAAU,KAAA;GACnC,oBAAkB,EAAA,WAAW,EAAA,CAAA,IAAa,KAAA;KACnC,EAAA,OAAS;GACjB,OAAM;GACL,OAAK,EAAA,kBAAsB,EAAA,CAAA,CAAO,CAAC,EAAA,KAAK,EAAA;GACxC,MAAM,EAAA,SAAI,gBAAA,gBAAqC,KAAA;GACxC;GACC;GACK;GACb,SAAO;;GAWR,EAqCS,UArCT,IAqCS,CApCP,EAqBO,EAAA,QAAA,UAAA,CAAA,SAAA,CApBL,EAmBM,OAnBN,GAmBM,CAjBI,EAAA,SAAA,EAAA,GADR,EAQc,GAAA;;IANX,IAAI,EAAA,CAAA;IACL,IAAG;IACH,SAAQ;IACR,OAAM;;qBAEK,CAAA,EAAA,EAAR,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA;;+BAGF,EAAA,YAAA,EAAA,GADR,EAQc,GAAA;;IANX,IAAI,EAAA,CAAA;IACL,SAAQ;IACR,MAAK;IACL,OAAM;;qBAEQ,CAAA,EAAA,EAAX,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA;;oCAIL,EAAA,aAAaA,EAAAA,OAAM,qBAAA,EAAA,GAA/B,EAaM,OAbN,GAaM,CAZJ,EAA8B,EAAA,QAAA,gBAAA,GAErB,EAAA,yBAAA,EAAA,GADT,EAUc,GAAA;;IARZ,OAAM;IACL,OAAO,EAAA;IACR,SAAQ;IACR,MAAK;IACL,MAAK;IACJ,SAAO;;qBAEmB,CAA3B,EAA2B,GAAA,EAAnB,MAAM,EAAA,CAAA,EAAS,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA;;;GAI7B,EAMM,OANN,GAMM;aALJ,EAAoE,QAAA;KAA9D,OAAM;KAAmC,eAAY;;IAC3D,EAEM,OAFN,GAEM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA;aAEV,EAAuE,QAAA;KAAjE,OAAM;KAAsC,eAAY;;;GAElDA,EAAAA,OAAO,UAAA,EAAA,GAArB,EAES,UAFT,GAES,CADP,EAAsB,EAAA,QAAA,QAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"VDialog.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VDialog/VDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @core\n/**\n * Native showModal supplies top-layer placement and modal focus. JavaScript bridges v-model to\n * imperative open/close and provides guarded dismissal where closedBy is absent.\n */\n\nimport { computed, nextTick, onBeforeUnmount, ref, useAttrs, useId, watch } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { close as closeIcon } from '../VIcon/icons/close'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport VTypography from '../VTypography/VTypography.vue'\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\n/** How assistive technology announces the dialog. */\nexport type DialogRole = 'dialog' | 'alertdialog'\n\ninterface DialogProps {\n /**\n * The title of the dialog, which also names it for assistive technology. It is\n * ignored when the `#header` slot replaces the whole header.\n */\n title?: string\n /** A line under the title, explaining what the dialog is asking. */\n subtitle?: string\n /**\n * How wide the dialog is: a number is read as pixels, a string as any CSS length. Left out,\n * it takes the `--vectis-control-size-dialog-width` token, 400px by default.\n */\n width?: number | string\n /**\n * What kind of dialog this is. `alertdialog` is for one that must be answered\n * explicitly, and it makes screen readers announce it more insistently. VDialogAlert is\n * exactly that.\n */\n role?: DialogRole\n /**\n * Takes the close cross out of the header, leaving the reader with Escape, the\n * backdrop and whatever the footer offers.\n */\n hideClose?: boolean\n /** Stops a click outside the dialog from closing it. */\n persistentBackdrop?: boolean\n /**\n * Stops the Escape key from closing the dialog. Note that refusing Escape while the\n * backdrop still closes cannot be expressed natively, so both routes are then\n * allowed.\n */\n persistentEscape?: boolean\n /** What the close cross does, in words. It falls back to the design system dictionary. */\n closeLabel?: string\n}\n\nconst props = withDefaults(defineProps<DialogProps>(), {\n title: undefined,\n subtitle: undefined,\n width: undefined,\n role: 'dialog',\n hideClose: false,\n persistentBackdrop: false,\n persistentEscape: false,\n closeLabel: undefined,\n})\n\nconst m = useMessages()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? m.value.common.close)\n\n/** Whether the dialog is showing. */\nconst open = defineModel<boolean>('open', { default: false })\n\n/** What the trigger has to carry: the click that opens the dialog, and the fact that it does. */\nexport type DialogTriggerProps = {\n onClick: () => void\n 'aria-haspopup': 'dialog'\n}\n\ndefineSlots<{\n /** The body of the dialog. This is the part that scrolls when there is too much of it. */\n default(): unknown\n /** Replaces the title and subtitle block with content of your own. */\n header?(): unknown\n /** Extra controls in the header, placed before the close cross: a menu, a full-screen toggle. */\n 'header-actions'?(): unknown\n /** The buttons at the foot of the dialog. */\n footer?(): unknown\n /**\n * The button that opens the dialog. Bind the `triggerProps` it receives onto it. It stays\n * rendered always, unlike the dialog itself.\n */\n trigger?(props: { triggerProps: DialogTriggerProps }): unknown\n}>()\n\ndefineOptions({ inheritAttrs: false })\n\nconst attrs = useAttrs()\nconst dialogEl = ref<HTMLDialogElement | null>(null)\nconst titleId = useId()\nconst subtitleId = useId()\n\n/**\n * Which dismissals the browser itself accepts, declared as an attribute rather than handled in\n * code: everything, Escape alone, or nothing. One combination cannot be expressed that way; a\n * click outside allowed while Escape is not; and it falls back to allowing both.\n */\nconst closedby = computed(() =>\n props.persistentBackdrop ? (props.persistentEscape ? 'none' : 'closerequest') : 'any',\n)\n\n// @fallback\n// The `closedby` attribute is newer than the type definitions shipped with TypeScript, so\n// writing it directly in the template would be reported as an unknown attribute. Passing it\n// inside a bound object goes through the same path as any forwarded attribute, which is not\n// checked element by element.\nconst rootAttrs = computed(() => ({ ...attrs, closedby: closedby.value }))\n\nfunction show(): Promise<void> {\n open.value = true\n return nextTick()\n}\n\nfunction requestClose() {\n // Closing the element is enough: the browser then fires its own close event, which puts the\n // model back in step below.\n dialogEl.value?.close()\n}\n\nconst triggerProps = computed<DialogTriggerProps>(() => ({\n onClick: show,\n 'aria-haspopup': 'dialog',\n}))\n\n// Close before v-if removes the element so the browser restores the invoker's focus.\nwatch(open, (value) => {\n if (!value) dialogEl.value?.close()\n})\n\n// @ssr\n// Template refs become available after mounting, including when hydrating an open dialog.\nwatch(dialogEl, (dialog) => dialog?.showModal(), { flush: 'post' })\n\n// Ignore close events from replaced elements: the queued event from a quick close-and-reopen\n// must not close the new dialog.\nfunction onClose(event: Event) {\n if (event.target !== dialogEl.value) return\n open.value = false\n}\n\n// @core\n// An open dialog removed with its parent (a `v-if`, a route change) runs no close steps,\n// so no close event would come: the model is handed back closed here, or it stayed `true`\n// and the dialog reopened by itself the next time its parent was shown.\nonBeforeUnmount(() => {\n if (open.value) open.value = false\n})\n\n// @fallback\n/*\n * `closedby` is what applies `persistentBackdrop` and `persistentEscape`, and Safari does not\n * implement it: there Escape always closes and the backdrop never does. The two halves are\n * rebuilt below, and only where the attribute is unknown, so a browser that has it is never\n * second-guessed.\n */\nconst closedbyUnsupported = () => !('closedBy' in HTMLDialogElement.prototype)\n\nfunction onCancel(event: Event) {\n if (closedbyUnsupported() && closedby.value === 'none') event.preventDefault()\n}\n\n/**\n * Whether a point lies outside the dialog's box, which is where the backdrop is: a click on\n * the `::backdrop` is dispatched to the dialog element itself.\n */\nfunction outsideBox(event: MouseEvent) {\n const box = dialogEl.value?.getBoundingClientRect()\n if (!box) return false\n return (\n event.clientX < box.left ||\n event.clientX > box.right ||\n event.clientY < box.top ||\n event.clientY > box.bottom\n )\n}\n\n// A press that STARTED inside and ended on the backdrop (a text selection dragged past the\n// edge) is not a click on the backdrop, so the press is remembered, not only the release.\nlet pressedOnBackdrop = false\nfunction onPointerdown(event: PointerEvent) {\n pressedOnBackdrop = closedbyUnsupported() && event.target === dialogEl.value && outsideBox(event)\n}\nfunction onBackdropClick(event: MouseEvent) {\n const onBackdrop = pressedOnBackdrop && event.target === dialogEl.value && outsideBox(event)\n pressedOnBackdrop = false\n if (onBackdrop && closedbyUnsupported() && closedby.value === 'any') requestClose()\n}\n\ndefineExpose({\n /**\n * Opens the dialog, exactly as setting `open` does. The opening lands on the next tick,\n * once the element has been rendered: `el` is still null right after the call, and the\n * promise returned settles once the dialog is showing.\n */\n show,\n /**\n * Closes the dialog. It closes unconditionally, `persistentEscape` and\n * `persistentBackdrop` governing only the two routes the reader can take.\n */\n close: requestClose,\n /** The `<dialog>` element. It is null while closed: each opening builds a fresh one. */\n el: dialogEl,\n})\n</script>\n\n<template>\n <slot name=\"trigger\" :trigger-props=\"triggerProps\" />\n <dialog\n v-if=\"open\"\n ref=\"dialogEl\"\n :aria-labelledby=\"title ? titleId : undefined\"\n :aria-describedby=\"subtitle ? subtitleId : undefined\"\n v-bind=\"rootAttrs\"\n class=\"v-dialog\"\n :style=\"{ '--dialog-width': cssSize(width) }\"\n :role=\"role === 'alertdialog' ? 'alertdialog' : undefined\"\n @close=\"onClose\"\n @cancel=\"onCancel\"\n @pointerdown=\"onPointerdown\"\n @click=\"onBackdropClick\"\n >\n <!--\n The header and the footer stay put while only the body scrolls, so the scrollbar\n is confined to the body and never runs along them.\n\n The lines that appear under the header and above the footer once the body is\n scrolled are drawn by two sentinels stuck INSIDE the scrolling area, and not by\n the header and footer themselves: a container query can only style what is inside\n the container it asks about, never a sibling of it.\n -->\n <header class=\"v-dialog-header\">\n <slot name=\"header\">\n <div class=\"v-dialog-titles\">\n <VTypography\n v-if=\"title\"\n :id=\"titleId\"\n as=\"h2\"\n variant=\"heading-3\"\n class=\"v-dialog-title\"\n >\n {{ title }}\n </VTypography>\n <VTypography\n v-if=\"subtitle\"\n :id=\"subtitleId\"\n variant=\"subtitle\"\n tone=\"muted\"\n class=\"v-dialog-subtitle\"\n >\n {{ subtitle }}\n </VTypography>\n </div>\n </slot>\n <div v-if=\"!hideClose || $slots['header-actions']\" class=\"v-dialog-header-actions\">\n <slot name=\"header-actions\" />\n <VIconButton\n v-if=\"!hideClose\"\n class=\"v-dialog-close\"\n :label=\"resolvedCloseLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n @click=\"requestClose\"\n >\n <VIcon :name=\"closeIcon\" />\n </VIconButton>\n </div>\n </header>\n <div class=\"v-dialog-scroll\">\n <span class=\"v-dialog-edge v-dialog-edge--top\" aria-hidden=\"true\" />\n <div class=\"v-dialog-body\">\n <slot />\n </div>\n <span class=\"v-dialog-edge v-dialog-edge--bottom\" aria-hidden=\"true\" />\n </div>\n <footer v-if=\"$slots.footer\" class=\"v-dialog-footer\">\n <slot name=\"footer\" />\n </footer>\n </dialog>\n</template>\n\n<style>\n@layer vectis.components {\n .v-dialog {\n /*\n * The token is declared on the element rather than written as a `var()` fallback. A custom\n * property inherits, and a dialog opened from inside another one is its DOM descendant:\n * with a fallback, an alert confirming something in an 800px dialog would read that\n * dialog's inline width and open 800px wide itself, with no error anywhere.\n */\n --dialog-width: var(--vectis-control-size-dialog-width);\n inline-size: var(--dialog-width);\n max-inline-size: calc(100dvi - 2 * var(--vectis-space-4));\n max-block-size: calc(100dvb - 2 * var(--vectis-space-4));\n /*\n * Restore the modal's automatic margins in the component layer because the reset removes\n * native dialog centring.\n */\n margin: auto;\n /* The header and footer stay put while only the body scrolls, and hiding the\n overflow is what keeps the content inside the rounded corners. */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 0;\n border: none;\n border-radius: var(--vectis-radius-overlay);\n background: var(--vectis-color-surface-overlay);\n color: var(--vectis-color-text);\n box-shadow: var(--vectis-shadow-xl);\n font-family: var(--vectis-text-family);\n }\n\n /*\n * An indispensable guard. The browser hides a closed dialog with a rule of its own, but any\n * display we declare above beats it; so without this, a closed dialog would sit in the page\n * at the top left, swallowing clicks.\n */\n .v-dialog:not([open]) {\n display: none;\n }\n\n /* Opening a modal puts the focus on the dialog itself. No ring is drawn around the\n whole thing for that: the focus a reader needs to see is the one on the controls\n inside. */\n .v-dialog:focus-visible {\n outline: none;\n }\n\n .v-dialog-scroll {\n /*\n * The zero minimum is load-bearing: without it a flex item refuses to shrink below its\n * content, and nothing would ever scroll.\n */\n flex: 1 1 auto;\n min-block-size: 0;\n overflow-y: auto;\n /* A wheel reaching the end of the content stops there rather than scrolling the page\n behind the modal. */\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n /*\n * This makes the box something its descendants can ask questions about; namely whether\n * there is content hidden above or below. It adds no containment of size.\n */\n container-type: scroll-state;\n }\n\n /*\n * The two sentinels: hairlines stuck to the top and the bottom of the scrolling area, and\n * descendants of it, which allows them to ask about its scroll state. Their negative margins\n * mean they occupy no space at all.\n */\n .v-dialog-edge {\n flex: none;\n block-size: 1px;\n position: sticky;\n background: transparent;\n }\n\n .v-dialog-edge--top {\n inset-block-start: 0;\n margin-block-end: -1px;\n }\n\n .v-dialog-edge--bottom {\n inset-block-end: 0;\n margin-block-start: -1px;\n }\n\n .v-dialog-header {\n flex: none;\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--vectis-space-4);\n padding: var(--vectis-space-6) var(--vectis-space-6) var(--vectis-space-3);\n }\n\n .v-dialog-titles {\n display: flex;\n flex-direction: column;\n min-inline-size: 0;\n }\n\n /* The title and the subtitle are rendered by VTypography, which carries their type.\n Their classes remain as hooks, for a consumer's overrides and for the tests. */\n\n .v-dialog-header-actions {\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n /* The cross is a button, so it carries invisible padding of its own; pulling the\n row back by that amount is what makes the glyph line up with the header's edge\n rather than floating inside it. */\n margin-block-start: calc(-1 * var(--vectis-space-1));\n margin-inline-end: calc(-1 * var(--vectis-space-2));\n }\n\n .v-dialog-body {\n /* Short content is stretched to fill the space, so the footer stays at the bottom\n of the dialog rather than floating halfway up; long content keeps its natural\n height, overflows, and is what scrolls. */\n flex: 1 0 auto;\n padding: var(--vectis-space-1) var(--vectis-space-6) var(--vectis-space-3);\n font-size: var(--vectis-text-body-md-size);\n line-height: var(--vectis-text-body-md-leading);\n }\n\n .v-dialog-footer {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n flex-wrap: wrap;\n gap: var(--vectis-space-3);\n padding: var(--vectis-space-3) var(--vectis-space-6) var(--vectis-space-6);\n }\n\n /* Where it is missing the sentinels simply stay transparent, which is the intended fallback. */\n @container scroll-state(scrollable: top) {\n .v-dialog-edge--top {\n background: var(--vectis-color-border);\n }\n }\n\n @container scroll-state(scrollable: bottom) {\n .v-dialog-edge--bottom {\n background: var(--vectis-color-border);\n }\n }\n\n /*\n * The dialog animates on the way in and not on the way out. Since it is removed from the page\n * the moment it closes, there is nothing left to animate out; that is the price of the clean\n * slate the lazy rendering buys, and it also spares the extra declarations an exit animation\n * would need.\n */\n .v-dialog {\n transition:\n opacity var(--vectis-duration-base) var(--vectis-ease-default),\n transform var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open] {\n opacity: 0;\n transform: scale(0.97);\n }\n }\n\n .v-dialog::backdrop {\n background: var(--vectis-color-backdrop);\n transition: opacity var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n @starting-style {\n .v-dialog[open]::backdrop {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-dialog,\n .v-dialog::backdrop {\n transition: none;\n }\n }\n\n /* An outline draws one without moving the layout by a pixel. */\n @media (forced-colors: active) {\n .v-dialog {\n outline: 1px solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDA,IAAM,IAAQ,GAWR,IAAI,EAAY,GAChB,IAAqB,QAAe,EAAM,cAAc,EAAE,MAAM,OAAO,KAAK,GAG5E,IAAO,EAAoB,GAAC,MAA0B,GA0BtD,IAAQ,EAAS,GACjB,IAAW,EAA8B,IAAI,GAC7C,IAAU,EAAM,GAChB,IAAa,EAAM,GAOnB,IAAW,QACf,EAAM,qBAAsB,EAAM,mBAAmB,SAAS,iBAAkB,KAClF,GAOM,IAAY,SAAgB;GAAE,GAAG;GAAO,UAAU,EAAS;EAAM,EAAE;EAEzE,SAAS,IAAsB;GAE7B,OADA,EAAK,QAAQ,IACN,EAAS;EAClB;EAEA,SAAS,IAAe;GAGtB,EAAS,OAAO,MAAM;EACxB;EAEA,IAAM,IAAe,SAAoC;GACvD,SAAS;GACT,iBAAiB;EACnB,EAAE;EASF,AANA,EAAM,IAAO,MAAU;GACrB,AAAK,KAAO,EAAS,OAAO,MAAM;EACpC,CAAC,GAID,EAAM,IAAW,MAAW,GAAQ,UAAU,GAAG,EAAE,OAAO,OAAO,CAAC;EAIlE,SAAS,EAAQ,GAAc;GACzB,EAAM,WAAW,EAAS,UAC9B,EAAK,QAAQ;EACf;EAMA,QAAsB;GACpB,AAAgB,EAAK,UAAQ;EAC/B,CAAC;EASD,IAAM,UAA4B,EAAE,cAAc,kBAAkB;EAEpE,SAAS,EAAS,GAAc;GAC9B,AAAI,EAAoB,KAAK,EAAS,UAAU,UAAQ,EAAM,eAAe;EAC/E;EAMA,SAAS,EAAW,GAAmB;GACrC,IAAM,IAAM,EAAS,OAAO,sBAAsB;GAElD,OADK,IAEH,EAAM,UAAU,EAAI,QACpB,EAAM,UAAU,EAAI,SACpB,EAAM,UAAU,EAAI,OACpB,EAAM,UAAU,EAAI,SALL;EAOnB;EAIA,IAAI,IAAoB;EACxB,SAAS,GAAc,GAAqB;GAC1C,IAAoB,EAAoB,KAAK,EAAM,WAAW,EAAS,SAAS,EAAW,CAAK;EAClG;EACA,SAAS,GAAgB,GAAmB;GAC1C,IAAM,IAAa,KAAqB,EAAM,WAAW,EAAS,SAAS,EAAW,CAAK;GAE3F,AADA,IAAoB,IAChB,KAAc,EAAoB,KAAK,EAAS,UAAU,SAAO,EAAa;EACpF;SAEA,EAAa;GAMX;GAKA,OAAO;GAEP,IAAI;EACN,CAAC,+BAIC,EAAqD,EAAA,QAAA,WAAA,EAA/B,cAAe,EAAA,MAAY,CAAA,GAEzC,EAAA,SAAA,EAAA,GADR,EAuES,UAvET,EAuES;;YArEH;GAAJ,KAAI;GACH,mBAAiB,EAAA,QAAQ,EAAA,CAAA,IAAU,KAAA;GACnC,oBAAkB,EAAA,WAAW,EAAA,CAAA,IAAa,KAAA;KACnC,EAAA,OAAS;GACjB,OAAM;GACL,OAAK,EAAA,kBAAsB,EAAA,CAAA,CAAO,CAAC,EAAA,KAAK,EAAA;GACxC,MAAM,EAAA,SAAI,gBAAA,gBAAqC,KAAA;GACxC;GACC;GACK;GACb,SAAO;;GAWR,EAqCS,UArCT,GAqCS,CApCP,EAqBO,EAAA,QAAA,UAAA,CAAA,SAAA,CApBL,EAmBM,OAnBN,GAmBM,CAjBI,EAAA,SAAA,EAAA,GADR,EAQc,GAAA;;IANX,IAAI,EAAA,CAAA;IACL,IAAG;IACH,SAAQ;IACR,OAAM;;qBAEK,CAAA,EAAA,EAAR,EAAA,KAAK,GAAA,CAAA,CAAA,CAAA;;+BAGF,EAAA,YAAA,EAAA,GADR,EAQc,GAAA;;IANX,IAAI,EAAA,CAAA;IACL,SAAQ;IACR,MAAK;IACL,OAAM;;qBAEQ,CAAA,EAAA,EAAX,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA;;oCAIL,EAAA,aAAaA,EAAAA,OAAM,qBAAA,EAAA,GAA/B,EAaM,OAbN,GAaM,CAZJ,EAA8B,EAAA,QAAA,gBAAA,GAErB,EAAA,yBAAA,EAAA,GADT,EAUc,GAAA;;IARZ,OAAM;IACL,OAAO,EAAA;IACR,SAAQ;IACR,MAAK;IACL,MAAK;IACJ,SAAO;;qBAEmB,CAA3B,EAA2B,GAAA,EAAnB,MAAM,EAAA,CAAA,EAAS,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA;;;GAI7B,EAMM,OANN,GAMM;aALJ,EAAoE,QAAA;KAA9D,OAAM;KAAmC,eAAY;;IAC3D,EAEM,OAFN,GAEM,CADJ,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA;aAEV,EAAuE,QAAA;KAAjE,OAAM;KAAsC,eAAY;;;GAElDA,EAAAA,OAAO,UAAA,EAAA,GAArB,EAES,UAFT,GAES,CADP,EAAsB,EAAA,QAAA,QAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
@@ -8,9 +8,8 @@ interface DialogAlertProps {
8
8
  /** A line under the title, spelling out the consequences of the answer. */
9
9
  subtitle?: string;
10
10
  /**
11
- * How wide the alert is: a number is read as pixels, a string as any CSS length. Left
12
- * out, it takes the `--vectis-control-size-dialog-width` token, 400px by default. It is
13
- * never allowed to exceed the width of the viewport.
11
+ * How wide the alert is: a number is read as pixels, a string as any CSS length. Left out, it
12
+ * takes the `--vectis-control-size-dialog-width` token, 400px by default.
14
13
  */
15
14
  width?: number | string;
16
15
  }