vectis-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +27 -0
- package/README.md +354 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +8 -0
- package/dist/components/VAccordion/VAccordion.css +2 -0
- package/dist/components/VAccordion/VAccordion.d.ts +59 -0
- package/dist/components/VAccordion/VAccordion.js +9 -0
- package/dist/components/VAccordion/VAccordion.js.map +1 -0
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VAccordion/VAccordionItem.css +2 -0
- package/dist/components/VAccordion/VAccordionItem.d.ts +64 -0
- package/dist/components/VAccordion/VAccordionItem.js +9 -0
- package/dist/components/VAccordion/VAccordionItem.js.map +1 -0
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VAccordion/context.d.ts +18 -0
- package/dist/components/VAccordion/context.js +6 -0
- package/dist/components/VAccordion/context.js.map +1 -0
- package/dist/components/VAvatar/VAvatar.css +2 -0
- package/dist/components/VAvatar/VAvatar.d.ts +68 -0
- package/dist/components/VAvatar/VAvatar.js +9 -0
- package/dist/components/VAvatar/VAvatar.js.map +1 -0
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +87 -0
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VAvatar/VAvatarGroup.css +2 -0
- package/dist/components/VAvatar/VAvatarGroup.d.ts +59 -0
- package/dist/components/VAvatar/VAvatarGroup.js +9 -0
- package/dist/components/VAvatar/VAvatarGroup.js.map +1 -0
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VAvatar/context.d.ts +17 -0
- package/dist/components/VAvatar/context.js +6 -0
- package/dist/components/VAvatar/context.js.map +1 -0
- package/dist/components/VBadge/VBadge.css +2 -0
- package/dist/components/VBadge/VBadge.d.ts +74 -0
- package/dist/components/VBadge/VBadge.js +9 -0
- package/dist/components/VBadge/VBadge.js.map +1 -0
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +40 -0
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.css +2 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +68 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.js +9 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VButton/VButton.css +2 -0
- package/dist/components/VButton/VButton.d.ts +88 -0
- package/dist/components/VButton/VButton.js +9 -0
- package/dist/components/VButton/VButton.js.map +1 -0
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +86 -0
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VButton/VButtonGroup.css +2 -0
- package/dist/components/VButton/VButtonGroup.d.ts +32 -0
- package/dist/components/VButton/VButtonGroup.js +9 -0
- package/dist/components/VButton/VButtonGroup.js.map +1 -0
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/VCalendar.css +2 -0
- package/dist/components/VCalendar/VCalendar.d.ts +129 -0
- package/dist/components/VCalendar/VCalendar.js +9 -0
- package/dist/components/VCalendar/VCalendar.js.map +1 -0
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +374 -0
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/VCalendarEvent.css +2 -0
- package/dist/components/VCalendar/VCalendarEvent.d.ts +71 -0
- package/dist/components/VCalendar/VCalendarEvent.js +9 -0
- package/dist/components/VCalendar/VCalendarEvent.js.map +1 -0
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +106 -0
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/VCalendarMonth.css +2 -0
- package/dist/components/VCalendar/VCalendarMonth.d.ts +60 -0
- package/dist/components/VCalendar/VCalendarMonth.js +9 -0
- package/dist/components/VCalendar/VCalendarMonth.js.map +1 -0
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +342 -0
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.css +2 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +85 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.js +9 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +621 -0
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/VCalendarYear.css +2 -0
- package/dist/components/VCalendar/VCalendarYear.d.ts +31 -0
- package/dist/components/VCalendar/VCalendarYear.js +9 -0
- package/dist/components/VCalendar/VCalendarYear.js.map +1 -0
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +76 -0
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCalendar/color.d.ts +9 -0
- package/dist/components/VCalendar/color.js +9 -0
- package/dist/components/VCalendar/color.js.map +1 -0
- package/dist/components/VCalendar/edgeStep.d.ts +38 -0
- package/dist/components/VCalendar/edgeStep.js +28 -0
- package/dist/components/VCalendar/edgeStep.js.map +1 -0
- package/dist/components/VCalendar/keyboard.d.ts +78 -0
- package/dist/components/VCalendar/keyboard.js +86 -0
- package/dist/components/VCalendar/keyboard.js.map +1 -0
- package/dist/components/VCalendar/layout.d.ts +355 -0
- package/dist/components/VCalendar/layout.js +292 -0
- package/dist/components/VCalendar/layout.js.map +1 -0
- package/dist/components/VCalendar/types.d.ts +78 -0
- package/dist/components/VCarousel/VCarousel.css +2 -0
- package/dist/components/VCarousel/VCarousel.d.ts +241 -0
- package/dist/components/VCarousel/VCarousel.js +9 -0
- package/dist/components/VCarousel/VCarousel.js.map +1 -0
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +262 -0
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCarousel/VCarouselItem.d.ts +41 -0
- package/dist/components/VCarousel/VCarouselItem.js +7 -0
- package/dist/components/VCarousel/VCarouselItem.js.map +1 -0
- package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js +25 -0
- package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCarousel/context.d.ts +23 -0
- package/dist/components/VCarousel/context.js +6 -0
- package/dist/components/VCarousel/context.js.map +1 -0
- package/dist/components/VCheckbox/VCheckbox.css +2 -0
- package/dist/components/VCheckbox/VCheckbox.d.ts +63 -0
- package/dist/components/VCheckbox/VCheckbox.js +9 -0
- package/dist/components/VCheckbox/VCheckbox.js.map +1 -0
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VChip/VChip.css +2 -0
- package/dist/components/VChip/VChip.d.ts +120 -0
- package/dist/components/VChip/VChip.js +9 -0
- package/dist/components/VChip/VChip.js.map +1 -0
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +118 -0
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCombobox/VCombobox.css +2 -0
- package/dist/components/VCombobox/VCombobox.d.ts +183 -0
- package/dist/components/VCombobox/VCombobox.js +9 -0
- package/dist/components/VCombobox/VCombobox.js.map +1 -0
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +428 -0
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCombobox/VComboboxGroup.css +2 -0
- package/dist/components/VCombobox/VComboboxGroup.d.ts +26 -0
- package/dist/components/VCombobox/VComboboxGroup.js +9 -0
- package/dist/components/VCombobox/VComboboxGroup.js.map +1 -0
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +21 -0
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCombobox/VComboboxOption.css +2 -0
- package/dist/components/VCombobox/VComboboxOption.d.ts +48 -0
- package/dist/components/VCombobox/VComboboxOption.js +9 -0
- package/dist/components/VCombobox/VComboboxOption.js.map +1 -0
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCombobox/VComboboxSeparator.css +2 -0
- package/dist/components/VCombobox/VComboboxSeparator.d.ts +3 -0
- package/dist/components/VCombobox/VComboboxSeparator.js +9 -0
- package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -0
- package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VCombobox/infiniteScroll.d.ts +22 -0
- package/dist/components/VCombobox/infiniteScroll.js +28 -0
- package/dist/components/VCombobox/infiniteScroll.js.map +1 -0
- package/dist/components/VDataTable/VDataTable.css +2 -0
- package/dist/components/VDataTable/VDataTable.d.ts +214 -0
- package/dist/components/VDataTable/VDataTable.js +9 -0
- package/dist/components/VDataTable/VDataTable.js.map +1 -0
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +396 -0
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VDateInput/VDateInput.css +2 -0
- package/dist/components/VDateInput/VDateInput.d.ts +152 -0
- package/dist/components/VDateInput/VDateInput.js +9 -0
- package/dist/components/VDateInput/VDateInput.js.map +1 -0
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +324 -0
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VDatePicker/VDatePicker.css +2 -0
- package/dist/components/VDatePicker/VDatePicker.d.ts +143 -0
- package/dist/components/VDatePicker/VDatePicker.js +9 -0
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -0
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +454 -0
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VDatePicker/keyboard.d.ts +56 -0
- package/dist/components/VDatePicker/keyboard.js +26 -0
- package/dist/components/VDatePicker/keyboard.js.map +1 -0
- package/dist/components/VDialog/VDialog.css +2 -0
- package/dist/components/VDialog/VDialog.d.ts +96 -0
- package/dist/components/VDialog/VDialog.js +9 -0
- package/dist/components/VDialog/VDialog.js.map +1 -0
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +134 -0
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VDialog/VDialogAlert.d.ts +67 -0
- package/dist/components/VDialog/VDialogAlert.js +7 -0
- package/dist/components/VDialog/VDialogAlert.js.map +1 -0
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VFileInput/VFileInput.css +2 -0
- package/dist/components/VFileInput/VFileInput.d.ts +156 -0
- package/dist/components/VFileInput/VFileInput.js +9 -0
- package/dist/components/VFileInput/VFileInput.js.map +1 -0
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +244 -0
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VFileInput/truncate.d.ts +29 -0
- package/dist/components/VFileInput/truncate.js +10 -0
- package/dist/components/VFileInput/truncate.js.map +1 -0
- package/dist/components/VFilePicker/VFilePicker.css +2 -0
- package/dist/components/VFilePicker/VFilePicker.d.ts +203 -0
- package/dist/components/VFilePicker/VFilePicker.js +9 -0
- package/dist/components/VFilePicker/VFilePicker.js.map +1 -0
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +266 -0
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VFilePicker/fileKind.d.ts +29 -0
- package/dist/components/VFilePicker/fileKind.js +91 -0
- package/dist/components/VFilePicker/fileKind.js.map +1 -0
- package/dist/components/VHotkeys/VHotkeys.css +2 -0
- package/dist/components/VHotkeys/VHotkeys.d.ts +100 -0
- package/dist/components/VHotkeys/VHotkeys.js +9 -0
- package/dist/components/VHotkeys/VHotkeys.js.map +1 -0
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +76 -0
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VHotkeys/platform.d.ts +82 -0
- package/dist/components/VHotkeys/platform.js +115 -0
- package/dist/components/VHotkeys/platform.js.map +1 -0
- package/dist/components/VIcon/VIcon.css +2 -0
- package/dist/components/VIcon/VIcon.d.ts +57 -0
- package/dist/components/VIcon/VIcon.js +9 -0
- package/dist/components/VIcon/VIcon.js.map +1 -0
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +99 -0
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VIcon/iconProps.d.ts +30 -0
- package/dist/components/VIcon/iconProps.js +6 -0
- package/dist/components/VIcon/iconProps.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_downward.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_downward.js +9 -0
- package/dist/components/VIcon/icons/arrow_downward.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_downward_alt.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_downward_alt.js +9 -0
- package/dist/components/VIcon/icons/arrow_downward_alt.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_drop_down.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_drop_down.js +9 -0
- package/dist/components/VIcon/icons/arrow_drop_down.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_drop_up.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_drop_up.js +9 -0
- package/dist/components/VIcon/icons/arrow_drop_up.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_left_alt.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_left_alt.js +9 -0
- package/dist/components/VIcon/icons/arrow_left_alt.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_right_alt.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_right_alt.js +9 -0
- package/dist/components/VIcon/icons/arrow_right_alt.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_upward.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_upward.js +9 -0
- package/dist/components/VIcon/icons/arrow_upward.js.map +1 -0
- package/dist/components/VIcon/icons/arrow_upward_alt.d.ts +5 -0
- package/dist/components/VIcon/icons/arrow_upward_alt.js +9 -0
- package/dist/components/VIcon/icons/arrow_upward_alt.js.map +1 -0
- package/dist/components/VIcon/icons/attach_file.d.ts +5 -0
- package/dist/components/VIcon/icons/attach_file.js +9 -0
- package/dist/components/VIcon/icons/attach_file.js.map +1 -0
- package/dist/components/VIcon/icons/audio_file.d.ts +5 -0
- package/dist/components/VIcon/icons/audio_file.js +9 -0
- package/dist/components/VIcon/icons/audio_file.js.map +1 -0
- package/dist/components/VIcon/icons/calendar_today.d.ts +5 -0
- package/dist/components/VIcon/icons/calendar_today.js +9 -0
- package/dist/components/VIcon/icons/calendar_today.js.map +1 -0
- package/dist/components/VIcon/icons/check.d.ts +5 -0
- package/dist/components/VIcon/icons/check.js +9 -0
- package/dist/components/VIcon/icons/check.js.map +1 -0
- package/dist/components/VIcon/icons/check_circle.d.ts +5 -0
- package/dist/components/VIcon/icons/check_circle.js +9 -0
- package/dist/components/VIcon/icons/check_circle.js.map +1 -0
- package/dist/components/VIcon/icons/chevron_left.d.ts +5 -0
- package/dist/components/VIcon/icons/chevron_left.js +9 -0
- package/dist/components/VIcon/icons/chevron_left.js.map +1 -0
- package/dist/components/VIcon/icons/chevron_right.d.ts +5 -0
- package/dist/components/VIcon/icons/chevron_right.js +9 -0
- package/dist/components/VIcon/icons/chevron_right.js.map +1 -0
- package/dist/components/VIcon/icons/close.d.ts +5 -0
- package/dist/components/VIcon/icons/close.js +9 -0
- package/dist/components/VIcon/icons/close.js.map +1 -0
- package/dist/components/VIcon/icons/cloud_upload.d.ts +5 -0
- package/dist/components/VIcon/icons/cloud_upload.js +9 -0
- package/dist/components/VIcon/icons/cloud_upload.js.map +1 -0
- package/dist/components/VIcon/icons/code.d.ts +5 -0
- package/dist/components/VIcon/icons/code.js +9 -0
- package/dist/components/VIcon/icons/code.js.map +1 -0
- package/dist/components/VIcon/icons/description.d.ts +5 -0
- package/dist/components/VIcon/icons/description.js +9 -0
- package/dist/components/VIcon/icons/description.js.map +1 -0
- package/dist/components/VIcon/icons/error.d.ts +5 -0
- package/dist/components/VIcon/icons/error.js +9 -0
- package/dist/components/VIcon/icons/error.js.map +1 -0
- package/dist/components/VIcon/icons/expand_less.d.ts +5 -0
- package/dist/components/VIcon/icons/expand_less.js +9 -0
- package/dist/components/VIcon/icons/expand_less.js.map +1 -0
- package/dist/components/VIcon/icons/expand_more.d.ts +5 -0
- package/dist/components/VIcon/icons/expand_more.js +9 -0
- package/dist/components/VIcon/icons/expand_more.js.map +1 -0
- package/dist/components/VIcon/icons/folder_zip.d.ts +5 -0
- package/dist/components/VIcon/icons/folder_zip.js +9 -0
- package/dist/components/VIcon/icons/folder_zip.js.map +1 -0
- package/dist/components/VIcon/icons/image.d.ts +5 -0
- package/dist/components/VIcon/icons/image.js +9 -0
- package/dist/components/VIcon/icons/image.js.map +1 -0
- package/dist/components/VIcon/icons/index.d.ts +183 -0
- package/dist/components/VIcon/icons/index.js +77 -0
- package/dist/components/VIcon/icons/index.js.map +1 -0
- package/dist/components/VIcon/icons/info.d.ts +5 -0
- package/dist/components/VIcon/icons/info.js +9 -0
- package/dist/components/VIcon/icons/info.js.map +1 -0
- package/dist/components/VIcon/icons/more_horiz.d.ts +5 -0
- package/dist/components/VIcon/icons/more_horiz.js +9 -0
- package/dist/components/VIcon/icons/more_horiz.js.map +1 -0
- package/dist/components/VIcon/icons/names.d.ts +11 -0
- package/dist/components/VIcon/icons/names.js +5 -0
- package/dist/components/VIcon/icons/names.js.map +1 -0
- package/dist/components/VIcon/icons/notifications.d.ts +5 -0
- package/dist/components/VIcon/icons/notifications.js +9 -0
- package/dist/components/VIcon/icons/notifications.js.map +1 -0
- package/dist/components/VIcon/icons/picture_as_pdf.d.ts +5 -0
- package/dist/components/VIcon/icons/picture_as_pdf.js +9 -0
- package/dist/components/VIcon/icons/picture_as_pdf.js.map +1 -0
- package/dist/components/VIcon/icons/schedule.d.ts +5 -0
- package/dist/components/VIcon/icons/schedule.js +9 -0
- package/dist/components/VIcon/icons/schedule.js.map +1 -0
- package/dist/components/VIcon/icons/search.d.ts +5 -0
- package/dist/components/VIcon/icons/search.js +9 -0
- package/dist/components/VIcon/icons/search.js.map +1 -0
- package/dist/components/VIcon/icons/swap_vert.d.ts +5 -0
- package/dist/components/VIcon/icons/swap_vert.js +9 -0
- package/dist/components/VIcon/icons/swap_vert.js.map +1 -0
- package/dist/components/VIcon/icons/table_chart.d.ts +5 -0
- package/dist/components/VIcon/icons/table_chart.js +9 -0
- package/dist/components/VIcon/icons/table_chart.js.map +1 -0
- package/dist/components/VIcon/icons/video_file.d.ts +5 -0
- package/dist/components/VIcon/icons/video_file.js +9 -0
- package/dist/components/VIcon/icons/video_file.js.map +1 -0
- package/dist/components/VIcon/icons/viewBox.d.ts +6 -0
- package/dist/components/VIcon/icons/viewBox.js +6 -0
- package/dist/components/VIcon/icons/viewBox.js.map +1 -0
- package/dist/components/VIcon/icons/warning.d.ts +5 -0
- package/dist/components/VIcon/icons/warning.js +9 -0
- package/dist/components/VIcon/icons/warning.js.map +1 -0
- package/dist/components/VIcon/resolver.d.ts +76 -0
- package/dist/components/VIcon/resolver.js +35 -0
- package/dist/components/VIcon/resolver.js.map +1 -0
- package/dist/components/VIcon/types.d.ts +77 -0
- package/dist/components/VIconButton/VIconButton.css +2 -0
- package/dist/components/VIconButton/VIconButton.d.ts +66 -0
- package/dist/components/VIconButton/VIconButton.js +9 -0
- package/dist/components/VIconButton/VIconButton.js.map +1 -0
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +70 -0
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VInput/VInput.css +2 -0
- package/dist/components/VInput/VInput.d.ts +152 -0
- package/dist/components/VInput/VInput.js +9 -0
- package/dist/components/VInput/VInput.js.map +1 -0
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +185 -0
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VInputOTP/VInputOTP.css +2 -0
- package/dist/components/VInputOTP/VInputOTP.d.ts +76 -0
- package/dist/components/VInputOTP/VInputOTP.js +9 -0
- package/dist/components/VInputOTP/VInputOTP.js.map +1 -0
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +149 -0
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenu.d.ts +91 -0
- package/dist/components/VMenu/VMenu.js +7 -0
- package/dist/components/VMenu/VMenu.js.map +1 -0
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +73 -0
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenuGroup.css +2 -0
- package/dist/components/VMenu/VMenuGroup.d.ts +22 -0
- package/dist/components/VMenu/VMenuGroup.js +9 -0
- package/dist/components/VMenu/VMenuGroup.js.map +1 -0
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +21 -0
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenuItem.css +2 -0
- package/dist/components/VMenu/VMenuItem.d.ts +85 -0
- package/dist/components/VMenu/VMenuItem.js +9 -0
- package/dist/components/VMenu/VMenuItem.js.map +1 -0
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +121 -0
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenuPanel.css +2 -0
- package/dist/components/VMenu/VMenuPanel.d.ts +91 -0
- package/dist/components/VMenu/VMenuPanel.js +9 -0
- package/dist/components/VMenu/VMenuPanel.js.map +1 -0
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/VMenuSeparator.css +2 -0
- package/dist/components/VMenu/VMenuSeparator.d.ts +3 -0
- package/dist/components/VMenu/VMenuSeparator.js +9 -0
- package/dist/components/VMenu/VMenuSeparator.js.map +1 -0
- package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js +13 -0
- package/dist/components/VMenu/VMenuSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VMenu/context.d.ts +33 -0
- package/dist/components/VMenu/context.js +9 -0
- package/dist/components/VMenu/context.js.map +1 -0
- package/dist/components/VPagination/VPagination.css +2 -0
- package/dist/components/VPagination/VPagination.d.ts +103 -0
- package/dist/components/VPagination/VPagination.js +9 -0
- package/dist/components/VPagination/VPagination.js.map +1 -0
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +270 -0
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VPopover/VPopover.css +2 -0
- package/dist/components/VPopover/VPopover.d.ts +82 -0
- package/dist/components/VPopover/VPopover.js +9 -0
- package/dist/components/VPopover/VPopover.js.map +1 -0
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +65 -0
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VProgressCircular/VProgressCircular.css +2 -0
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +60 -0
- package/dist/components/VProgressCircular/VProgressCircular.js +9 -0
- package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -0
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +74 -0
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VProgressLinear/VProgressLinear.css +2 -0
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +74 -0
- package/dist/components/VProgressLinear/VProgressLinear.js +9 -0
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -0
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +74 -0
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VRadio/VRadio.css +2 -0
- package/dist/components/VRadio/VRadio.d.ts +58 -0
- package/dist/components/VRadio/VRadio.js +9 -0
- package/dist/components/VRadio/VRadio.js.map +1 -0
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSeparator/VSeparator.css +2 -0
- package/dist/components/VSeparator/VSeparator.d.ts +23 -0
- package/dist/components/VSeparator/VSeparator.js +9 -0
- package/dist/components/VSeparator/VSeparator.js.map +1 -0
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigation.css +2 -0
- package/dist/components/VSideNavigation/VSideNavigation.d.ts +64 -0
- package/dist/components/VSideNavigation/VSideNavigation.js +9 -0
- package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +67 -0
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.css +2 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +33 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.js +9 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +20 -0
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.css +2 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +103 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.js +9 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +154 -0
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSideNavigation/VSideNavigationSeparator.css +2 -0
- package/dist/components/VSideNavigation/VSideNavigationSeparator.d.ts +3 -0
- package/dist/components/VSideNavigation/VSideNavigationSeparator.js +17 -0
- package/dist/components/VSideNavigation/VSideNavigationSeparator.js.map +1 -0
- package/dist/components/VSideNavigation/context.d.ts +37 -0
- package/dist/components/VSideNavigation/context.js +6 -0
- package/dist/components/VSideNavigation/context.js.map +1 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.css +2 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +75 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.js +9 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js +61 -0
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSlider/VSlider.css +2 -0
- package/dist/components/VSlider/VSlider.d.ts +82 -0
- package/dist/components/VSlider/VSlider.js +9 -0
- package/dist/components/VSlider/VSlider.js.map +1 -0
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +220 -0
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSnackbar/VSnackbar.css +2 -0
- package/dist/components/VSnackbar/VSnackbar.d.ts +51 -0
- package/dist/components/VSnackbar/VSnackbar.js +9 -0
- package/dist/components/VSnackbar/VSnackbar.js.map +1 -0
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +83 -0
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSnackbar/state.d.ts +92 -0
- package/dist/components/VSnackbar/state.js +18 -0
- package/dist/components/VSnackbar/state.js.map +1 -0
- package/dist/components/VSpinner/VSpinner.css +2 -0
- package/dist/components/VSpinner/VSpinner.d.ts +21 -0
- package/dist/components/VSpinner/VSpinner.js +9 -0
- package/dist/components/VSpinner/VSpinner.js.map +1 -0
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +25 -0
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VSwitch/VSwitch.css +2 -0
- package/dist/components/VSwitch/VSwitch.d.ts +46 -0
- package/dist/components/VSwitch/VSwitch.js +9 -0
- package/dist/components/VSwitch/VSwitch.js.map +1 -0
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +51 -0
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTabs/VTab.css +2 -0
- package/dist/components/VTabs/VTab.d.ts +42 -0
- package/dist/components/VTabs/VTab.js +9 -0
- package/dist/components/VTabs/VTab.js.map +1 -0
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +66 -0
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTabs/VTabPanel.css +2 -0
- package/dist/components/VTabs/VTabPanel.d.ts +34 -0
- package/dist/components/VTabs/VTabPanel.js +9 -0
- package/dist/components/VTabs/VTabPanel.js.map +1 -0
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +34 -0
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTabs/VTabs.css +2 -0
- package/dist/components/VTabs/VTabs.d.ts +107 -0
- package/dist/components/VTabs/VTabs.js +9 -0
- package/dist/components/VTabs/VTabs.js.map +1 -0
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +199 -0
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTabs/context.d.ts +43 -0
- package/dist/components/VTabs/context.js +6 -0
- package/dist/components/VTabs/context.js.map +1 -0
- package/dist/components/VTextarea/VTextarea.css +2 -0
- package/dist/components/VTextarea/VTextarea.d.ts +140 -0
- package/dist/components/VTextarea/VTextarea.js +9 -0
- package/dist/components/VTextarea/VTextarea.js.map +1 -0
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +187 -0
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTimeInput/VTimeInput.css +2 -0
- package/dist/components/VTimeInput/VTimeInput.d.ts +112 -0
- package/dist/components/VTimeInput/VTimeInput.js +9 -0
- package/dist/components/VTimeInput/VTimeInput.js.map +1 -0
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +385 -0
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTimePicker/VTimePicker.css +2 -0
- package/dist/components/VTimePicker/VTimePicker.d.ts +89 -0
- package/dist/components/VTimePicker/VTimePicker.js +9 -0
- package/dist/components/VTimePicker/VTimePicker.js.map +1 -0
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +257 -0
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VToast/VToast.css +2 -0
- package/dist/components/VToast/VToast.d.ts +24 -0
- package/dist/components/VToast/VToast.js +9 -0
- package/dist/components/VToast/VToast.js.map +1 -0
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VToast/VToaster.css +2 -0
- package/dist/components/VToast/VToaster.d.ts +42 -0
- package/dist/components/VToast/VToaster.js +9 -0
- package/dist/components/VToast/VToaster.js.map +1 -0
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +112 -0
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VToast/state.d.ts +74 -0
- package/dist/components/VToast/state.js +25 -0
- package/dist/components/VToast/state.js.map +1 -0
- package/dist/components/VToggle/VToggle.css +2 -0
- package/dist/components/VToggle/VToggle.d.ts +84 -0
- package/dist/components/VToggle/VToggle.js +9 -0
- package/dist/components/VToggle/VToggle.js.map +1 -0
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +103 -0
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VToggle/VToggleItem.css +2 -0
- package/dist/components/VToggle/VToggleItem.d.ts +35 -0
- package/dist/components/VToggle/VToggleItem.js +9 -0
- package/dist/components/VToggle/VToggleItem.js.map +1 -0
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +51 -0
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VToggle/context.d.ts +37 -0
- package/dist/components/VToggle/context.js +6 -0
- package/dist/components/VToggle/context.js.map +1 -0
- package/dist/components/VTooltip/VTooltip.css +2 -0
- package/dist/components/VTooltip/VTooltip.d.ts +76 -0
- package/dist/components/VTooltip/VTooltip.js +9 -0
- package/dist/components/VTooltip/VTooltip.js.map +1 -0
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +50 -0
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VTypography/VTypography.css +2 -0
- package/dist/components/VTypography/VTypography.d.ts +46 -0
- package/dist/components/VTypography/VTypography.js +9 -0
- package/dist/components/VTypography/VTypography.js.map +1 -0
- package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composables/useAriaLabel.d.ts +19 -0
- package/dist/composables/useAriaLabel.js +10 -0
- package/dist/composables/useAriaLabel.js.map +1 -0
- package/dist/composables/useFieldIds.d.ts +21 -0
- package/dist/composables/useFieldIds.js +14 -0
- package/dist/composables/useFieldIds.js.map +1 -0
- package/dist/composables/useFieldPanel.d.ts +61 -0
- package/dist/composables/useFieldPanel.js +39 -0
- package/dist/composables/useFieldPanel.js.map +1 -0
- package/dist/composables/useFileDrop.d.ts +30 -0
- package/dist/composables/useFileDrop.js +28 -0
- package/dist/composables/useFileDrop.js.map +1 -0
- package/dist/composables/useFileField.d.ts +36 -0
- package/dist/composables/useFileField.js +45 -0
- package/dist/composables/useFileField.js.map +1 -0
- package/dist/composables/useFocusoutDismiss.d.ts +17 -0
- package/dist/composables/useFocusoutDismiss.js +11 -0
- package/dist/composables/useFocusoutDismiss.js.map +1 -0
- package/dist/composables/useIconClickHandlers.d.ts +27 -0
- package/dist/composables/useIconClickHandlers.js +13 -0
- package/dist/composables/useIconClickHandlers.js.map +1 -0
- package/dist/composables/useMaskedField.d.ts +65 -0
- package/dist/composables/useMaskedField.js +54 -0
- package/dist/composables/useMaskedField.js.map +1 -0
- package/dist/composables/usePopover.d.ts +7 -0
- package/dist/composables/usePopover.js +24 -0
- package/dist/composables/usePopover.js.map +1 -0
- package/dist/composables/useProgressValue.d.ts +13 -0
- package/dist/composables/useProgressValue.js +14 -0
- package/dist/composables/useProgressValue.js.map +1 -0
- package/dist/composables/useRootAttrs.d.ts +34 -0
- package/dist/composables/useRootAttrs.js +15 -0
- package/dist/composables/useRootAttrs.js.map +1 -0
- package/dist/composables/useTextLimit.d.ts +31 -0
- package/dist/composables/useTextLimit.js +19 -0
- package/dist/composables/useTextLimit.js.map +1 -0
- package/dist/composables/useTimer.d.ts +18 -0
- package/dist/composables/useTimer.js +19 -0
- package/dist/composables/useTimer.js.map +1 -0
- package/dist/i18n/en.d.ts +10 -0
- package/dist/i18n/en.js +179 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/fr.d.ts +18 -0
- package/dist/i18n/fr.js +179 -0
- package/dist/i18n/fr.js.map +1 -0
- package/dist/i18n/state.d.ts +64 -0
- package/dist/i18n/state.js +40 -0
- package/dist/i18n/state.js.map +1 -0
- package/dist/i18n/types.d.ts +345 -0
- package/dist/icons.d.ts +16 -0
- package/dist/icons.js +38 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +64 -0
- package/dist/styles.css +1 -0
- package/dist/tokens/css.d.ts +25 -0
- package/dist/tokens/css.js +29 -0
- package/dist/tokens/css.js.map +1 -0
- package/dist/tokens/index.d.ts +370 -0
- package/dist/tokens/index.js +15 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/primitives.d.ts +101 -0
- package/dist/tokens/primitives.js +166 -0
- package/dist/tokens/primitives.js.map +1 -0
- package/dist/tokens/semantic.d.ts +236 -0
- package/dist/tokens/semantic.js +219 -0
- package/dist/tokens/semantic.js.map +1 -0
- package/dist/tokens/themes/dark.d.ts +49 -0
- package/dist/tokens/themes/dark.js +53 -0
- package/dist/tokens/themes/dark.js.map +1 -0
- package/dist/tokens/types.d.ts +38 -0
- package/dist/tokens/types.js +16 -0
- package/dist/tokens/types.js.map +1 -0
- package/dist/tokens.json +1516 -0
- package/dist/utils/array.d.ts +10 -0
- package/dist/utils/array.js +8 -0
- package/dist/utils/array.js.map +1 -0
- package/dist/utils/arrowNav.d.ts +27 -0
- package/dist/utils/arrowNav.js +26 -0
- package/dist/utils/arrowNav.js.map +1 -0
- package/dist/utils/chip.d.ts +26 -0
- package/dist/utils/chip.js +13 -0
- package/dist/utils/chip.js.map +1 -0
- package/dist/utils/css.d.ts +19 -0
- package/dist/utils/css.js +13 -0
- package/dist/utils/css.js.map +1 -0
- package/dist/utils/date.d.ts +199 -0
- package/dist/utils/date.js +225 -0
- package/dist/utils/date.js.map +1 -0
- package/dist/utils/direction.d.ts +18 -0
- package/dist/utils/direction.js +8 -0
- package/dist/utils/direction.js.map +1 -0
- package/dist/utils/env.d.ts +10 -0
- package/dist/utils/file.d.ts +95 -0
- package/dist/utils/file.js +70 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/focus.d.ts +24 -0
- package/dist/utils/focus.js +13 -0
- package/dist/utils/focus.js.map +1 -0
- package/dist/utils/matcher.d.ts +13 -0
- package/dist/utils/matcher.js +11 -0
- package/dist/utils/matcher.js.map +1 -0
- package/dist/utils/number.d.ts +9 -0
- package/dist/utils/number.js +8 -0
- package/dist/utils/number.js.map +1 -0
- package/dist/utils/text.d.ts +19 -0
- package/dist/utils/text.js +12 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/time.d.ts +138 -0
- package/dist/utils/time.js +123 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/vnode.d.ts +21 -0
- package/dist/utils/vnode.js +14 -0
- package/dist/utils/vnode.js.map +1 -0
- package/package.json +114 -0
package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VCalendar/VCalendarTimeGrid.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @keyboard @core\n/**\n * The time grid: a column per day on show, an hour per row, and the events drawn over it.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it. It computes nothing about dates or overlaps: it is handed\n * the days and the already-placed segments, and its whole job is to turn them into boxes.\n *\n * WHY EVERY CELL EXISTS. Twenty-four rows times seven days is a hundred and sixty-eight\n * elements, where the rules between the hours could have been one repeating gradient. Two\n * things pay for them. A background is forced to `Canvas` under Windows forced-colors and\n * the ruling would vanish, where a border is forced to `CanvasText` and survives — the\n * argument VSeparator and the VIcon registry both make. And the ARIA \"grid\" pattern needs\n * real cells to move a focus between, which is what gives the keyboard somewhere to be and\n * what satisfies the rule that a scrolling region must hold something reachable by Tab.\n *\n * WHY THE CARDS SIT INSIDE THE CELLS. An event is placed absolutely against the whole\n * columns box, so putting the cards in one overlay layer would have been simpler CSS. They\n * are instead children of the cell their start falls in, because an absolutely positioned\n * element leaves its parent's box for LAYOUT while staying inside it in the document — and\n * therefore in the accessibility tree. In an overlay they would sit outside the grid\n * entirely, which breaks the reading order and fails `aria-required-children` the moment\n * anything tries to put them back.\n *\n * The day names are NOT marked up as column headers. They live above the scrolling area so\n * that they can stay in view, which puts them outside the grid; instead every cell names\n * its own day in full (\"Wednesday 10 June, 09:00\"), so nothing is lost to a reader who\n * never sees the row at all.\n */\nimport { computed, nextTick, onBeforeUnmount, ref, useId, watch } from 'vue'\n\nimport { formatDisplay as formatDate } from '../../utils/date'\nimport { isRtl as isElementRtl } from '../../utils/direction'\nimport { clamp } from '../../utils/number'\nimport { formatDisplay as formatTimeDisplay, type HourFormat } from '../../utils/time'\n\nimport { useMessages } from '../../i18n/state'\n\nimport VCalendarEvent from './VCalendarEvent.vue'\nimport {\n DRAG_THRESHOLD,\n blockEdgeAt,\n floorToSlot,\n fractionOf,\n inlineEdgeAt,\n isAllDayEvent,\n minutesAt,\n moveEvent,\n moveEventToDay,\n packAllDay,\n packDayColumn,\n pointToCell,\n pointWithin,\n resizeEvent,\n snapToSlot,\n timeOf,\n timedSegments,\n timesOf,\n type AllDaySpan,\n type PlacedSegment,\n type TimeWindow,\n} from './layout'\nimport { calendarIntent } from './keyboard'\nimport { EDGE_BAND, useEdgeStep } from './edgeStep'\nimport type { CalendarEvent, CalendarEventId, CalendarEventTimes } from './types'\n\n/** Where the keyboard focus is in the grid, as a day and a moment in it. */\nexport interface FocusedCell {\n iso: string\n minutes: number\n}\n\nexport interface TimeGridProps<T> {\n days: string[]\n events: T[]\n window: TimeWindow\n slotDuration: number\n locale: string\n hourFormat: HourFormat\n /** Today's date, or nothing on the server, where it cannot be known. */\n today: string | null\n /**\n * The time it is now, in minutes since midnight — again nothing on the server. It is\n * passed in rather than read here so that one clock drives every view, and so that a\n * calendar showing no time grid still costs no timer.\n */\n now: number | null\n /** Whether events can be moved and stretched. */\n editable: boolean\n /** Whether an empty part of the grid makes an event when it is taken up. */\n creatable: boolean\n /** The node telling a reader how a card can be moved, shared by every card. */\n hintId: string\n /** How long a drag rests against an edge before the view pages. Zero turns paging off. */\n edgeStepDelay: number\n /** Whether dragging near the top or bottom scrolls the grid. */\n autoScroll: boolean\n /** What the grid as a whole is called — the range it is showing. */\n label: string\n}\n\nconst props = defineProps<TimeGridProps<E>>()\n\nconst emit = defineEmits<{\n /** An empty part of the grid was activated, at this day and this moment. */\n 'cell-activate': [iso: string, minutes: number]\n /** A card was clicked or activated. */\n 'event-activate': [event: E]\n /** An event was dropped somewhere else, or stretched to a new end. */\n 'event-drop': [id: CalendarEventId, times: CalendarEventTimes, kind: 'move' | 'resize']\n /** An empty stretch of a day was drawn out, and is asking to become an event. */\n 'slot-create': [times: CalendarEventTimes]\n /** Something happened that a reader who cannot see the grid needs told. */\n announce: [message: string]\n /** A page key asked for the previous or next period, which only the calendar can do. */\n step: [delta: -1 | 1]\n}>()\n\n/** Which cell holds the tab stop. The calendar owns it, so the toolbar can move it too. */\nconst focused = defineModel<FocusedCell>('focused', { required: true })\n\ndefineSlots<{\n event?(props: {\n event: E\n layout: 'block' | 'chip'\n timeText: string\n continuesBefore: boolean\n continuesAfter: boolean\n dragging: boolean\n grabbed: boolean\n }): unknown\n 'day-header'?(props: { iso: string; weekday: string; day: string; today: boolean }): unknown\n 'all-day-label'?(): unknown\n}>()\n\nconst m = useMessages()\nconst uid = useId()\n\nconst MINUTES_PER_HOUR = 60\n\n/** The hour each row stands for, as minutes since midnight. */\nconst hours = computed(() => {\n const rows: number[] = []\n for (let at = props.window.start; at < props.window.end; at += MINUTES_PER_HOUR) rows.push(at)\n return rows\n})\n\n/**\n * The id a stretch of empty grid carries while it is being drawn out. It never leaves this\n * component: on release the calendar is handed the times alone and mints an id of its own.\n */\nconst DRAFT_ID = '__vectis-calendar-draft__'\n\n/**\n * The id the faded echo of a dragged event carries.\n *\n * It has to DIFFER from the event's own, or the two would collide in every map the layout\n * keys by id and only one of them would ever be drawn. The original is recovered from it —\n * and handed to the card as `ghostOf` — because the colour of an event is derived from its\n * id, so an echo under a fresh id would come out a different colour from the card it belongs\n * to. `hueOf` reads a number and its digits as the same event, so the string form is enough.\n */\nconst GHOST_PREFIX = '__vectis-calendar-ghost__'\nconst ghostIdOf = (id: CalendarEventId) => `${GHOST_PREFIX}${id}`\nconst originalIdOf = (id: CalendarEventId) => String(id).slice(GHOST_PREFIX.length)\nconst isGhostId = (id: CalendarEventId) => String(id).startsWith(GHOST_PREFIX)\n\n/**\n * A gesture under way, whether it came from a pointer or from the keyboard.\n *\n * `move-days` is the whole-day one: an all-day bar dragged along the band above the grid. It\n * is a kind of its own rather than a flag on `move` because the two answer different\n * questions — one asks what MOMENT the pointer is over, the other only what day — and because\n * a bar spanning three days must keep spanning three when it lands.\n */\ninterface Gesture {\n kind: 'move' | 'move-days' | 'resize' | 'create'\n id: CalendarEventId\n /**\n * Where the event was when the gesture began. Every frame is computed from THIS and never\n * from the frame before it, so a long drag cannot accumulate rounding drift.\n */\n origin: CalendarEventTimes\n /** What the card shows right now. The model is not touched until the gesture ends. */\n preview: CalendarEventTimes\n pointerId: number | null\n originX: number\n originY: number\n /** How far into the card the pointer took hold, so the card does not jump under it. */\n grabOffset: number\n grabColumn: number\n /**\n * Where the pointer last was.\n *\n * Kept because two things move the calendar UNDER a still pointer — paging at an edge, and\n * auto-scrolling — and each has to work out afresh what the pointer is now over. Without it\n * a hand held motionless at an edge would page the view and leave the card behind on a day\n * that is no longer on screen.\n */\n lastX: number\n lastY: number\n /**\n * The share of its column the dragged card had when the gesture began — and nothing else.\n *\n * That much is recorded because the echo must not take part in the overlap layout: were it\n * packed alongside the card being dragged, the two would share the width of their column\n * the moment they overlapped, and the card under the pointer would halve in width and then\n * grow back as it moved away.\n *\n * WHERE the echo goes is deliberately NOT recorded, and is recomputed on every render from\n * the origin times against the days currently on show. Holding at an edge pages the view\n * under a live drag, and both of these boxes are described by INDEX into `props.days`: a\n * `dayIndex` captured in one week names a different date in the next, so a frozen box would\n * follow the column rather than the day — an event dragged out of Tuesday the 9th leaving\n * its echo on Tuesday the 2nd, instead of leaving with the week it belonged to.\n *\n * Exactly one of the two is ever set — a timed event is a segment, an all-day one a bar.\n */\n ghostColumn: Pick<PlacedSegment, 'column' | 'span' | 'columns'> | null\n ghostLane: number | null\n /** Whether the pointer has travelled far enough for this to be a drag and not a click. */\n moved: boolean\n /**\n * Whether the pointer is off the calendar altogether — over the toolbar, or over the page\n * beside it. Letting go here abandons the gesture whole and writes nothing.\n *\n * A KEYBOARD grab can never set it, and structurally rather than by a guard: `onPointermove`\n * is the only thing that writes it, and it returns on the id mismatch before reaching that\n * line — a grab's `pointerId` is null, which no real pointer's id ever equals.\n */\n outside: boolean\n}\n\nconst gesture = ref<Gesture | null>(null)\n\n/** True while a card is being held by the keyboard rather than dragged by a pointer. */\nconst grabbing = computed(() => gesture.value !== null && gesture.value.pointerId === null)\n\n/**\n * The event the echo stands for: the one being dragged, back where the drag began.\n *\n * ONE predicate, read by the three places that have to agree — the event list, the packing\n * and the band. They were briefly allowed to disagree, and the failure was immediate and\n * total: a placement with no event behind it, and every card in the grid failing to render.\n * A press that has not travelled yet produces none, or a click would flash a second card\n * over the first.\n */\nconst ghostEvent = computed<E | null>(() => {\n const state = gesture.value\n if (!state?.moved) return null\n const original = props.events.find((event) => event.id === state.id)\n return original ? ({ ...original, ...state.origin, id: ghostIdOf(state.id) } as E) : null\n})\n\n/**\n * Where the echo goes, worked out afresh on every render rather than remembered.\n *\n * The two helpers are the SAME ones every other box goes through, run on a list of one — so\n * the echo answers to the days on show exactly as an ordinary event does, and in particular\n * is dropped when its day is not among them. That is what makes it leave with its week when\n * a drag held at an edge pages the view, instead of staying on the column it used to occupy.\n * It is also what keeps the two kinds mutually exclusive by construction rather than by\n * chance: `timedSegments` passes over an all-day event and `packAllDay` over a timed one.\n *\n * Only the packing captured at the start of the gesture is put back on top — see\n * `ghostColumn` above for why that one part must NOT be recomputed.\n */\nconst ghostSegment = computed<PlacedSegment | null>(() => {\n const state = gesture.value\n const event = ghostEvent.value\n if (!event || !state?.ghostColumn) return null\n const [segment] = timedSegments([event], props.days, props.window, props.slotDuration)\n return segment ? { ...segment, ...state.ghostColumn } : null\n})\n\nconst ghostSpan = computed<AllDaySpan | null>(() => {\n const state = gesture.value\n const event = ghostEvent.value\n if (!event || state?.ghostLane == null) return null\n const [span] = packAllDay([event], props.days)\n return span ? { ...span, lane: state.ghostLane } : null\n})\n\n/**\n * The events as the grid should currently DRAW them — which is the model, with the one being\n * gestured at moved to wherever it is now.\n *\n * Running the preview through the same packing as everything else is what makes the other\n * events reflow live around the one being dragged, with no special case anywhere: the layout\n * does not know a gesture is happening, only that an event is somewhere.\n */\nconst drawnEvents = computed<E[]>(() => {\n const state = gesture.value\n if (!state) return props.events\n\n if (state.kind === 'create') {\n const draft = {\n id: DRAFT_ID,\n title: m.value.calendar.newEvent(props.events.length + 1),\n ...state.preview,\n // A draft carries exactly the fields `CalendarEvent` declares, and a consumer's own\n // type may require more. It exists for one render and never reaches the model, which\n // is what makes the cast safe — the calendar mints the real event on release.\n } as unknown as E\n return [...props.events, draft]\n }\n\n const moving = props.events.map((event) =>\n event.id === state.id ? ({ ...event, ...state.preview } as E) : event,\n )\n\n /*\n * The echo of where it started. It is listed here whether or not it has a box to draw on,\n * because this is what `eventsById` is built from and the template reads a card's event\n * back out of that map. An echo whose day the view has paged past simply produces no\n * placement below — which is what happens to any ordinary event on a day that is off show.\n */\n return ghostEvent.value ? [...moving, ghostEvent.value] : moving\n})\n\nconst eventsById = computed(() => new Map(drawnEvents.value.map((event) => [event.id, event])))\n\n/**\n * The bars above the grid, and how many rows they need between them.\n *\n * The echo is taken OUT of the packing and put back with the position it had when the drag\n * began. Left in, it would compete for lanes with the bar being dragged, and both would jump\n * a row whenever they happened to overlap.\n */\nconst allDay = computed(() => {\n const ghost = ghostSpan.value\n const spans = packAllDay(\n ghost ? drawnEvents.value.filter((event) => event.id !== ghost.id) : drawnEvents.value,\n props.days,\n )\n return ghost ? [...spans, ghost] : spans\n})\nconst allDayLanes = computed(() =>\n allDay.value.reduce((most, span) => Math.max(most, span.lane + 1), 0),\n)\n\n/**\n * Where the current-time line goes, or nothing when it has no business being drawn: on the\n * server, on a range that does not include today, or at an hour the window has cropped\n * away.\n */\nconst nowMark = computed(() => {\n if (props.now === null || props.today === null) return null\n const dayIndex = props.days.indexOf(props.today)\n if (dayIndex === -1) return null\n if (props.now < props.window.start || props.now > props.window.end) return null\n const row = Math.floor((props.now - props.window.start) / MINUTES_PER_HOUR)\n return {\n dayIndex,\n // Clamped so the line at the very end of the window still has a cell to live in.\n cell: `${dayIndex}:${clamp(row, 0, hours.value.length - 1)}`,\n fraction: fractionOf(props.now, props.window),\n }\n})\n\n/**\n * The placed boxes, day by day. `packDayColumn` works on one column at a time, so the\n * segments are split before it sees them: events on different days never compete for width,\n * and packing them together would make a busy Monday narrow a quiet Tuesday.\n */\nconst placed = computed(() => {\n const segments = timedSegments(drawnEvents.value, props.days, props.window, props.slotDuration)\n const ghost = ghostSegment.value\n\n const byDay = new Map<number, typeof segments>()\n for (const segment of segments) {\n /*\n * The echo is held OUT of the packing and put back below with the width and column it had\n * when the drag began. Packed with the rest, it would share its column with the card\n * being dragged the moment the two overlapped — so the card under the pointer would halve\n * in width and then grow back as it moved away, which reads as the drag going wrong.\n */\n if (ghost && segment.id === ghost.id) continue\n const list = byDay.get(segment.dayIndex)\n if (list) list.push(segment)\n else byDay.set(segment.dayIndex, [segment])\n }\n\n const real = [...byDay.values()].flatMap((list) => packDayColumn(list))\n return ghost ? [...real, ghost] : real\n})\n\n/**\n * The cards, filed under the cell their start falls in. Grouping once here is what keeps\n * the template from asking every cell to search the whole list — a hundred and sixty-eight\n * searches per render otherwise.\n */\nconst byCell = computed(() => {\n const map = new Map<string, PlacedSegment[]>()\n for (const segment of placed.value) {\n const row = Math.floor((segment.start - props.window.start) / MINUTES_PER_HOUR)\n const key = `${segment.dayIndex}:${clamp(row, 0, hours.value.length - 1)}`\n const list = map.get(key)\n if (list) list.push(segment)\n else map.set(key, [segment])\n }\n return map\n})\n\nconst cellId = (iso: string, minutes: number) => `${uid}-c-${iso}-${minutes}`\n\n/*\n * Every label the grid writes, worked out once per day and once per hour instead of once\n * per CELL — the shape `byCell` above already uses, and for the same reason.\n *\n * The grid renders `hours × days` cells, 24 × 7 by default. Reading these straight from\n * `formatDate` in the template meant 168 `cellLabel` calls per render, each doing a\n * `parseISO`, a `JSON.stringify` to build the formatter's cache key and two `Intl` formats,\n * plus `dayName`/`dayNumber` twice per column (slot props, then the fallback content). None\n * of it depends on the pointer — yet `applyPoint` assigns a new `state.preview` on every\n * `pointermove`, so the whole template re-renders at pointer rate and all of it was\n * recomputed on every frame of a drag.\n *\n * Two maps of 7 and 24 entries replace that: they recompute when the locale, the days or\n * the window change, and never because a card moved.\n */\nconst dayLabels = computed(() => {\n const map = new Map<string, { short: string; number: string; full: string }>()\n for (const iso of props.days) {\n map.set(iso, {\n short: formatDate(iso, props.locale, { weekday: 'short' }),\n number: formatDate(iso, props.locale, { day: 'numeric' }),\n full: formatDate(iso, props.locale, { weekday: 'long', day: 'numeric', month: 'long' }),\n })\n }\n return map\n})\n\nconst hourLabels = computed(() => {\n const map = new Map<number, string>()\n for (const minutes of hours.value)\n map.set(minutes, formatTimeDisplay(timeOf(minutes), props.locale, props.hourFormat))\n return map\n})\n\n/*\n * The hour gutter and the drag readout both ask for an hour that is not always one of the\n * rows — a preview lands between them — so this falls back to formatting rather than\n * assuming the map holds every minute.\n */\nconst hourLabel = (minutes: number) =>\n hourLabels.value.get(minutes) ??\n formatTimeDisplay(timeOf(minutes), props.locale, props.hourFormat)\n\nconst dayName = (iso: string, weekday: 'short' | 'long') =>\n weekday === 'short'\n ? (dayLabels.value.get(iso)?.short ?? formatDate(iso, props.locale, { weekday }))\n : formatDate(iso, props.locale, { weekday })\n\nconst dayNumber = (iso: string) =>\n dayLabels.value.get(iso)?.number ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/** What one cell is called: the day in full, then the hour. */\nconst cellLabel = (iso: string, minutes: number) =>\n `${dayLabels.value.get(iso)?.full ?? iso}, ${hourLabel(minutes)}`\n\n/**\n * An event's times, written out for the reader. The time zone is appended as an annotation\n * and never applied: the card's place in the grid comes from the local times given, which\n * is the whole of the design system's position on the matter.\n */\nfunction timeTextOf(event: E): string {\n const start = formatTimeDisplay(event.startTime, props.locale, props.hourFormat)\n const end = formatTimeDisplay(event.endTime, props.locale, props.hourFormat)\n const range = `${start} – ${end}`\n return event.timezone ? `${range} (${event.timezone})` : range\n}\n\nfunction styleFor(segment: PlacedSegment) {\n return {\n '--event-start': String(fractionOf(segment.start, props.window)),\n '--event-end': String(fractionOf(segment.end, props.window)),\n '--event-day': String(segment.dayIndex),\n '--event-column': String(segment.column),\n '--event-span': String(segment.span),\n '--event-columns': String(segment.columns),\n }\n}\n\nconst isFocused = (iso: string, minutes: number) =>\n focused.value.iso === iso && focused.value.minutes === minutes\n\n/**\n * Where the tab stop goes when the focused cell is not one of the cells on screen — after\n * a view change, or before anything has been focused at all. Without it no cell would carry\n * `tabindex=\"0\"`, the grid would drop out of the tab order, and the scrolling region would\n * have nothing reachable inside it, which is an accessibility failure and not merely an\n * inconvenience.\n */\nconst fallbackCell = computed(() => {\n const iso = props.days[0]\n if (!iso) return null\n return { iso, minutes: props.window.start }\n})\n\nconst tabbable = computed<FocusedCell | null>(() => {\n const current = focused.value\n if (props.days.includes(current.iso)) {\n const rounded =\n Math.floor((current.minutes - props.window.start) / MINUTES_PER_HOUR) * MINUTES_PER_HOUR +\n props.window.start\n if (rounded >= props.window.start && rounded < props.window.end) {\n return { iso: current.iso, minutes: rounded }\n }\n }\n return fallbackCell.value\n})\n\nconst isTabStop = (iso: string, minutes: number) =>\n tabbable.value?.iso === iso && tabbable.value.minutes === minutes\n\nfunction moveFocusTo(iso: string, minutes: number) {\n focused.value = { iso, minutes }\n // @a11y — the model is what decides which cell is tabbable, so the DOM focus can only be\n // moved once the render that applied it has run.\n void nextTick(() => document.getElementById(cellId(iso, minutes))?.focus())\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const target = event.target as HTMLElement | null\n\n // A card answers a different table from the grid it sits in — that is what a grab mode IS.\n // Delegated here, on the same element as the pointer, so the two never drift apart.\n const card = target?.closest<HTMLElement>('.v-calendar-event')\n if (card) {\n onCardKeydown(event, card)\n return\n }\n\n const cell = target?.closest<HTMLElement>('.v-calendar-cell')\n if (!cell) return\n\n const intent = calendarIntent(event.key, event.shiftKey, 'cell', props.slotDuration, isRtl())\n if (!intent) return\n\n const iso = cell.dataset.iso!\n const minutes = Number(cell.dataset.minutes)\n const index = props.days.indexOf(iso)\n\n if (intent.kind === 'moveFocus') {\n const day = props.days[clamp(index + intent.days, 0, props.days.length - 1)]!\n const at = clamp(\n minutes + intent.minutes,\n props.window.start,\n props.window.end - MINUTES_PER_HOUR,\n )\n event.preventDefault()\n moveFocusTo(day, at)\n return\n }\n\n if (intent.kind === 'rowEdge') {\n const day = intent.edge === 'start' ? props.days[0] : props.days.at(-1)\n if (!day) return\n event.preventDefault()\n moveFocusTo(day, minutes)\n return\n }\n\n if (intent.kind === 'period') {\n event.preventDefault()\n emit('step', intent.delta)\n return\n }\n\n if (intent.kind === 'activate') {\n event.preventDefault()\n emit('cell-activate', iso, minutes)\n }\n}\n\n/* ------------------------------------------------------------------ the gestures */\n\n/**\n * Starts a gesture, from whichever of the three ways one can begin.\n *\n * Every entry point funnels through here, so the rules that make a gesture safe — one at a\n * time, the origin captured once, the pointer taken hold of on the GRID — are written once\n * rather than three times.\n */\nfunction begin(\n state: Omit<\n Gesture,\n 'preview' | 'moved' | 'outside' | 'lastX' | 'lastY' | 'ghostColumn' | 'ghostLane'\n >,\n event?: PointerEvent,\n) {\n /*\n * Read BEFORE the gesture is set. Both are derived from `drawnEvents`, which the gesture\n * immediately starts rewriting — a line later and they would already describe the preview\n * rather than the place it came from. Which of the two answers is also what says whether\n * this is a timed card or an all-day bar, and therefore which of the echo's two shapes the\n * gesture has to carry.\n */\n const segment = placed.value.find((item) => item.id === state.id)\n const span = allDay.value.find((item) => item.id === state.id)\n\n gesture.value = {\n ...state,\n preview: { ...state.origin },\n lastX: state.originX,\n lastY: state.originY,\n ghostColumn: segment\n ? { column: segment.column, span: segment.span, columns: segment.columns }\n : null,\n ghostLane: span ? span.lane : null,\n moved: false,\n outside: false,\n }\n\n if (!event) return\n /*\n * @fallback — capturing the pointer on the COLUMNS box, and not on the card, is what makes\n * one set of move and up handlers serve all three gestures and what keeps a drag alive\n * when the pointer wanders off the grid: capture retargets every later pointer event back\n * to the captured element, so the bindings in the template are the whole of it — no\n * document listener, no release, nothing to tear down on unmount.\n *\n * It is wrapped because a pointer event fired by a TEST refers to no real pointer, and the\n * call then throws. Failing to capture merely means the drag stops at the edge, which no\n * test is checking.\n */\n try {\n // The SCROLLER, not the columns box: the all-day band sits in the sticky header, and this\n // is the only element that contains both it and the canvas. Capture retargets every later\n // pointer event here, which is why one set of move and up bindings serves all four kinds.\n rootEl.value?.setPointerCapture(event.pointerId)\n } catch {\n /* a synthetic pointer: nothing to capture */\n }\n}\n\n/**\n * Every press on the grid, dispatched by WHAT it landed on.\n *\n * One delegated handler rather than a listener per card and per strip. That is not only\n * fewer bindings on a grid that may hold a hundred: it is what removes the question of\n * which listener runs first. Three handlers stacked on nested elements would each have to\n * guard against the others, and `stopPropagation` would make the answer depend on the order\n * they happened to be bound in. Here the target is examined once and the gesture chosen\n * once, so the strip inside a card and the card inside a cell cannot disagree.\n */\nfunction onGridPointerdown(event: PointerEvent) {\n endLastGesture()\n // Left button only: a right-click is opening a context menu, not starting a drag.\n if (gesture.value || event.button !== 0) return\n\n const target = event.target as HTMLElement | null\n if (!target) return\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n\n const point = pointToCell(\n { x: event.clientX, y: event.clientY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n const card = target.closest<HTMLElement>('.v-calendar-event')\n if (card) {\n if (!props.editable) return\n const item = eventsById.value.get(cardIdOf(card))\n if (!item || isAllDayEvent(item)) return\n\n const resizing = target.closest('[data-calendar-handle]') !== null\n begin(\n {\n kind: resizing ? 'resize' : 'move',\n id: item.id,\n origin: timesOf(item),\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n // Where inside the card the pointer took hold, so it does not jump under the finger.\n grabOffset: resizing ? 0 : point.minutes - minutesAt(item.startTime, props.window.start),\n grabColumn: point.columnIndex,\n },\n event,\n )\n return\n }\n\n if (!props.creatable || !target.closest('.v-calendar-cell')) return\n const iso = props.days[point.columnIndex]\n if (!iso) return\n\n /*\n * A new event begins at the top of the slot the pointer went down in — rounded DOWN, never\n * to the nearest — because a press at 09:07 means \"the nine o'clock slot\" and not the\n * quarter past. It is one slot long to begin with, so a press that never moves creates\n * exactly the short event a click is meant to create, and a press that travels stretches\n * its end instead. One path serves both, and a click is simply the drag that stayed still.\n */\n const start = floorToSlot(point.minutes, props.slotDuration)\n begin(\n {\n kind: 'create',\n id: DRAFT_ID,\n origin: {\n start: iso,\n end: iso,\n startTime: timeOf(start),\n endTime: timeOf(Math.min(start + props.slotDuration, props.window.end)),\n },\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n grabOffset: 0,\n grabColumn: point.columnIndex,\n },\n event,\n )\n}\n\n/**\n * A press on the band of all-day bars above the grid.\n *\n * It has a handler of its own rather than joining the delegated one below it, because the\n * band is not inside `.v-calendar-columns` — it lives in the sticky header, which is the one\n * part of the calendar that scroll does not carry. Everything after the press IS shared: the\n * capture, the move, the release, all of them on the scroller both boxes sit in.\n */\nfunction onBandPointerdown(event: PointerEvent) {\n endLastGesture()\n if (gesture.value || !props.editable || event.button !== 0) return\n\n const card = (event.target as HTMLElement | null)?.closest<HTMLElement>('.v-calendar-event')\n if (!card) return\n const item = eventsById.value.get(cardIdOf(card))\n if (!item) return\n\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n const point = pointToCell(\n { x: event.clientX, y: event.clientY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n begin(\n {\n kind: 'move-days',\n id: item.id,\n origin: timesOf(item),\n pointerId: event.pointerId,\n originX: event.clientX,\n originY: event.clientY,\n grabOffset: 0,\n grabColumn: point.columnIndex,\n },\n event,\n )\n}\n\n/** The event a card stands for, read back off the attribute the card publishes. */\nfunction cardIdOf(card: HTMLElement): CalendarEventId {\n const raw = card.dataset.eventId ?? ''\n /*\n * An id may be a number, and an attribute is always text. The map is keyed by the ORIGINAL\n * value, so a numeric id has to be turned back into one — otherwise every card belonging\n * to a numerically-keyed calendar would look up as a miss and nothing would drag.\n */\n return eventsById.value.has(raw) ? raw : Number(raw)\n}\n\nfunction onPointermove(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n\n state.lastX = event.clientX\n state.lastY = event.clientY\n\n // Below the threshold nothing has happened yet. That is what keeps a click a click: the\n // hand's tremor during a press would otherwise register as a one-pixel drag.\n if (\n !state.moved &&\n Math.abs(event.clientX - state.originX) < DRAG_THRESHOLD &&\n Math.abs(event.clientY - state.originY) < DRAG_THRESHOLD\n ) {\n return\n }\n\n state.moved = true\n state.outside = isPointerOutside(state)\n applyPoint(state)\n watchEdges(state)\n}\n\n/**\n * Whether the pointer has left the calendar's own box.\n *\n * The box is the WHOLE view — the scroller, the element carrying `.v-calendar-view` — and\n * deliberately not `.v-calendar-columns`, whose rect excludes the sticky day names, the all-day\n * band and the hour gutter: a bar dropped on the band is an ordinary thing to do, and measured\n * against the columns it would read as dropped off the calendar and silently revert.\n *\n * The rect goes in RAW and never through `geometryOf`, whose `inlineStart` is the box's RIGHT\n * edge in a right-to-left page: containment has no reading direction, and flipping the axis here\n * would answer a question nobody asked — every right-to-left drop would read as outside.\n *\n * It is called from `onPointermove` ALONE, and not from `applyPoint`. That function has three\n * callers, and the other two — the view paging, and the auto-scroll frame — move the days and\n * the scroll position under a pointer that has not moved at all: they cannot change this answer,\n * and asking them to recompute it would force a layout on every animation frame.\n *\n * TRAP — neither `applyPoint` nor `watchEdges` is gated on the result, and neither may become\n * so. The card must keep following the pointer while it is out (that is what makes coming back\n * in seamless), and paging must keep running (pushing past the edge is how one crosses into the\n * next week). Being outside decides what happens on RELEASE, and nothing else.\n */\nfunction isPointerOutside(state: Gesture): boolean {\n const rect = rootEl.value?.getBoundingClientRect()\n return rect ? !pointWithin({ x: state.lastX, y: state.lastY }, rect) : false\n}\n\n/**\n * Works out where the dragged event now belongs, from wherever the pointer last was.\n *\n * It is separate from the handler because THREE things call it: the pointer moving, the view\n * paging out from under a still pointer, and the grid scrolling under one. The last two would\n * otherwise leave the card behind on a day or an hour that is no longer where the pointer is.\n */\nfunction applyPoint(state: Gesture) {\n const rect = columnsEl.value?.getBoundingClientRect()\n if (!rect) return\n // Measuring here is safe: this runs from a handler or a frame, hence in a browser, never\n // in a render.\n const point = pointToCell(\n { x: state.lastX, y: state.lastY },\n geometryOf(rect),\n props.window,\n isRtl(),\n )\n\n if (state.kind === 'move-days') {\n /*\n * A bar keeps its length in days, so the target is its START shifted by however many\n * columns the pointer has crossed — not the column the pointer is over. Grab a\n * Monday-to-Wednesday bar by its Tuesday and the pointer stays on its Tuesday.\n */\n const column = clamp(\n originColumn(state) + (point.columnIndex - state.grabColumn),\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column]\n if (iso) state.preview = moveEventToDay(state.origin, iso)\n return\n }\n\n if (state.kind === 'move') {\n /*\n * The day comes from the COLUMN the pointer is over, read out of the list of days on\n * show — never from date arithmetic on how many columns were crossed, which would count\n * the days the calendar is hiding and land the event on a Saturday nobody can see.\n */\n const column = clamp(\n originColumn(state) + (point.columnIndex - state.grabColumn),\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column]!\n const start = snapToSlot(point.minutes - state.grabOffset, props.slotDuration)\n const delta = start - minutesAt(state.origin.startTime, props.window.start)\n state.preview = { ...moveEvent(state.origin, 0, delta, props.window), start: iso, end: iso }\n return\n }\n\n state.preview = resizeEvent(\n state.origin,\n snapToSlot(point.minutes, props.slotDuration),\n props.slotDuration,\n props.window,\n )\n}\n\n/* ------------------------------------------------------- crossing the boundaries */\n\n/**\n * How many pixels a frame the grid scrolls at full tilt.\n *\n * At sixty frames a second that is roughly eight hundred a second, which crosses a whole\n * twenty-four-hour day in about two — fast enough to be worth doing, slow enough to stop on.\n */\nconst AUTO_SCROLL_SPEED = 14\n\nconst edge = useEdgeStep(\n (direction) => emit('step', direction),\n () => props.edgeStepDelay,\n)\n\n/** Which edge is counting down, in words, for the stylesheet to light up. */\nconst edgeCue = computed(() =>\n edge.pending.value === -1 ? 'start' : edge.pending.value === 1 ? 'end' : undefined,\n)\n\n/** Tells the two boundary mechanisms where the pointer now is. */\nfunction watchEdges(state: Gesture) {\n const columns = columnsEl.value?.getBoundingClientRect()\n const scroller = rootEl.value?.getBoundingClientRect()\n if (!columns || !scroller) return\n\n // Paging is measured against the COLUMNS, which is what the days occupy; scrolling against\n // the SCROLLER, which is what actually moves.\n edge.watchEdge(inlineEdgeAt(state.lastX, geometryOf(columns), EDGE_BAND, isRtl()))\n setScrollSpeed(props.autoScroll ? blockEdgeAt(state.lastY, scroller, EDGE_BAND) : 0)\n}\n\n/*\n * The design system's only `requestAnimationFrame` loop, and it earns that: a pointer held\n * still fires no events at all, so nothing else can drive continuous motion. Everything else\n * that moves here is either a transition or a timer.\n */\nlet scrollFrame: number | null = null\nlet scrollSpeed = 0\n\nfunction setScrollSpeed(speed: number) {\n scrollSpeed = speed\n if (speed === 0) {\n stopScrolling()\n return\n }\n scrollFrame ??= requestAnimationFrame(scrollStep)\n}\n\nfunction scrollStep() {\n scrollFrame = null\n const root = rootEl.value\n const state = gesture.value\n if (!root || !state || scrollSpeed === 0) return\n\n root.scrollTop += scrollSpeed * AUTO_SCROLL_SPEED\n // The hours have moved under a pointer that has not, so what it is over has changed.\n applyPoint(state)\n scrollFrame = requestAnimationFrame(scrollStep)\n}\n\nfunction stopScrolling() {\n if (scrollFrame !== null) cancelAnimationFrame(scrollFrame)\n scrollFrame = null\n scrollSpeed = 0\n}\n\n/** Everything a gesture leaves running, dropped on every path out of one. */\nfunction releaseBoundaries() {\n edge.cancel()\n stopScrolling()\n}\n\nonBeforeUnmount(stopScrolling)\n\n/*\n * Paging swaps the days out from under a live drag, and the dragged event's day is then off\n * screen — the card would vanish until the next pointer move, which never comes if the hand\n * is holding still against the edge. Re-applying the last position as soon as the new days\n * are rendered is what keeps the card under the pointer across the boundary.\n */\nwatch(\n () => props.days,\n () => {\n const state = gesture.value\n if (state?.moved) applyPoint(state)\n },\n { flush: 'post' },\n)\n\n/**\n * Which column the event being moved started in.\n *\n * The fallback is what makes the formula above general rather than a special case. For a\n * TIMED card these two are necessarily equal — you grab a card, and a card lives inside its\n * own column — so the offset is zero and the event simply follows the pointer. For a BAR they\n * differ, which is what keeps a three-day one from jumping when grabbed by its middle. And\n * when the origin day is not on screen at all — a bar that began before this range, or an\n * event whose view has been paged out from under the drag — falling back to the grab column\n * makes the offset zero again, so the event lands under the pointer instead of nowhere.\n */\nfunction originColumn(state: Gesture): number {\n const index = props.days.indexOf(state.origin.start)\n return index === -1 ? state.grabColumn : index\n}\n\n/**\n * Whether the press that is about to become a click was a drag.\n *\n * A plain `let`, since nothing renders it: `pointerup` always fires before `click`, so this\n * is written on the way out of the gesture and read by the click that immediately follows.\n * Without it, letting go of a card at the end of a drag would ALSO open it — the consumer's\n * editor would appear over every event the reader had just moved.\n */\nlet justDragged = false\n\n/**\n * Closes the books on whatever gesture came before, at the start of a new press.\n *\n * TRAP — without this the flag can be left STANDING, and what it then breaks surfaces nowhere\n * near its cause. It is lowered by the click that reads it, and that click only reaches\n * `onCardClick` when it lands on a card: draw a new event and the press began on a CELL, so the\n * click goes there and the flag stays raised.\n *\n * What normally hides that is `onPointerup` overwriting the flag with its own `moved` — so the\n * next press heals it, and only a press that starts NO gesture does not. Which is a real\n * configuration and not a curiosity: a calendar that lets events be drawn but not moved\n * (`creatable` without `editable`) reaches it every time. The reader clicks an event to open it,\n * nothing happens, they click again and it works.\n *\n * Clearing it HERE makes the flag incapable of outliving its own interaction, and the ordering\n * is the whole argument: the click this exists to swallow follows its own `pointerup` with no\n * press in between, so it is still protected — while any LATER click on a card is necessarily\n * preceded by a press on that card, which arrives here first.\n *\n * It runs before every guard in the three handlers that call it, deliberately: a press that\n * starts no gesture at all is still the start of a new interaction, and those are precisely the\n * cases this is for.\n */\nfunction endLastGesture() {\n justDragged = false\n}\n\nfunction onPointerup(event: PointerEvent) {\n const state = gesture.value\n if (!state || state.pointerId !== event.pointerId) return\n gesture.value = null\n justDragged = state.moved\n releaseBoundaries()\n\n /*\n * Let go with the pointer off the calendar and the gesture is abandoned whole: no move, no new\n * length, and no new event either. The card goes back to where the model still says it is,\n * which is where the echo has been showing all along. It is the hand's version of the Escape\n * the keyboard grab already has — a gesture that ends somewhere it cannot mean anything must\n * mean nothing.\n *\n * TRAP — `justDragged` above is what still has to happen, and it is the ONE thing the cancel\n * path deliberately does not do: `pointerup` fires before `click`, so without it an abandoned\n * drag would end by OPENING the very event it has just refused to move. Which is also why\n * this branch and `onPointercancel` must NOT be factored into one helper. They differ by\n * exactly that line and it is correct in both directions — no click follows a cancel, so a\n * `true` left behind there would swallow the next genuine one instead.\n *\n * Nothing is announced. The pointer says nothing on a SUCCESSFUL drop either: `grabbed`,\n * `dropped` and `reverted` belong to the keyboard grab, which has no pointer to show where the\n * event went. A revert that spoke would be the only thing the pointer ever said.\n */\n if (state.outside) return\n\n if (state.kind === 'create') {\n emit('slot-create', state.preview)\n return\n }\n\n // A press that never travelled is an ordinary click, which the button's own click event is\n // about to report. Writing anything here would move an event nobody dragged.\n if (!state.moved) return\n\n emit('event-drop', state.id, state.preview, state.kind === 'resize' ? 'resize' : 'move')\n}\n\nfunction onCardClick(id: CalendarEventId) {\n if (justDragged) {\n justDragged = false\n return\n }\n const item = eventsById.value.get(id)\n if (item && id !== DRAFT_ID) emit('event-activate', item)\n}\n\n/**\n * A click on an empty part of a day, for a calendar that does NOT make events itself.\n *\n * When it does, the press has already become a `create` gesture and reported itself on\n * release; saying it again here would report the same click twice. So this path exists only\n * for a consumer who turned creation off to run their own form — they still get told where\n * the reader pointed, which is the whole point of turning it off rather than ignoring it.\n */\nfunction onGridClick(event: MouseEvent) {\n if (props.creatable) return\n const target = event.target as HTMLElement | null\n if (target?.closest('.v-calendar-event')) return\n const cell = target?.closest<HTMLElement>('.v-calendar-cell')\n if (!cell) return\n emit('cell-activate', cell.dataset.iso!, Number(cell.dataset.minutes))\n}\n\nfunction onPointercancel() {\n /*\n * The gesture was taken away — a system gesture, a context menu, the page starting to\n * scroll. Nothing is written and nothing is announced: the card simply goes back to where\n * the model still says it is.\n */\n gesture.value = null\n releaseBoundaries()\n}\n\n/* ------------------------------------------------------------ the keyboard's version */\n\nfunction announceTimes(title: string, times: CalendarEventTimes) {\n const start = formatTimeDisplay(times.startTime, props.locale, props.hourFormat)\n const end = formatTimeDisplay(times.endTime, props.locale, props.hourFormat)\n const day = formatDate(times.start, props.locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n })\n emit('announce', m.value.calendar.movedTo(title, `${day}, ${start} – ${end}`))\n}\n\n/** Puts the focus back on a card that has just been redrawn somewhere else. */\nfunction refocusCard(id: CalendarEventId) {\n void nextTick(() => {\n /*\n * The card is found by WALKING the cards rather than by building an attribute selector.\n * An id belongs to the consumer, so it may hold a quote or a backslash that a selector\n * would need escaped — and `CSS.escape` cannot do that escaping here: jsdom defines no\n * `CSS` object at all, so the call threw on every keyboard grab, from inside a `nextTick`\n * where nothing could catch it (an unhandled rejection, which fails the run while every\n * assertion still passes). `menuInvoker` in VMenu/context.ts escapes by hand for the same\n * reason; comparing the attribute's own text sidesteps the question entirely, since\n * `data-event-id` is written as exactly `String(event.id)`.\n */\n const cards = columnsEl.value?.querySelectorAll<HTMLElement>('.v-calendar-event')\n Array.from(cards ?? [])\n .find((card) => card.dataset.eventId === String(id))\n ?.focus()\n })\n}\n\nfunction onCardKeydown(event: KeyboardEvent, card: HTMLElement) {\n const item = eventsById.value.get(cardIdOf(card))\n if (!item) return\n\n const held = grabbing.value && gesture.value?.id === item.id\n const intent = calendarIntent(\n event.key,\n event.shiftKey,\n held ? 'grabbed' : 'event',\n props.slotDuration,\n isRtl(),\n )\n if (!intent) return\n\n if (!held) {\n if (intent.kind !== 'activate') return\n // An event that cannot be moved keeps a button's ordinary behaviour: Enter opens it,\n // which the click handler below already reports.\n if (!props.editable || isAllDayEvent(item)) return\n /*\n * Enter and Space are ALSO how a button is pressed. Without this the same keystroke\n * would take hold of the event and open it at once, and every attempt to move something\n * would fire the consumer's editor over the top of it.\n */\n event.preventDefault()\n begin({\n kind: 'move',\n id: item.id,\n origin: timesOf(item),\n pointerId: null,\n originX: 0,\n originY: 0,\n grabOffset: 0,\n grabColumn: 0,\n })\n emit('announce', m.value.calendar.grabbed)\n return\n }\n\n const state = gesture.value!\n event.preventDefault()\n\n if (intent.kind === 'grabResize') {\n /*\n * Each step is applied to the PREVIEW rather than to the origin, so the arrows accumulate\n * the way a reader expects — three presses of Down move three slots, not one. That is the\n * opposite of the pointer, which recomputes from the origin every frame because it always\n * knows where it is; the keyboard only knows how far it has just asked to go.\n */\n state.preview = resizeEvent(\n state.preview,\n minutesAt(state.preview.endTime, props.window.end) + intent.minutes,\n props.slotDuration,\n props.window,\n )\n state.moved = true\n announceTimes(item.title, state.preview)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'grabMove') {\n // Sideways is a step along the days ON SHOW, exactly as the pointer's is: date\n // arithmetic would count the days the calendar is hiding.\n const column = clamp(\n props.days.indexOf(state.preview.start) + intent.days,\n 0,\n props.days.length - 1,\n )\n const iso = props.days[column] ?? state.preview.start\n state.preview = {\n ...moveEvent(state.preview, 0, intent.minutes, props.window),\n start: iso,\n end: iso,\n }\n state.moved = true\n announceTimes(item.title, state.preview)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'activate') {\n gesture.value = null\n if (state.moved) {\n emit('event-drop', state.id, state.preview, state.kind === 'resize' ? 'resize' : 'move')\n }\n emit('announce', m.value.calendar.dropped)\n refocusCard(state.id)\n return\n }\n\n if (intent.kind === 'cancel') {\n gesture.value = null\n emit('announce', m.value.calendar.reverted)\n refocusCard(state.id)\n }\n}\n\n/* ---------------------------------------------------------------------- measurement */\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst canvasEl = ref<HTMLElement | null>(null)\nconst columnsEl = ref<HTMLElement | null>(null)\n\n/** The columns box as the pure geometry wants it: plain numbers, no element. */\nfunction geometryOf(rect: DOMRect) {\n const rtl = isRtl()\n return {\n top: rect.top,\n height: rect.height,\n // The edge the first column starts at, which is the other one in a right-to-left page.\n inlineStart: rtl ? rect.right : rect.left,\n inlineSize: rect.width,\n columns: props.days.length,\n }\n}\n\nconst isRtl = () => isElementRtl(columnsEl.value)\n\n/**\n * Brings a moment of the day to the top of the visible area.\n *\n * The row height is measured rather than read from the token, because the token is a length\n * a consumer may override and the browser is the only thing that knows what it came to. It\n * is a handler-time read, never a render-time one, and it degrades to doing nothing where\n * nothing has been laid out — which is exactly what the test environment wants.\n */\nfunction scrollToMinutes(minutes: number) {\n const root = rootEl.value\n const canvas = canvasEl.value\n if (!root || !canvas || hours.value.length === 0) return\n const rowHeight = canvas.offsetHeight / hours.value.length\n if (rowHeight <= 0) return\n root.scrollTop = ((minutes - props.window.start) / MINUTES_PER_HOUR) * rowHeight\n}\n\n/** Puts the focus on whichever cell currently holds the tab stop. */\nfunction focus() {\n const cell = tabbable.value\n if (cell) document.getElementById(cellId(cell.iso, cell.minutes))?.focus()\n}\n\ndefineExpose({ focus, scrollToMinutes })\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n class=\"v-calendar-grid\"\n :data-outside=\"gesture?.outside ? '' : undefined\"\n :style=\"{ '--calendar-columns': String(days.length) }\"\n @pointermove=\"onPointermove\"\n @pointerup=\"onPointerup\"\n @pointercancel=\"onPointercancel\"\n >\n <div class=\"v-calendar-head\">\n <div class=\"v-calendar-head-gutter\" />\n <div\n v-for=\"iso in days\"\n :key=\"iso\"\n class=\"v-calendar-head-day\"\n :data-today=\"iso === today ? '' : undefined\"\n >\n <slot\n name=\"day-header\"\n :iso=\"iso\"\n :weekday=\"dayName(iso, 'short')\"\n :day=\"dayNumber(iso)\"\n :today=\"iso === today\"\n >\n <span class=\"v-calendar-head-weekday\">{{ dayName(iso, 'short') }}</span>\n <span class=\"v-calendar-head-number\">{{ dayNumber(iso) }}</span>\n </slot>\n </div>\n\n <!-- The band of all-day bars, kept INSIDE the header so that the whole of it is one\n sticky box: two boxes would each need to know how tall the other was. -->\n <template v-if=\"allDay.length > 0\">\n <div class=\"v-calendar-allday-label\">\n <slot name=\"all-day-label\">{{ m.calendar.allDay }}</slot>\n </div>\n <div\n class=\"v-calendar-allday\"\n role=\"group\"\n :aria-label=\"m.calendar.allDay\"\n :style=\"{ '--calendar-lanes': String(allDayLanes) }\"\n @pointerdown=\"onBandPointerdown\"\n >\n <VCalendarEvent\n v-for=\"span in allDay\"\n :key=\"span.id\"\n class=\"v-calendar-bar\"\n :event=\"eventsById.get(span.id)!\"\n layout=\"chip\"\n :continues-before=\"span.continuesBefore\"\n :continues-after=\"span.continuesAfter\"\n :dragging=\"gesture?.id === span.id && gesture.pointerId !== null\"\n :rejected=\"gesture?.id === span.id && gesture.outside\"\n :grabbed=\"grabbing && gesture?.id === span.id\"\n :hint-id=\"editable && !isGhostId(span.id) ? hintId : undefined\"\n :ghost-of=\"isGhostId(span.id) ? originalIdOf(span.id) : undefined\"\n :style=\"{\n '--event-day': String(span.startIndex),\n '--event-span': String(span.span),\n '--event-lane': String(span.lane),\n }\"\n @click=\"onCardClick(span.id)\"\n >\n <template v-if=\"$slots.event\" #default=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarEvent>\n </div>\n </template>\n </div>\n\n <div ref=\"canvasEl\" class=\"v-calendar-canvas\">\n <div class=\"v-calendar-hours\" aria-hidden=\"true\">\n <span v-for=\"minutes in hours\" :key=\"minutes\" class=\"v-calendar-hour\">\n {{ hourLabel(minutes) }}\n </span>\n </div>\n\n <div\n ref=\"columnsEl\"\n class=\"v-calendar-columns\"\n role=\"grid\"\n :aria-label=\"label\"\n :data-gesture=\"gesture?.kind\"\n :data-edge=\"edgeCue\"\n @keydown=\"onKeydown\"\n @click=\"onGridClick\"\n @pointerdown=\"onGridPointerdown\"\n >\n <div v-for=\"(minutes, row) in hours\" :key=\"minutes\" role=\"row\" class=\"v-calendar-row\">\n <div\n v-for=\"(iso, day) in days\"\n :id=\"cellId(iso, minutes)\"\n :key=\"iso\"\n role=\"gridcell\"\n class=\"v-calendar-cell\"\n :data-iso=\"iso\"\n :data-minutes=\"minutes\"\n :data-today=\"iso === today ? '' : undefined\"\n :tabindex=\"isTabStop(iso, minutes) ? 0 : -1\"\n :aria-label=\"cellLabel(iso, minutes)\"\n :aria-selected=\"isFocused(iso, minutes) ? true : undefined\"\n >\n <VCalendarEvent\n v-for=\"segment in byCell.get(`${day}:${row}`) ?? []\"\n :key=\"segment.id\"\n class=\"v-calendar-block\"\n :event=\"eventsById.get(segment.id)!\"\n layout=\"block\"\n :time-text=\"timeTextOf(eventsById.get(segment.id)!)\"\n :continues-before=\"segment.clippedStart\"\n :continues-after=\"segment.clippedEnd\"\n :resizable=\"editable && segment.id !== DRAFT_ID\"\n :dragging=\"gesture?.id === segment.id && gesture.pointerId !== null\"\n :rejected=\"gesture?.id === segment.id && gesture.outside\"\n :grabbed=\"grabbing && gesture?.id === segment.id\"\n :hint-id=\"editable && !isGhostId(segment.id) ? hintId : undefined\"\n :ghost-of=\"isGhostId(segment.id) ? originalIdOf(segment.id) : undefined\"\n :style=\"styleFor(segment)\"\n @click=\"onCardClick(segment.id)\"\n >\n <template v-if=\"$slots.event\" #default=\"slotProps\">\n <slot name=\"event\" v-bind=\"slotProps\" />\n </template>\n </VCalendarEvent>\n\n <!-- The line is drawn INSIDE the cell holding the current hour, never as a\n direct child of the grid or of a row: a `grid` owns only rows and a row only\n cells, so an extra box at either level fails `aria-required-children`. -->\n <div\n v-if=\"nowMark && nowMark.cell === `${day}:${row}`\"\n class=\"v-calendar-now\"\n aria-hidden=\"true\"\n :style=\"{\n '--event-day': String(nowMark.dayIndex),\n '--calendar-now': String(nowMark.fraction),\n }\"\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-grid {\n /*\n * The one scrolling box. The day names are sticky INSIDE it rather than in a container\n * of their own, which is what keeps them aligned with the columns for free: a separate\n * header would have to be told how far the body had scrolled sideways, and told again\n * every time the column widths changed.\n */\n --calendar-hour: var(--vectis-control-size-calendar-hour);\n --calendar-gutter: var(--vectis-control-size-calendar-gutter);\n /*\n * Half a line of an hour label. It is used TWICE and in opposite directions — the label\n * is pulled up by it so it straddles its rule, and the tick is pushed back down by it so\n * it lands on that same rule. One number, so the two cannot drift apart; two literals\n * would misalign the moment the caption's leading changed, with nothing to point at it.\n */\n --calendar-hour-lift: calc(\n var(--vectis-text-caption-size) * var(--vectis-text-caption-leading) / 2\n );\n\n position: relative;\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n /*\n * A drag currently held off the calendar. `not-allowed` is the word the library already uses\n * for \"you cannot do this\", on every disabled control.\n *\n * BEST-EFFORT, and never the signal: while a pointer is captured the cursor is resolved\n * against the capture target rather than against whatever sits under the pointer, and engines\n * differ on it. What carries the message is the card's own paint, which is why this is a\n * second cue and not the first.\n */\n .v-calendar-grid[data-outside] {\n cursor: not-allowed;\n }\n\n .v-calendar-head,\n .v-calendar-canvas {\n display: grid;\n grid-template-columns: var(--calendar-gutter) repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n /*\n * The tracks have a floor, so on a narrow screen they add up to more than the box and\n * the calendar scrolls sideways. Without this the BOX would stay the width of the\n * scroller while the tracks spilled out of it: the sticky day names would paint their\n * background only as far as the original width, and the columns would run out from\n * under them halfway across. `min-content` on a grid is the sum of its track minimums,\n * which is exactly the width wanted here.\n */\n min-inline-size: min-content;\n }\n\n /*\n * THE STACKING ORDER OF THE WHOLE GRID, in one place because it is decided in four:\n *\n * 1 .v-calendar-block an event card\n * 2 .v-calendar-now the current-time line, over every card\n * 3 [data-dragging] / [data-grabbed] a card being moved, over the line\n * 4 .v-calendar-head the sticky day names, over everything\n *\n * Neither `.v-calendar-grid` nor `.v-calendar-columns` establishes a stacking context —\n * both are `relative` with no `z-index` — so all four compete at the root, and any TIE is\n * broken by document order. That is what put the current-time line over the header while\n * both sat at 2: the line is further down the template. The header has to sit above the\n * dragged card as well, which is why it is 4 and not 3.\n */\n .v-calendar-head {\n position: sticky;\n inset-block-start: 0;\n z-index: 4;\n background: var(--vectis-color-surface);\n border-block-end: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-head-gutter {\n /* The corner above the hour labels. It is empty, and it is here so the day names line\n up with their columns rather than starting at the edge of the box. */\n border-inline-end: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-head-day {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--vectis-space-1);\n padding-block: var(--vectis-space-2);\n padding-inline: var(--vectis-space-1);\n }\n\n .v-calendar-head-weekday {\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-overline-size);\n font-weight: var(--vectis-text-overline-weight);\n letter-spacing: var(--vectis-text-overline-tracking);\n text-transform: uppercase;\n }\n\n .v-calendar-head-number {\n display: flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--vectis-control-height-sm);\n block-size: var(--vectis-control-height-sm);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-body-lg-size);\n }\n\n /* Today is marked on the number alone, the way a calendar marks a date rather than a\n column. Semibold here is state emphasis, not a type role. */\n .v-calendar-head-day[data-today] .v-calendar-head-number {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n .v-calendar-allday-label {\n display: flex;\n align-items: start;\n justify-content: end;\n padding-block-start: var(--vectis-space-1);\n padding-inline-end: var(--vectis-space-2);\n border-block-start: 1px solid var(--vectis-color-border);\n border-inline-end: 1px solid var(--vectis-color-border);\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n }\n\n .v-calendar-allday {\n /*\n * The band's two axes are DISCRETE — a day, and a row — where the time grid's vertical\n * axis is continuous. That is why the bars are placed with real grid lines here and\n * with fractions there: forcing one mechanism onto both would cost a translation in\n * each direction and buy nothing.\n */\n display: grid;\n grid-column: 2 / -1;\n grid-template-columns: repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n grid-template-rows: repeat(\n var(--calendar-lanes),\n var(--vectis-control-size-calendar-allday-lane)\n );\n gap: 1px;\n overflow-y: auto;\n max-block-size: var(--vectis-control-size-calendar-allday-max);\n padding-block: var(--vectis-space-1);\n /*\n * No inline padding, deliberately. The band's tracks have to line up with the canvas's\n * exactly, because dragging a bar reads the pointer against the CANVAS geometry — the two\n * boxes span the same grid columns, so one measurement serves both. A few pixels of\n * padding here would put the last column out by that much, and a bar dropped on the right\n * edge would land a day early.\n */\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n .v-calendar-bar {\n grid-column: calc(var(--event-day) + 1) / span var(--event-span);\n grid-row: calc(var(--event-lane) + 1);\n min-inline-size: 0;\n }\n\n .v-calendar-hours {\n display: grid;\n grid-auto-rows: var(--calendar-hour);\n border-inline-end: 1px solid var(--vectis-color-border);\n }\n\n /*\n * The label names the hour its row BEGINS at, and it is drawn ON that rule rather than\n * under it: `align-self: start` shrinks the span from its 4rem row down to its one line,\n * and the negative margin then straddles it across the rule above.\n */\n .v-calendar-hour {\n position: relative;\n align-self: start;\n margin-block-start: calc(-1 * var(--calendar-hour-lift));\n padding-inline-end: var(--vectis-space-2);\n color: var(--vectis-color-text-muted);\n font-size: var(--vectis-text-caption-size);\n line-height: var(--vectis-text-caption-leading);\n text-align: end;\n }\n\n /* The rule carried a little way back into the gutter, so the eye joins the label to the\n line it names. A border and not a background: Windows forced-colors flattens a\n background to Canvas and the tick would vanish, where a border keeps a colour — the\n argument VSeparator and the icon registry both make. */\n .v-calendar-hour::before {\n content: '';\n position: absolute;\n inset-block-start: var(--calendar-hour-lift);\n inset-inline-end: 0;\n inline-size: var(--vectis-control-size-calendar-tick);\n border-block-start: 1px solid var(--vectis-color-border);\n }\n\n /*\n * The first hour has no rule of its own: the sticky header already draws a border along\n * that edge, and a second one under it reads as a thick smudge. Its label goes with it,\n * since half of it would sit above the top of the canvas anyway — the cost you accepted,\n * paid in one label a reader can work out from the one below.\n *\n * `visibility` carries the tick away too, being inherited, so the pseudo-element needs no\n * rule of its own here.\n *\n * TRAP — HIDDEN and not removed. The span has to go on occupying its grid row: `display:\n * none` would take the row with it and shift every hour below up by one.\n */\n .v-calendar-hour:first-child {\n visibility: hidden;\n }\n\n .v-calendar-row:first-child .v-calendar-cell {\n border-block-start: none;\n }\n\n .v-calendar-columns {\n /* The containing block every card is placed against. The rows below are `display:\n contents`, so the cells themselves are this grid's items. */\n position: relative;\n display: grid;\n grid-column: 2 / -1;\n /*\n * The same track recipe as the canvas above, deliberately restated rather than borrowed\n * with `subgrid`. This box spans exactly the canvas columns it repeats, and both sides\n * divide the same width by the same rule, so the two resolve identically — which makes\n * subgrid a second mechanism buying nothing, the conclusion the library's own audit of\n * it reached.\n */\n grid-template-columns: repeat(\n var(--calendar-columns),\n minmax(var(--vectis-control-size-calendar-day-min), 1fr)\n );\n grid-auto-rows: var(--calendar-hour);\n }\n\n /*\n * The strip that lights up when a drag is resting against an edge, counting down to turn\n * the page. It is what stops the paging being a surprise.\n *\n * Drawn INSIDE the columns box rather than on the scroller, because a scroller's absolutely\n * positioned child is placed against its content and scrolls away with it — here the box is\n * as tall as the whole day, so the strip is visible wherever the reader happens to be. An\n * absolutely positioned pseudo-element is not a grid item, so it disturbs no column.\n *\n * Its width is `--vectis-control-size-calendar-edge`, whose twin is `EDGE_BAND` in\n * `edgeStep.ts` — the JavaScript that decides where the countdown actually starts. Neither\n * may move without the other.\n */\n .v-calendar-columns[data-edge]::after {\n content: '';\n position: absolute;\n inset-block: 0;\n inline-size: var(--vectis-control-size-calendar-edge);\n background: var(--vectis-color-accent-surface);\n z-index: 2;\n pointer-events: none;\n }\n\n .v-calendar-columns[data-edge='start']::after {\n inset-inline-start: 0;\n }\n\n .v-calendar-columns[data-edge='end']::after {\n inset-inline-end: 0;\n }\n\n .v-calendar-row {\n /* The row exists for the accessibility tree and must not exist for the layout: a real\n box here would make the cells its children instead of the grid's, and every column\n would collapse. */\n display: contents;\n }\n\n .v-calendar-cell {\n border-block-start: 1px solid var(--vectis-color-border);\n border-inline-start: 1px solid var(--vectis-color-border);\n cursor: pointer;\n }\n\n .v-calendar-cell:first-child {\n border-inline-start: none;\n }\n\n .v-calendar-cell:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n /* Drawn inwards: the grid is a scrolling box, and an outward ring on a cell at the edge\n would be cropped by it. */\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-calendar-cell[data-today] {\n background: var(--vectis-color-accent-surface);\n }\n\n /*\n * A card is positioned against the whole columns box, not against its cell — which is why\n * the horizontal formula carries the day index. Being a child of the cell is what keeps\n * it in the accessibility tree in the right place; being placed against the grid is what\n * lets it be any length at all.\n */\n /*\n * TRAP — the height is the event's own length and NOTHING ELSE. There used to be a `max()`\n * against a floor token here, and it is what made a quarter of an hour spill over the slot\n * below it.\n *\n * The floor it was providing is already applied where it belongs: `timedSegments` stretches\n * every segment to at least `slotDuration` BEFORE the overlap packing sees it, so what is\n * drawn and what the packing believes are the same box. A second floor in CSS could only\n * ever disagree with the first — the packing cannot see a stylesheet — which is exactly how\n * two cards came to be laid out side by side and then drawn on top of each other.\n *\n * So a card is never taller than its slot, whatever `slotDuration` is set to. Making the\n * text fit inside a slot that short is the stylesheet's problem, and VCalendarEvent solves\n * it by asking how tall the card actually came out.\n */\n .v-calendar-block {\n position: absolute;\n inset-block-start: calc(var(--event-start) * 100%);\n block-size: calc((var(--event-end) - var(--event-start)) * 100%);\n inset-inline-start: calc(\n (var(--event-day) + var(--event-column) / var(--event-columns)) / var(--calendar-columns) *\n 100%\n );\n inline-size: calc(\n var(--event-span) / var(--event-columns) / var(--calendar-columns) * 100% - 2px\n );\n z-index: 1;\n }\n\n /*\n * The current-time line, placed the same way a card is — against the whole columns box,\n * so its formula carries the day index too. It is `aria-hidden`: it is a second rendering\n * of something the cell labels and the day marked as today already say, and announcing\n * \"current time\" from the middle of a grid would interrupt without informing.\n */\n .v-calendar-now {\n position: absolute;\n inset-block-start: calc(var(--calendar-now) * 100%);\n inset-inline-start: calc(var(--event-day) / var(--calendar-columns) * 100%);\n inline-size: calc(100% / var(--calendar-columns));\n border-block-start: 1px solid var(--vectis-color-danger);\n /* Above the cards: it is the one thing that must stay readable over a full day. */\n z-index: 2;\n pointer-events: none;\n }\n\n .v-calendar-now::before {\n content: '';\n position: absolute;\n inset-inline-start: 0;\n inline-size: var(--vectis-control-size-calendar-now-dot);\n block-size: var(--vectis-control-size-calendar-now-dot);\n /* Half its own size upwards and backwards, so the dot is centred ON the line's start\n rather than hanging below it. */\n margin-block-start: calc(var(--vectis-control-size-calendar-now-dot) / -2);\n margin-inline-start: calc(var(--vectis-control-size-calendar-now-dot) / -2);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-danger);\n }\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
+
@layer vectis.components{.v-calendar-year{gap:var(--vectis-space-4);block-size:100%;min-block-size:0;padding:var(--vectis-space-3);font-family:var(--vectis-text-family);color:var(--vectis-color-text);grid-template-columns:repeat(auto-fill,minmax(13rem,1fr));display:grid;overflow:auto}.v-calendar-year-month{gap:var(--vectis-space-2);flex-direction:column;display:flex}.v-calendar-year-title{justify-content:space-between;align-items:center;gap:var(--vectis-space-2);padding:var(--vectis-space-1) var(--vectis-space-2);border-radius:var(--vectis-radius-interactive);color:var(--vectis-color-text);font-family:inherit;font-size:var(--vectis-text-heading-4-size);font-weight:var(--vectis-text-heading-4-weight);text-align:start;text-transform:capitalize;cursor:pointer;transition:background-color var(--vectis-duration-fast) var(--vectis-ease-default);background:0 0;border:none;display:flex}.v-calendar-year-title:hover{background:var(--vectis-color-surface-muted)}.v-calendar-year-title:focus-visible{outline:var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);outline-offset:var(--vectis-focus-ring-offset)}.v-calendar-year-count{min-inline-size:var(--vectis-control-size-calendar-year-cell);padding-inline:var(--vectis-space-1);border-radius:var(--vectis-radius-pill);background:var(--vectis-color-accent-surface);color:var(--vectis-color-accent-text);font-size:var(--vectis-text-caption-size);font-weight:var(--vectis-font-weight-medium);flex:none;justify-content:center;align-items:center;display:flex}.v-calendar-year-grid{grid-template-columns:repeat(7,1fr);gap:1px;display:grid}.v-calendar-year-day{aspect-ratio:1;min-inline-size:var(--vectis-control-size-calendar-year-cell);border-radius:var(--vectis-radius-pill);font-size:var(--vectis-text-caption-size);justify-content:center;align-items:center;display:flex}.v-calendar-year-day[data-adjacent]{color:var(--vectis-color-text-subtle)}.v-calendar-year-day[data-busy]{border:1px solid var(--vectis-color-accent-border);background:var(--vectis-color-accent-surface);color:var(--vectis-color-accent-text)}.v-calendar-year-day[data-today]{background:var(--vectis-color-accent);color:var(--vectis-color-text-on-accent);font-weight:var(--vectis-font-weight-semibold)}@media (prefers-reduced-motion:reduce){.v-calendar-year-title{transition:none}}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { CalendarEvent } from './types.js';
|
|
2
|
+
export interface CalendarYearProps<T> {
|
|
3
|
+
/** The first day of each month of the year on show. */
|
|
4
|
+
months: string[];
|
|
5
|
+
events: T[];
|
|
6
|
+
locale: string;
|
|
7
|
+
/** Which weekdays are on show, so a mini-month drops the same columns as the others. */
|
|
8
|
+
weekdays: number[];
|
|
9
|
+
today: string | null;
|
|
10
|
+
label: string;
|
|
11
|
+
}
|
|
12
|
+
declare const __VLS_export: <E extends CalendarEvent>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
13
|
+
props: import('vue').PublicProps & __VLS_PrettifyLocal<CalendarYearProps<E> & {
|
|
14
|
+
"onMonth-activate"?: ((iso: string) => any) | undefined;
|
|
15
|
+
}> & (typeof globalThis extends {
|
|
16
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
17
|
+
} ? P : {});
|
|
18
|
+
expose: (exposed: {}) => void;
|
|
19
|
+
attrs: any;
|
|
20
|
+
slots: {};
|
|
21
|
+
emit: (evt: "month-activate", iso: string) => void;
|
|
22
|
+
}>) => import('vue').VNode & {
|
|
23
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
24
|
+
};
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
28
|
+
[K in keyof T]: T[K];
|
|
29
|
+
} : {
|
|
30
|
+
[K in keyof T as K]: T[K];
|
|
31
|
+
}) & {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './VCalendarYear.css';
|
|
2
|
+
import e from "./VCalendarYear.vue_vue_type_script_setup_true_lang.js";
|
|
3
|
+
/* empty css */
|
|
4
|
+
//#region src/components/VCalendar/VCalendarYear.vue
|
|
5
|
+
var t = e;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { t as default };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=VCalendarYear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VCalendarYear.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarYear.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * The year view: twelve small months, each marking the days that have something on them.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it.\n *\n * WHY THE DAYS HERE ARE NOT BUTTONS, unlike every other view. A year is three hundred and\n * sixty-five days, and making each one focusable would put that many stops in the tab\n * order for a view whose whole purpose is to be glanced at. Twelve roving grids would fix\n * the count but leave the arrows unable to cross from one month to the next, which is\n * exactly the movement a year view invites.\n *\n * So this view is a SUMMARY and says so: the days are text, with the busy ones ringed, and\n * the thing you can reach and act on is the month, whose name carries how many of its days\n * carry something. Choosing a day is what the month and day views are for, and the heading\n * is the way through to them.\n */\nimport { computed } from 'vue'\n\nimport { addDays, formatDisplay as formatDate, parseISO } from '../../utils/date'\n\nimport { coversDay, monthWeeks, type MonthCell } from './layout'\nimport type { CalendarEvent } from './types'\n\nexport interface CalendarYearProps<T> {\n /** The first day of each month of the year on show. */\n months: string[]\n events: T[]\n locale: string\n /** Which weekdays are on show, so a mini-month drops the same columns as the others. */\n weekdays: number[]\n today: string | null\n label: string\n}\n\nconst props = defineProps<CalendarYearProps<E>>()\n\nconst emit = defineEmits<{\n /** A month was chosen, and is where the calendar should go next. */\n 'month-activate': [iso: string]\n}>()\n\nconst monthName = (iso: string) => formatDate(iso, props.locale, { month: 'long' })\n\n/** The days of the year that have something on them, worked out once for all twelve. */\nconst busyDays = computed(() => {\n const days = new Set<string>()\n for (const event of props.events) {\n const start = parseISO(event.start)\n const end = parseISO(event.end)\n if (!start || !end) continue\n /*\n * Walked day by day rather than tested against every square: a year holds far more\n * squares than a schedule holds days, so filling a set from the events and asking it\n * one question per square is the cheaper way round. The walk is bounded to a year so a\n * malformed range cannot spin.\n */\n let iso = event.start\n for (let guard = 0; guard < 366 && coversDay(event, iso); guard++) {\n days.add(iso)\n iso = addDays(iso, 1)\n }\n }\n return days\n})\n\n/*\n * The twelve grids and their day numbers, built ONCE per render.\n *\n * `weeksOf` used to be a plain function, and the template reached it three times per month\n * — once in the `v-for`, and twice through `busyCount`, which appears in both the `v-if` and\n * the text beside it. Twelve months therefore rebuilt 36 grids, some 1500 `MonthCell`\n * objects, on every render; the 504 day numbers were formatted alongside them. None of that\n * depends on anything but the anchor, the weekdays and the locale.\n *\n * `busyCount` is a map for the same reason: reading it twice must not cost twice.\n */\nconst grids = computed(() => {\n const map = new Map<string, MonthCell[][]>()\n for (const month of props.months) map.set(month, monthWeeks(month, props.weekdays))\n return map\n})\n\nconst weeksOf = (month: string) => grids.value.get(month) ?? []\n\nconst dayNumbers = computed(() => {\n const map = new Map<string, string>()\n for (const weeks of grids.value.values()) {\n for (const week of weeks) {\n for (const cell of week) {\n if (!map.has(cell.iso))\n map.set(cell.iso, formatDate(cell.iso, props.locale, { day: 'numeric' }))\n }\n }\n }\n return map\n})\n\nconst dayNumber = (iso: string) =>\n dayNumbers.value.get(iso) ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/** How many of a month's own days carry something, which is what its name announces. */\nconst busyCounts = computed(() => {\n const map = new Map<string, number>()\n for (const [month, weeks] of grids.value) {\n let count = 0\n for (const week of weeks) {\n for (const cell of week) if (cell.adjacent === null && busyDays.value.has(cell.iso)) count++\n }\n map.set(month, count)\n }\n return map\n})\n\nconst busyCount = (month: string) => busyCounts.value.get(month) ?? 0\n\nconst isBusy = (cell: MonthCell) => cell.adjacent === null && busyDays.value.has(cell.iso)\n</script>\n\n<template>\n <div class=\"v-calendar-year\" role=\"group\" :aria-label=\"label\">\n <section v-for=\"month in months\" :key=\"month\" class=\"v-calendar-year-month\">\n <button type=\"button\" class=\"v-calendar-year-title\" @click=\"emit('month-activate', month)\">\n {{ monthName(month) }}\n <!-- The count is part of the button's own text, so a month that has something on it\n says so in its accessible name — which is what makes the days below safe to hide\n from the accessibility tree. -->\n <span v-if=\"busyCount(month) > 0\" class=\"v-calendar-year-count\">\n {{ busyCount(month) }}\n </span>\n </button>\n\n <div class=\"v-calendar-year-grid\" aria-hidden=\"true\">\n <template v-for=\"(week, row) in weeksOf(month)\" :key=\"row\">\n <span\n v-for=\"cell in week\"\n :key=\"cell.iso\"\n class=\"v-calendar-year-day\"\n :data-adjacent=\"cell.adjacent ?? undefined\"\n :data-today=\"cell.iso === today ? '' : undefined\"\n :data-busy=\"isBusy(cell) ? '' : undefined\"\n >\n {{ dayNumber(cell.iso) }}\n </span>\n </template>\n </div>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-year {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));\n gap: var(--vectis-space-4);\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n padding: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-calendar-year-month {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-2);\n }\n\n .v-calendar-year-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--vectis-space-2);\n padding: var(--vectis-space-1) var(--vectis-space-2);\n border: none;\n border-radius: var(--vectis-radius-interactive);\n background: none;\n color: var(--vectis-color-text);\n font-family: inherit;\n font-size: var(--vectis-text-heading-4-size);\n font-weight: var(--vectis-text-heading-4-weight);\n text-align: start;\n text-transform: capitalize;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-year-title:hover {\n background: var(--vectis-color-surface-muted);\n }\n\n .v-calendar-year-title:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-calendar-year-count {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-font-weight-medium);\n }\n\n .v-calendar-year-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 1px;\n }\n\n .v-calendar-year-day {\n display: flex;\n align-items: center;\n justify-content: center;\n aspect-ratio: 1;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-caption-size);\n }\n\n .v-calendar-year-day[data-adjacent] {\n color: var(--vectis-color-text-subtle);\n }\n\n /* A busy day is RINGED rather than dotted: at this size a dot would be about one pixel,\n and it would be drawn as a background, which Windows forced-colors flattens away —\n where a border keeps a colour of its own. The tint is a second, redundant signal for\n anyone the ring alone is too fine for. */\n .v-calendar-year-day[data-busy] {\n border: 1px solid var(--vectis-color-accent-border);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-calendar-year-day[data-today] {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-year-title {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { addDays as e, formatDisplay as t, parseISO as n } from "../../utils/date.js";
|
|
2
|
+
import { coversDay as r, monthWeeks as i } from "./layout.js";
|
|
3
|
+
import { Fragment as a, computed as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, defineComponent as d, openBlock as f, renderList as p, toDisplayString as m } from "vue";
|
|
4
|
+
//#region src/components/VCalendar/VCalendarYear.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var h = ["aria-label"], g = ["onClick"], _ = {
|
|
6
|
+
key: 0,
|
|
7
|
+
class: "v-calendar-year-count"
|
|
8
|
+
}, v = {
|
|
9
|
+
class: "v-calendar-year-grid",
|
|
10
|
+
"aria-hidden": "true"
|
|
11
|
+
}, y = [
|
|
12
|
+
"data-adjacent",
|
|
13
|
+
"data-today",
|
|
14
|
+
"data-busy"
|
|
15
|
+
], b = /*@__PURE__*/ d({
|
|
16
|
+
__name: "VCalendarYear",
|
|
17
|
+
props: {
|
|
18
|
+
months: {},
|
|
19
|
+
events: {},
|
|
20
|
+
locale: {},
|
|
21
|
+
weekdays: {},
|
|
22
|
+
today: {},
|
|
23
|
+
label: {}
|
|
24
|
+
},
|
|
25
|
+
emits: ["month-activate"],
|
|
26
|
+
setup(d, { emit: b }) {
|
|
27
|
+
let x = d, S = b, C = (e) => t(e, x.locale, { month: "long" }), w = o(() => {
|
|
28
|
+
let t = /* @__PURE__ */ new Set();
|
|
29
|
+
for (let i of x.events) {
|
|
30
|
+
let a = n(i.start), o = n(i.end);
|
|
31
|
+
if (!a || !o) continue;
|
|
32
|
+
let s = i.start;
|
|
33
|
+
for (let n = 0; n < 366 && r(i, s); n++) t.add(s), s = e(s, 1);
|
|
34
|
+
}
|
|
35
|
+
return t;
|
|
36
|
+
}), T = o(() => {
|
|
37
|
+
let e = /* @__PURE__ */ new Map();
|
|
38
|
+
for (let t of x.months) e.set(t, i(t, x.weekdays));
|
|
39
|
+
return e;
|
|
40
|
+
}), E = (e) => T.value.get(e) ?? [], D = o(() => {
|
|
41
|
+
let e = /* @__PURE__ */ new Map();
|
|
42
|
+
for (let n of T.value.values()) for (let r of n) for (let n of r) e.has(n.iso) || e.set(n.iso, t(n.iso, x.locale, { day: "numeric" }));
|
|
43
|
+
return e;
|
|
44
|
+
}), O = (e) => D.value.get(e) ?? t(e, x.locale, { day: "numeric" }), k = o(() => {
|
|
45
|
+
let e = /* @__PURE__ */ new Map();
|
|
46
|
+
for (let [t, n] of T.value) {
|
|
47
|
+
let r = 0;
|
|
48
|
+
for (let e of n) for (let t of e) t.adjacent === null && w.value.has(t.iso) && r++;
|
|
49
|
+
e.set(t, r);
|
|
50
|
+
}
|
|
51
|
+
return e;
|
|
52
|
+
}), A = (e) => k.value.get(e) ?? 0, j = (e) => e.adjacent === null && w.value.has(e.iso);
|
|
53
|
+
return (e, t) => (f(), c("div", {
|
|
54
|
+
class: "v-calendar-year",
|
|
55
|
+
role: "group",
|
|
56
|
+
"aria-label": d.label
|
|
57
|
+
}, [(f(!0), c(a, null, p(d.months, (e) => (f(), c("section", {
|
|
58
|
+
key: e,
|
|
59
|
+
class: "v-calendar-year-month"
|
|
60
|
+
}, [l("button", {
|
|
61
|
+
type: "button",
|
|
62
|
+
class: "v-calendar-year-title",
|
|
63
|
+
onClick: (t) => S("month-activate", e)
|
|
64
|
+
}, [u(m(C(e)) + " ", 1), A(e) > 0 ? (f(), c("span", _, m(A(e)), 1)) : s("", !0)], 8, g), l("div", v, [(f(!0), c(a, null, p(E(e), (e, t) => (f(), c(a, { key: t }, [(f(!0), c(a, null, p(e, (e) => (f(), c("span", {
|
|
65
|
+
key: e.iso,
|
|
66
|
+
class: "v-calendar-year-day",
|
|
67
|
+
"data-adjacent": e.adjacent ?? void 0,
|
|
68
|
+
"data-today": e.iso === d.today ? "" : void 0,
|
|
69
|
+
"data-busy": j(e) ? "" : void 0
|
|
70
|
+
}, m(O(e.iso)), 9, y))), 128))], 64))), 128))])]))), 128))], 8, h));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
//#endregion
|
|
74
|
+
export { b as default };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=VCalendarYear.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VCalendarYear.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VCalendar/VCalendarYear.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"E extends CalendarEvent\">\n// @a11y @core\n/**\n * The year view: twelve small months, each marking the days that have something on them.\n *\n * It is internal to VCalendar and has no story of its own — its documentation lives with\n * the component that renders it.\n *\n * WHY THE DAYS HERE ARE NOT BUTTONS, unlike every other view. A year is three hundred and\n * sixty-five days, and making each one focusable would put that many stops in the tab\n * order for a view whose whole purpose is to be glanced at. Twelve roving grids would fix\n * the count but leave the arrows unable to cross from one month to the next, which is\n * exactly the movement a year view invites.\n *\n * So this view is a SUMMARY and says so: the days are text, with the busy ones ringed, and\n * the thing you can reach and act on is the month, whose name carries how many of its days\n * carry something. Choosing a day is what the month and day views are for, and the heading\n * is the way through to them.\n */\nimport { computed } from 'vue'\n\nimport { addDays, formatDisplay as formatDate, parseISO } from '../../utils/date'\n\nimport { coversDay, monthWeeks, type MonthCell } from './layout'\nimport type { CalendarEvent } from './types'\n\nexport interface CalendarYearProps<T> {\n /** The first day of each month of the year on show. */\n months: string[]\n events: T[]\n locale: string\n /** Which weekdays are on show, so a mini-month drops the same columns as the others. */\n weekdays: number[]\n today: string | null\n label: string\n}\n\nconst props = defineProps<CalendarYearProps<E>>()\n\nconst emit = defineEmits<{\n /** A month was chosen, and is where the calendar should go next. */\n 'month-activate': [iso: string]\n}>()\n\nconst monthName = (iso: string) => formatDate(iso, props.locale, { month: 'long' })\n\n/** The days of the year that have something on them, worked out once for all twelve. */\nconst busyDays = computed(() => {\n const days = new Set<string>()\n for (const event of props.events) {\n const start = parseISO(event.start)\n const end = parseISO(event.end)\n if (!start || !end) continue\n /*\n * Walked day by day rather than tested against every square: a year holds far more\n * squares than a schedule holds days, so filling a set from the events and asking it\n * one question per square is the cheaper way round. The walk is bounded to a year so a\n * malformed range cannot spin.\n */\n let iso = event.start\n for (let guard = 0; guard < 366 && coversDay(event, iso); guard++) {\n days.add(iso)\n iso = addDays(iso, 1)\n }\n }\n return days\n})\n\n/*\n * The twelve grids and their day numbers, built ONCE per render.\n *\n * `weeksOf` used to be a plain function, and the template reached it three times per month\n * — once in the `v-for`, and twice through `busyCount`, which appears in both the `v-if` and\n * the text beside it. Twelve months therefore rebuilt 36 grids, some 1500 `MonthCell`\n * objects, on every render; the 504 day numbers were formatted alongside them. None of that\n * depends on anything but the anchor, the weekdays and the locale.\n *\n * `busyCount` is a map for the same reason: reading it twice must not cost twice.\n */\nconst grids = computed(() => {\n const map = new Map<string, MonthCell[][]>()\n for (const month of props.months) map.set(month, monthWeeks(month, props.weekdays))\n return map\n})\n\nconst weeksOf = (month: string) => grids.value.get(month) ?? []\n\nconst dayNumbers = computed(() => {\n const map = new Map<string, string>()\n for (const weeks of grids.value.values()) {\n for (const week of weeks) {\n for (const cell of week) {\n if (!map.has(cell.iso))\n map.set(cell.iso, formatDate(cell.iso, props.locale, { day: 'numeric' }))\n }\n }\n }\n return map\n})\n\nconst dayNumber = (iso: string) =>\n dayNumbers.value.get(iso) ?? formatDate(iso, props.locale, { day: 'numeric' })\n\n/** How many of a month's own days carry something, which is what its name announces. */\nconst busyCounts = computed(() => {\n const map = new Map<string, number>()\n for (const [month, weeks] of grids.value) {\n let count = 0\n for (const week of weeks) {\n for (const cell of week) if (cell.adjacent === null && busyDays.value.has(cell.iso)) count++\n }\n map.set(month, count)\n }\n return map\n})\n\nconst busyCount = (month: string) => busyCounts.value.get(month) ?? 0\n\nconst isBusy = (cell: MonthCell) => cell.adjacent === null && busyDays.value.has(cell.iso)\n</script>\n\n<template>\n <div class=\"v-calendar-year\" role=\"group\" :aria-label=\"label\">\n <section v-for=\"month in months\" :key=\"month\" class=\"v-calendar-year-month\">\n <button type=\"button\" class=\"v-calendar-year-title\" @click=\"emit('month-activate', month)\">\n {{ monthName(month) }}\n <!-- The count is part of the button's own text, so a month that has something on it\n says so in its accessible name — which is what makes the days below safe to hide\n from the accessibility tree. -->\n <span v-if=\"busyCount(month) > 0\" class=\"v-calendar-year-count\">\n {{ busyCount(month) }}\n </span>\n </button>\n\n <div class=\"v-calendar-year-grid\" aria-hidden=\"true\">\n <template v-for=\"(week, row) in weeksOf(month)\" :key=\"row\">\n <span\n v-for=\"cell in week\"\n :key=\"cell.iso\"\n class=\"v-calendar-year-day\"\n :data-adjacent=\"cell.adjacent ?? undefined\"\n :data-today=\"cell.iso === today ? '' : undefined\"\n :data-busy=\"isBusy(cell) ? '' : undefined\"\n >\n {{ dayNumber(cell.iso) }}\n </span>\n </template>\n </div>\n </section>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-calendar-year {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));\n gap: var(--vectis-space-4);\n overflow: auto;\n block-size: 100%;\n min-block-size: 0;\n padding: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n color: var(--vectis-color-text);\n }\n\n .v-calendar-year-month {\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-2);\n }\n\n .v-calendar-year-title {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--vectis-space-2);\n padding: var(--vectis-space-1) var(--vectis-space-2);\n border: none;\n border-radius: var(--vectis-radius-interactive);\n background: none;\n color: var(--vectis-color-text);\n font-family: inherit;\n font-size: var(--vectis-text-heading-4-size);\n font-weight: var(--vectis-text-heading-4-weight);\n text-align: start;\n text-transform: capitalize;\n cursor: pointer;\n transition: background-color var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-calendar-year-title:hover {\n background: var(--vectis-color-surface-muted);\n }\n\n .v-calendar-year-title:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: var(--vectis-focus-ring-offset);\n }\n\n .v-calendar-year-count {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n padding-inline: var(--vectis-space-1);\n border-radius: var(--vectis-radius-pill);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n font-size: var(--vectis-text-caption-size);\n font-weight: var(--vectis-font-weight-medium);\n }\n\n .v-calendar-year-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 1px;\n }\n\n .v-calendar-year-day {\n display: flex;\n align-items: center;\n justify-content: center;\n aspect-ratio: 1;\n min-inline-size: var(--vectis-control-size-calendar-year-cell);\n border-radius: var(--vectis-radius-pill);\n font-size: var(--vectis-text-caption-size);\n }\n\n .v-calendar-year-day[data-adjacent] {\n color: var(--vectis-color-text-subtle);\n }\n\n /* A busy day is RINGED rather than dotted: at this size a dot would be about one pixel,\n and it would be drawn as a background, which Windows forced-colors flattens away —\n where a border keeps a colour of its own. The tint is a second, redundant signal for\n anyone the ring alone is too fine for. */\n .v-calendar-year-day[data-busy] {\n border: 1px solid var(--vectis-color-accent-border);\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-calendar-year-day[data-today] {\n background: var(--vectis-color-accent);\n color: var(--vectis-color-text-on-accent);\n font-weight: var(--vectis-font-weight-semibold);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-calendar-year-title {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;EAqCA,IAAM,IAAQ,GAER,IAAO,GAKP,KAAa,MAAgB,EAAW,GAAK,EAAM,QAAQ,EAAE,OAAO,OAAO,CAAC,GAG5E,IAAW,QAAe;GAC9B,IAAM,oBAAO,IAAI,IAAY;GAC7B,KAAK,IAAM,KAAS,EAAM,QAAQ;IAChC,IAAM,IAAQ,EAAS,EAAM,KAAK,GAC5B,IAAM,EAAS,EAAM,GAAG;IAC9B,IAAI,CAAC,KAAS,CAAC,GAAK;IAOpB,IAAI,IAAM,EAAM;IAChB,KAAK,IAAI,IAAQ,GAAG,IAAQ,OAAO,EAAU,GAAO,CAAG,GAAG,KAExD,AADA,EAAK,IAAI,CAAG,GACZ,IAAM,EAAQ,GAAK,CAAC;GAExB;GACA,OAAO;EACT,CAAC,GAaK,IAAQ,QAAe;GAC3B,IAAM,oBAAM,IAAI,IAA2B;GAC3C,KAAK,IAAM,KAAS,EAAM,QAAQ,EAAI,IAAI,GAAO,EAAW,GAAO,EAAM,QAAQ,CAAC;GAClF,OAAO;EACT,CAAC,GAEK,KAAW,MAAkB,EAAM,MAAM,IAAI,CAAK,KAAK,CAAC,GAExD,IAAa,QAAe;GAChC,IAAM,oBAAM,IAAI,IAAoB;GACpC,KAAK,IAAM,KAAS,EAAM,MAAM,OAAO,GACrC,KAAK,IAAM,KAAQ,GACjB,KAAK,IAAM,KAAQ,GACjB,AAAK,EAAI,IAAI,EAAK,GAAG,KACnB,EAAI,IAAI,EAAK,KAAK,EAAW,EAAK,KAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC,CAAC;GAIhF,OAAO;EACT,CAAC,GAEK,KAAa,MACjB,EAAW,MAAM,IAAI,CAAG,KAAK,EAAW,GAAK,EAAM,QAAQ,EAAE,KAAK,UAAU,CAAC,GAGzE,IAAa,QAAe;GAChC,IAAM,oBAAM,IAAI,IAAoB;GACpC,KAAK,IAAM,CAAC,GAAO,MAAU,EAAM,OAAO;IACxC,IAAI,IAAQ;IACZ,KAAK,IAAM,KAAQ,GACjB,KAAK,IAAM,KAAQ,GAAM,AAAI,EAAK,aAAa,QAAQ,EAAS,MAAM,IAAI,EAAK,GAAG,KAAG;IAEvF,EAAI,IAAI,GAAO,CAAK;GACtB;GACA,OAAO;EACT,CAAC,GAEK,KAAa,MAAkB,EAAW,MAAM,IAAI,CAAK,KAAK,GAE9D,KAAU,MAAoB,EAAK,aAAa,QAAQ,EAAS,MAAM,IAAI,EAAK,GAAG;yBAIvF,EA2BM,OAAA;GA3BD,OAAM;GAAkB,MAAK;GAAS,cAAY,EAAA;cACrD,EAyBU,GAAA,MAAA,EAzBe,EAAA,SAAT,YAAhB,EAyBU,WAAA;GAzBwB,KAAK;GAAO,OAAM;MAClD,EAQS,UAAA;GARD,MAAK;GAAS,OAAM;GAAyB,UAAK,MAAE,EAAI,kBAAmB,CAAK;UACnF,EAAU,CAAK,CAAA,IAAI,KAItB,CAAA,GAAY,EAAU,CAAK,IAAA,KAAA,EAAA,GAA3B,EAEO,QAFP,GAEO,EADF,EAAU,CAAK,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,GAAA,CAAA,GAItB,EAaM,OAbN,GAaM,EAAA,EAAA,EAAA,GAZJ,EAWW,GAAA,MAAA,EAXqB,EAAQ,CAAK,IAA3B,GAAM,wBAA8B,EAAG,GAAA,EAAA,EAAA,EAAA,GACvD,EASO,GAAA,MAAA,EARU,IAAR,YADT,EASO,QAAA;GAPJ,KAAK,EAAK;GACX,OAAM;GACL,iBAAe,EAAK,YAAY,KAAA;GAChC,cAAY,EAAK,QAAQ,EAAA,QAAK,KAAQ,KAAA;GACtC,aAAW,EAAO,CAAI,IAAA,KAAS,KAAA;OAE7B,EAAU,EAAK,GAAG,CAAA,GAAA,GAAA,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CalendarEventId } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A stable hue, 0 to 359, for an event that carries no colour of its own.
|
|
4
|
+
*
|
|
5
|
+
* The hash is the usual djb2 walk over the id written out as text, so a numeric id and the
|
|
6
|
+
* string of the same digits agree — which matters because an id makes the round trip
|
|
7
|
+
* through a consumer's JSON and may well come back as the other one.
|
|
8
|
+
*/
|
|
9
|
+
export declare function hueOf(id: CalendarEventId): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.js","names":[],"sources":["../../../src/components/VCalendar/color.ts"],"sourcesContent":["// @core\n/**\n * The colour an event is drawn in when it names none.\n *\n * The rule is that the same event is always the same colour, whatever order the list\n * arrives in and whatever a filter has just removed from it — so the colour is derived\n * from the event's id and from nothing else. Deriving it from the position in the array\n * would repaint the whole calendar every time one event was added at the top.\n *\n * Only the HUE is derived. The lightness and the chroma that go with it live in the token\n * layer, one pair per theme, which is what keeps the title's contrast against its card a\n * fixed quantity rather than something that varies around the colour wheel: in OKLCH the\n * L axis is perceptual, so two fixed lightnesses are the same perceived distance apart at\n * every hue. See the `color.event-*` tokens in `tokens/semantic.ts`.\n *\n * Pure, hence deterministic, hence the server and the browser derive the same hue and\n * hydration has nothing to disagree about.\n */\nimport type { CalendarEventId } from './types'\n\n/**\n * Knuth's multiplicative constant — the odd integer nearest to 2³² divided by the golden\n * ratio.\n *\n * TRAP — it is not decoration, and removing it makes the palette collapse without any\n * error to show for it. A plain string hash of `\"1\"`, `\"2\"`, `\"3\"` produces three\n * CONSECUTIVE numbers, so taking them modulo 360 directly would give three hues one degree\n * apart: a calendar whose events are numbered in order would come out entirely one colour.\n * Multiplying first scatters neighbouring hashes across the whole circle, which is exactly\n * what the constant is for.\n */\nconst GOLDEN = 2654435761\n\n/** How many degrees the colour wheel has. */\nconst HUES = 360\n\n/**\n * A stable hue, 0 to 359, for an event that carries no colour of its own.\n *\n * The hash is the usual djb2 walk over the id written out as text, so a numeric id and the\n * string of the same digits agree — which matters because an id makes the round trip\n * through a consumer's JSON and may well come back as the other one.\n */\nexport function hueOf(id: CalendarEventId): number {\n const text = String(id)\n let hash = 5381\n for (let i = 0; i < text.length; i++) {\n // `| 0` keeps the running value a 32-bit integer, so the result cannot depend on how\n // far a double drifts once the multiplications exceed the exactly representable range.\n hash = ((hash << 5) + hash + text.charCodeAt(i)) | 0\n }\n return Math.abs(Math.imul(hash, GOLDEN) >>> 0) % HUES\n}\n"],"mappings":"AA2CA,SAAgB,EAAM,GAA6B;CACjD,IAAM,IAAO,OAAO,CAAE,GAClB,IAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAG/B,KAAS,KAAQ,KAAK,IAAO,EAAK,WAAW,CAAC,IAAK;CAErD,OAAO,KAAK,IAAI,KAAK,KAAK,GAAM,UAAM,MAAM,CAAC,IAAI;AACnD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* How long a dragged event rests against an edge before the calendar pages, in milliseconds.
|
|
4
|
+
*
|
|
5
|
+
* Long enough that aiming at the edge column never pages by accident, short enough that
|
|
6
|
+
* deliberately holding there does not feel broken. It is a matter of feel rather than of
|
|
7
|
+
* correctness, so it is tuned by eye and exposed as `edgeStepDelay` for anyone who disagrees
|
|
8
|
+
* — which is also why no test pins the number itself.
|
|
9
|
+
*/
|
|
10
|
+
export declare const EDGE_STEP_DELAY = 800;
|
|
11
|
+
/**
|
|
12
|
+
* How wide the edge zone is, in pixels.
|
|
13
|
+
*
|
|
14
|
+
* TRAP — this number is the twin of `--vectis-control-size-calendar-edge`, the width of the
|
|
15
|
+
* band the stylesheet lights up to show that paging is coming. They describe the same strip:
|
|
16
|
+
* moving one without the other leaves the calendar paging from somewhere other than where it
|
|
17
|
+
* said it would, with nothing anywhere to point at it. The same arrangement as
|
|
18
|
+
* `DIAL_INNER_THRESHOLD` in `utils/time.ts`, and it carries the same warning at both ends.
|
|
19
|
+
*/
|
|
20
|
+
export declare const EDGE_BAND = 48;
|
|
21
|
+
/** Which way the calendar is being asked to go: back a period, or on to the next. */
|
|
22
|
+
export type EdgeDirection = -1 | 1;
|
|
23
|
+
export interface EdgeStep {
|
|
24
|
+
/**
|
|
25
|
+
* Told on every pointer move which edge the drag is now against, or nothing when it is
|
|
26
|
+
* back in the middle.
|
|
27
|
+
*/
|
|
28
|
+
watchEdge(edge: EdgeDirection | null): void;
|
|
29
|
+
/** Drops whatever is armed, without stepping. */
|
|
30
|
+
cancel(): void;
|
|
31
|
+
/** The edge currently counting down, for the stylesheet to show. */
|
|
32
|
+
pending: Readonly<Ref<EdgeDirection | null>>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `delay` is a getter rather than a number so a consumer can turn paging off mid-drag by
|
|
36
|
+
* binding it to zero — the reactive-prop-as-switch shape VCarousel's `autoplay` uses.
|
|
37
|
+
*/
|
|
38
|
+
export declare function useEdgeStep(onStep: (direction: EdgeDirection) => void, delay: () => number): EdgeStep;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useTimer as e } from "../../composables/useTimer.js";
|
|
2
|
+
import { readonly as t, ref as n } from "vue";
|
|
3
|
+
//#region src/components/VCalendar/edgeStep.ts
|
|
4
|
+
function r(r, i) {
|
|
5
|
+
let a = e(), o = n(null);
|
|
6
|
+
function s() {
|
|
7
|
+
a.cancel(), o.value = null;
|
|
8
|
+
}
|
|
9
|
+
function c(e) {
|
|
10
|
+
if (e === o.value || (s(), e === null)) return;
|
|
11
|
+
let t = i();
|
|
12
|
+
if (t <= 0) return;
|
|
13
|
+
o.value = e;
|
|
14
|
+
let n = () => {
|
|
15
|
+
r(e), a.start(n, t);
|
|
16
|
+
};
|
|
17
|
+
a.start(n, t);
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
watchEdge: c,
|
|
21
|
+
cancel: s,
|
|
22
|
+
pending: t(o)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { r as useEdgeStep };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=edgeStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edgeStep.js","names":[],"sources":["../../../src/components/VCalendar/edgeStep.ts"],"sourcesContent":["// @core\n/**\n * Holding a dragged event against the side of the calendar to turn the page.\n *\n * Without it, moving a meeting to next week means dropping it, navigating, and picking it up\n * again — the drag can only ever reach what is already on screen. With it, resting against an\n * edge shows the previous or next period and the event carries on travelling.\n *\n * WHY IT WAITS. Paging the instant the pointer touched the edge would make the last day of the\n * week unaimable: you would have to approach it from above and stop dead, and the smallest\n * overshoot would throw you into the following week. The delay is what separates \"I am aiming\n * at the edge column\" from \"I want to go further\", and it is the only thing that does.\n *\n * It sits in VCalendar's own folder rather than in `composables/` because VCalendar owns the\n * contract and both of its consumers are inside this component — the same reasoning as\n * `VCombobox/infiniteScroll.ts`, which is likewise a Vue-using module living beside the thing\n * it belongs to.\n */\nimport { readonly, ref, type Ref } from 'vue'\n\nimport { useTimer } from '../../composables/useTimer'\n\n/**\n * How long a dragged event rests against an edge before the calendar pages, in milliseconds.\n *\n * Long enough that aiming at the edge column never pages by accident, short enough that\n * deliberately holding there does not feel broken. It is a matter of feel rather than of\n * correctness, so it is tuned by eye and exposed as `edgeStepDelay` for anyone who disagrees\n * — which is also why no test pins the number itself.\n */\nexport const EDGE_STEP_DELAY = 800\n\n/**\n * How wide the edge zone is, in pixels.\n *\n * TRAP — this number is the twin of `--vectis-control-size-calendar-edge`, the width of the\n * band the stylesheet lights up to show that paging is coming. They describe the same strip:\n * moving one without the other leaves the calendar paging from somewhere other than where it\n * said it would, with nothing anywhere to point at it. The same arrangement as\n * `DIAL_INNER_THRESHOLD` in `utils/time.ts`, and it carries the same warning at both ends.\n */\nexport const EDGE_BAND = 48\n\n/** Which way the calendar is being asked to go: back a period, or on to the next. */\nexport type EdgeDirection = -1 | 1\n\nexport interface EdgeStep {\n /**\n * Told on every pointer move which edge the drag is now against, or nothing when it is\n * back in the middle.\n */\n watchEdge(edge: EdgeDirection | null): void\n /** Drops whatever is armed, without stepping. */\n cancel(): void\n /** The edge currently counting down, for the stylesheet to show. */\n pending: Readonly<Ref<EdgeDirection | null>>\n}\n\n/**\n * `delay` is a getter rather than a number so a consumer can turn paging off mid-drag by\n * binding it to zero — the reactive-prop-as-switch shape VCarousel's `autoplay` uses.\n */\nexport function useEdgeStep(\n onStep: (direction: EdgeDirection) => void,\n delay: () => number,\n): EdgeStep {\n const timer = useTimer()\n const pending = ref<EdgeDirection | null>(null)\n\n function cancel() {\n timer.cancel()\n pending.value = null\n }\n\n function watchEdge(edge: EdgeDirection | null) {\n // Staying on the SAME edge must leave the armed timer alone. Re-arming on every move\n // would mean a pointer trembling by a pixel never reached the delay at all, and the\n // calendar would simply never page for anyone with an unsteady hand.\n if (edge === pending.value) return\n\n cancel()\n if (edge === null) return\n\n /*\n * TRAP — the guard is what stops this recursing, not a convenience. `useTimer` runs a\n * delay of zero or less SYNCHRONOUSLY by design, and the callback below re-arms itself,\n * so arming at zero would call it again and again until the stack gave out. Refusing to\n * arm is also how a consumer switches paging off, so the two are one line.\n */\n const wait = delay()\n if (wait <= 0) return\n\n pending.value = edge\n\n const fire = () => {\n onStep(edge)\n // Re-armed, so holding against the edge keeps paging rather than stopping after one.\n timer.start(fire, wait)\n }\n timer.start(fire, wait)\n }\n\n return { watchEdge, cancel, pending: readonly(pending) }\n}\n"],"mappings":";;;AA8DA,SAAgB,EACd,GACA,GACU;CACV,IAAM,IAAQ,EAAS,GACjB,IAAU,EAA0B,IAAI;CAE9C,SAAS,IAAS;EAEhB,AADA,EAAM,OAAO,GACb,EAAQ,QAAQ;CAClB;CAEA,SAAS,EAAU,GAA4B;EAO7C,IAHI,MAAS,EAAQ,UAErB,EAAO,GACH,MAAS,OAAM;EAQnB,IAAM,IAAO,EAAM;EACnB,IAAI,KAAQ,GAAG;EAEf,EAAQ,QAAQ;EAEhB,IAAM,UAAa;GAGjB,AAFA,EAAO,CAAI,GAEX,EAAM,MAAM,GAAM,CAAI;EACxB;EACA,EAAM,MAAM,GAAM,CAAI;CACxB;CAEA,OAAO;EAAE;EAAW;EAAQ,SAAS,EAAS,CAAO;CAAE;AACzD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure half of VCalendar's keyboard: it answers the single question "what does this
|
|
3
|
+
* key mean here?", and does nothing else. Moving the focus, writing to the model, calling
|
|
4
|
+
* `preventDefault` and announcing the result all stay in the component, where the reactive
|
|
5
|
+
* state lives.
|
|
6
|
+
*
|
|
7
|
+
* It sits in VCalendar's own folder rather than in `utils/` because it has exactly one
|
|
8
|
+
* consumer, which fails the admission rule for shared code (the same reasoning as
|
|
9
|
+
* `VDatePicker/keyboard.ts` and `VHotkeys/platform.ts`). Being pure is also what makes the
|
|
10
|
+
* whole keyboard testable without mounting anything, since the environment the tests run
|
|
11
|
+
* in lays nothing out and the handlers in the component only ever move DOM focus.
|
|
12
|
+
*
|
|
13
|
+
* `utils/arrowNav` is deliberately not used. It navigates a flat DOM list of controls; this
|
|
14
|
+
* navigates a two-dimensional space of DATES AND TIMES whose edges are a domain clamp, not
|
|
15
|
+
* a list end — the same reason VDatePicker, VCombobox and VTimePicker stay out of it.
|
|
16
|
+
*
|
|
17
|
+
* WHY A GRAB MODE, and not arrows that move an event outright. Every gesture the pointer
|
|
18
|
+
* offers has to have a keyboard equivalent (WCAG 2.1.1), and a card is reached by the
|
|
19
|
+
* arrows in the first place — so if the arrows also moved it, arriving at an event and
|
|
20
|
+
* nudging it would be the same keystroke, and there would be no way to pass over one
|
|
21
|
+
* without dragging it. Entering a mode separates the two, and Escape gives back the one
|
|
22
|
+
* thing a pointer drag has that a keypress does not: the chance to change your mind.
|
|
23
|
+
*/
|
|
24
|
+
/** What one key means, given where the focus is. */
|
|
25
|
+
export type CalendarIntent =
|
|
26
|
+
/** Move the focused cell by whole days and whole hours. */
|
|
27
|
+
{
|
|
28
|
+
kind: 'moveFocus';
|
|
29
|
+
days: number;
|
|
30
|
+
minutes: number;
|
|
31
|
+
}
|
|
32
|
+
/** Jump to the first or last day of the row. */
|
|
33
|
+
| {
|
|
34
|
+
kind: 'rowEdge';
|
|
35
|
+
edge: 'start' | 'end';
|
|
36
|
+
}
|
|
37
|
+
/** Show the previous or next period, as the toolbar's buttons do. */
|
|
38
|
+
| {
|
|
39
|
+
kind: 'period';
|
|
40
|
+
delta: -1 | 1;
|
|
41
|
+
}
|
|
42
|
+
/** Take up what is focused: create here, open a card, or commit a move under way. */
|
|
43
|
+
| {
|
|
44
|
+
kind: 'activate';
|
|
45
|
+
}
|
|
46
|
+
/** Back out: leave a card for its cell, or abandon a move and put the event back. */
|
|
47
|
+
| {
|
|
48
|
+
kind: 'cancel';
|
|
49
|
+
}
|
|
50
|
+
/** Move the grabbed event. */
|
|
51
|
+
| {
|
|
52
|
+
kind: 'grabMove';
|
|
53
|
+
days: number;
|
|
54
|
+
minutes: number;
|
|
55
|
+
}
|
|
56
|
+
/** Change how long the grabbed event lasts. */
|
|
57
|
+
| {
|
|
58
|
+
kind: 'grabResize';
|
|
59
|
+
minutes: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Where the focus is when the key arrives, which is what decides the answer:
|
|
63
|
+
*
|
|
64
|
+
* - `cell` — an empty part of the grid. The arrows travel, Enter creates.
|
|
65
|
+
* - `event` — a card, at rest. Enter takes hold of it, Escape goes back to the grid.
|
|
66
|
+
* - `grabbed` — a card being moved. The arrows now move the EVENT, Enter commits, Escape
|
|
67
|
+
* puts it back where it was.
|
|
68
|
+
*/
|
|
69
|
+
export type CalendarFocus = 'cell' | 'event' | 'grabbed';
|
|
70
|
+
/**
|
|
71
|
+
* What a key means. Returning nothing says the key is none of this table's business and
|
|
72
|
+
* the event must be left entirely alone — which is what keeps Tab, the browser's own
|
|
73
|
+
* shortcuts and anything a consumer has bound working.
|
|
74
|
+
*
|
|
75
|
+
* `rtl` is passed in rather than read here: which way is "forward" is a property of the
|
|
76
|
+
* document, and a pure table has no business consulting one.
|
|
77
|
+
*/
|
|
78
|
+
export declare function calendarIntent(key: string, shiftKey: boolean, focus: CalendarFocus, slotMinutes: number, rtl: boolean): CalendarIntent | undefined;
|