vectis-ui 0.8.1 → 0.9.1
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.
- package/README.md +3 -3
- package/dist/components/VAccordion/VAccordionItem.d.ts +4 -6
- package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +21 -19
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAccordion/context.d.ts +6 -1
- package/dist/components/VAccordion/context.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.css +1 -1
- package/dist/components/VAvatar/VAvatar.d.ts +5 -3
- package/dist/components/VAvatar/VAvatar.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +53 -39
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.d.ts +12 -3
- package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +27 -20
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/context.d.ts +2 -2
- package/dist/components/VAvatar/context.js.map +1 -1
- package/dist/components/VBadge/VBadge.css +1 -1
- package/dist/components/VBadge/VBadge.d.ts +8 -4
- package/dist/components/VBadge/VBadge.js.map +1 -1
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +5 -4
- package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +8 -3
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButton.css +1 -1
- package/dist/components/VButton/VButton.d.ts +4 -1
- package/dist/components/VButton/VButton.js.map +1 -1
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +8 -7
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.css +1 -1
- package/dist/components/VCalendar/VCalendar.d.ts +15 -6
- package/dist/components/VCalendar/VCalendar.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +144 -126
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.css +1 -1
- package/dist/components/VCalendar/VCalendarEvent.d.ts +1 -1
- package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.css +1 -1
- package/dist/components/VCalendar/VCalendarMonth.d.ts +1 -1
- package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +99 -90
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +3 -3
- package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +256 -246
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.css +1 -1
- package/dist/components/VCalendar/VCalendarYear.d.ts +8 -1
- package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +39 -32
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/color.d.ts +1 -1
- package/dist/components/VCalendar/color.js.map +1 -1
- package/dist/components/VCalendar/edgeStep.d.ts +3 -3
- package/dist/components/VCalendar/edgeStep.js +5 -0
- package/dist/components/VCalendar/edgeStep.js.map +1 -1
- package/dist/components/VCalendar/gesture.d.ts +10 -9
- package/dist/components/VCalendar/gesture.js +60 -45
- package/dist/components/VCalendar/gesture.js.map +1 -1
- package/dist/components/VCalendar/keyboard.d.ts +22 -5
- package/dist/components/VCalendar/keyboard.js +17 -16
- package/dist/components/VCalendar/keyboard.js.map +1 -1
- package/dist/components/VCalendar/layout.d.ts +47 -37
- package/dist/components/VCalendar/layout.js +47 -37
- package/dist/components/VCalendar/layout.js.map +1 -1
- package/dist/components/VCalendar/timeGrid.d.ts +4 -4
- package/dist/components/VCalendar/timeGrid.js +6 -6
- package/dist/components/VCalendar/timeGrid.js.map +1 -1
- package/dist/components/VCalendar/types.d.ts +5 -5
- package/dist/components/VCarousel/VCarousel.css +1 -1
- package/dist/components/VCarousel/VCarousel.d.ts +59 -38
- package/dist/components/VCarousel/VCarousel.js.map +1 -1
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +161 -132
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.d.ts +1 -1
- package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/context.d.ts +1 -1
- package/dist/components/VCarousel/context.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.css +1 -1
- package/dist/components/VCheckbox/VCheckbox.d.ts +2 -2
- package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +10 -8
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VChip/VChip.css +1 -1
- package/dist/components/VChip/VChip.d.ts +7 -2
- package/dist/components/VChip/VChip.js.map +1 -1
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +69 -55
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.css +1 -1
- package/dist/components/VCombobox/VCombobox.d.ts +50 -36
- package/dist/components/VCombobox/VCombobox.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +167 -161
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.css +1 -1
- package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/infiniteScroll.d.ts +12 -3
- package/dist/components/VCombobox/infiniteScroll.js +18 -12
- package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.css +1 -1
- package/dist/components/VDataTable/VDataTable.d.ts +55 -24
- package/dist/components/VDataTable/VDataTable.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +192 -155
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.css +1 -1
- package/dist/components/VDateInput/VDateInput.d.ts +15 -12
- package/dist/components/VDateInput/VDateInput.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +180 -160
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDateInput/mask.d.ts +95 -0
- package/dist/components/VDateInput/mask.js +118 -0
- package/dist/components/VDateInput/mask.js.map +1 -0
- package/dist/components/VDatePicker/VDatePicker.css +1 -1
- package/dist/components/VDatePicker/VDatePicker.d.ts +6 -5
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +204 -173
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/keyboard.d.ts +3 -3
- package/dist/components/VDatePicker/keyboard.js.map +1 -1
- package/dist/components/VDatePicker/names.d.ts +34 -0
- package/dist/components/VDatePicker/names.js +42 -0
- package/dist/components/VDatePicker/names.js.map +1 -0
- package/dist/components/VDialog/VDialog.css +1 -1
- package/dist/components/VDialog/VDialog.d.ts +2 -2
- package/dist/components/VDialog/VDialog.js.map +1 -1
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +63 -41
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.d.ts +38 -25
- package/dist/components/VFileInput/VFileInput.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +74 -71
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFileInput/truncate.d.ts +4 -4
- package/dist/components/VFileInput/truncate.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.css +1 -1
- package/dist/components/VFilePicker/VFilePicker.d.ts +54 -37
- package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +152 -135
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/fileKind.d.ts +2 -2
- package/dist/components/VFilePicker/fileKind.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.css +1 -1
- package/dist/components/VHotkeys/VHotkeys.d.ts +10 -8
- package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +22 -20
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VHotkeys/platform.d.ts +9 -7
- package/dist/components/VHotkeys/platform.js +41 -30
- package/dist/components/VHotkeys/platform.js.map +1 -1
- package/dist/components/VIcon/VIcon.css +1 -1
- package/dist/components/VIcon/VIcon.d.ts +6 -6
- package/dist/components/VIcon/VIcon.js.map +1 -1
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VIcon/iconProps.d.ts +4 -4
- package/dist/components/VIcon/iconProps.js.map +1 -1
- package/dist/components/VIcon/icons/index.d.ts +1 -1
- package/dist/components/VIcon/icons/index.js.map +1 -1
- package/dist/components/VIcon/icons/names.d.ts +1 -1
- package/dist/components/VIcon/icons/names.js.map +1 -1
- package/dist/components/VIcon/resolver.d.ts +3 -3
- package/dist/components/VIcon/resolver.js +23 -20
- package/dist/components/VIcon/resolver.js.map +1 -1
- package/dist/components/VIcon/types.d.ts +4 -4
- package/dist/components/VIconButton/VIconButton.d.ts +4 -4
- package/dist/components/VIconButton/VIconButton.js.map +1 -1
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInput.d.ts +16 -8
- package/dist/components/VInput/VInput.js.map +1 -1
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +22 -16
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInputGroup.css +1 -1
- package/dist/components/VInput/VInputGroup.js.map +1 -1
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +43 -28
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.css +1 -1
- package/dist/components/VInputOTP/VInputOTP.d.ts +3 -3
- package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +152 -85
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenu.d.ts +4 -4
- package/dist/components/VMenu/VMenu.js.map +1 -1
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.css +1 -1
- package/dist/components/VMenu/VMenuGroup.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +18 -11
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.css +1 -1
- package/dist/components/VMenu/VMenuItem.d.ts +6 -6
- package/dist/components/VMenu/VMenuItem.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +83 -69
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.css +1 -1
- package/dist/components/VMenu/VMenuPanel.d.ts +2 -2
- package/dist/components/VMenu/VMenuPanel.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +56 -55
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/context.d.ts +2 -2
- package/dist/components/VMenu/context.js.map +1 -1
- package/dist/components/VPagination/VPagination.css +1 -1
- package/dist/components/VPagination/VPagination.d.ts +31 -9
- package/dist/components/VPagination/VPagination.js.map +1 -1
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +82 -52
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VPopover/VPopover.css +1 -1
- package/dist/components/VPopover/VPopover.d.ts +1 -1
- package/dist/components/VPopover/VPopover.js.map +1 -1
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +12 -7
- package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +15 -10
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VRadio/VRadio.css +1 -1
- package/dist/components/VRadio/VRadio.js.map +1 -1
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.d.ts +1 -1
- package/dist/components/VSeparator/VSeparator.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.d.ts +2 -2
- package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +12 -13
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +87 -68
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +10 -7
- package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSlider/VSlider.css +1 -1
- package/dist/components/VSlider/VSlider.d.ts +21 -7
- package/dist/components/VSlider/VSlider.js.map +1 -1
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +159 -140
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.css +1 -1
- package/dist/components/VSnackbar/VSnackbar.d.ts +4 -4
- package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +85 -59
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/state.d.ts +7 -7
- package/dist/components/VSnackbar/state.js +13 -11
- package/dist/components/VSnackbar/state.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.css +1 -1
- package/dist/components/VSpinner/VSpinner.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.css +1 -1
- package/dist/components/VSwitch/VSwitch.d.ts +1 -1
- package/dist/components/VSwitch/VSwitch.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTab.css +1 -1
- package/dist/components/VTabs/VTab.d.ts +4 -0
- package/dist/components/VTabs/VTab.js.map +1 -1
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +9 -8
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTabs.css +1 -1
- package/dist/components/VTabs/VTabs.d.ts +17 -7
- package/dist/components/VTabs/VTabs.js.map +1 -1
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +84 -77
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.d.ts +8 -8
- package/dist/components/VTextarea/VTextarea.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +71 -69
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.css +1 -1
- package/dist/components/VTimeInput/VTimeInput.d.ts +21 -12
- package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +230 -206
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/search.d.ts +17 -2
- package/dist/components/VTimeInput/search.js +19 -9
- package/dist/components/VTimeInput/search.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.css +1 -1
- package/dist/components/VTimePicker/VTimePicker.d.ts +8 -7
- package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +128 -106
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimePicker/limits.d.ts +11 -4
- package/dist/components/VTimePicker/limits.js +3 -2
- package/dist/components/VTimePicker/limits.js.map +1 -1
- package/dist/components/VToast/VToast.css +1 -1
- package/dist/components/VToast/VToast.js.map +1 -1
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +33 -37
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/VToaster.js.map +1 -1
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +91 -61
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/state.d.ts +8 -6
- package/dist/components/VToast/state.js +15 -13
- package/dist/components/VToast/state.js.map +1 -1
- package/dist/components/VToggle/VToggle.css +1 -1
- package/dist/components/VToggle/VToggle.d.ts +9 -4
- package/dist/components/VToggle/VToggle.js.map +1 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.d.ts +4 -0
- package/dist/components/VToggle/VToggleItem.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.css +1 -1
- package/dist/components/VTooltip/VTooltip.d.ts +17 -10
- package/dist/components/VTooltip/VTooltip.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +46 -26
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTypography/VTypography.css +1 -1
- package/dist/components/VTypography/VTypography.d.ts +6 -4
- package/dist/components/VTypography/VTypography.js.map +1 -1
- package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/useAriaLabel.js +1 -1
- package/dist/composables/useAriaLabel.js.map +1 -1
- package/dist/composables/useClearable.d.ts +2 -2
- package/dist/composables/useClearable.js.map +1 -1
- package/dist/composables/useDetailsOpen.d.ts +3 -3
- package/dist/composables/useDetailsOpen.js +14 -12
- package/dist/composables/useDetailsOpen.js.map +1 -1
- package/dist/composables/useFieldIds.d.ts +2 -1
- package/dist/composables/useFieldIds.js +6 -5
- package/dist/composables/useFieldIds.js.map +1 -1
- package/dist/composables/useFieldPanel.d.ts +2 -2
- package/dist/composables/useFieldPanel.js +47 -37
- package/dist/composables/useFieldPanel.js.map +1 -1
- package/dist/composables/useFileDrop.js +3 -3
- package/dist/composables/useFileDrop.js.map +1 -1
- package/dist/composables/useFileField.d.ts +1 -1
- package/dist/composables/useFileField.js +62 -41
- package/dist/composables/useFileField.js.map +1 -1
- package/dist/composables/useIconClickHandlers.d.ts +3 -3
- package/dist/composables/useIconClickHandlers.js +14 -13
- package/dist/composables/useIconClickHandlers.js.map +1 -1
- package/dist/composables/useInertLink.js +12 -10
- package/dist/composables/useInertLink.js.map +1 -1
- package/dist/composables/useLiveAnnouncer.d.ts +5 -0
- package/dist/composables/useLiveAnnouncer.js +23 -0
- package/dist/composables/useLiveAnnouncer.js.map +1 -0
- package/dist/composables/useMaskedField.d.ts +5 -5
- package/dist/composables/useMaskedField.js.map +1 -1
- package/dist/composables/usePopover.d.ts +3 -3
- package/dist/composables/usePopover.js +6 -4
- package/dist/composables/usePopover.js.map +1 -1
- package/dist/composables/useProgressValue.js +11 -2
- package/dist/composables/useProgressValue.js.map +1 -1
- package/dist/composables/useRootAttrs.d.ts +1 -1
- package/dist/composables/useRootAttrs.js.map +1 -1
- package/dist/composables/useSlotNodes.d.ts +18 -0
- package/dist/composables/useSlotNodes.js +13 -0
- package/dist/composables/useSlotNodes.js.map +1 -0
- package/dist/composables/useTextLimit.d.ts +2 -1
- package/dist/composables/useTextLimit.js +2 -2
- package/dist/composables/useTextLimit.js.map +1 -1
- package/dist/composables/useTimer.d.ts +5 -0
- package/dist/composables/useTimer.js +22 -11
- package/dist/composables/useTimer.js.map +1 -1
- package/dist/i18n/en.js +1 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.js +14 -14
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/state.d.ts +7 -7
- package/dist/i18n/state.js +37 -28
- package/dist/i18n/state.js.map +1 -1
- package/dist/i18n/types.d.ts +12 -12
- package/dist/icons.d.ts +2 -2
- package/dist/index.d.ts +12 -11
- package/dist/styles.css +1 -1
- package/dist/tokens/css.d.ts +1 -1
- package/dist/tokens/css.js.map +1 -1
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/semantic.d.ts +6 -0
- package/dist/tokens/semantic.js +66 -60
- package/dist/tokens/semantic.js.map +1 -1
- package/dist/tokens/themes/dark.js +3 -3
- package/dist/tokens/themes/dark.js.map +1 -1
- package/dist/tokens.json +130 -66
- package/dist/types.d.ts +1 -1
- package/dist/utils/arrowNav.d.ts +4 -1
- package/dist/utils/arrowNav.js +7 -7
- package/dist/utils/arrowNav.js.map +1 -1
- package/dist/utils/chip.d.ts +1 -1
- package/dist/utils/chip.js.map +1 -1
- package/dist/utils/clock.d.ts +113 -0
- package/dist/utils/clock.js +84 -0
- package/dist/utils/clock.js.map +1 -0
- package/dist/utils/css.d.ts +6 -4
- package/dist/utils/css.js +2 -2
- package/dist/utils/css.js.map +1 -1
- package/dist/utils/date.d.ts +7 -102
- package/dist/utils/date.js +33 -160
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/direction.d.ts +1 -1
- package/dist/utils/direction.js.map +1 -1
- package/dist/utils/env.d.ts +12 -3
- package/dist/utils/env.js +6 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/file.d.ts +3 -3
- package/dist/utils/file.js +1 -1
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/focus.d.ts +1 -1
- package/dist/utils/focus.js.map +1 -1
- package/dist/utils/hostWarns.d.ts +1 -1
- package/dist/utils/hostWarns.js.map +1 -1
- package/dist/utils/ids.d.ts +1 -1
- package/dist/utils/ids.js.map +1 -1
- package/dist/utils/matcher.d.ts +2 -2
- package/dist/utils/matcher.js.map +1 -1
- package/dist/utils/memo.d.ts +1 -1
- package/dist/utils/memo.js.map +1 -1
- package/dist/utils/text.d.ts +3 -3
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/time.d.ts +2 -101
- package/dist/utils/time.js +22 -98
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/vnode.d.ts +5 -3
- package/dist/utils/vnode.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VDateInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VDateInput/VDateInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * A field for choosing a date: a VInput, and a VDatePicker in a panel below it.\n *\n * The panel is `mode=\"manual\"` and driven imperatively, which is not a detail — `popovertarget`\n * is invalid on a text `<input>`, and opening it ourselves is also what lets focus be moved\n * INTO the grid so the keyboard lands on the dates. Closing is ours too: `focusout`, or Escape.\n *\n * Two FIELD modes, `mode`: `input` (the default) types digits only, the separators appearing\n * as they go in the order and punctuation of the reader's locale; `picker` makes the calendar\n * the only way in. What the field is FOR is a different question from the `readonly` prop,\n * which freezes whatever it holds by every route at once.\n *\n * That is a different question from WHAT is chosen — one date, a range, or several — which is\n * `selection`, passed straight through to the picker.\n */\n\nimport { computed, inject, provide, ref, watchEffect } from 'vue'\n\nimport { inputGroupKey } from '../VInput/context'\n\nimport VDatePicker from '../VDatePicker/VDatePicker.vue'\nimport type {\n DatePickerDaySlotProps,\n DatePickerEvent,\n DatePickerSelection,\n DatePickerValue,\n DatePickerMatcher,\n DatePickerRange,\n} from '../VDatePicker/VDatePicker.vue'\nimport {\n caretAfterDigits,\n compareISO,\n dateMaskFor,\n formatDateDisplay,\n formatDateMask,\n formatDisplayRange,\n isDateAllowed,\n isValidISO,\n isoToMask,\n maskPlaceholder,\n parseDateMask,\n} from '../../utils/date'\nimport { digitsOf } from '../../utils/text'\nimport { resolveMatcher } from '../../utils/matcher'\nimport { isDev } from '../../utils/env'\nimport { hostWarnsKey } from '../../utils/hostWarns'\nimport { calendar_today as calendarTodayIcon } from '../VIcon/icons/calendar_today'\nimport type { IconSource } from '../VIcon/types'\nimport VInput from '../VInput/VInput.vue'\nimport VPopover from '../VPopover/VPopover.vue'\n\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\nimport { useFieldPanel } from '../../composables/useFieldPanel'\nimport { canClear } from '../../composables/useClearable'\nimport { iconStartListener } from '../../composables/useIconClickHandlers'\nimport { useMaskedField } from '../../composables/useMaskedField'\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\n/** Where the calendar opens relative to the field. */\nexport type DateInputPlacement =\n 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end'\n\n/** Whether the field can be typed into, or only filled from the calendar. */\nexport type DateInputMode = 'picker' | 'input'\n\nconst MODES: DateInputMode[] = ['picker', 'input']\n\n/**\n * The century a two-digit year is expanded into — \"10/06/26\" becomes 2026 — applied only\n * when the reader leaves the field.\n *\n * It is FIXED and never derived from the current year. A sliding rule would make the\n * component's behaviour depend on when it runs, which is the same objection that keeps\n * today's date out of VDatePicker's setup, and it would give the tests a shelf life.\n */\nconst YEAR_PIVOT = 2000\n\nconst DEFAULT_DISPLAY_FORMAT: Intl.DateTimeFormatOptions = {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n}\n\n/** The height of the field: 32, 40 or 48 pixels. */\nexport type DateInputSize = 'sm' | 'md' | 'lg'\n\ninterface DateInputProps {\n // Everything from here to `events` is handed straight to the calendar.\n /** What is being chosen: one date, a period between two, or several separate dates. */\n selection?: DatePickerSelection\n /**\n * A BCP 47 locale, which decides the month and day names, the first day of the week and\n * the order the field is typed in. It TAKES PRECEDENCE over the design system's global\n * locale and falls back to it — which is why it has no literal default: `undefined` has\n * to stay recognizable for the global locale to have its chance.\n */\n locale?: string\n /** Forces the day the weeks start on, from 0 for Sunday to 6 for Saturday. */\n firstDayOfWeek?: number\n /** The earliest date that can be chosen, as an ISO string. */\n min?: string\n /** The latest date that can be chosen, as an ISO string. */\n max?: string\n /** Dates that cannot be chosen, as a list or as a function. */\n disabledDates?: DatePickerMatcher\n /** Fills the corners of the grid with the greyed days of the neighbouring months. */\n showAdjacentDays?: boolean\n /** Lets those neighbouring days be clicked, which implies showing them. */\n selectAdjacentDays?: boolean\n /** Events to mark under the days they fall on. */\n events?: DatePickerEvent[]\n // From here on: the field.\n /**\n * Whether the field can be TYPED into — the default, using the numeric form of the\n * reader's language — or is filled from the calendar alone, which is `picker`.\n *\n * Typing is reserved for choosing a SINGLE date: a period or a list falls back to\n * `picker`, there being no sensible way to type either.\n */\n mode?: DateInputMode\n /**\n * Offers the date picker alongside a field that can be typed into: an icon at the end of\n * the field, and a panel that opens on focus. It means nothing in `picker` mode, where\n * the calendar is already the only way to choose.\n */\n showPicker?: boolean\n /** The label above the field. */\n label?: string\n /** A line of help under the field. */\n hint?: string\n /** What the field says while empty. */\n placeholder?: string\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: DateInputSize\n /** Takes 4px off the height. */\n compact?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the date without letting it be changed: nothing can be typed, there is no\n * calendar and no clear cross. The field stays focusable and can be copied from,\n * which is what separates it from `disabled`, and it is a different question from\n * `mode`, which says how a field that CAN be changed is filled in.\n */\n readonly?: boolean\n /** Marks the field as invalid — for a rule of your own. */\n invalid?: boolean\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes a\n * real button as soon as a `@click:icon-start` listener is attached, in which case it\n * needs `iconStartLabel`.\n */\n iconStart?: IconSource\n /** What the start icon does, in words, once it is clickable. */\n iconStartLabel?: string\n /**\n * What the calendar button does, in words. It names the button `pickerIcon` renders,\n * and falls back to the design system dictionary.\n */\n pickerIconLabel?: string\n /**\n * Shows a spinner at the end of the field, in place of the calendar icon. It says\n * that something is being loaded and changes nothing else: the field can still be\n * typed into and the panel still opens.\n */\n loading?: boolean\n /**\n * What screen readers announce while the spinner turns. It falls back to the design\n * system dictionary.\n */\n loadingLabel?: string\n /** Offers a cross that empties the value, shown before the end icon. */\n clearable?: boolean\n /** What that cross does, in words. It falls back to the design system dictionary. */\n clearLabel?: string\n /**\n * The icon that opens the date picker, at the end of the field. The clear cross appears\n * to its left rather than in its place, and no icon is rendered at all when there is no\n * panel to open.\n */\n pickerIcon?: IconSource\n /**\n * How the date is WRITTEN OUT in the field. It has no effect on a field being typed\n * into, which necessarily shows the numeric form one types — so it concerns the\n * `picker` mode, and the period and list selections, which fall back to it.\n */\n displayFormat?: Intl.DateTimeFormatOptions\n /** Where the panel opens relative to the field. */\n placement?: DateInputPlacement\n}\n\nconst props = withDefaults(defineProps<DateInputProps>(), {\n selection: 'single',\n locale: undefined,\n firstDayOfWeek: undefined,\n min: undefined,\n max: undefined,\n disabledDates: undefined,\n showAdjacentDays: false,\n selectAdjacentDays: false,\n events: undefined,\n // Deliberately left undefined rather than defaulted to the typed mode: that is what\n // distinguishes \"the prop was not given\" from \"the prop was given this value\", and\n // therefore what allows warning ONLY the consumer who explicitly asked for something\n // that cannot work.\n mode: undefined,\n showPicker: false,\n label: undefined,\n hint: undefined,\n placeholder: undefined,\n size: 'md',\n compact: false,\n disabled: false,\n readonly: false,\n invalid: false,\n iconStart: undefined,\n iconStartLabel: undefined,\n pickerIconLabel: undefined,\n loading: false,\n loadingLabel: undefined,\n clearable: false,\n clearLabel: undefined,\n pickerIcon: () => calendarTodayIcon,\n // Left undefined rather than defaulted to the format object, for the same reason: it is\n // what lets the component notice that a consumer has asked for a display format in a\n // mode where it has no effect, and say so.\n displayFormat: undefined,\n placement: 'bottom-start',\n})\n\n/**\n * The date or dates chosen, in the shape `selection` calls for: an ISO `YYYY-MM-DD` string\n * for `single`, a `{ start, end }` pair for `range`, an array for `multiple`. Nothing is\n * selected to begin with.\n *\n * While the reader types, it is only written once what they have entered is a complete and\n * acceptable date; an unfinished or refused entry leaves it untouched and is reverted when\n * they leave the field.\n */\nconst model = defineModel<DatePickerValue>({ default: null })\n\nconst emit = defineEmits<{\n /** The clear cross emptied the field. The value has already been reset. */\n clear: []\n /** The start icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-start': [event: MouseEvent]\n}>()\n\ndefineSlots<{\n /**\n * Content at the start of the field, rendered after `iconStart` rather than in its place,\n * as in VInput.\n */\n start?(): unknown\n /**\n * Controls of your own inside the field, placed before the ones the field owns — the clear\n * cross and the icon that opens the panel. Those two are this component's own affordance,\n * which is why there is no `#end` here: it would replace them.\n */\n 'value-end'?(): unknown\n /** What a day cell shows, handed straight to the calendar. */\n day?(props: DatePickerDaySlotProps): unknown\n /**\n * The strip at the foot of the panel — actions, or preset dates such as \"today\". It\n * receives `close`, which is what lets one of those buttons dismiss the panel.\n */\n footer?(props: { close: () => void }): unknown\n}>()\n\n// `class` and `style` stay on the wrapper; everything else goes down to the text field,\n// which is what a consumer's label points at and what assistive technology deals with.\ndefineOptions({ inheritAttrs: false })\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// Declared as this component's own event, `click:icon-start` is out of `$attrs`, so the\n// listener is relayed to the field by hand — and only when the consumer wrote one.\nconst iconStartClick = iconStartListener((event) => emit('click:icon-start', event))\n\n/** What reaches the field: the consumer's own attributes, plus that listener. */\nconst fieldAttrs = computed(() => ({ ...forwardedAttrs.value, ...iconStartClick }))\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelRef = ref<InstanceType<typeof VPopover> | null>(null)\nconst inputRef = ref<InstanceType<typeof VInput> | null>(null)\nconst pickerRef = ref<InstanceType<typeof VDatePicker> | null>(null)\n\n/** The real input inside the field, which the mask and the caret work on. */\nconst fieldEl = computed<HTMLInputElement | null>(() => inputRef.value?.el ?? null)\n\n/** What was asked for, falling back to the default when nothing or nonsense was given. */\nconst requestedMode = computed<DateInputMode>(() =>\n props.mode !== undefined && MODES.includes(props.mode) ? props.mode : 'input',\n)\n/**\n * What is actually used. Typing is only possible for a single date: a period or a list\n * has no form one could type into a single field.\n */\nconst resolvedMode = computed<DateInputMode>(() =>\n requestedMode.value === 'input' && props.selection === 'single' ? 'input' : 'picker',\n)\nconst typing = computed(() => resolvedMode.value === 'input')\n\n/**\n * Whether there is a panel at all. The calendar is only optional beside a field one can\n * type into: in `picker` mode it is the only way to choose anything, and a frozen field\n * has none at all.\n */\nconst hasPanel = computed(() => !props.readonly && (!typing.value || props.showPicker))\n\n// @devwarn\nif (isDev) {\n // The calendar receives `min` and `max` as they stand, so what it would say about them is\n // said here, under the name the consumer wrote (utils/hostWarns).\n provide(hostWarnsKey, true)\n watchEffect(() => {\n if (props.min && props.max && compareISO(props.min, props.max) > 0)\n console.warn(\n `[VDateInput] min \"${props.min}\" falls after max \"${props.max}\", so no date can be chosen.`,\n )\n // Without a panel there is no icon to draw and no button to name. A read-only field is\n // left out: it is a state that comes and goes, not a configuration to correct.\n if (typing.value && !props.showPicker) {\n const inert = ([] as string[]).concat(\n props.pickerIcon !== calendarTodayIcon ? 'pickerIcon' : [],\n props.pickerIconLabel ? 'pickerIconLabel' : [],\n )\n if (inert.length > 0)\n console.warn(\n `[VDateInput] ${inert.join(', ')} ${inert.length > 1 ? 'are' : 'is'} ignored without showPicker: a field one types into has no calendar icon unless it offers the calendar.`,\n )\n }\n if (props.mode !== undefined && !MODES.includes(props.mode))\n console.warn(\n `[VDateInput] unknown mode \"${props.mode}\": use \"input\" (the default) or \"picker\".`,\n )\n // Tested on the PROP and not on what was resolved from it: typing being the default,\n // a period or a list falls back on its own with nobody having asked for anything.\n // Only a consumer who explicitly asked to type deserves to be told it cannot work.\n if (props.mode === 'input' && props.selection !== 'single')\n console.warn(\n `[VDateInput] mode=\"input\" ignored in \"${props.selection}\" selection: a range or a list of dates cannot be typed on the keyboard.`,\n )\n // Here it is the RESOLVED mode that matters: the format really was supplied, and it\n // really will have no effect, whichever route led to a typed field. The warning stays\n // something the consumer can act on.\n if (props.displayFormat && typing.value)\n console.warn(\n '[VDateInput] displayFormat is ignored in \"input\" mode (the default): the field displays the locale\\'s numeric mask, the only typeable format. Pass mode=\"picker\" for a formatted display.',\n )\n })\n}\n\n// A VInputGroup joins several controls into one object, so the shape of this field is the\n// row's decision rather than its own (VInput/context.ts).\nconst group = inject(inputGroupKey, null)\nconst {\n size: resolvedSize,\n compact: resolvedCompact,\n disabled: resolvedDisabled,\n} = useControlShape(props, group)\n\n// The whole \"field plus panel\" shell, shared with VTimeInput: opening and closing, the\n// focus leaving the component and coming back to the field, a click on the field or its\n// icon, and the Escape, ArrowDown and Enter keys.\nconst {\n open,\n panelId,\n closeAndFocus,\n focusField,\n onFieldFocus,\n toggleFromIcon,\n onControlClick,\n onFocusout,\n onKeydown,\n onPanelMousedown,\n} = useFieldPanel({\n rootEl,\n panelRef,\n field: inputRef,\n // With no panel there is nothing to open. This is the composable's SINGLE cut-off\n // point, and every way in passes through it — clicking the field, focusing it, the\n // down arrow, Enter, the icon — so the condition never has to be repeated in a\n // handler.\n disabled: () => resolvedDisabled.value || !hasPanel.value,\n focusInPanel: () => pickerRef.value?.focus(),\n // The calendar stays mounted while the panel is closed, so it is put back on the days\n // view both ways: a field that opens on focus never goes through `focus()`.\n onOpen: () => pickerRef.value?.reset(),\n onClose: () => pickerRef.value?.reset(),\n // Beside a field one types into, the panel opens on focus WITHOUT taking it: typing\n // carries on in the field, and the down arrow remains the way into the grid.\n openOnFocus: () => typing.value,\n})\n\nconst hasValue = computed(() => {\n if (props.selection === 'multiple') return Array.isArray(model.value) && model.value.length > 0\n if (props.selection === 'range') {\n const r = model.value as DatePickerRange | null\n return !!(r && (r.start || r.end))\n }\n return typeof model.value === 'string' && !!model.value\n})\n\n/* TRAP — this component is the SINGLE place the locale is resolved: what flows down to the\n calendar is the RESULT, never the prop, which would usually be undefined and would have\n the calendar resolve the language a second time — with every chance of the two\n disagreeing after a later change. */\nconst resolvedLocale = useResolvedLocale(() => props.locale)\n\nconst displayText = computed(() => {\n const locale = resolvedLocale.value\n const displayFormat = props.displayFormat ?? DEFAULT_DISPLAY_FORMAT\n if (props.selection === 'single') {\n return typeof model.value === 'string' && isValidISO(model.value)\n ? formatDateDisplay(model.value, locale, displayFormat)\n : ''\n }\n if (props.selection === 'range') {\n const r = model.value as DatePickerRange | null\n if (!r?.start) return ''\n if (!r.end) return formatDateDisplay(r.start, locale, displayFormat)\n return formatDisplayRange(r.start, r.end, locale, displayFormat)\n }\n const list = Array.isArray(model.value) ? model.value : []\n return list.map((iso) => formatDateDisplay(iso, locale, displayFormat)).join(', ')\n})\n\n/* From here on: everything the typed field needs. */\n\nconst mask = computed(() => dateMaskFor(resolvedLocale.value))\nconst maskHint = computed(() => maskPlaceholder(resolvedLocale.value, mask.value))\nconst isDisabledDate = computed(() => resolveMatcher(props.disabledDates))\n\n/**\n * Whether a date the reader has finished typing may actually be taken: it has to fall\n * within the allowed bounds and not be one of the excluded days.\n */\nconst acceptable = (iso: string) => isDateAllowed(iso, props.min, props.max, isDisabledDate.value)\n\n/*\n * The mask machinery — the text being typed, the bridge to the value, the reformatting\n * that preserves the caret, the commit as soon as the date is complete and the silent\n * revert when it is not — is shared with VTimeInput and lives in `useMaskedField`.\n *\n * What is injected here is the date VOCABULARY alone: the order of the fields, the\n * separator between them and their widths, all derived from the reader's language.\n */\nconst {\n draft,\n fieldModel,\n writeField,\n commitOrRevert,\n onFieldInput,\n onKeydown: onMaskKeydown,\n onPaste,\n} = useMaskedField({\n fieldEl,\n typing: () => typing.value,\n displayText: () => displayText.value,\n readValue: () =>\n typeof model.value === 'string' && isValidISO(model.value) ? model.value : null,\n writeValue: (iso) => {\n model.value = iso\n },\n maxDigits: () => mask.value.size,\n format: (digits) => formatDateMask(digits, mask.value),\n caret: (text, digitsBefore, inserting) =>\n caretAfterDigits(text, digitsBefore, inserting ? mask.value.separator : undefined),\n // A two-digit year is only expanded on the FINAL commit, when the reader leaves the\n // field — never while they are still typing, where \"26\" may well be on its way to\n // becoming \"2026\".\n parse: (text, final) =>\n parseDateMask(text, mask.value, final ? { yearPivot: YEAR_PIVOT } : undefined),\n toMask: (iso) => (iso ? isoToMask(iso, mask.value) : ''),\n acceptable,\n})\n\n/**\n * Typing anything that is not a digit — a slash, a dot, a space — completes the field\n * being typed with a leading zero and moves on to the next. It is what lets someone type\n * \"5/6/2026\" and get the same result as typing all eight digits.\n *\n * It applies to the day and the month only: a year cut short has no such convention, \"26\"\n * being neither 0026 nor 2026 until the reader has finished.\n */\nfunction padCurrentField(el: HTMLInputElement) {\n const start = el.selectionStart ?? el.value.length\n const before = digitsOf(el.value.slice(0, start)).length\n const digits = digitsOf(el.value)\n let offset = 0\n for (let k = 0; k < mask.value.order.length; k++) {\n const len = mask.value.lengths[k] as number\n if (before < offset + len) {\n const filled = before - offset\n if (mask.value.order[k] === 'year' || filled !== len - 1) return\n const next = digits.slice(0, offset) + '0'.repeat(len - filled) + digits.slice(offset)\n const text = formatDateMask(next.slice(0, mask.value.size), mask.value)\n writeField(text, caretAfterDigits(text, offset + len, mask.value.separator))\n return\n }\n offset += len\n }\n}\n\n// @keyboard — what the mask's keys mean for a date: a separator completes the field being\n// typed, and the down arrow is the one explicit way from the field into the calendar.\nfunction onFieldKeydown(event: KeyboardEvent) {\n onMaskKeydown(event, {\n onSeparator: padCurrentField,\n onArrowDown: () => {\n if (!open.value) return false\n pickerRef.value?.focus()\n return true\n },\n onEnter: closeAndFocus,\n })\n}\n\n/**\n * Pasting. A date recognizable as a whole — in the ISO form, or already written the way\n * this field writes them — is adopted as it stands; anything else contributes its digits\n * alone.\n */\nfunction onFieldPaste(event: ClipboardEvent) {\n onPaste(event, (pasted) =>\n isValidISO(pasted) ? pasted : parseDateMask(pasted, mask.value, { yearPivot: YEAR_PIVOT }),\n )\n}\n\n/*\n * The clear cross is the field's own, which renders it BEFORE the end icon rather than in\n * its place — the convention every field in the design system follows, so the two live\n * side by side.\n *\n * Whether it is shown has to be answered explicitly here: outside the typed mode the field\n * is read-only, and a read-only field hides its cross by default, rightly so — but here\n * the value comes from the panel, so there is something to clear all the same. The\n * `readonly` PROP is the one case where the default answer was right: frozen, the field\n * offers no route to a new value, so it offers no route to none either.\n */\nconst clearVisible = computed(() =>\n canClear(props, resolvedDisabled.value, hasValue.value || (typing.value && !!draft.value)),\n)\nconst endIcon = computed<IconSource | undefined>(() =>\n hasPanel.value ? props.pickerIcon : undefined,\n)\n// @a11y @devwarn\n/*\n * TRAP — the LABEL is defined at all times, even when no icon is rendered at all.\n *\n * The helper detecting a click handler on an icon warns AT SETUP if one is attached\n * without a label, and it has no way of knowing whether an icon exists. Since the\n * listener here is attached permanently and that detection is static, making the label\n * conditional would produce a false warning every time a field without a calendar is\n * mounted.\n *\n * The wording itself has no prop: the dictionary is where it is changed — see `src/i18n/`.\n */\nconst m = useMessages()\n\nconst endIconLabel = computed(() => props.pickerIconLabel ?? m.value.dateInput.openPicker)\nconst resolvedClearLabel = computed(() => props.clearLabel ?? m.value.dateInput.clear)\n\n/*\n * Emptying the value, called by the field as it emits its clear event. The focus is taken\n * through `focusField`, whose note says why that stops the panel reopening.\n */\nfunction clearValue() {\n model.value =\n props.selection === 'multiple'\n ? []\n : props.selection === 'range'\n ? { start: null, end: null }\n : null\n // The typed text is emptied EXPLICITLY: when the value was already empty, nothing\n // changes, and the guard that keeps the field and the value from chasing each other\n // would leave the text where it was.\n if (typing.value) writeField('')\n focusField()\n emit('clear')\n}\n\n/**\n * A date was chosen in the calendar. Choosing ONE date finishes the job, so the panel\n * closes; a period or a list is still being built and it stays open.\n */\nfunction onSelect() {\n if (props.selection === 'single') closeAndFocus()\n}\n\ndefineExpose({\n /** Moves the focus to the text field. */\n focus: (options?: FocusOptions) => inputRef.value?.focus(options),\n /** Selects what the field is showing. */\n select: () => inputRef.value?.select(),\n /** The real `<input>` behind the field, for what neither of the two above covers. */\n el: computed(() => inputRef.value?.el ?? null),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-date-input\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-open=\"open ? '' : undefined\"\n :data-mode=\"resolvedMode\"\n @focusout=\"onFocusout\"\n @keydown=\"onKeydown\"\n >\n <div class=\"v-date-input-control\" @click=\"onControlClick\">\n <!-- The field is declared a combobox rather than left as the plain text box it\n implicitly is, because a text box may not carry the attribute saying whether\n something is expanded — and a text field with a panel attached IS the combobox\n pattern, the same role VCombobox gives its own field.\n\n The role and the three attributes are all conditioned on the SAME thing, so the\n role never appears without the expanded state it requires, and nothing ever\n points at a panel that was not rendered. -->\n <VInput\n ref=\"inputRef\"\n v-model=\"fieldModel\"\n :inputmode=\"typing ? 'numeric' : undefined\"\n :autocomplete=\"typing ? 'off' : undefined\"\n v-bind=\"fieldAttrs\"\n :readonly=\"!typing || readonly\"\n :label=\"label\"\n :hint=\"hint\"\n :placeholder=\"placeholder ?? (typing ? maskHint : undefined)\"\n :size=\"resolvedSize\"\n :compact=\"resolvedCompact\"\n :disabled=\"resolvedDisabled\"\n :invalid=\"invalid\"\n :clearable=\"clearable\"\n :clear-visible=\"clearVisible\"\n :clear-label=\"resolvedClearLabel\"\n :icon-start=\"iconStart\"\n :icon-start-label=\"iconStartLabel\"\n :loading=\"loading\"\n :loading-label=\"loadingLabel\"\n :icon-end=\"endIcon\"\n :icon-end-label=\"endIconLabel\"\n :role=\"hasPanel ? 'combobox' : undefined\"\n :aria-haspopup=\"hasPanel ? 'dialog' : undefined\"\n :aria-expanded=\"hasPanel ? open : undefined\"\n :aria-controls=\"hasPanel ? panelId : undefined\"\n @click:icon-end=\"toggleFromIcon\"\n @clear=\"clearValue\"\n @focus=\"onFieldFocus\"\n @input=\"onFieldInput\"\n @change=\"commitOrRevert\"\n @blur=\"commitOrRevert\"\n @keydown=\"onFieldKeydown\"\n @paste=\"onFieldPaste\"\n >\n <template v-if=\"$slots.start\" #start><slot name=\"start\" /></template>\n <template v-if=\"$slots['value-end']\" #value-end><slot name=\"value-end\" /></template>\n </VInput>\n </div>\n\n <!-- With no panel rendered there is nothing to hold a reference to, and the open state\n — which is fed by the panel's own events — can no longer become true. The absence\n of a panel is therefore self-enforcing. -->\n <VPopover\n v-if=\"hasPanel\"\n :id=\"panelId\"\n ref=\"panelRef\"\n v-model:open=\"open\"\n mode=\"manual\"\n anchor=\"--date-input-anchor\"\n :placement=\"placement\"\n role=\"dialog\"\n :aria-label=\"label ?? m.dateInput.pickerLabel\"\n class=\"v-date-input-panel\"\n @mousedown=\"onPanelMousedown\"\n >\n <VDatePicker\n ref=\"pickerRef\"\n v-model=\"model\"\n :selection=\"selection\"\n :locale=\"resolvedLocale\"\n :first-day-of-week=\"firstDayOfWeek\"\n :min=\"min\"\n :max=\"max\"\n :disabled-dates=\"disabledDates\"\n :show-adjacent-days=\"showAdjacentDays\"\n :select-adjacent-days=\"selectAdjacentDays\"\n :events=\"events\"\n @select=\"onSelect\"\n >\n <template v-if=\"$slots.day\" #day=\"slotProps\">\n <slot name=\"day\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.footer\" #footer>\n <slot name=\"footer\" :close=\"closeAndFocus\" />\n </template>\n </VDatePicker>\n </VPopover>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-date-input {\n /* Confines the anchor to this instance (the root = the common ancestor of the\n control and the panel) */\n anchor-scope: --date-input-anchor;\n display: block;\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n .v-date-input-control {\n display: block;\n cursor: pointer;\n }\n\n /* The anchor is the FIELD's box and not this wrapper's, which also holds the label and\n the hint: anchored to the wrapper, the calendar opens a hint's height below the field,\n and a label's height above it once there is no room below and `flip-block` turns it\n over. Against the field it covers whichever of the two it lands on, which is what a\n panel belonging to a control is supposed to do. */\n .v-date-input-control .v-input-field {\n anchor-name: --date-input-anchor;\n }\n\n /* Input mode: the field is editable, and the <input>'s text caret takes over from the\n control's `pointer` (which signals \"this opens a panel\"). The mask has a fixed width:\n tabular figures, otherwise the caret jitters from one digit to the next. */\n .v-date-input[data-mode='input'] .v-date-input-control {\n cursor: text;\n }\n\n .v-date-input[data-mode='input'] .v-input-control {\n font-variant-numeric: tabular-nums;\n }\n\n /* `position-anchor` and the chrome come from VPopover (the `anchor` prop, and the\n `.v-panel` it sets on any panel that is not `bare`): only the dimensions are left here,\n which `panel.css` deliberately does not carry. The panel's OWN padding is cancelled,\n VDatePicker padding itself as VTimePicker does, so both pickers keep the same room\n on a page and in a panel. Compounded with `.v-popover-panel` (VPopover puts both\n classes on the same element) because `.v-panel` declares `padding` too, and at\n equal specificity the winner would depend on the order in which the consumer's\n bundler concatenates the CSS. */\n .v-popover-panel.v-date-input-panel {\n width: max-content;\n padding: 0;\n }\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VDateInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VDateInput/VDateInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// @a11y @core\n/**\n * A field for choosing a date: a VInput, and a VDatePicker in a panel below it.\n *\n * The panel is `mode=\"manual\"` and driven imperatively, which is not a detail — `popovertarget`\n * is invalid on a text `<input>`, and opening it ourselves is also what lets focus be moved\n * INTO the grid so the keyboard lands on the dates. Closing is ours too: `focusout`, or Escape.\n *\n * Two FIELD modes, `mode`: `input` (the default) types digits only, the separators appearing\n * as they go in the order and punctuation of the reader's locale; `picker` makes the calendar\n * the only way in. What the field is FOR is a different question from the `readonly` prop,\n * which freezes whatever it holds by every route at once.\n *\n * That is a different question from WHAT is chosen — one date, a range, or several — which is\n * `selection`, passed straight through to the picker.\n */\n\nimport { computed, inject, provide, ref, watchEffect } from 'vue'\n\nimport { inputGroupKey } from '../VInput/context'\n\nimport VDatePicker from '../VDatePicker/VDatePicker.vue'\nimport type {\n DatePickerDaySlotProps,\n DatePickerEvent,\n DatePickerSelection,\n DatePickerValue,\n DatePickerMatcher,\n DatePickerRange,\n} from '../VDatePicker/VDatePicker.vue'\nimport {\n compareISO,\n formatDateDisplay,\n formatDisplayRange,\n isDateAllowed,\n isValidISO,\n} from '../../utils/date'\nimport {\n caretAfterDigits,\n dateMaskFor,\n formatDateMask,\n isoToMask,\n maskPlaceholder,\n parseDateMask,\n} from './mask'\nimport { digitsOf } from '../../utils/text'\nimport { resolveMatcher } from '../../utils/matcher'\nimport { isDev } from '../../utils/env'\nimport { hostWarnsKey } from '../../utils/hostWarns'\nimport { calendar_today as calendarTodayIcon } from '../VIcon/icons/calendar_today'\nimport type { IconSource } from '../VIcon/types'\nimport VInput from '../VInput/VInput.vue'\nimport VPopover from '../VPopover/VPopover.vue'\n\nimport { useControlShape } from '../../composables/useControlShape'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\nimport { useFieldPanel } from '../../composables/useFieldPanel'\nimport { canClear } from '../../composables/useClearable'\nimport { iconStartListener } from '../../composables/useIconClickHandlers'\nimport { useMaskedField } from '../../composables/useMaskedField'\nimport { useMessages, useResolvedLocale } from '../../i18n/state'\n\n/** Where the calendar opens relative to the field. */\nexport type DateInputPlacement =\n 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end'\n\n/** Whether the field can be typed into, or only filled from the calendar. */\nexport type DateInputMode = 'picker' | 'input'\n\n/** What the `#footer` slot receives. */\nexport interface DateInputFooterSlotProps {\n /** Closes the panel and hands the focus back to the field. */\n close: () => void\n}\n\nconst MODES: DateInputMode[] = ['picker', 'input']\n\n/**\n * The century a two-digit year is expanded into — \"10/06/26\" becomes 2026 — applied only\n * when the reader leaves the field.\n *\n * It is FIXED and never derived from the current year. A sliding rule would make the\n * component's behaviour depend on when it runs, which is the same objection that keeps\n * today's date out of VDatePicker's setup, and it would give the tests a shelf life.\n */\nconst YEAR_PIVOT = 2000\n\nconst DEFAULT_DISPLAY_FORMAT: Intl.DateTimeFormatOptions = {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n}\n\n/** The height of the field: 32, 40 or 48 pixels. */\nexport type DateInputSize = 'sm' | 'md' | 'lg'\n\ninterface DateInputProps {\n // Everything from here to `events` is handed straight to the calendar.\n /** What is being chosen: one date, a period between two, or several separate dates. */\n selection?: DatePickerSelection\n /**\n * A BCP 47 locale, which decides the month and day names, the first day of the week and\n * the order the field is typed in. It TAKES PRECEDENCE over the design system's global\n * locale and falls back to it, which is why it has no literal default: `undefined` has\n * to stay recognizable for the global locale to have its chance.\n */\n locale?: string\n /** Forces the day the weeks start on, from 0 for Sunday to 6 for Saturday. */\n firstDayOfWeek?: number\n /** The earliest date that can be chosen, as an ISO string. */\n min?: string\n /** The latest date that can be chosen, as an ISO string. */\n max?: string\n /** Dates that cannot be chosen, as a list or as a function. */\n disabledDates?: DatePickerMatcher\n /** Fills the corners of the grid with the greyed days of the neighbouring months. */\n showAdjacentDays?: boolean\n /** Lets those neighbouring days be clicked, which implies showing them. */\n selectAdjacentDays?: boolean\n /** Events to mark under the days they fall on. */\n events?: DatePickerEvent[]\n // From here on: the field.\n /**\n * Whether the field can be TYPED into (the default, using the numeric form of the\n * reader's language) or is filled from the calendar alone, which is `picker`.\n *\n * Typing is reserved for choosing a SINGLE date: a period or a list falls back to\n * `picker`, there being no sensible way to type either.\n */\n mode?: DateInputMode\n /**\n * Offers the date picker alongside a field that can be typed into: an icon at the end of\n * the field, and a panel that opens on focus. It means nothing in `picker` mode, where\n * the calendar is already the only way to choose.\n */\n showPicker?: boolean\n /** The label above the field. */\n label?: string\n /** A line of help under the field. */\n hint?: string\n /** What the field says while empty. */\n placeholder?: string\n /** The height of the field: 32, 40 or 48 pixels. */\n size?: DateInputSize\n /** Takes 4px off the height. */\n compact?: boolean\n /** Makes the field unusable, greyed out through the colour tokens. */\n disabled?: boolean\n /**\n * Shows the date without letting it be changed: nothing can be typed, there is no\n * calendar and no clear cross. The field stays focusable and can be copied from,\n * which is what separates it from `disabled`, and it is a different question from\n * `mode`, which says how a field that CAN be changed is filled in.\n */\n readonly?: boolean\n /** Marks the field as invalid, for a rule of your own. */\n invalid?: boolean\n /**\n * An icon inside the field, at the start. It is decorative by default and becomes a\n * real button as soon as a `@click:icon-start` listener is attached, in which case it\n * needs `iconStartLabel`.\n */\n iconStart?: IconSource\n /** What the start icon does, in words, once it is clickable. */\n iconStartLabel?: string\n /**\n * What the calendar button does, in words. It names the button `pickerIcon` renders,\n * and falls back to the design system dictionary.\n */\n pickerIconLabel?: string\n /**\n * Shows a spinner at the end of the field, in place of the calendar icon. It says\n * that something is being loaded and changes nothing else: the field can still be\n * typed into and the panel still opens.\n */\n loading?: boolean\n /**\n * What screen readers announce while the spinner turns. It falls back to the design\n * system dictionary.\n */\n loadingText?: string\n /** Offers a cross that empties the value, shown before the end icon. */\n clearable?: boolean\n /** What that cross does, in words. It falls back to the design system dictionary. */\n clearLabel?: string\n /**\n * The icon that opens the date picker, at the end of the field. The clear cross appears\n * to its left rather than in its place, and no icon is rendered at all when there is no\n * panel to open.\n */\n pickerIcon?: IconSource\n /**\n * How the date is WRITTEN OUT in the field. It has no effect on a field being typed\n * into, which necessarily shows the numeric form one types, so it concerns the\n * `picker` mode, and the period and list selections, which fall back to it.\n */\n displayFormat?: Intl.DateTimeFormatOptions\n /** Where the panel opens relative to the field. */\n placement?: DateInputPlacement\n}\n\nconst props = withDefaults(defineProps<DateInputProps>(), {\n selection: 'single',\n locale: undefined,\n firstDayOfWeek: undefined,\n min: undefined,\n max: undefined,\n disabledDates: undefined,\n showAdjacentDays: false,\n selectAdjacentDays: false,\n events: undefined,\n // Deliberately left undefined rather than defaulted to the typed mode: that is what\n // distinguishes \"the prop was not given\" from \"the prop was given this value\", and\n // therefore what allows warning ONLY the consumer who explicitly asked for something\n // that cannot work.\n mode: undefined,\n showPicker: false,\n label: undefined,\n hint: undefined,\n placeholder: undefined,\n size: 'md',\n compact: false,\n disabled: false,\n readonly: false,\n invalid: false,\n iconStart: undefined,\n iconStartLabel: undefined,\n pickerIconLabel: undefined,\n loading: false,\n loadingText: undefined,\n clearable: false,\n clearLabel: undefined,\n pickerIcon: () => calendarTodayIcon,\n // Left undefined rather than defaulted to the format object, for the same reason: it is\n // what lets the component notice that a consumer has asked for a display format in a\n // mode where it has no effect, and say so.\n displayFormat: undefined,\n placement: 'bottom-start',\n})\n\n/**\n * The date or dates chosen, in the shape `selection` calls for: an ISO `YYYY-MM-DD` string\n * for `single`, a `{ start, end }` pair for `range`, an array for `multiple`. Nothing is\n * selected to begin with.\n *\n * While the reader types, it is only written once what they have entered is a complete and\n * acceptable date; an unfinished or refused entry leaves it untouched and is reverted when\n * they leave the field.\n */\nconst model = defineModel<DatePickerValue>({ default: null })\n\nconst emit = defineEmits<{\n /** The clear cross emptied the field. The value has already been reset. */\n clear: []\n /** The start icon was clicked. Attaching this listener is what makes it a button. */\n 'click:icon-start': [event: MouseEvent]\n}>()\n\ndefineSlots<{\n /**\n * Content at the start of the field, rendered after `iconStart` rather than in its place,\n * as in VInput.\n */\n start?(): unknown\n /**\n * Controls of your own inside the field, placed before the ones the field owns: the clear\n * cross and the icon that opens the panel. Those two are this component's own affordance,\n * which is why there is no `#end` here: it would replace them.\n */\n 'value-end'?(): unknown\n /** What a day cell shows, handed straight to the calendar. */\n day?(props: DatePickerDaySlotProps): unknown\n /**\n * The strip at the foot of the panel: actions, or preset dates such as \"today\". It\n * receives `close`, which is what lets one of those buttons dismiss the panel.\n */\n footer?(props: DateInputFooterSlotProps): unknown\n}>()\n\n// `class` and `style` stay on the wrapper; everything else goes down to the text field,\n// which is what a consumer's label points at and what assistive technology deals with.\ndefineOptions({ inheritAttrs: false })\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\n// Declared as this component's own event, `click:icon-start` is out of `$attrs`, so the\n// listener is relayed to the field by hand — and only when the consumer wrote one.\nconst iconStartClick = iconStartListener((event) => emit('click:icon-start', event))\n\n/** What reaches the field: the consumer's own attributes, plus that listener. */\nconst fieldAttrs = computed(() => ({ ...forwardedAttrs.value, ...iconStartClick }))\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelRef = ref<InstanceType<typeof VPopover> | null>(null)\nconst inputRef = ref<InstanceType<typeof VInput> | null>(null)\nconst pickerRef = ref<InstanceType<typeof VDatePicker> | null>(null)\n\n/** The real input inside the field, which the mask and the caret work on. */\nconst fieldEl = computed<HTMLInputElement | null>(() => inputRef.value?.el ?? null)\n\n/** What was asked for, falling back to the default when nothing or nonsense was given. */\nconst requestedMode = computed<DateInputMode>(() =>\n props.mode !== undefined && MODES.includes(props.mode) ? props.mode : 'input',\n)\n/**\n * What is actually used. Typing is only possible for a single date: a period or a list\n * has no form one could type into a single field.\n */\nconst resolvedMode = computed<DateInputMode>(() =>\n requestedMode.value === 'input' && props.selection === 'single' ? 'input' : 'picker',\n)\nconst typing = computed(() => resolvedMode.value === 'input')\n\n/**\n * Whether there is a panel at all. The calendar is only optional beside a field one can\n * type into: in `picker` mode it is the only way to choose anything, and a frozen field\n * has none at all.\n */\nconst hasPanel = computed(() => !props.readonly && (!typing.value || props.showPicker))\n\n// @devwarn\nif (isDev) {\n // The calendar receives `min` and `max` as they stand, so what it would say about them is\n // said here, under the name the consumer wrote (utils/hostWarns).\n provide(hostWarnsKey, true)\n watchEffect(() => {\n if (props.min && props.max && compareISO(props.min, props.max) > 0)\n console.warn(\n `[VDateInput] min \"${props.min}\" falls after max \"${props.max}\", so no date can be chosen.`,\n )\n // Without a panel there is no icon to draw and no button to name. A read-only field is\n // left out: it is a state that comes and goes, not a configuration to correct.\n if (typing.value && !props.showPicker) {\n const inert = ([] as string[]).concat(\n props.pickerIcon !== calendarTodayIcon ? 'pickerIcon' : [],\n props.pickerIconLabel ? 'pickerIconLabel' : [],\n )\n if (inert.length > 0)\n console.warn(\n `[VDateInput] ${inert.join(', ')} ${inert.length > 1 ? 'are' : 'is'} ignored without showPicker: a field one types into has no calendar icon unless it offers the calendar.`,\n )\n }\n if (props.mode !== undefined && !MODES.includes(props.mode))\n console.warn(\n `[VDateInput] unknown mode \"${props.mode}\": use \"input\" (the default) or \"picker\".`,\n )\n // Tested on the PROP and not on what was resolved from it: typing being the default,\n // a period or a list falls back on its own with nobody having asked for anything.\n // Only a consumer who explicitly asked to type deserves to be told it cannot work.\n if (props.mode === 'input' && props.selection !== 'single')\n console.warn(\n `[VDateInput] mode=\"input\" ignored in \"${props.selection}\" selection: a range or a list of dates cannot be typed on the keyboard.`,\n )\n // Here it is the RESOLVED mode that matters: the format really was supplied, and it\n // really will have no effect, whichever route led to a typed field. The warning stays\n // something the consumer can act on.\n if (props.displayFormat && typing.value)\n console.warn(\n '[VDateInput] displayFormat is ignored in \"input\" mode (the default): the field displays the locale\\'s numeric mask, the only typeable format. Pass mode=\"picker\" for a formatted display.',\n )\n })\n}\n\n// A VInputGroup joins several controls into one object, so the shape of this field is the\n// row's decision rather than its own (VInput/context.ts).\nconst group = inject(inputGroupKey, null)\nconst {\n size: resolvedSize,\n compact: resolvedCompact,\n disabled: resolvedDisabled,\n} = useControlShape(props, group)\n\n// The whole \"field plus panel\" shell, shared with VTimeInput: opening and closing, the\n// focus leaving the component and coming back to the field, a click on the field or its\n// icon, and the Escape, ArrowDown and Enter keys.\nconst {\n open,\n panelId,\n closeAndFocus,\n focusField,\n onFieldFocus,\n toggleFromIcon,\n onControlClick,\n onFocusout,\n onKeydown,\n onPanelMousedown,\n} = useFieldPanel({\n rootEl,\n panelRef,\n field: inputRef,\n // With no panel there is nothing to open. This is the composable's SINGLE cut-off\n // point, and every way in passes through it — clicking the field, focusing it, the\n // down arrow, Enter, the icon — so the condition never has to be repeated in a\n // handler.\n disabled: () => resolvedDisabled.value || !hasPanel.value,\n focusInPanel: () => pickerRef.value?.focus(),\n // The calendar stays mounted while the panel is closed, so it is put back on the days\n // view both ways: a field that opens on focus never goes through `focus()`.\n onOpen: () => pickerRef.value?.reset(),\n onClose: () => pickerRef.value?.reset(),\n // Beside a field one types into, the panel opens on focus WITHOUT taking it: typing\n // carries on in the field, and the down arrow remains the way into the grid.\n openOnFocus: () => typing.value,\n})\n\n// @a11y\n// TRAP — the popup wiring is spread OVER the forwarded attributes, never bound as four\n// attributes after them. A binding written after `v-bind` wins even when it is\n// `undefined`, so a field with no panel would erase the consumer's own `role` or\n// `aria-controls`; spread, the wiring carries no key at all when there is no panel, and\n// wins over the consumer's when there is one, which is what a combobox needs.\nconst inputAttrs = computed(() =>\n hasPanel.value\n ? {\n ...fieldAttrs.value,\n role: 'combobox',\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open.value,\n 'aria-controls': panelId,\n }\n : fieldAttrs.value,\n)\n\nconst hasValue = computed(() => {\n if (props.selection === 'multiple') return Array.isArray(model.value) && model.value.length > 0\n if (props.selection === 'range') {\n const r = model.value as DatePickerRange | null\n return !!(r && (r.start || r.end))\n }\n return typeof model.value === 'string' && !!model.value\n})\n\n/* TRAP — this component is the SINGLE place the locale is resolved: what flows down to the\n calendar is the RESULT, never the prop, which would usually be undefined and would have\n the calendar resolve the language a second time — with every chance of the two\n disagreeing after a later change. */\nconst resolvedLocale = useResolvedLocale(() => props.locale)\n\nconst displayText = computed(() => {\n const locale = resolvedLocale.value\n const displayFormat = props.displayFormat ?? DEFAULT_DISPLAY_FORMAT\n if (props.selection === 'single') {\n return typeof model.value === 'string' && isValidISO(model.value)\n ? formatDateDisplay(model.value, locale, displayFormat)\n : ''\n }\n if (props.selection === 'range') {\n const r = model.value as DatePickerRange | null\n if (!r?.start) return ''\n if (!r.end) return formatDateDisplay(r.start, locale, displayFormat)\n return formatDisplayRange(r.start, r.end, locale, displayFormat)\n }\n const list = Array.isArray(model.value) ? model.value : []\n return list.map((iso) => formatDateDisplay(iso, locale, displayFormat)).join(', ')\n})\n\n/* From here on: everything the typed field needs. */\n\nconst mask = computed(() => dateMaskFor(resolvedLocale.value))\nconst maskHint = computed(() => maskPlaceholder(resolvedLocale.value, mask.value))\nconst isDisabledDate = computed(() => resolveMatcher(props.disabledDates))\n\n/**\n * Whether a date the reader has finished typing may actually be taken: it has to fall\n * within the allowed bounds and not be one of the excluded days.\n */\nconst acceptable = (iso: string) => isDateAllowed(iso, props.min, props.max, isDisabledDate.value)\n\n/*\n * The mask machinery — the text being typed, the bridge to the value, the reformatting\n * that preserves the caret, the commit as soon as the date is complete and the silent\n * revert when it is not — is shared with VTimeInput and lives in `useMaskedField`.\n *\n * What is injected here is the date VOCABULARY alone: the order of the fields, the\n * separator between them and their widths, all derived from the reader's language.\n */\nconst {\n draft,\n fieldModel,\n writeField,\n commitOrRevert,\n onFieldInput,\n onKeydown: onMaskKeydown,\n onPaste,\n} = useMaskedField({\n fieldEl,\n typing: () => typing.value,\n displayText: () => displayText.value,\n readValue: () =>\n typeof model.value === 'string' && isValidISO(model.value) ? model.value : null,\n writeValue: (iso) => {\n model.value = iso\n },\n maxDigits: () => mask.value.size,\n format: (digits) => formatDateMask(digits, mask.value),\n caret: (text, digitsBefore, inserting) =>\n caretAfterDigits(text, digitsBefore, inserting ? mask.value.separator : undefined),\n // A two-digit year is only expanded on the FINAL commit, when the reader leaves the\n // field — never while they are still typing, where \"26\" may well be on its way to\n // becoming \"2026\".\n parse: (text, final) =>\n parseDateMask(text, mask.value, final ? { yearPivot: YEAR_PIVOT } : undefined),\n toMask: (iso) => (iso ? isoToMask(iso, mask.value) : ''),\n acceptable,\n})\n\n/**\n * Typing anything that is not a digit — a slash, a dot, a space — completes the field\n * being typed with a leading zero and moves on to the next. It is what lets someone type\n * \"5/6/2026\" and get the same result as typing all eight digits.\n *\n * It applies to the day and the month only: a year cut short has no such convention, \"26\"\n * being neither 0026 nor 2026 until the reader has finished.\n */\nfunction padCurrentField(el: HTMLInputElement) {\n const start = el.selectionStart ?? el.value.length\n const before = digitsOf(el.value.slice(0, start)).length\n const digits = digitsOf(el.value)\n let offset = 0\n for (let k = 0; k < mask.value.order.length; k++) {\n const len = mask.value.lengths[k] as number\n if (before < offset + len) {\n const filled = before - offset\n if (mask.value.order[k] === 'year' || filled !== len - 1) return\n const next = digits.slice(0, offset) + '0'.repeat(len - filled) + digits.slice(offset)\n const text = formatDateMask(next.slice(0, mask.value.size), mask.value)\n writeField(text, caretAfterDigits(text, offset + len, mask.value.separator))\n return\n }\n offset += len\n }\n}\n\n// @keyboard\n// What the mask's keys mean for a date: a separator completes the field being\n// typed, and the down arrow is the one explicit way from the field into the calendar.\nfunction onFieldKeydown(event: KeyboardEvent) {\n onMaskKeydown(event, {\n onSeparator: padCurrentField,\n onArrowDown: () => {\n if (!open.value) return false\n pickerRef.value?.focus()\n return true\n },\n onEnter: closeAndFocus,\n })\n}\n\n/**\n * Pasting. A date recognizable as a whole — in the ISO form, or already written the way\n * this field writes them — is adopted as it stands; anything else contributes its digits\n * alone.\n */\nfunction onFieldPaste(event: ClipboardEvent) {\n onPaste(event, (pasted) =>\n isValidISO(pasted) ? pasted : parseDateMask(pasted, mask.value, { yearPivot: YEAR_PIVOT }),\n )\n}\n\n/*\n * The clear cross is the field's own, which renders it BEFORE the end icon rather than in\n * its place — the convention every field in the design system follows, so the two live\n * side by side.\n *\n * Whether it is shown has to be answered explicitly here: outside the typed mode the field\n * is read-only, and a read-only field hides its cross by default, rightly so — but here\n * the value comes from the panel, so there is something to clear all the same. The\n * `readonly` PROP is the one case where the default answer was right: frozen, the field\n * offers no route to a new value, so it offers no route to none either.\n */\nconst clearVisible = computed(() =>\n canClear(props, resolvedDisabled.value, hasValue.value || (typing.value && !!draft.value)),\n)\nconst endIcon = computed<IconSource | undefined>(() =>\n hasPanel.value ? props.pickerIcon : undefined,\n)\n// @a11y @devwarn\n/*\n * TRAP — the LABEL is defined at all times, even when no icon is rendered at all.\n *\n * The helper detecting a click handler on an icon warns AT SETUP if one is attached\n * without a label, and it has no way of knowing whether an icon exists. Since the\n * listener here is attached permanently and that detection is static, making the label\n * conditional would produce a false warning every time a field without a calendar is\n * mounted.\n *\n * The wording itself has no prop: the dictionary is where it is changed — see `src/i18n/`.\n */\nconst m = useMessages()\n\nconst endIconLabel = computed(() => props.pickerIconLabel ?? m.value.dateInput.openPicker)\nconst resolvedClearLabel = computed(() => props.clearLabel ?? m.value.dateInput.clear)\n\n/*\n * Emptying the value, called by the field as it emits its clear event. The focus is taken\n * through `focusField`, whose note says why that stops the panel reopening.\n */\nfunction clearValue() {\n model.value =\n props.selection === 'multiple'\n ? []\n : props.selection === 'range'\n ? { start: null, end: null }\n : null\n // The typed text is emptied EXPLICITLY: when the value was already empty, nothing\n // changes, and the guard that keeps the field and the value from chasing each other\n // would leave the text where it was.\n if (typing.value) writeField('')\n focusField()\n emit('clear')\n}\n\n/**\n * A date was chosen in the calendar. Choosing ONE date finishes the job, so the panel\n * closes; a period or a list is still being built and it stays open.\n */\nfunction onSelect() {\n if (props.selection === 'single') closeAndFocus()\n}\n\ndefineExpose({\n /** Moves the focus to the text field. */\n focus: (options?: FocusOptions) => inputRef.value?.focus(options),\n /** Selects what the field is showing. */\n select: () => inputRef.value?.select(),\n /** The real `<input>` behind the field, for what neither of the two above covers. */\n el: computed(() => inputRef.value?.el ?? null),\n})\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-date-input\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :data-open=\"open ? '' : undefined\"\n :data-mode=\"resolvedMode\"\n :data-disabled=\"resolvedDisabled ? '' : undefined\"\n :data-readonly=\"readonly ? '' : undefined\"\n @focusout=\"onFocusout\"\n @keydown=\"onKeydown\"\n >\n <div class=\"v-date-input-control\" @click=\"onControlClick\">\n <!-- The field is declared a combobox rather than left as the plain text box it\n implicitly is, because a text box may not carry the attribute saying whether\n something is expanded — and a text field with a panel attached IS the combobox\n pattern, the same role VCombobox gives its own field.\n\n The role and the three attributes are all conditioned on the SAME thing, so the\n role never appears without the expanded state it requires, and nothing ever\n points at a panel that was not rendered. -->\n <VInput\n ref=\"inputRef\"\n v-model=\"fieldModel\"\n :inputmode=\"typing ? 'numeric' : undefined\"\n :autocomplete=\"typing ? 'off' : undefined\"\n v-bind=\"inputAttrs\"\n :readonly=\"readonly\"\n :no-typing=\"!typing\"\n :label=\"label\"\n :hint=\"hint\"\n :placeholder=\"placeholder ?? (typing ? maskHint : undefined)\"\n :size=\"resolvedSize\"\n :compact=\"resolvedCompact\"\n :disabled=\"resolvedDisabled\"\n :invalid=\"invalid\"\n :clearable=\"clearable\"\n :clear-visible=\"clearVisible\"\n :clear-label=\"resolvedClearLabel\"\n :icon-start=\"iconStart\"\n :icon-start-label=\"iconStartLabel\"\n :loading=\"loading\"\n :loading-text=\"loadingText\"\n :icon-end=\"endIcon\"\n :icon-end-label=\"endIconLabel\"\n @click:icon-end=\"toggleFromIcon\"\n @clear=\"clearValue\"\n @focus=\"onFieldFocus\"\n @input=\"onFieldInput\"\n @change=\"commitOrRevert\"\n @blur=\"commitOrRevert\"\n @keydown=\"onFieldKeydown\"\n @paste=\"onFieldPaste\"\n >\n <template v-if=\"$slots.start\" #start><slot name=\"start\" /></template>\n <template v-if=\"$slots['value-end']\" #value-end><slot name=\"value-end\" /></template>\n </VInput>\n </div>\n\n <!-- With no panel rendered there is nothing to hold a reference to, and the open state\n — which is fed by the panel's own events — can no longer become true. The absence\n of a panel is therefore self-enforcing. -->\n <VPopover\n v-if=\"hasPanel\"\n :id=\"panelId\"\n ref=\"panelRef\"\n v-model:open=\"open\"\n mode=\"manual\"\n anchor=\"--date-input-anchor\"\n :placement=\"placement\"\n role=\"dialog\"\n :aria-label=\"label ?? m.dateInput.pickerLabel\"\n class=\"v-date-input-panel\"\n @mousedown=\"onPanelMousedown\"\n >\n <VDatePicker\n ref=\"pickerRef\"\n v-model=\"model\"\n :selection=\"selection\"\n :locale=\"resolvedLocale\"\n :first-day-of-week=\"firstDayOfWeek\"\n :min=\"min\"\n :max=\"max\"\n :disabled-dates=\"disabledDates\"\n :show-adjacent-days=\"showAdjacentDays\"\n :select-adjacent-days=\"selectAdjacentDays\"\n :events=\"events\"\n @select=\"onSelect\"\n >\n <template v-if=\"$slots.day\" #day=\"slotProps\">\n <slot name=\"day\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.footer\" #footer>\n <slot name=\"footer\" :close=\"closeAndFocus\" />\n </template>\n </VDatePicker>\n </VPopover>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-date-input {\n /* Confines the anchor to this instance (the root = the common ancestor of the\n control and the panel) */\n anchor-scope: --date-input-anchor;\n display: block;\n width: 100%;\n font-family: var(--vectis-text-family);\n }\n\n /* The pointer says \"this opens a panel\", which a read-only or disabled field no longer\n does: the VFileInput gating. */\n .v-date-input:not([data-disabled]):not([data-readonly]) .v-date-input-control {\n cursor: pointer;\n }\n\n /* The anchor is the FIELD's box and not this wrapper's, which also holds the label and\n the hint: anchored to the wrapper, the calendar opens a hint's height below the field,\n and a label's height above it once there is no room below and `flip-block` turns it\n over. Against the field it covers whichever of the two it lands on, which is what a\n panel belonging to a control is supposed to do. */\n .v-date-input-control .v-input-field {\n anchor-name: --date-input-anchor;\n }\n\n /* Input mode: the field is editable, and the <input>'s text caret takes over from the\n control's `pointer` (which signals \"this opens a panel\"). The mask has a fixed width:\n tabular figures, otherwise the caret jitters from one digit to the next. */\n .v-date-input[data-mode='input']:not([data-disabled]):not([data-readonly]) .v-date-input-control {\n cursor: text;\n }\n\n .v-date-input[data-mode='input'] .v-input-control {\n font-variant-numeric: tabular-nums;\n }\n\n /* `position-anchor` and the chrome come from VPopover (the `anchor` prop, and the\n `.v-panel` it sets on any panel that is not `bare`): only the dimensions are left here,\n which `panel.css` deliberately does not carry. The panel's OWN padding is cancelled,\n VDatePicker padding itself as VTimePicker does, so both pickers keep the same room\n on a page and in a panel. Compounded with `.v-popover-panel` (VPopover puts both\n classes on the same element) because `.v-panel` declares `padding` too, and at\n equal specificity the winner would depend on the order in which the consumer's\n bundler concatenates the CSS. */\n .v-popover-panel.v-date-input-panel {\n width: max-content;\n padding: 0;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GAuFM,IAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAVnB,IAAM,IAAyB,CAAC,UAAU,OAAO,GAY3C,KAAqD;GACzD,KAAK;GACL,OAAO;GACP,MAAM;EACR,GA8GM,IAAQ,GAgDR,IAAQ,GAA4B,GAAA,YAAkB,GAEtD,IAAO,GA+BP,EAAE,eAAW,eAAW,uBAAmB,EAAa,GAIxD,KAAiB,IAAmB,MAAU,EAAK,oBAAoB,CAAK,CAAC,GAG7E,IAAa,SAAgB;GAAE,GAAG,GAAe;GAAO,GAAG;EAAe,EAAE,GAE5E,IAAS,EAAwB,IAAI,GACrC,IAAW,EAA0C,IAAI,GACzD,IAAW,EAAwC,IAAI,GACvD,IAAY,EAA6C,IAAI,GAG7D,KAAU,QAAwC,EAAS,OAAO,MAAM,IAAI,GAG5E,KAAgB,QACpB,EAAM,SAAS,KAAA,KAAa,EAAM,SAAS,EAAM,IAAI,IAAI,EAAM,OAAO,OACxE,GAKM,IAAe,QACnB,GAAc,UAAU,WAAW,EAAM,cAAc,WAAW,UAAU,QAC9E,GACM,IAAS,QAAe,EAAa,UAAU,OAAO,GAOtD,IAAW,QAAe,CAAC,EAAM,aAAa,CAAC,EAAO,SAAS,EAAM,WAAW;EAGtF,AAAI,MAGF,GAAQ,IAAc,EAAI,GAC1B,SAAkB;GAOhB,IANI,EAAM,OAAO,EAAM,OAAO,GAAW,EAAM,KAAK,EAAM,GAAG,IAAI,KAC/D,QAAQ,KACN,qBAAqB,EAAM,IAAI,qBAAqB,EAAM,IAAI,6BAChE,GAGE,EAAO,SAAS,CAAC,EAAM,YAAY;IACrC,IAAM,IAAS,CAAC,CAAC,CAAc,OAC7B,EAAM,eAAe,IAAmC,CAAC,IAAhB,cACzC,EAAM,kBAAkB,oBAAoB,CAAC,CAC/C;IACA,AAAI,EAAM,SAAS,KACjB,QAAQ,KACN,gBAAgB,EAAM,KAAK,IAAI,EAAE,GAAG,EAAM,SAAS,IAAI,QAAQ,KAAK,wGACtE;GACJ;GAeA,AAdI,EAAM,SAAS,KAAA,KAAa,CAAC,EAAM,SAAS,EAAM,IAAI,KACxD,QAAQ,KACN,8BAA8B,EAAM,KAAK,0CAC3C,GAIE,EAAM,SAAS,WAAW,EAAM,cAAc,YAChD,QAAQ,KACN,yCAAyC,EAAM,UAAU,yEAC3D,GAIE,EAAM,iBAAiB,EAAO,SAChC,QAAQ,KACN,8LACF;EACJ,CAAC;EAMH,IAAM,EACJ,MAAM,IACN,SAAS,IACT,UAAU,MACR,EAAgB,GALN,GAAO,IAAe,IAKT,CAAK,GAK1B,EACJ,SACA,YACA,kBACA,gBACA,kBACA,oBACA,mBACA,eACA,cACA,yBACE,GAAc;GAChB;GACA;GACA,OAAO;GAKP,gBAAgB,EAAiB,SAAS,CAAC,EAAS;GACpD,oBAAoB,EAAU,OAAO,MAAM;GAG3C,cAAc,EAAU,OAAO,MAAM;GACrC,eAAe,EAAU,OAAO,MAAM;GAGtC,mBAAmB,EAAO;EAC5B,CAAC,GAQK,KAAa,QACjB,EAAS,QACL;GACE,GAAG,EAAW;GACd,MAAM;GACN,iBAAiB;GACjB,iBAAiB,EAAK;GACtB,iBAAiB;EACnB,IACA,EAAW,KACjB,GAEM,KAAW,QAAe;GAC9B,IAAI,EAAM,cAAc,YAAY,OAAO,MAAM,QAAQ,EAAM,KAAK,KAAK,EAAM,MAAM,SAAS;GAC9F,IAAI,EAAM,cAAc,SAAS;IAC/B,IAAM,IAAI,EAAM;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE;GAC/B;GACA,OAAO,OAAO,EAAM,SAAU,YAAY,CAAC,CAAC,EAAM;EACpD,CAAC,GAMK,IAAiB,QAAwB,EAAM,MAAM,GAErD,KAAc,QAAe;GACjC,IAAM,IAAS,EAAe,OACxB,IAAgB,EAAM,iBAAiB;GAC7C,IAAI,EAAM,cAAc,UACtB,OAAO,OAAO,EAAM,SAAU,YAAY,EAAW,EAAM,KAAK,IAC5D,EAAkB,EAAM,OAAO,GAAQ,CAAa,IACpD;GAEN,IAAI,EAAM,cAAc,SAAS;IAC/B,IAAM,IAAI,EAAM;IAGhB,OAFK,GAAG,QACH,EAAE,MACA,GAAmB,EAAE,OAAO,EAAE,KAAK,GAAQ,CAAa,IAD5C,EAAkB,EAAE,OAAO,GAAQ,CAAa,IAD7C;GAGxB;GAEA,QADa,MAAM,QAAQ,EAAM,KAAK,IAAI,EAAM,QAAQ,CAAC,EAAA,CAC7C,KAAK,MAAQ,EAAkB,GAAK,GAAQ,CAAa,CAAC,CAAC,CAAC,KAAK,IAAI;EACnF,CAAC,GAIK,IAAO,QAAe,GAAY,EAAe,KAAK,CAAC,GACvD,KAAW,QAAe,GAAgB,EAAe,OAAO,EAAK,KAAK,CAAC,GAC3E,KAAiB,QAAe,EAAe,EAAM,aAAa,CAAC,GAgBnE,EACJ,WACA,eACA,eACA,mBACA,kBACA,WAAW,IACX,gBACE,EAAe;GACjB;GACA,cAAc,EAAO;GACrB,mBAAmB,GAAY;GAC/B,iBACE,OAAO,EAAM,SAAU,YAAY,EAAW,EAAM,KAAK,IAAI,EAAM,QAAQ;GAC7E,aAAa,MAAQ;IACnB,EAAM,QAAQ;GAChB;GACA,iBAAiB,EAAK,MAAM;GAC5B,SAAS,MAAW,EAAe,GAAQ,EAAK,KAAK;GACrD,QAAQ,GAAM,GAAc,MAC1B,EAAiB,GAAM,GAAc,IAAY,EAAK,MAAM,YAAY,KAAA,CAAS;GAInF,QAAQ,GAAM,MACZ,EAAc,GAAM,EAAK,OAAO,IAAQ,EAAE,WAAW,EAAW,IAAI,KAAA,CAAS;GAC/E,SAAS,MAAS,IAAM,GAAU,GAAK,EAAK,KAAK,IAAI;GACrD,aArCkB,MAAgB,GAAc,GAAK,EAAM,KAAK,EAAM,KAAK,GAAe,KAAK;EAsCjG,CAAC;EAUD,SAAS,GAAgB,GAAsB;GAC7C,IAAM,IAAQ,EAAG,kBAAkB,EAAG,MAAM,QACtC,IAAS,EAAS,EAAG,MAAM,MAAM,GAAG,CAAK,CAAC,CAAC,CAAC,QAC5C,IAAS,EAAS,EAAG,KAAK,GAC5B,IAAS;GACb,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,MAAM,MAAM,QAAQ,KAAK;IAChD,IAAM,IAAM,EAAK,MAAM,QAAQ;IAC/B,IAAI,IAAS,IAAS,GAAK;KACzB,IAAM,IAAS,IAAS;KACxB,IAAI,EAAK,MAAM,MAAM,OAAO,UAAU,MAAW,IAAM,GAAG;KAE1D,IAAM,IAAO,GADA,EAAO,MAAM,GAAG,CAAM,IAAI,IAAI,OAAO,IAAM,CAAM,IAAI,EAAO,MAAM,CAAM,EAAA,CACpD,MAAM,GAAG,EAAK,MAAM,IAAI,GAAG,EAAK,KAAK;KACtE,EAAW,GAAM,EAAiB,GAAM,IAAS,GAAK,EAAK,MAAM,SAAS,CAAC;KAC3E;IACF;IACA,KAAU;GACZ;EACF;EAKA,SAAS,EAAe,GAAsB;GAC5C,GAAc,GAAO;IACnB,aAAa;IACb,mBACO,EAAK,SACV,EAAU,OAAO,MAAM,GAChB,MAFiB;IAI1B,SAAS;GACX,CAAC;EACH;EAOA,SAAS,GAAa,GAAuB;GAC3C,GAAQ,IAAQ,MACd,EAAW,CAAM,IAAI,IAAS,EAAc,GAAQ,EAAK,OAAO,EAAE,WAAW,EAAW,CAAC,CAC3F;EACF;EAaA,IAAM,KAAe,QACnB,GAAS,GAAO,EAAiB,OAAO,GAAS,SAAU,EAAO,SAAS,CAAC,CAAC,GAAM,KAAM,CAC3F,GACM,KAAU,QACd,EAAS,QAAQ,EAAM,aAAa,KAAA,CACtC,GAaM,IAAI,EAAY,GAEhB,KAAe,QAAe,EAAM,mBAAmB,EAAE,MAAM,UAAU,UAAU,GACnF,KAAqB,QAAe,EAAM,cAAc,EAAE,MAAM,UAAU,KAAK;EAMrF,SAAS,KAAa;GAYpB,AAXA,EAAM,QACJ,EAAM,cAAc,aAChB,CAAC,IACD,EAAM,cAAc,UAClB;IAAE,OAAO;IAAM,KAAK;GAAK,IACzB,MAIJ,EAAO,SAAO,EAAW,EAAE,GAC/B,GAAW,GACX,EAAK,OAAO;EACd;EAMA,SAAS,KAAW;GAClB,AAAI,EAAM,cAAc,YAAU,EAAc;EAClD;SAEA,EAAa;GAEX,QAAQ,MAA2B,EAAS,OAAO,MAAM,CAAO;GAEhE,cAAc,EAAS,OAAO,OAAO;GAErC,IAAI,QAAe,EAAS,OAAO,MAAM,IAAI;EAC/C,CAAC,mBAIC,GAiGM,OAAA;YAhGA;GAAJ,KAAI;GACJ,OAAK,GAAA,CAAC,gBACE,EAAA,EAAA,CAAS,CAAA;GAChB,OAAK,GAAE,EAAA,EAAA,CAAS;GAChB,aAAW,EAAA,CAAA,IAAI,KAAQ,KAAA;GACvB,aAAW,EAAA;GACX,iBAAe,EAAA,CAAA,IAAgB,KAAQ,KAAA;GACvC,iBAAe,EAAA,WAAQ,KAAQ,KAAA;GAC/B,YAAQ,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;GACV,WAAO,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;MAEV,GA6CM,OAAA;GA7CD,OAAM;GAAwB,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;MASxC,EAmCS,IAnCT,GAmCS;YAlCH;GAAJ,KAAI;eACK,EAAA,CAAA;mDAAU,QAAA,IAAA;GAClB,WAAW,EAAA,QAAM,YAAe,KAAA;GAChC,cAAc,EAAA,QAAM,QAAW,KAAA;KACxB,GAAA,OAAU;GACjB,UAAU,EAAA;GACV,aAAS,CAAG,EAAA;GACZ,OAAO,EAAA;GACP,MAAM,EAAA;GACN,aAAa,EAAA,gBAAgB,EAAA,QAAS,GAAA,QAAW,KAAA;GACjD,MAAM,EAAA,EAAA;GACN,SAAS,EAAA,EAAA;GACT,UAAU,EAAA,CAAA;GACV,SAAS,EAAA;GACT,WAAW,EAAA;GACX,iBAAe,GAAA;GACf,eAAa,GAAA;GACb,cAAY,EAAA;GACZ,oBAAkB,EAAA;GAClB,SAAS,EAAA;GACT,gBAAc,EAAA;GACd,YAAU,GAAA;GACV,kBAAgB,GAAA;GAChB,mBAAgB,EAAA,EAAA;GAChB,SAAO;GACP,SAAO,EAAA,EAAA;GACP,SAAO,EAAA,EAAA;GACP,UAAQ,EAAA,CAAA;GACR,QAAM,EAAA,CAAA;GACN,WAAS;GACT,SAAO;mBAEQA,EAAAA,OAAO,QAAA;SAAQ;eAA2B,CAArB,EAAqB,EAAA,QAAA,OAAA,CAAA,CAAA;;cAC1CA,EAAAA,OAAM,eAAA;SAAgB;eAAmC,CAAzB,EAAyB,EAAA,QAAA,WAAA,CAAA,CAAA;;8TAQrE,EAAA,SAAA,EAAA,GADR,GAkCW,GAAA;;GAhCR,IAAI,EAAA,CAAA;YACD;GAAJ,KAAI;GACI,MAAM,EAAA,CAAA;6CAAI,QAAA,IAAA;GAClB,MAAK;GACL,QAAO;GACN,WAAW,EAAA;GACZ,MAAK;GACJ,cAAY,EAAA,SAAS,EAAA,CAAA,CAAC,CAAC,UAAU;GAClC,OAAM;GACL,aAAW,EAAA,EAAA;;oBAsBE,CApBd,EAoBc,IAAA;aAnBR;IAAJ,KAAI;gBACK,EAAA;6CAAK,QAAA;IACb,WAAW,EAAA;IACX,QAAQ,EAAA,CAAA;IACR,qBAAmB,EAAA;IACnB,KAAK,EAAA;IACL,KAAK,EAAA;IACL,kBAAgB,EAAA;IAChB,sBAAoB,EAAA;IACpB,wBAAsB,EAAA;IACtB,QAAQ,EAAA;IACA;mBAEOA,EAAAA,OAAO,MAAA;UAAM;WAAK,MAAS,CACzC,EAAsC,EAAA,QAAA,OAAA,GAAA,GAAb,CAAS,CAAA,CAAA,CAAA,CAAA;;eAEpBA,EAAAA,OAAO,SAAA;UAAS;gBACe,CAA7C,EAA6C,EAAA,QAAA,UAAA,EAAxB,OAAO,EAAA,CAAA,EAAa,CAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a date is TYPED: the numeric mask of VDateInput's field, whose order, separator and
|
|
3
|
+
* placeholder are derived from the locale.
|
|
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 a mask no calendar ever shows, the `VTimeInput/search.ts` argument.
|
|
8
|
+
*/
|
|
9
|
+
export type DateMaskField = 'day' | 'month' | 'year';
|
|
10
|
+
/** Everything a locale decides about how a date is typed. */
|
|
11
|
+
export interface DateMask {
|
|
12
|
+
/**
|
|
13
|
+
* The order the three fields appear in: day, month, year in the United Kingdom,
|
|
14
|
+
* month, day, year in the United States, year, month, day in Japan.
|
|
15
|
+
*/
|
|
16
|
+
order: readonly DateMaskField[];
|
|
17
|
+
/** The single character between two fields, stripped of bidi marks and spaces. */
|
|
18
|
+
separator: string;
|
|
19
|
+
/** How many digits each field takes, in the same order: 4 for the year, 2 otherwise. */
|
|
20
|
+
lengths: readonly number[];
|
|
21
|
+
/** How many digits the complete mask holds, which is always 8. */
|
|
22
|
+
size: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Works out how a date is typed in a given locale, by formatting a known date and
|
|
26
|
+
* looking at what came out.
|
|
27
|
+
*
|
|
28
|
+
* The calendar and the numbering system are FORCED to Gregorian and Latin digits.
|
|
29
|
+
* Without that, `fa-IR` answers with a Persian year (1400 rather than 2021) and
|
|
30
|
+
* `ar-EG` with Arabic-Indic digits: two things a numeric field could neither
|
|
31
|
+
* display nor read back. An invalid locale throws, and the answer then falls back to
|
|
32
|
+
* day/month/year separated by "/".
|
|
33
|
+
*/
|
|
34
|
+
export declare function dateMaskFor(locale: string): DateMask;
|
|
35
|
+
/**
|
|
36
|
+
* Lays a run of digits out as masked text. The separator appears AS SOON AS the field
|
|
37
|
+
* before it is full: typing "22" already gives "22/", so the reader sees their
|
|
38
|
+
* progress without ever having to type a separator themselves.
|
|
39
|
+
*
|
|
40
|
+
* This has a consequence the component must honour: pressing Backspace on such a
|
|
41
|
+
* separator has to delete the DIGIT before it. Deleting the separator alone would
|
|
42
|
+
* see the mask write it straight back, and the key would look dead.
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatDateMask(digits: string, mask: DateMask): string;
|
|
45
|
+
/**
|
|
46
|
+
* Writes an ISO date in the mask of the locale, ready to be put in the field: the
|
|
47
|
+
* same day reads "10/06/2026" in London and "06/10/2026" in Chicago.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isoToMask(iso: string, mask: DateMask): string;
|
|
50
|
+
export interface ParseMaskOptions {
|
|
51
|
+
/**
|
|
52
|
+
* The century a two-digit year is expanded into: with 2000, "10/06/26" is read as
|
|
53
|
+
* 2026. It is only accepted when the year is the LAST field of the mask, since
|
|
54
|
+
* elsewhere the following separator already tells the two apart.
|
|
55
|
+
*
|
|
56
|
+
* Leaving it out refuses any year shorter than four digits, and that is the mode
|
|
57
|
+
* used while the reader types, so that "26", passed through on the way to "2026",
|
|
58
|
+
* is never committed as a year of its own.
|
|
59
|
+
*/
|
|
60
|
+
yearPivot?: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Reads masked text back into an ISO date, or returns `null` when the text is
|
|
64
|
+
* incomplete, holds too many digits, or names a day that does not exist: 31
|
|
65
|
+
* February passes every length check and is caught by the round trip `isValidISO`
|
|
66
|
+
* performs.
|
|
67
|
+
*
|
|
68
|
+
* Whether the resulting date is allowed is a different question: the `min`/`max`
|
|
69
|
+
* bounds and the disabled dates belong to the component, and this function knows
|
|
70
|
+
* nothing about props.
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseDateMask(text: string, mask: DateMask, options?: ParseMaskOptions): string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Where the caret has to go to sit just after the nth digit. Counting digits is the
|
|
75
|
+
* only landmark that survives a reformat: an absolute position jumps by one the
|
|
76
|
+
* moment a separator appears or disappears, so restoring it would leave the caret in
|
|
77
|
+
* the wrong place on exactly the keystrokes that matter.
|
|
78
|
+
*
|
|
79
|
+
* When a separator is passed and it directly follows that position, the caret steps
|
|
80
|
+
* over it: while typing, it must land in the NEXT field rather than in front of a
|
|
81
|
+
* separator that has just been written. On deletion the argument is omitted, so the
|
|
82
|
+
* caret stays before it and the next Backspace reaches the digit.
|
|
83
|
+
*/
|
|
84
|
+
export declare function caretAfterDigits(text: string, n: number, separator?: string): number;
|
|
85
|
+
/**
|
|
86
|
+
* The empty template shown in the field: "dd/mm/yyyy" in English, "jj/mm/aaaa" in
|
|
87
|
+
* French, "tt.mm.jjjj" in German, "дд/мм/гггг" in Russian.
|
|
88
|
+
*
|
|
89
|
+
* Each letter is the first letter of the field's own name in that language, taken
|
|
90
|
+
* from `Intl.DisplayNames`, which lands on the attested convention of every
|
|
91
|
+
* alphabetic script without a table to maintain. It falls back to the Latin letters
|
|
92
|
+
* when that part of `Intl` is missing, or when the script is ideographic and the
|
|
93
|
+
* repetition would mean nothing.
|
|
94
|
+
*/
|
|
95
|
+
export declare function maskPlaceholder(locale: string, mask: DateMask): string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { digitsOf as e } from "../../utils/text.js";
|
|
2
|
+
import { memo as t } from "../../utils/memo.js";
|
|
3
|
+
import { isValidISO as n } from "../../utils/date.js";
|
|
4
|
+
//#region src/components/VDateInput/mask.ts
|
|
5
|
+
var r = {
|
|
6
|
+
order: [
|
|
7
|
+
"day",
|
|
8
|
+
"month",
|
|
9
|
+
"year"
|
|
10
|
+
],
|
|
11
|
+
separator: "/",
|
|
12
|
+
lengths: [
|
|
13
|
+
2,
|
|
14
|
+
2,
|
|
15
|
+
4
|
|
16
|
+
],
|
|
17
|
+
size: 8
|
|
18
|
+
}, i = Date.UTC(2021, 10, 22), a = /[]/g, o = /* @__PURE__ */ new Map();
|
|
19
|
+
function s(e) {
|
|
20
|
+
return t(o, e, () => c(e));
|
|
21
|
+
}
|
|
22
|
+
function c(e) {
|
|
23
|
+
try {
|
|
24
|
+
let t = new Intl.DateTimeFormat(e, {
|
|
25
|
+
day: "2-digit",
|
|
26
|
+
month: "2-digit",
|
|
27
|
+
year: "numeric",
|
|
28
|
+
timeZone: "UTC",
|
|
29
|
+
calendar: "gregory",
|
|
30
|
+
numberingSystem: "latn"
|
|
31
|
+
}).formatToParts(i), n = t.map((e) => e.type).filter((e) => e === "day" || e === "month" || e === "year"), r = t.findIndex((e) => e.type !== "literal"), o = t.slice(r).find((e) => e.type === "literal")?.value.replace(a, "").trim();
|
|
32
|
+
if (n.length === 3 && o) return {
|
|
33
|
+
order: n,
|
|
34
|
+
separator: o,
|
|
35
|
+
lengths: n.map((e) => e === "year" ? 4 : 2),
|
|
36
|
+
size: 8
|
|
37
|
+
};
|
|
38
|
+
} catch {}
|
|
39
|
+
return r;
|
|
40
|
+
}
|
|
41
|
+
function l(t, n) {
|
|
42
|
+
let r = e(t).slice(0, n.size), i = "", a = 0;
|
|
43
|
+
for (let e = 0; e < n.lengths.length; e++) {
|
|
44
|
+
let t = n.lengths[e], o = r.slice(a, a + t);
|
|
45
|
+
if (!o || (i += o, a += t, o.length < t)) break;
|
|
46
|
+
e < n.lengths.length - 1 && (i += n.separator);
|
|
47
|
+
}
|
|
48
|
+
return i;
|
|
49
|
+
}
|
|
50
|
+
function u(e, t) {
|
|
51
|
+
if (!n(e)) return "";
|
|
52
|
+
let [r, i, a] = e.split("-"), o = {
|
|
53
|
+
year: r,
|
|
54
|
+
month: i,
|
|
55
|
+
day: a
|
|
56
|
+
};
|
|
57
|
+
return l(t.order.map((e) => o[e]).join(""), t);
|
|
58
|
+
}
|
|
59
|
+
function d(t, r, i = {}) {
|
|
60
|
+
let a = e(t), o = {}, s = 0;
|
|
61
|
+
for (let e = 0; e < r.order.length; e++) {
|
|
62
|
+
let t = r.order[e], n = r.lengths[e], c = a.slice(s, s + n);
|
|
63
|
+
if (c.length === n) s += n;
|
|
64
|
+
else if (t === "year" && i.yearPivot !== void 0 && e === r.order.length - 1 && c.length === 2) s += 2;
|
|
65
|
+
else return null;
|
|
66
|
+
o[t] = c;
|
|
67
|
+
}
|
|
68
|
+
if (s !== a.length) return null;
|
|
69
|
+
let c = `${o.year.length === 2 ? String(i.yearPivot + Number(o.year)) : o.year}-${o.month}-${o.day}`;
|
|
70
|
+
return n(c) ? c : null;
|
|
71
|
+
}
|
|
72
|
+
function f(e, t, n) {
|
|
73
|
+
let r = 0;
|
|
74
|
+
if (t > 0) {
|
|
75
|
+
r = e.length;
|
|
76
|
+
let n = 0;
|
|
77
|
+
for (let i = 0; i < e.length; i++) {
|
|
78
|
+
let a = e.charCodeAt(i);
|
|
79
|
+
if (a >= 48 && a <= 57 && ++n === t) {
|
|
80
|
+
r = i + 1;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return n && e.startsWith(n, r) && (r += n.length), r;
|
|
86
|
+
}
|
|
87
|
+
var p = {
|
|
88
|
+
day: "d",
|
|
89
|
+
month: "m",
|
|
90
|
+
year: "y"
|
|
91
|
+
}, m = /[\p{sc=Han}\p{sc=Hangul}\p{sc=Hiragana}\p{sc=Katakana}]/u;
|
|
92
|
+
function h(e, t) {
|
|
93
|
+
let n = _(e);
|
|
94
|
+
return t.order.map((e, r) => n[e].repeat(t.lengths[r])).join(t.separator);
|
|
95
|
+
}
|
|
96
|
+
var g = /* @__PURE__ */ new Map();
|
|
97
|
+
function _(e) {
|
|
98
|
+
return t(g, e, () => v(e));
|
|
99
|
+
}
|
|
100
|
+
function v(e) {
|
|
101
|
+
let t = { ...p };
|
|
102
|
+
try {
|
|
103
|
+
let n = new Intl.DisplayNames(e, { type: "dateTimeField" });
|
|
104
|
+
for (let r of [
|
|
105
|
+
"day",
|
|
106
|
+
"month",
|
|
107
|
+
"year"
|
|
108
|
+
]) {
|
|
109
|
+
let i = [...n.of(r) ?? ""][0];
|
|
110
|
+
i && /\p{L}/u.test(i) && !m.test(i) && (t[r] = i.toLocaleLowerCase(e));
|
|
111
|
+
}
|
|
112
|
+
} catch {}
|
|
113
|
+
return t;
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { f as caretAfterDigits, s as dateMaskFor, l as formatDateMask, u as isoToMask, h as maskPlaceholder, d as parseDateMask };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=mask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask.js","names":[],"sources":["../../../src/components/VDateInput/mask.ts"],"sourcesContent":["// @core\n/**\n * How a date is TYPED: the numeric mask of VDateInput's field, whose order, separator and\n * placeholder are derived from the locale.\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 a mask no calendar ever shows, the `VTimeInput/search.ts` argument.\n */\n\nimport { isValidISO } from '../../utils/date'\nimport { memo } from '../../utils/memo'\nimport { digitsOf } from '../../utils/text'\n\n/*\n * The numeric input mask, used by VDateInput when its field can be typed into.\n *\n * A field being typed into never shows the long display format — \"10 June 2026\" is\n * not something one can type — but a purely numeric mask instead. The order of the\n * three fields and the separator between them are DERIVED from the locale rather\n * than hardcoded, which is what makes the same field work for a reader in Tokyo and\n * one in Chicago.\n */\n\nexport type DateMaskField = 'day' | 'month' | 'year'\n\n/** Everything a locale decides about how a date is typed. */\nexport interface DateMask {\n /**\n * The order the three fields appear in: day, month, year in the United Kingdom,\n * month, day, year in the United States, year, month, day in Japan.\n */\n order: readonly DateMaskField[]\n /** The single character between two fields, stripped of bidi marks and spaces. */\n separator: string\n /** How many digits each field takes, in the same order: 4 for the year, 2 otherwise. */\n lengths: readonly number[]\n /** How many digits the complete mask holds, which is always 8. */\n size: number\n}\n\nconst MASK_FALLBACK: DateMask = {\n order: ['day', 'month', 'year'],\n separator: '/',\n lengths: [2, 2, 4],\n size: 8,\n}\n\n/**\n * The date the mask is read from: 22 November 2021. Its three numbers all differ, so\n * whichever order the locale prints them in, each one can be told apart.\n */\nconst REF_MASK_DATE = Date.UTC(2021, 10, 22)\n\n/** The invisible direction marks some locales insert, such as U+200F before \"/\" in ar-EG. */\nconst BIDI_MARKS = /[]/g\n\nconst maskCache = new Map<string, DateMask>()\n\n/**\n * Works out how a date is typed in a given locale, by formatting a known date and\n * looking at what came out.\n *\n * The calendar and the numbering system are FORCED to Gregorian and Latin digits.\n * Without that, `fa-IR` answers with a Persian year (1400 rather than 2021) and\n * `ar-EG` with Arabic-Indic digits: two things a numeric field could neither\n * display nor read back. An invalid locale throws, and the answer then falls back to\n * day/month/year separated by \"/\".\n */\nexport function dateMaskFor(locale: string): DateMask {\n return memo(maskCache, locale, () => buildDateMask(locale))\n}\n\n/*\n * TRAP — the returned `DateMask` is SHARED between every caller for a locale, so it must be\n * treated as read-only. Nothing mutates it today (it is read field by field in\n * `formatDateMask`, `parseDateMask` and `maskPlaceholder`), and it is the same contract the\n * memoized `Intl` formatters in this file already have.\n */\nfunction buildDateMask(locale: string): DateMask {\n try {\n const parts = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n timeZone: 'UTC',\n calendar: 'gregory',\n numberingSystem: 'latn',\n }).formatToParts(REF_MASK_DATE)\n\n const order = parts\n .map((p) => p.type)\n .filter((t): t is DateMaskField => t === 'day' || t === 'month' || t === 'year')\n\n // The separator is the first literal appearing AFTER the first field, and not\n // simply the first literal: Hungarian and Korean end the whole format with a dot\n // (\"2021. 11. 22.\"), which must not be mistaken for it.\n const firstField = parts.findIndex((p) => p.type !== 'literal')\n const separator = parts\n .slice(firstField)\n .find((p) => p.type === 'literal')\n ?.value.replace(BIDI_MARKS, '')\n .trim()\n\n if (order.length === 3 && separator) {\n const lengths = order.map((f) => (f === 'year' ? 4 : 2))\n return { order, separator, lengths, size: 8 }\n }\n } catch {\n /* an invalid locale throws a RangeError: fall through to the fallback */\n }\n return MASK_FALLBACK\n}\n\n/**\n * Lays a run of digits out as masked text. The separator appears AS SOON AS the field\n * before it is full: typing \"22\" already gives \"22/\", so the reader sees their\n * progress without ever having to type a separator themselves.\n *\n * This has a consequence the component must honour: pressing Backspace on such a\n * separator has to delete the DIGIT before it. Deleting the separator alone would\n * see the mask write it straight back, and the key would look dead.\n */\nexport function formatDateMask(digits: string, mask: DateMask): string {\n const all = digitsOf(digits).slice(0, mask.size)\n let out = ''\n let i = 0\n for (let f = 0; f < mask.lengths.length; f++) {\n const len = mask.lengths[f] as number\n const chunk = all.slice(i, i + len)\n if (!chunk) break\n out += chunk\n i += len\n if (chunk.length < len) break // this field is still being typed: no separator yet\n if (f < mask.lengths.length - 1) out += mask.separator\n }\n return out\n}\n\n/**\n * Writes an ISO date in the mask of the locale, ready to be put in the field: the\n * same day reads \"10/06/2026\" in London and \"06/10/2026\" in Chicago.\n */\nexport function isoToMask(iso: string, mask: DateMask): string {\n if (!isValidISO(iso)) return ''\n const [year, month, day] = iso.split('-') as [string, string, string]\n const by: Record<DateMaskField, string> = { year, month, day }\n return formatDateMask(mask.order.map((f) => by[f]).join(''), mask)\n}\n\nexport interface ParseMaskOptions {\n /**\n * The century a two-digit year is expanded into: with 2000, \"10/06/26\" is read as\n * 2026. It is only accepted when the year is the LAST field of the mask, since\n * elsewhere the following separator already tells the two apart.\n *\n * Leaving it out refuses any year shorter than four digits, and that is the mode\n * used while the reader types, so that \"26\", passed through on the way to \"2026\",\n * is never committed as a year of its own.\n */\n yearPivot?: number\n}\n\n/**\n * Reads masked text back into an ISO date, or returns `null` when the text is\n * incomplete, holds too many digits, or names a day that does not exist: 31\n * February passes every length check and is caught by the round trip `isValidISO`\n * performs.\n *\n * Whether the resulting date is allowed is a different question: the `min`/`max`\n * bounds and the disabled dates belong to the component, and this function knows\n * nothing about props.\n */\nexport function parseDateMask(\n text: string,\n mask: DateMask,\n options: ParseMaskOptions = {},\n): string | null {\n const digits = digitsOf(text)\n const by: Partial<Record<DateMaskField, string>> = {}\n let i = 0\n for (let k = 0; k < mask.order.length; k++) {\n const field = mask.order[k] as DateMaskField\n const len = mask.lengths[k] as number\n const chunk = digits.slice(i, i + len)\n if (chunk.length === len) i += len\n else if (\n field === 'year' &&\n options.yearPivot !== undefined &&\n k === mask.order.length - 1 &&\n chunk.length === 2\n )\n i += 2\n else return null\n by[field] = chunk\n }\n if (i !== digits.length) return null // digits are left over: the entry is too long\n const year =\n (by.year as string).length === 2\n ? String((options.yearPivot as number) + Number(by.year))\n : (by.year as string)\n const iso = `${year}-${by.month}-${by.day}`\n return isValidISO(iso) ? iso : null\n}\n\n/**\n * Where the caret has to go to sit just after the nth digit. Counting digits is the\n * only landmark that survives a reformat: an absolute position jumps by one the\n * moment a separator appears or disappears, so restoring it would leave the caret in\n * the wrong place on exactly the keystrokes that matter.\n *\n * When a separator is passed and it directly follows that position, the caret steps\n * over it: while typing, it must land in the NEXT field rather than in front of a\n * separator that has just been written. On deletion the argument is omitted, so the\n * caret stays before it and the next Backspace reaches the digit.\n */\nexport function caretAfterDigits(text: string, n: number, separator?: string): number {\n let pos = 0\n if (n > 0) {\n pos = text.length\n let seen = 0\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i)\n if (code >= 48 && code <= 57 && ++seen === n) {\n pos = i + 1\n break\n }\n }\n }\n if (separator && text.startsWith(separator, pos)) pos += separator.length\n return pos\n}\n\nconst PLACEHOLDER_FALLBACK: Record<DateMaskField, string> = { day: 'd', month: 'm', year: 'y' }\n\n/**\n * Ideographic scripts, which are excluded from the placeholder: a repeated \"日\" does\n * not read as a template the way a repeated letter does.\n */\nconst IDEOGRAPHIC = /[\\p{sc=Han}\\p{sc=Hangul}\\p{sc=Hiragana}\\p{sc=Katakana}]/u\n\n// @fallback\n/**\n * The empty template shown in the field: \"dd/mm/yyyy\" in English, \"jj/mm/aaaa\" in\n * French, \"tt.mm.jjjj\" in German, \"дд/мм/гггг\" in Russian.\n *\n * Each letter is the first letter of the field's own name in that language, taken\n * from `Intl.DisplayNames`, which lands on the attested convention of every\n * alphabetic script without a table to maintain. It falls back to the Latin letters\n * when that part of `Intl` is missing, or when the script is ideographic and the\n * repetition would mean nothing.\n */\nexport function maskPlaceholder(locale: string, mask: DateMask): string {\n const letters = placeholderLetters(locale)\n return mask.order.map((f, k) => letters[f].repeat(mask.lengths[k] as number)).join(mask.separator)\n}\n\nconst placeholderLetterCache = new Map<string, typeof PLACEHOLDER_FALLBACK>()\n\n/**\n * The three letters a locale writes its date fields with, worked out once per locale.\n *\n * The LETTERS are cached, not the finished placeholder: that also depends on the mask handed\n * in, and would be wrong the moment a caller passes one that is not `dateMaskFor(locale)`.\n * All the cost is here anyway — `Intl.DisplayNames` is this file's most expensive\n * constructor by an order of magnitude (~0.22 ms against ~0.07 for `dateMaskFor`).\n */\nfunction placeholderLetters(locale: string): typeof PLACEHOLDER_FALLBACK {\n return memo(placeholderLetterCache, locale, () => buildPlaceholderLetters(locale))\n}\n\nfunction buildPlaceholderLetters(locale: string): typeof PLACEHOLDER_FALLBACK {\n const letters = { ...PLACEHOLDER_FALLBACK }\n try {\n const names = new Intl.DisplayNames(locale, { type: 'dateTimeField' })\n for (const field of ['day', 'month', 'year'] as const) {\n const first = [...(names.of(field) ?? '')][0]\n if (first && /\\p{L}/u.test(first) && !IDEOGRAPHIC.test(first))\n letters[field] = first.toLocaleLowerCase(locale)\n }\n } catch {\n /* Intl.DisplayNames is unavailable here: keep the Latin letters */\n }\n return letters\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
-
@layer vectis.components{.v-date-picker{--date-picker-cell:max(var(--vectis-control-size-date-picker-cell), calc(var(--vectis-control-size-date-picker-day) + var(--vectis-space-1)));gap:var(--vectis-space-2);padding:var(--vectis-space-3);font-family:var(--vectis-text-family);color:var(--vectis-color-text);flex-direction:column;display:inline-flex}.v-date-picker-header{justify-content:space-between;align-items:center;gap:var(--vectis-space-2);display:flex}.v-date-picker-nav{align-items:center;display:flex}.v-date-picker-view-toggle{min-inline-size:var(--vectis-control-size-date-picker-nav-min);font-weight:var(--vectis-font-weight-semibold);text-transform:capitalize}.v-date-picker-grid{min-inline-size:calc(7 * var(--date-picker-cell))}.v-date-picker-weekdays,.v-date-picker-week{grid-template-columns:repeat(7,1fr);display:grid}.v-date-picker-weekday{height:var(--vectis-control-height-sm);font-size:var(--vectis-text-overline-size);font-weight:var(--vectis-text-overline-weight);letter-spacing:var(--vectis-text-overline-tracking);color:var(--vectis-color-text-muted);text-transform:capitalize;justify-content:center;align-items:center;display:flex}.v-date-picker-cell{height:var(--date-picker-cell);justify-content:center;align-items:center;display:flex;position:relative}.v-date-picker-cell[data-in-range]:before{content:"";inset-block:calc((100% - var(--vectis-control-size-date-picker-day)) / 2);background:var(--vectis-color-accent-surface);z-index:0;position:absolute;inset-inline:0}.v-date-picker-cell[data-range-start]:before{border-start-start-radius:var(--vectis-radius-pill);border-end-start-radius:var(--vectis-radius-pill);inset-inline-start:calc((100% - var(--vectis-control-size-date-picker-day)) / 2)}.v-date-picker-cell[data-range-end]:before{border-start-end-radius:var(--vectis-radius-pill);border-end-end-radius:var(--vectis-radius-pill);inset-inline-end:calc((100% - var(--vectis-control-size-date-picker-day)) / 2)}.v-date-picker-cell[data-range-start][data-range-end]:before{content:none}.v-date-picker-day{z-index:1;inline-size:var(--vectis-control-size-date-picker-day);block-size:var(--vectis-control-size-date-picker-day);border-radius:var(--vectis-radius-pill);color:inherit;font:inherit;font-size:var(--vectis-text-body-md-size);cursor:pointer;transition:background-color var(--vectis-duration-fast) var(--vectis-ease-default), color var(--vectis-duration-fast) var(--vectis-ease-default);background:0 0;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.v-date-picker-day:hover:not([aria-disabled=true]):not([data-selected]):not(.v-date-picker-day--static){background:var(--vectis-color-surface-muted)}.v-date-picker-day[data-outside]{color:var(--vectis-color-text-subtle)}.v-date-picker-day[data-today]:not([data-selected]){box-shadow:inset 0 0 0 1px var(--vectis-color-accent-border);color:var(--vectis-color-accent-text);font-weight:var(--vectis-font-weight-semibold)}.v-date-picker-day[data-selected]{background:var(--vectis-color-accent);color:var(--vectis-color-text-on-accent);font-weight:var(--vectis-font-weight-semibold)}.v-date-picker-day[data-unavailable]{color:var(--vectis-color-text-subtle);cursor:not-allowed;text-decoration:line-through}.v-date-picker[data-readonly] .v-date-picker-day:not([data-unavailable]){cursor:default}.v-date-picker-day:disabled{color:var(--vectis-color-text-subtle);cursor:not-allowed}.v-date-picker[data-disabled] .v-date-picker-day[data-selected]{background:var(--vectis-color-surface-muted);color:var(--vectis-color-text-subtle)}.v-date-picker-day--static{color:var(--vectis-color-text-subtle);cursor:default}.v-date-picker-day--static[data-disabled]{cursor:not-allowed;text-decoration:line-through}.v-date-picker-day:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:var(--vectis-focus-ring-offset)}.v-date-picker-day-num{line-height:var(--vectis-text-control-leading)}.v-date-picker-dots{gap:
|
|
2
|
+
@layer vectis.components{.v-date-picker{--date-picker-cell:max(var(--vectis-control-size-date-picker-cell), calc(var(--vectis-control-size-date-picker-day) + var(--vectis-space-1)));gap:var(--vectis-space-2);padding:var(--vectis-space-3);font-family:var(--vectis-text-family);color:var(--vectis-color-text);flex-direction:column;display:inline-flex}.v-date-picker-header{justify-content:space-between;align-items:center;gap:var(--vectis-space-2);display:flex}.v-date-picker-nav{align-items:center;display:flex}.v-date-picker-view-toggle[data-size]{min-inline-size:var(--vectis-control-size-date-picker-nav-min);font-weight:var(--vectis-font-weight-semibold);text-transform:capitalize}.v-date-picker-grid{min-inline-size:calc(7 * var(--date-picker-cell))}.v-date-picker-weekdays,.v-date-picker-week{grid-template-columns:repeat(7,1fr);display:grid}.v-date-picker-weekday{height:var(--vectis-control-height-sm);font-size:var(--vectis-text-overline-size);font-weight:var(--vectis-text-overline-weight);letter-spacing:var(--vectis-text-overline-tracking);color:var(--vectis-color-text-muted);text-transform:capitalize;justify-content:center;align-items:center;display:flex}.v-date-picker-cell{height:var(--date-picker-cell);justify-content:center;align-items:center;display:flex;position:relative}.v-date-picker-cell[data-in-range]:before{content:"";inset-block:calc((100% - var(--vectis-control-size-date-picker-day)) / 2);background:var(--vectis-color-accent-surface);z-index:0;position:absolute;inset-inline:0}.v-date-picker-cell[data-range-start]:before{border-start-start-radius:var(--vectis-radius-pill);border-end-start-radius:var(--vectis-radius-pill);inset-inline-start:calc((100% - var(--vectis-control-size-date-picker-day)) / 2)}.v-date-picker-cell[data-range-end]:before{border-start-end-radius:var(--vectis-radius-pill);border-end-end-radius:var(--vectis-radius-pill);inset-inline-end:calc((100% - var(--vectis-control-size-date-picker-day)) / 2)}.v-date-picker-cell[data-range-start][data-range-end]:before{content:none}.v-date-picker-day{z-index:1;inline-size:var(--vectis-control-size-date-picker-day);block-size:var(--vectis-control-size-date-picker-day);border-radius:var(--vectis-radius-pill);color:inherit;font:inherit;font-size:var(--vectis-text-body-md-size);cursor:pointer;transition:background-color var(--vectis-duration-fast) var(--vectis-ease-default), color var(--vectis-duration-fast) var(--vectis-ease-default);background:0 0;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:inline-flex;position:relative}.v-date-picker-day:hover:not(:disabled):not([aria-disabled=true]):not([data-selected]):not(.v-date-picker-day--static){background:var(--vectis-color-surface-muted)}.v-date-picker-day[data-outside]{color:var(--vectis-color-text-subtle)}.v-date-picker-day[data-today]:not([data-selected]){box-shadow:inset 0 0 0 1px var(--vectis-color-accent-border);color:var(--vectis-color-accent-text);font-weight:var(--vectis-font-weight-semibold)}.v-date-picker-day[data-selected]{background:var(--vectis-color-accent);color:var(--vectis-color-text-on-accent);font-weight:var(--vectis-font-weight-semibold)}.v-date-picker-day[data-unavailable]{color:var(--vectis-color-text-subtle);cursor:not-allowed;text-decoration:line-through}.v-date-picker[data-readonly] .v-date-picker-day:not([data-unavailable]){cursor:default}.v-date-picker-day:disabled{color:var(--vectis-color-text-subtle);cursor:not-allowed}.v-date-picker[data-disabled] .v-date-picker-day[data-selected]{background:var(--vectis-color-surface-muted);color:var(--vectis-color-text-subtle)}.v-date-picker-day--static{color:var(--vectis-color-text-subtle);cursor:default}.v-date-picker-day--static[data-disabled]{cursor:not-allowed;text-decoration:line-through}.v-date-picker-day:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:var(--vectis-focus-ring-offset)}.v-date-picker-day-num{line-height:var(--vectis-text-control-leading)}.v-date-picker-dots{gap:calc(var(--vectis-control-size-date-picker-dot) / 2);display:flex;position:absolute;inset-block-end:calc(var(--vectis-control-size-date-picker-dot) / 2)}.v-date-picker-dot{inline-size:var(--vectis-control-size-date-picker-dot);block-size:var(--vectis-control-size-date-picker-dot);border-radius:var(--vectis-radius-pill);background:var(--date-picker-dot-color,var(--vectis-color-accent))}.v-date-picker-day[data-selected] .v-date-picker-dot{background:var(--vectis-color-text-on-accent)}.v-date-picker-view{gap:var(--vectis-space-1);min-inline-size:calc(7 * var(--date-picker-cell));grid-template-columns:repeat(3,1fr);display:grid}.v-date-picker-view-row{display:contents}.v-date-picker-view--years{max-block-size:calc(6 * var(--date-picker-cell));overflow-y:auto}.v-date-picker-view-cell{block-size:var(--vectis-control-height-lg);border-radius:var(--vectis-radius-pill);color:inherit;font:inherit;font-size:var(--vectis-text-body-md-size);text-transform:capitalize;cursor:pointer;transition:background-color var(--vectis-duration-fast) var(--vectis-ease-default);background:0 0;border:none;justify-content:center;align-items:center;display:flex}.v-date-picker-view-cell:hover:not(:disabled):not([data-selected]){background:var(--vectis-color-surface-muted)}.v-date-picker-view-cell[data-selected]{background:var(--vectis-color-accent);color:var(--vectis-color-text-on-accent);font-weight:var(--vectis-font-weight-semibold)}.v-date-picker-view-cell:disabled{color:var(--vectis-color-text-subtle);cursor:not-allowed}.v-date-picker-view-cell:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:calc(-1 * var(--vectis-focus-ring-width))}.v-date-picker-footer{justify-content:flex-end;align-items:center;gap:var(--vectis-space-2);border-block-start:1px solid var(--vectis-color-border);padding-block-start:var(--vectis-space-2);display:flex}@media (prefers-reduced-motion:reduce){.v-date-picker-day,.v-date-picker-view-cell{transition:none}}}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** What a click selects: one date, a period between two, or a list of dates. */
|
|
1
2
|
export type DatePickerSelection = 'single' | 'range' | 'multiple';
|
|
2
3
|
/**
|
|
3
4
|
* A period between two dates, the value of a `range` selection. Either bound may be
|
|
@@ -15,7 +16,7 @@ export interface DatePickerEvent {
|
|
|
15
16
|
date: string;
|
|
16
17
|
/** The colour of the dot, as any CSS colour. It is the accent colour by default. */
|
|
17
18
|
color?: string;
|
|
18
|
-
/** A description of the event
|
|
19
|
+
/** A description of the event, spoken as part of the day's accessible name. */
|
|
19
20
|
label?: string;
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
@@ -53,7 +54,7 @@ interface DatePickerProps {
|
|
|
53
54
|
/**
|
|
54
55
|
* A BCP 47 locale, which decides the month and day names and the first day of the
|
|
55
56
|
* week. It TAKES PRECEDENCE over the design system's global locale (`setLocale`)
|
|
56
|
-
* and falls back to it
|
|
57
|
+
* and falls back to it, which is why it has no literal default here: `undefined`
|
|
57
58
|
* has to stay recognizable for the global locale to have its chance.
|
|
58
59
|
*/
|
|
59
60
|
locale?: string;
|
|
@@ -96,7 +97,7 @@ interface DatePickerProps {
|
|
|
96
97
|
disabled?: boolean;
|
|
97
98
|
/**
|
|
98
99
|
* Shows what is selected without letting it be changed. The calendar can still be
|
|
99
|
-
* read and walked through
|
|
100
|
+
* read and walked through (another month, another year), which is what separates it
|
|
100
101
|
* from `disabled`.
|
|
101
102
|
*/
|
|
102
103
|
readonly?: boolean;
|
|
@@ -110,8 +111,8 @@ interface DatePickerProps {
|
|
|
110
111
|
type __VLS_Props = DatePickerProps;
|
|
111
112
|
type __VLS_Slots = {
|
|
112
113
|
/**
|
|
113
|
-
* Replaces the content of a day cell
|
|
114
|
-
* number
|
|
114
|
+
* Replaces the content of a day cell, to show a price or an availability under the
|
|
115
|
+
* number for instance. It receives everything known about that day, including
|
|
115
116
|
* whether it belongs to the displayed month.
|
|
116
117
|
*/
|
|
117
118
|
day?(props: DatePickerDaySlotProps): unknown;
|