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
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { IconSource } from '../VIcon/types.js';
|
|
2
|
+
export type CarouselEffect = 'slide' | 'fade' | 'scale' | 'cover';
|
|
3
|
+
export type CarouselOrientation = 'horizontal' | 'vertical';
|
|
4
|
+
/** Where the position dots go: nowhere, over the slides, or after them. */
|
|
5
|
+
export type CarouselIndicators = false | 'inside' | 'outside';
|
|
6
|
+
/** Where the previous and next buttons go: nowhere, over the slides, or beside them. */
|
|
7
|
+
export type CarouselControls = false | 'inside' | 'outside';
|
|
8
|
+
/**
|
|
9
|
+
* When those buttons are visible. It is a named choice rather than a yes-or-no, because
|
|
10
|
+
* "on hover" would misname what actually happens: they also appear on keyboard focus, and
|
|
11
|
+
* they stay permanently visible where there is no pointer to hover with.
|
|
12
|
+
*/
|
|
13
|
+
export type CarouselControlsVisibility = 'always' | 'hover';
|
|
14
|
+
/**
|
|
15
|
+
* A carousel: content the reader moves through one screenful at a time — images, cards,
|
|
16
|
+
* text — across the page or down it.
|
|
17
|
+
*
|
|
18
|
+
* It is built on ONE thing: a box that scrolls, whose content snaps into place. Touch,
|
|
19
|
+
* the trackpad, the scrollbar, the keyboard and the snapping itself therefore all come
|
|
20
|
+
* from the browser. There is no track being moved by code, and no slides cloned anywhere —
|
|
21
|
+
* including for the loop: going past the last slide scrolls the real track back to the
|
|
22
|
+
* first, a rewind the reader sees rather than a seam hidden behind copies.
|
|
23
|
+
*
|
|
24
|
+
* How many slides fit is decided entirely in CSS, with no breakpoints and nothing being
|
|
25
|
+
* measured: `itemsPerView` is a MAXIMUM and `itemMinSize` a floor, and taking whichever of
|
|
26
|
+
* the two is larger IS the responsive rule. The strip of the next slide left showing falls
|
|
27
|
+
* out of the same formula.
|
|
28
|
+
*
|
|
29
|
+
* The transitions between slides are driven by the SCROLL itself rather than played over
|
|
30
|
+
* a fixed duration, so they follow the finger during a drag and reverse when it does.
|
|
31
|
+
* They are an enhancement: where a browser does not support them the carousel simply
|
|
32
|
+
* slides, and a reader who has asked for less motion never sees them at all.
|
|
33
|
+
*
|
|
34
|
+
* The JavaScript is limited to what nothing else can do:
|
|
35
|
+
*
|
|
36
|
+
* - moving the scroller when the VALUE changes — nothing in CSS scrolls a box to its Nth
|
|
37
|
+
* child on demand;
|
|
38
|
+
* - reading back which slide the reader has landed on, and measuring how many positions
|
|
39
|
+
* there actually are, which is subtler than it sounds: not every slide can lead, and the
|
|
40
|
+
* last position is the END of the track rather than any slide's edge;
|
|
41
|
+
* - advancing on a timer, no stylesheet having a clock, and asking once whether the reader
|
|
42
|
+
* wants less motion — a media query can stop an animation but never a timer, and what
|
|
43
|
+
* the guideline is about is the CONTENT moving;
|
|
44
|
+
* - the arrow keys. A focused scrolling box does move by itself, but by a fixed number of
|
|
45
|
+
* pixels that the snapping immediately undoes, so the net movement is nothing.
|
|
46
|
+
*
|
|
47
|
+
* Nothing touches the page outside handlers and effects that run after it has been
|
|
48
|
+
* updated, which is what lets the component render on a server.
|
|
49
|
+
*/
|
|
50
|
+
interface CarouselProps {
|
|
51
|
+
/**
|
|
52
|
+
* How many slides may be visible at once. It is a MAXIMUM and not a target: the floor
|
|
53
|
+
* below decides how many actually fit, which is what makes the whole thing responsive
|
|
54
|
+
* without a single breakpoint.
|
|
55
|
+
*/
|
|
56
|
+
itemsPerView?: number;
|
|
57
|
+
/**
|
|
58
|
+
* How small a slide is allowed to get. Once an equal share would fall below this, fewer
|
|
59
|
+
* slides fit and the carousel simply scrolls further instead. A number is read as
|
|
60
|
+
* pixels; anything else is used as given, so `'20vw'` works.
|
|
61
|
+
*/
|
|
62
|
+
itemMinSize?: number | string;
|
|
63
|
+
/**
|
|
64
|
+
* How much of the NEXT slide is left showing, as a hint that there is more. It includes
|
|
65
|
+
* the gap before it, which is what keeps the sizing formula free of special cases.
|
|
66
|
+
*
|
|
67
|
+
* It cannot be combined with the fade transition: fading assumes a slide exactly fills
|
|
68
|
+
* the view.
|
|
69
|
+
*/
|
|
70
|
+
peek?: number | string;
|
|
71
|
+
/** The space between two slides. */
|
|
72
|
+
gap?: number | string;
|
|
73
|
+
/** Whether the carousel scrolls across the page or down it. */
|
|
74
|
+
orientation?: CarouselOrientation;
|
|
75
|
+
/**
|
|
76
|
+
* How one slide gives way to the next, driven by the scroll itself. Sliding means no
|
|
77
|
+
* animation at all.
|
|
78
|
+
*
|
|
79
|
+
* Fading requires ONE slide at a time and no peek — it works by holding each slide in
|
|
80
|
+
* place while the scroll moves under it, which only lands correctly when a slide fills
|
|
81
|
+
* the view exactly. Asked for otherwise, it falls back to sliding rather than degrading.
|
|
82
|
+
*/
|
|
83
|
+
effect?: CarouselEffect;
|
|
84
|
+
/**
|
|
85
|
+
* The height of the visible area.
|
|
86
|
+
*
|
|
87
|
+
* GIVE ONE when the carousel scrolls downwards: a slide sized as a share of the height
|
|
88
|
+
* needs a height to take a share OF, and without it every slide collapses onto its own
|
|
89
|
+
* content. Scrolling across the page, the height comes from the slides themselves.
|
|
90
|
+
*/
|
|
91
|
+
height?: number | string;
|
|
92
|
+
/**
|
|
93
|
+
* Whether the carousel comes back round: past the last position it returns to the first,
|
|
94
|
+
* and before the first it goes to the last. Off by default, which stops it at both ends.
|
|
95
|
+
*
|
|
96
|
+
* Nothing is cloned to achieve it. Coming back round scrolls the REAL track back, so the
|
|
97
|
+
* reader sees it rewind — over several slides that is a visible movement, and it is the
|
|
98
|
+
* honest one: the carousel really is returning to where it started.
|
|
99
|
+
*
|
|
100
|
+
* It has no effect where there is only one position to rest on, and the buttons stay
|
|
101
|
+
* disabled there rather than becoming two controls that do nothing. The dots always go
|
|
102
|
+
* straight to the position they name, and so do the Home and End keys.
|
|
103
|
+
*/
|
|
104
|
+
loop?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* How long each slide is shown before the next one, in milliseconds; zero means it does
|
|
107
|
+
* not advance by itself. It stops at the last page unless the carousel loops — in which
|
|
108
|
+
* case it goes round for as long as the page is open — pauses while the pointer rests on
|
|
109
|
+
* it or the KEYBOARD focus is inside it, and never runs at all for a reader who has asked
|
|
110
|
+
* for less motion.
|
|
111
|
+
*
|
|
112
|
+
* The component deliberately renders NO pause button. This prop is reactive and setting
|
|
113
|
+
* it to zero cancels the timer at once, so a stop control is a one-line binding on your
|
|
114
|
+
* side — and it is worth adding: the guideline asks for a way to stop content that moves
|
|
115
|
+
* on its own, and hover and focus leave a touch user with none. Looping makes that
|
|
116
|
+
* binding MANDATORY rather than advisable, the movement no longer ending on its own.
|
|
117
|
+
*/
|
|
118
|
+
autoplay?: number;
|
|
119
|
+
/**
|
|
120
|
+
* Where the previous and next buttons go: over the slides, beside them, or nowhere.
|
|
121
|
+
*
|
|
122
|
+
* Placed beside, they sit at the ends of the scrolling axis and their room is reserved
|
|
123
|
+
* as padding, so the component's footprint is unchanged and the slides narrow instead.
|
|
124
|
+
* Either way they are centred on the SLIDES and never on the slides plus the dots.
|
|
125
|
+
*/
|
|
126
|
+
controls?: CarouselControls;
|
|
127
|
+
/**
|
|
128
|
+
* Where the position dots go: over the slides, after them, or nowhere. After them means
|
|
129
|
+
* below when the carousel scrolls across the page, and beside it when it scrolls down.
|
|
130
|
+
*/
|
|
131
|
+
indicators?: CarouselIndicators;
|
|
132
|
+
/**
|
|
133
|
+
* Whether those buttons are always visible, or appear when the pointer is over the
|
|
134
|
+
* carousel or the keyboard focus is inside it. Where there is no pointer to hover with,
|
|
135
|
+
* they stay visible whatever this says. The dots are never hidden.
|
|
136
|
+
*/
|
|
137
|
+
controlsVisibility?: CarouselControlsVisibility;
|
|
138
|
+
/** The icon of the previous button. It follows the orientation by default. */
|
|
139
|
+
prevIcon?: IconSource;
|
|
140
|
+
/** The icon of the next button. It follows the orientation by default. */
|
|
141
|
+
nextIcon?: IconSource;
|
|
142
|
+
/** What the previous button does, in words. It falls back to the dictionary. */
|
|
143
|
+
prevLabel?: string;
|
|
144
|
+
/** What the next button does, in words. It falls back to the dictionary. */
|
|
145
|
+
nextLabel?: string;
|
|
146
|
+
/**
|
|
147
|
+
* What screen readers announce for the carousel as a whole.
|
|
148
|
+
*
|
|
149
|
+
* Give a DISTINCT one to every carousel on a page: this is a landmark of the page, and
|
|
150
|
+
* two landmarks bearing the same name cannot be told apart by someone navigating between
|
|
151
|
+
* them.
|
|
152
|
+
*/
|
|
153
|
+
label?: string;
|
|
154
|
+
}
|
|
155
|
+
type __VLS_Props = CarouselProps;
|
|
156
|
+
type __VLS_Slots = {
|
|
157
|
+
/**
|
|
158
|
+
* The slides. How many there are is read from what this slot RENDERS, so a `v-for` is
|
|
159
|
+
* perfectly fine — but the slot must not depend on something only true in a browser, or
|
|
160
|
+
* the server and the client would count differently.
|
|
161
|
+
*/
|
|
162
|
+
default(): unknown;
|
|
163
|
+
/**
|
|
164
|
+
* Replaces the previous and next buttons entirely, their placement included — so custom
|
|
165
|
+
* content positions itself, and the visibility setting no longer applies to it.
|
|
166
|
+
*/
|
|
167
|
+
controls?(props: {
|
|
168
|
+
previous: () => void;
|
|
169
|
+
next: () => void;
|
|
170
|
+
atStart: boolean;
|
|
171
|
+
atEnd: boolean;
|
|
172
|
+
index: number;
|
|
173
|
+
/** How many slides there are. */
|
|
174
|
+
count: number;
|
|
175
|
+
/** How many positions the carousel can actually rest on, which is usually fewer. */
|
|
176
|
+
pageCount: number;
|
|
177
|
+
/** Which way it scrolls — a bar of your own cannot choose its icons without knowing. */
|
|
178
|
+
orientation: CarouselOrientation;
|
|
179
|
+
}): unknown;
|
|
180
|
+
/**
|
|
181
|
+
* Replaces the whole bar of dots.
|
|
182
|
+
*
|
|
183
|
+
* TRAP — render one control per POSITION and not per slide. A position past the last one
|
|
184
|
+
* cannot be reached, so a bar built on the number of slides offers dots that scroll
|
|
185
|
+
* nowhere. The slide count is passed as well, for wording such as "3 of 8".
|
|
186
|
+
*/
|
|
187
|
+
indicators?(props: {
|
|
188
|
+
index: number;
|
|
189
|
+
count: number;
|
|
190
|
+
pageCount: number;
|
|
191
|
+
goTo: (index: number) => void;
|
|
192
|
+
orientation: CarouselOrientation;
|
|
193
|
+
}): unknown;
|
|
194
|
+
/**
|
|
195
|
+
* Replaces what is drawn INSIDE one dot. The button itself, and everything that makes it
|
|
196
|
+
* announce and behave correctly, stays the design system's.
|
|
197
|
+
*/
|
|
198
|
+
indicator?(props: {
|
|
199
|
+
index: number;
|
|
200
|
+
active: boolean;
|
|
201
|
+
}): unknown;
|
|
202
|
+
};
|
|
203
|
+
type __VLS_ModelProps = {
|
|
204
|
+
/**
|
|
205
|
+
* Which slide is current: the first one fully visible when several fit at once, which is
|
|
206
|
+
* also the position the carousel has come to rest on.
|
|
207
|
+
*/
|
|
208
|
+
modelValue?: number;
|
|
209
|
+
};
|
|
210
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
211
|
+
declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
212
|
+
"update:modelValue": (value: number) => any;
|
|
213
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
214
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
215
|
+
}>, {
|
|
216
|
+
label: string;
|
|
217
|
+
indicators: CarouselIndicators;
|
|
218
|
+
orientation: CarouselOrientation;
|
|
219
|
+
prevIcon: IconSource;
|
|
220
|
+
nextIcon: IconSource;
|
|
221
|
+
prevLabel: string;
|
|
222
|
+
nextLabel: string;
|
|
223
|
+
gap: number | string;
|
|
224
|
+
height: number | string;
|
|
225
|
+
itemsPerView: number;
|
|
226
|
+
itemMinSize: number | string;
|
|
227
|
+
peek: number | string;
|
|
228
|
+
effect: CarouselEffect;
|
|
229
|
+
loop: boolean;
|
|
230
|
+
autoplay: number;
|
|
231
|
+
controls: CarouselControls;
|
|
232
|
+
controlsVisibility: CarouselControlsVisibility;
|
|
233
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
234
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
235
|
+
declare const _default: typeof __VLS_export;
|
|
236
|
+
export default _default;
|
|
237
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
238
|
+
new (): {
|
|
239
|
+
$slots: S;
|
|
240
|
+
};
|
|
241
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VCarousel.js","names":[],"sources":["../../../src/components/VCarousel/VCarousel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n cloneVNode,\n computed,\n onBeforeUnmount,\n onMounted,\n nextTick,\n ref,\n provide,\n useSlots,\n watch,\n watchEffect,\n} from 'vue'\nimport type { StyleValue } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { arrow_downward_alt as arrowDownwardAltIcon } from '../VIcon/icons/arrow_downward_alt'\nimport { arrow_left_alt as arrowLeftAltIcon } from '../VIcon/icons/arrow_left_alt'\nimport { arrow_right_alt as arrowRightAltIcon } from '../VIcon/icons/arrow_right_alt'\nimport { arrow_upward_alt as arrowUpwardAltIcon } from '../VIcon/icons/arrow_upward_alt'\nimport type { IconSource } from '../VIcon/types'\nimport VIconButton from '../VIconButton/VIconButton.vue'\nimport { carouselKey } from './context'\n\nimport { cssSize } from '../../utils/css'\nimport { isRtl } from '../../utils/direction'\nimport { isDev } from '../../utils/env'\nimport { isKeyboardFocus } from '../../utils/focus'\nimport { clamp } from '../../utils/number'\nimport { flattenSlot } from '../../utils/vnode'\n\nimport { useAriaLabel } from '../../composables/useAriaLabel'\nimport { useTimer } from '../../composables/useTimer'\nimport { useMessages } from '../../i18n/state'\n\nexport type CarouselEffect = 'slide' | 'fade' | 'scale' | 'cover'\nexport type CarouselOrientation = 'horizontal' | 'vertical'\n/** Where the position dots go: nowhere, over the slides, or after them. */\nexport type CarouselIndicators = false | 'inside' | 'outside'\n/** Where the previous and next buttons go: nowhere, over the slides, or beside them. */\nexport type CarouselControls = false | 'inside' | 'outside'\n/**\n * When those buttons are visible. It is a named choice rather than a yes-or-no, because\n * \"on hover\" would misname what actually happens: they also appear on keyboard focus, and\n * they stay permanently visible where there is no pointer to hover with.\n */\nexport type CarouselControlsVisibility = 'always' | 'hover'\n\n// @keyboard @a11y @ssr @core — the DS's densest script; every block below carries\n// its own tag.\n/**\n * A carousel: content the reader moves through one screenful at a time — images, cards,\n * text — across the page or down it.\n *\n * It is built on ONE thing: a box that scrolls, whose content snaps into place. Touch,\n * the trackpad, the scrollbar, the keyboard and the snapping itself therefore all come\n * from the browser. There is no track being moved by code, and no slides cloned anywhere —\n * including for the loop: going past the last slide scrolls the real track back to the\n * first, a rewind the reader sees rather than a seam hidden behind copies.\n *\n * How many slides fit is decided entirely in CSS, with no breakpoints and nothing being\n * measured: `itemsPerView` is a MAXIMUM and `itemMinSize` a floor, and taking whichever of\n * the two is larger IS the responsive rule. The strip of the next slide left showing falls\n * out of the same formula.\n *\n * The transitions between slides are driven by the SCROLL itself rather than played over\n * a fixed duration, so they follow the finger during a drag and reverse when it does.\n * They are an enhancement: where a browser does not support them the carousel simply\n * slides, and a reader who has asked for less motion never sees them at all.\n *\n * The JavaScript is limited to what nothing else can do:\n *\n * - moving the scroller when the VALUE changes — nothing in CSS scrolls a box to its Nth\n * child on demand;\n * - reading back which slide the reader has landed on, and measuring how many positions\n * there actually are, which is subtler than it sounds: not every slide can lead, and the\n * last position is the END of the track rather than any slide's edge;\n * - advancing on a timer, no stylesheet having a clock, and asking once whether the reader\n * wants less motion — a media query can stop an animation but never a timer, and what\n * the guideline is about is the CONTENT moving;\n * - the arrow keys. A focused scrolling box does move by itself, but by a fixed number of\n * pixels that the snapping immediately undoes, so the net movement is nothing.\n *\n * Nothing touches the page outside handlers and effects that run after it has been\n * updated, which is what lets the component render on a server.\n */\ninterface CarouselProps {\n /**\n * How many slides may be visible at once. It is a MAXIMUM and not a target: the floor\n * below decides how many actually fit, which is what makes the whole thing responsive\n * without a single breakpoint.\n */\n itemsPerView?: number\n /**\n * How small a slide is allowed to get. Once an equal share would fall below this, fewer\n * slides fit and the carousel simply scrolls further instead. A number is read as\n * pixels; anything else is used as given, so `'20vw'` works.\n */\n itemMinSize?: number | string\n /**\n * How much of the NEXT slide is left showing, as a hint that there is more. It includes\n * the gap before it, which is what keeps the sizing formula free of special cases.\n *\n * It cannot be combined with the fade transition: fading assumes a slide exactly fills\n * the view.\n */\n peek?: number | string\n /** The space between two slides. */\n gap?: number | string\n /** Whether the carousel scrolls across the page or down it. */\n orientation?: CarouselOrientation\n /**\n * How one slide gives way to the next, driven by the scroll itself. Sliding means no\n * animation at all.\n *\n * Fading requires ONE slide at a time and no peek — it works by holding each slide in\n * place while the scroll moves under it, which only lands correctly when a slide fills\n * the view exactly. Asked for otherwise, it falls back to sliding rather than degrading.\n */\n effect?: CarouselEffect\n /**\n * The height of the visible area.\n *\n * GIVE ONE when the carousel scrolls downwards: a slide sized as a share of the height\n * needs a height to take a share OF, and without it every slide collapses onto its own\n * content. Scrolling across the page, the height comes from the slides themselves.\n */\n height?: number | string\n /**\n * Whether the carousel comes back round: past the last position it returns to the first,\n * and before the first it goes to the last. Off by default, which stops it at both ends.\n *\n * Nothing is cloned to achieve it. Coming back round scrolls the REAL track back, so the\n * reader sees it rewind — over several slides that is a visible movement, and it is the\n * honest one: the carousel really is returning to where it started.\n *\n * It has no effect where there is only one position to rest on, and the buttons stay\n * disabled there rather than becoming two controls that do nothing. The dots always go\n * straight to the position they name, and so do the Home and End keys.\n */\n loop?: boolean\n /**\n * How long each slide is shown before the next one, in milliseconds; zero means it does\n * not advance by itself. It stops at the last page unless the carousel loops — in which\n * case it goes round for as long as the page is open — pauses while the pointer rests on\n * it or the KEYBOARD focus is inside it, and never runs at all for a reader who has asked\n * for less motion.\n *\n * The component deliberately renders NO pause button. This prop is reactive and setting\n * it to zero cancels the timer at once, so a stop control is a one-line binding on your\n * side — and it is worth adding: the guideline asks for a way to stop content that moves\n * on its own, and hover and focus leave a touch user with none. Looping makes that\n * binding MANDATORY rather than advisable, the movement no longer ending on its own.\n */\n autoplay?: number\n /**\n * Where the previous and next buttons go: over the slides, beside them, or nowhere.\n *\n * Placed beside, they sit at the ends of the scrolling axis and their room is reserved\n * as padding, so the component's footprint is unchanged and the slides narrow instead.\n * Either way they are centred on the SLIDES and never on the slides plus the dots.\n */\n controls?: CarouselControls\n /**\n * Where the position dots go: over the slides, after them, or nowhere. After them means\n * below when the carousel scrolls across the page, and beside it when it scrolls down.\n */\n indicators?: CarouselIndicators\n /**\n * Whether those buttons are always visible, or appear when the pointer is over the\n * carousel or the keyboard focus is inside it. Where there is no pointer to hover with,\n * they stay visible whatever this says. The dots are never hidden.\n */\n controlsVisibility?: CarouselControlsVisibility\n /** The icon of the previous button. It follows the orientation by default. */\n prevIcon?: IconSource\n /** The icon of the next button. It follows the orientation by default. */\n nextIcon?: IconSource\n /** What the previous button does, in words. It falls back to the dictionary. */\n prevLabel?: string\n /** What the next button does, in words. It falls back to the dictionary. */\n nextLabel?: string\n /**\n * What screen readers announce for the carousel as a whole.\n *\n * Give a DISTINCT one to every carousel on a page: this is a landmark of the page, and\n * two landmarks bearing the same name cannot be told apart by someone navigating between\n * them.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<CarouselProps>(), {\n itemsPerView: 1,\n itemMinSize: undefined,\n peek: undefined,\n gap: undefined,\n orientation: 'horizontal',\n effect: 'slide',\n height: undefined,\n loop: false,\n autoplay: 0,\n controls: 'inside',\n indicators: 'outside',\n controlsVisibility: 'always',\n prevIcon: undefined,\n nextIcon: undefined,\n prevLabel: undefined,\n nextLabel: undefined,\n label: undefined,\n})\n\nconst slots = useSlots()\n\ndefineSlots<{\n /**\n * The slides. How many there are is read from what this slot RENDERS, so a `v-for` is\n * perfectly fine — but the slot must not depend on something only true in a browser, or\n * the server and the client would count differently.\n */\n default(): unknown\n /**\n * Replaces the previous and next buttons entirely, their placement included — so custom\n * content positions itself, and the visibility setting no longer applies to it.\n */\n controls?(props: {\n previous: () => void\n next: () => void\n atStart: boolean\n atEnd: boolean\n index: number\n /** How many slides there are. */\n count: number\n /** How many positions the carousel can actually rest on, which is usually fewer. */\n pageCount: number\n /** Which way it scrolls — a bar of your own cannot choose its icons without knowing. */\n orientation: CarouselOrientation\n }): unknown\n /**\n * Replaces the whole bar of dots.\n *\n * TRAP — render one control per POSITION and not per slide. A position past the last one\n * cannot be reached, so a bar built on the number of slides offers dots that scroll\n * nowhere. The slide count is passed as well, for wording such as \"3 of 8\".\n */\n indicators?(props: {\n index: number\n count: number\n pageCount: number\n goTo: (index: number) => void\n orientation: CarouselOrientation\n }): unknown\n /**\n * Replaces what is drawn INSIDE one dot. The button itself, and everything that makes it\n * announce and behave correctly, stays the design system's.\n */\n indicator?(props: { index: number; active: boolean }): unknown\n}>()\n\n/**\n * Which slide is current: the first one fully visible when several fit at once, which is\n * also the position the carousel has come to rest on.\n */\nconst model = defineModel<number>({ default: 0 })\n\nconst m = useMessages()\nconst ariaLabel = useAriaLabel(() => props.label ?? m.value.carousel.label)\nconst resolvedPrevLabel = computed(() => props.prevLabel ?? m.value.carousel.previous)\nconst resolvedNextLabel = computed(() => props.nextLabel ?? m.value.carousel.next)\nconst isVertical = computed(() => props.orientation === 'vertical')\n/* Arrows with a shaft rather than the chevrons VTabs and VPagination use, and the\n difference is the surface they sit on: those two put their control in a dense bar,\n where a chevron is exactly the right weight, while this pair is a round button laid\n over whatever media the slides carry. A hairline chevron dissolves at the centre of\n a 40px disc; a shaft fills it and reads at a glance. */\nconst resolvedPrevIcon = computed(\n () => props.prevIcon ?? (isVertical.value ? arrowUpwardAltIcon : arrowLeftAltIcon),\n)\nconst resolvedNextIcon = computed(\n () => props.nextIcon ?? (isVertical.value ? arrowDownwardAltIcon : arrowRightAltIcon),\n)\n\n// @ssr\n/*\n * The count comes from the slot's VNODES, never from a registry the items feed at\n * mount: a registry renders 0 slides on the server and N on the client — a\n * guaranteed hydration mismatch, and the very reason VTabs derives `hasPanels`\n * from `slots` too. `cloneVNode` is then what carries each slide its position:\n * `setup()` order is deterministic on the first render but not on a later\n * insertion, so a self-incrementing counter would drift.\n */\nconst slides = computed(() => flattenSlot(slots.default?.()))\nconst count = computed(() => slides.value.length)\n\n// A functional component: it renders already-captured VNodes, which\n// <component :is> cannot do (it expects a definition). The VAvatarGroup idiom.\nconst Slides = () =>\n slides.value.map((node, index) => cloneVNode(node, { index, key: node.key ?? index }))\n\n/*\n * `fade` counter-translates every slide onto the same spot, so past one item per\n * view — or with a peek strip — the slides do not merely look degraded, they pile\n * up. The downgrade makes the combination unrepresentable; the dev warn explains.\n */\nconst resolvedEffect = computed<CarouselEffect>(() =>\n props.effect === 'fade' && (props.itemsPerView > 1 || props.peek !== undefined)\n ? 'slide'\n : props.effect,\n)\n\nprovide(carouselKey, {\n get count() {\n return count.value\n },\n get slideRoleDescription() {\n return m.value.carousel.slideRoleDescription\n },\n slideLabel: (index: number) => m.value.carousel.slide(index + 1, count.value),\n})\n\nconst rootStyle = computed<StyleValue>(() => ({\n '--carousel-per-view': String(props.itemsPerView),\n '--carousel-item-min': cssSize(props.itemMinSize),\n '--carousel-peek': cssSize(props.peek),\n '--carousel-gap': cssSize(props.gap),\n '--carousel-viewport-block': cssSize(props.height),\n}))\n\nconst viewportEl = ref<HTMLElement | null>(null)\n\n/*\n * Raised while a programmatic scroll is in flight, so the read-back does not fight\n * the request: without it, asking for slide 4 would be overwritten by slides 1, 2\n * and 3 as they pass under the scrollport.\n *\n * A `ref` and NOT the non-reactive `let` of `useTimer`, because LOWERING it has to\n * be able to re-run the sync. `scrollend` and the observer callback race, and a\n * smooth scroll the user interrupts is exactly the losing order: the observer\n * reports the final position while the flag is still up, the flag drops a moment\n * later, and with a plain `let` nothing would ever come back to write the model —\n * desynchronized for good. Caught by the `Default` play function.\n */\nconst settling = ref(false)\n\n/*\n * The arrival position, read AGAIN — and that second reading is the whole point.\n * The observer is the only other source of one and it delivers on a threshold\n * crossing alone, so after a backward scroll under a `peek` its last delivery is a\n * MID-FLIGHT one naming the page being left (see `measure`). Lowering the guard on\n * its own hands that stale index to the watcher below, which writes it into the model\n * while `readBack` suppresses the scroll that would have corrected it: the dot then\n * sits one page ahead of the content, for good.\n *\n * It is the CALL that removes the race, not its position: the sync watcher below is a\n * `pre` one, so both writes land in the same flush and it runs once, on the final\n * values, whatever the order here. Measuring first is intent, not mechanism.\n */\nconst onScrollEnd = () => {\n const port = viewportEl.value\n if (port) measure(port)\n settling.value = false\n}\n\n/*\n * Raised for exactly the model write the read-back makes, and lowered on the next\n * tick — once `watch(model)` below has read it.\n *\n * It is what stops the two directions from CHAINING, and the bug it fixes is a\n * touch one: DOM → model runs on every frame of a drag, and each of those writes\n * came straight back as a programmatic `scrollBy`. The scroller jumped to the\n * slide the read-back had just named while the finger was still down, the release\n * then snapped it again, and one gesture produced two animations. A wheel or a\n * keyboard rarely shows it — they leave the scroller between two snap positions\n * far less often than a drag does.\n *\n * `scrollToIndex`'s own \"already there\" test does NOT cover this: it only holds at\n * rest, and mid-gesture the delta is a real one. Nothing needs writing anyway —\n * the scroller is where the read-back read it, or on its way there under the\n * browser's own snapping.\n */\nlet readBack = false\n\n/**\n * Writes the DOM from the model. The deltas come from the RECTS, hence physical:\n * LTR, RTL and vertical all fall out with no direction test (the VTabs\n * `watch(model)` idiom). `behavior` is omitted so CSS `scroll-behavior` governs,\n * hence `prefers-reduced-motion`; `scrollBy?.()` is optional-called because jsdom\n * implements no scrolling.\n *\n * The LAST page is the exception it deliberately does not special-case: its index\n * names the slide that leads at the END of the track, whose start edge lies past\n * `scrollWidth - clientWidth`, so the request overshoots and the browser clamps it.\n * What makes the scroller REST there is the end-aligned last slide in the sheet.\n * Writing the clamped offset by hand would mean `scrollTo` and a signed `scrollLeft`,\n * the one thing the rect delta exists to avoid.\n */\nfunction scrollToIndex(index: number) {\n const port = viewportEl.value\n const slide = port?.querySelector<HTMLElement>(`[data-carousel-index='${index}']`)\n if (!port || !slide) return\n const target = slide.getBoundingClientRect()\n // The VIEWPORT's rect, not the stage's: every DOM read in this component is\n // viewport-scoped, and the `outside` gutter is padding on the root, so nothing here\n // has to know about it.\n const origin = port.getBoundingClientRect()\n const left = target.left - origin.left\n const top = target.top - origin.top\n /*\n * Already there — which is what a model change coming FROM the read-back looks\n * like. Arming the guard here would be the other way to strand it: no movement\n * means no `scrollend` to lower it again.\n */\n if (Math.abs(left) < 1 && Math.abs(top) < 1) return\n settling.value = true\n port.scrollBy?.({ left, top })\n}\n\nwatch(model, (index) => {\n if (readBack) return\n void nextTick(() => scrollToIndex(index))\n})\n\nconst observedIndex = ref<number>()\nconst measuredPages = ref<number>()\n\n/**\n * Slack, in pixels, on every comparison below. `scrollWidth` and `clientWidth` are\n * INTEGERS where the flex layout is fractional, so a position that is exactly\n * reachable can measure a hair short — and symmetrically a sub-pixel leftover must\n * never mint a page, or the dot count would change with the canvas width.\n */\nconst SLACK = 2\n\n/**\n * Reads the scroller ONCE and answers both questions from the same numbers: how many\n * positions it can rest on, and which one it is resting on now. They share every\n * intermediate value, and computing them apart is exactly what let them disagree.\n *\n * A position is a PAGE, not a slide. `scroll-snap-align: start` makes each slide's\n * start edge a position, but one lying past `scrollWidth - clientWidth` is\n * UNREACHABLE — the scroller clamps short of it — so a `peek` or an active\n * `itemMinSize` costs the last of them. What replaces it is the END of the track,\n * declared by `.v-carousel-slide:last-child { scroll-snap-align: end }` in the sheet\n * and counted here as one extra page whenever the leftover is more than rounding\n * noise. Without that page the last slide is never fully revealed: the scroller stops\n * a strip short of the end and no index asks it to go further.\n *\n * Page indices ARE slide indices, which is why nothing downstream translates: at\n * `p · step` slide `p` leads, and at the end of the track the leading fully visible\n * slide is `ceil(scrollable / step)`, which is `pages - 1` in both branches. The\n * indicator labels, the live region and `scrollToIndex` all keep reading the model as\n * a slide index.\n *\n * TRAP — the reading is POSITIONAL, and going back to an `intersectionRatio` would\n * bring back the bug it fixes. A ratio has to be DELIVERED to be read, and an observer\n * only delivers on a threshold crossing: with a `peek` the outgoing slide keeps a\n * strip's worth of slack and stays fully visible for the WHOLE of a backward scroll —\n * including at the destination — so every mid-flight reading names the page being\n * left, while the incoming slide, parked at 0.997 by a fractional layout, crosses\n * nothing on arrival. The symptom is a dot stuck one page ahead of the content.\n *\n * RECTS and the scroller's own sizes only, never `getComputedStyle`: this runs on\n * every frame of a smooth scroll. `step` and `offset` are both rect DELTAS, hence\n * physical and unsigned — RTL and vertical fall out with no direction test, the\n * `scrollToIndex` idiom, where `scrollLeft` would be negative in RTL.\n *\n * TRAP — `offset` assumes the viewport carries NO padding and NO border, so that\n * slide 0's start edge coincides with the port's at rest. The `outside` gutter is\n * padding on the ROOT for exactly that reason; give the viewport padding of its own\n * and both this reading and `scrollToIndex`'s delta pick up a constant bias, with\n * nothing to report it.\n */\nfunction measure(port: HTMLElement) {\n const boxes = port.querySelectorAll<HTMLElement>('[data-carousel-index]')\n const first = boxes[0]?.getBoundingClientRect()\n const second = boxes[1]?.getBoundingClientRect()\n if (!first || !second) return\n const origin = port.getBoundingClientRect()\n const vertical = isVertical.value\n const step = vertical ? Math.abs(second.top - first.top) : Math.abs(second.left - first.left)\n // No layout at all (jsdom, a display:none ancestor). Writing a 0 here would drag\n // every clamp down with it; the prop-derived fallback stays the answer until there\n // IS a layout.\n if (step <= 0) return\n // How far the scroller has travelled: the first slide's start edge has left the\n // port's by exactly that much.\n const offset = vertical ? Math.abs(first.top - origin.top) : Math.abs(first.left - origin.left)\n const scrollable = vertical\n ? port.scrollHeight - port.clientHeight\n : port.scrollWidth - port.clientWidth\n\n const starts = Math.floor((scrollable + SLACK) / step)\n const residual = scrollable - starts * step\n const pages = starts + 1 + (residual > SLACK ? 1 : 0)\n // The end of the track is recognized by POSITION and not by rounding: it is the one\n // page that is not a multiple of `step`, so rounding would name the start position\n // it falls short of — the page the user has just left.\n const page = offset >= scrollable - SLACK ? pages - 1 : Math.round(offset / step)\n\n measuredPages.value = pages\n /*\n * Clamped against `pageCount` and not against the local `pages`, because that is the\n * one which also caps at `count`, and the write above is what makes it fresh. A\n * slide LARGER than the port is the case that needs it: `starts` already reaches the\n * last slide there and the leftover still mints a page, so the raw answer names an\n * index no slide carries — `scrollToIndex` would then silently do nothing and\n * `settling` would never come back down.\n */\n observedIndex.value = clamp(page, 0, pageCount.value - 1)\n}\n\n// @ssr @fallback\n/**\n * SSR, jsdom and the first paint. `itemsPerView` is not a guess there, and it is exact\n * for a `peek` too: the strip costs the last START-aligned position and gives back the\n * END of the track, so the two cancel and the reachable count is\n * `count - itemsPerView + 1` either way. What still makes this a fallback rather than\n * the answer is an ACTIVE `itemMinSize`: fewer slides then fit than the prop asks for,\n * the flooring form over-counts, and only a measurement can tell. A pure function of\n * the props is also what keeps the dot list identical on the server and on the client —\n * measuring here would be a hydration mismatch.\n *\n * The clamp lives here rather than in `measure` for two reasons: a stale measurement\n * must not outlive the removal of a slide (`count` is reactive, the raw measurement is\n * not), and a slide larger than the port mints one page more than there are slides —\n * see the clamp `measure` takes against this computed.\n */\nconst pageCount = computed(() =>\n count.value === 0\n ? 0\n : clamp(measuredPages.value ?? count.value - props.itemsPerView + 1, 1, count.value),\n)\n\n/*\n * DOM → model, with ONE observer, which also carries the page measurement.\n *\n * TRAP — `1` must stay in `threshold`. Nothing READS an intersection ratio any more,\n * but the buckets are still what decides WHEN this callback runs, and this observer is\n * what makes the component cover a ROOT RESIZE — which an IntersectionObserver does\n * NOT do on its own (it queues an entry only when a threshold bucket is crossed):\n * `pageCount` changes exactly when the number of FULLY visible slides changes, which\n * crosses the 1.0 bucket, which queues the callback that re-measures. Drop the 1 and\n * the page count silently freezes on a resize. Its premise is that a slide's box never\n * exceeds the port on the cross axis, so the area ratio equals the scroll-axis ratio\n * and a slide becoming fully visible really does cross 1.0 — the CSS guarantees it.\n */\nwatch(\n [viewportEl, count],\n ([port], _previous, onCleanup) => {\n // @fallback\n // IntersectionObserver exists neither in SSR nor in jsdom: `scrollend` still\n // measures there, and the whole loop is verified in the browser (play functions).\n if (!port || typeof IntersectionObserver === 'undefined') return\n const observer = new IntersectionObserver(\n () => {\n measure(port)\n // The request has arrived, so there is nothing left to protect. This is also\n // the ONLY exit when the browser clamps a programmatic scroll to no movement\n // at all — `scrollend` never fires there.\n if (observedIndex.value === model.value) settling.value = false\n },\n { root: port, threshold: [0, 0.25, 0.5, 0.75, 1] },\n )\n for (const slide of port.querySelectorAll('[data-carousel-index]')) observer.observe(slide)\n onCleanup(() => observer.disconnect())\n },\n { flush: 'post' },\n)\n\n// Watching `settling` as well as the reading is the whole point of making it a ref:\n// whichever of the two lands last, the sync runs.\nwatch([observedIndex, settling], () => {\n const index = observedIndex.value\n if (settling.value || index === undefined || index === model.value) return\n readBack = true\n model.value = index\n /*\n * Lowered here and not inside `watch(model)`: a CONTROLLED v-model that refuses\n * the value fires no watcher at all, and the flag would then swallow the\n * consumer's next legitimate change. The pre-flush watcher runs inside the flush\n * this write schedules, a `nextTick` callback only after it — so it has read the\n * flag by the time this lands.\n */\n void nextTick(() => (readBack = false))\n})\n\n/*\n * The `loop` prop, resolved ONCE against what there is to loop through, because below\n * two positions it is not merely pointless but wrong twice over: the modulo would divide\n * by zero on an empty carousel, and on a single page it would hand the reader two enabled\n * buttons that move nothing — where the disabled pair says the truth. So the prop asks,\n * and this is the answer every consumer below reads.\n */\nconst looping = computed(() => props.loop && pageCount.value > 1)\n\n/*\n * Pure derivations, and they can be because `pageCount` never over-counts: index 0 is\n * always reachable, and so is `pageCount - 1` by construction. The observed ends this\n * replaces existed only to survive a model that could request an unreachable index —\n * which, with a correct page count, it no longer can. What that insured against was\n * autoplay-shaped (a false `atEnd` re-arms the timer on every bounce, forever), and\n * the `Pages` play function is what keeps that honest.\n *\n * Once a `peek` or an active floor makes the fit fractional, `pageCount - 1` is the\n * END of the track rather than a slide's start edge — a page all the same: `goTo` and\n * `End` reach it and `measure` reads it back.\n *\n * A looping carousel HAS no ends, which is the whole of what the prop changes here — and,\n * through `atEnd`, the whole of what it changes for autoplay too: `rotating` below already\n * reads this, so the timer keeps re-arming with not a line of its own. That is the same\n * \"false `atEnd` re-arms forever\" the paragraph above calls a bug, and it is one only\n * where the movement has nowhere to go: each re-arm here advances a page.\n */\nconst atStart = computed(() => !looping.value && model.value <= 0)\nconst atEnd = computed(() => !looping.value && model.value >= pageCount.value - 1)\n\nfunction goTo(index: number) {\n const pages = pageCount.value\n /*\n * TRAP — the double modulo is not superstition: `%` in JS keeps the sign of the\n * DIVIDEND, so `previous()` on page 0 gives `-1 % 5 === -1` and a single one would\n * hand the model an index no slide carries, whereupon `scrollToIndex` finds nothing\n * and the carousel stops dead with no error anywhere.\n *\n * Home and End (and every dot) pass an index already inside the range, where the\n * modulo is the identity — which is why they stay ABSOLUTE with no guard of their\n * own. Only a step off either edge, from the buttons, the arrows or autoplay, ever\n * has anything to wrap.\n *\n * `clamp` returns `min` on an empty interval, which is the right answer with no slide.\n */\n model.value = looping.value ? ((index % pages) + pages) % pages : clamp(index, 0, pages - 1)\n}\nconst previous = () => goTo(model.value - 1)\nconst next = () => goTo(model.value + 1)\n\n// @keyboard\n/**\n * The one keyboard concession, and it is not the one it looks like. A focused\n * scroll container DOES move on the arrows — but Chromium scrolls it by a fixed\n * pixel step, and MANDATORY snapping then pulls it straight back to the slide it\n * started on, so the net movement is zero. Home/End behave the same way.\n * (Covered by the `Keyboard` play function, verified red without this handler.)\n *\n * Contract: it moves the MODEL, never the scroller — the scroll then goes through\n * `scrollToIndex` like every other route, so there is a single write path.\n * `arrowNav` is not the tool: its job is moving focus between sibling controls,\n * and slides are neither focusable nor a list.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const port = viewportEl.value\n if (!port || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return\n\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault()\n goTo(event.key === 'Home' ? 0 : pageCount.value - 1)\n return\n }\n\n // Only the axis the carousel actually scrolls: the other one must stay with the\n // browser, which is what still scrolls a slide taller than the viewport.\n const steps: Record<string, number | undefined> = isVertical.value\n ? { ArrowUp: -1, ArrowDown: 1 }\n : { ArrowLeft: -1, ArrowRight: 1 }\n const step = steps[event.key]\n if (step === undefined) return\n event.preventDefault()\n // The INLINE arrows are physical, hence inverted in RTL (the `arrowNav` rule);\n // the block axis does not flip.\n const rtl = !isVertical.value && isRtl(port)\n goTo(model.value + (rtl ? -step : step))\n}\n\nconst { start, cancel } = useTimer()\nconst hovered = ref(false)\n// @a11y\n// KEYBOARD focus, not any focus, hence `isKeyboardFocus` rather than a bare `focusin` flag.\n// Clicking `next` leaves the focus on it, and a plain flag would then pause the rotation for\n// good — the user has to click outside the carousel to get it going again, which is not a\n// pause, it is a trap. What the pause is FOR is the keyboard user reading a slide.\nconst focused = ref(false)\n\nconst reducedMotion = ref(false)\n\n/*\n * Every reason to stop, gathered in ONE computed so a single watch re-arms the\n * timer (the single-instance idiom of VTooltip and VMenuItem).\n *\n * `autoplay > 0` is a GUARD, not a default: `useTimer` runs a delay ≤ 0\n * SYNCHRONOUSLY (the DS convention), and a synchronous callback bumping the model\n * would recurse until the stack blows. It is ALSO the consumer's stop control —\n * the prop is reactive, so binding it to `0` cancels the timer on the spot, which\n * is what a pause button of your own would drive.\n */\nconst rotating = computed(\n () =>\n props.autoplay > 0 && !hovered.value && !focused.value && !reducedMotion.value && !atEnd.value,\n)\n\n// `immediate`: without it the first delay would only be armed by a LATER change,\n// so an autoplay that nobody touches would never advance at all.\nwatch(\n [rotating, model],\n () => {\n cancel()\n if (rotating.value) start(next, props.autoplay)\n },\n { immediate: true },\n)\n\n// @a11y @ssr — WCAG 2.2.2. Client-only: the server has no `matchMedia`.\n/*\n * The DS's second browser-preference read (after VHotkeys' `navigator`), and it\n * is not redundant with the CSS media query: that one stops a transition, never a\n * TIMER, and WCAG 2.2.2 is about the content moving at all. Client only, listener\n * released on unmount.\n */\nlet releaseMotionQuery: (() => void) | undefined\nonMounted(() => {\n const query = window.matchMedia?.('(prefers-reduced-motion: reduce)')\n if (!query) return\n const sync = () => (reducedMotion.value = query.matches)\n sync()\n query.addEventListener('change', sync)\n releaseMotionQuery = () => query.removeEventListener('change', sync)\n})\nonBeforeUnmount(() => releaseMotionQuery?.())\n\n// @a11y\n/*\n * Announced only at rest: narrating an auto-rotating carousel floods the screen\n * reader (APG). The region itself stays mounted — a live container inserted at\n * the same time as its text is not announced (the VDataTable footer rule).\n */\nconst liveMessage = computed(() =>\n rotating.value || count.value === 0 ? '' : m.value.carousel.slide(model.value + 1, count.value),\n)\n\n// @devwarn\nif (isDev) {\n watchEffect(() => {\n if (props.effect === 'fade' && props.itemsPerView > 1)\n console.warn(\n '[VCarousel] `fade` needs one item per view: over a single view timeline every slide is counter-translated onto the same spot, so they would pile up. Downgraded to `slide`.',\n )\n if (props.effect === 'fade' && props.peek !== undefined)\n console.warn(\n '[VCarousel] `fade` and `peek` are mutually exclusive: the counter-translate parks every slide over the viewport, so the peeked strip is covered. Downgraded to `slide`.',\n )\n /*\n * Not a misuse — the combination is supported and does exactly what it says. What it\n * costs is the exemption the component leans on everywhere else: content that moves on\n * its own needs a way to stop it, and the five-second grace only ever applied because\n * the rotation ENDED. Looping, it does not, and hover and focus leave a touch user with\n * nothing. Hence a warning where the fix is a one-line binding rather than a button\n * this component would have to render for everyone.\n */\n if (props.loop && props.autoplay > 0)\n console.warn(\n '[VCarousel] `loop` with `autoplay` rotates for as long as the page is open, so WCAG 2.2.2 asks for a way to stop it. Bind `autoplay` to 0 from a control of your own.',\n )\n if (isVertical.value && props.height === undefined)\n console.warn(\n '[VCarousel] a vertical carousel needs a `height`: a percentage flex-basis has no definite reference on the block axis. Falling back to --vectis-control-size-carousel-block.',\n )\n if (!Number.isInteger(props.itemsPerView) || props.itemsPerView < 1)\n console.warn(\n `[VCarousel] \\`itemsPerView\\` must be an integer ≥ 1, got ${props.itemsPerView}.`,\n )\n })\n}\n</script>\n\n<template>\n <div\n class=\"v-carousel\"\n role=\"region\"\n :aria-roledescription=\"m.carousel.roleDescription\"\n :aria-label=\"ariaLabel\"\n :style=\"rootStyle\"\n :data-orientation=\"orientation\"\n :data-effect=\"resolvedEffect\"\n :data-controls=\"controls || undefined\"\n :data-indicators=\"indicators || undefined\"\n :data-controls-visibility=\"controlsVisibility\"\n @pointerenter=\"hovered = true\"\n @pointerleave=\"hovered = false\"\n @focusin=\"focused = isKeyboardFocus($event.target)\"\n @focusout=\"focused = false\"\n >\n <!--\n The stage holds the viewport, the controls and the autoplay control — and\n NOTHING else. The indicator bar is a sibling on purpose: inside this box it\n would join the height the controls are centred on, and the pair would sit\n visibly below the middle of the slides.\n -->\n <div class=\"v-carousel-stage\">\n <!--\n tabindex=\"0\" is MANDATORY, not defensive: a scroll container needs a\n TABBABLE descendant (axe `scrollable-region-focusable`) and slide content\n is arbitrary. It is also what makes the track the keyboard target of\n `onKeydown` — the browser's own arrow scrolling is real, but mandatory\n snapping undoes it, see there. A focusable box with an aria-label must\n carry a role, or axe reports `aria-prohibited-attr`.\n -->\n <div\n ref=\"viewportEl\"\n class=\"v-carousel-viewport\"\n role=\"group\"\n tabindex=\"0\"\n :aria-label=\"m.carousel.slides\"\n @keydown=\"onKeydown\"\n @scrollend=\"onScrollEnd\"\n >\n <component :is=\"Slides\" />\n </div>\n\n <slot\n name=\"controls\"\n :previous=\"previous\"\n :next=\"next\"\n :at-start=\"atStart\"\n :at-end=\"atEnd\"\n :index=\"model\"\n :count=\"count\"\n :page-count=\"pageCount\"\n :orientation=\"orientation\"\n >\n <div v-if=\"controls\" class=\"v-carousel-controls\">\n <VIconButton\n class=\"v-carousel-control\"\n :label=\"resolvedPrevLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n shape=\"circular\"\n elevated\n :disabled=\"atStart\"\n @click=\"previous\"\n >\n <VIcon v-bind=\"iconProps(resolvedPrevIcon)\" />\n </VIconButton>\n <VIconButton\n class=\"v-carousel-control\"\n :label=\"resolvedNextLabel\"\n variant=\"ghost\"\n tone=\"neutral\"\n shape=\"circular\"\n elevated\n :disabled=\"atEnd\"\n @click=\"next\"\n >\n <VIcon v-bind=\"iconProps(resolvedNextIcon)\" />\n </VIconButton>\n </div>\n </slot>\n </div>\n\n <slot\n name=\"indicators\"\n :index=\"model\"\n :count=\"count\"\n :page-count=\"pageCount\"\n :go-to=\"goTo\"\n :orientation=\"orientation\"\n >\n <div\n v-if=\"indicators\"\n class=\"v-carousel-indicators\"\n role=\"group\"\n :aria-label=\"m.carousel.indicators\"\n >\n <!--\n One control per REACHABLE position, not per slide: with 6 slides three at\n a time the scroller can only lead with 1 to 4, and dots 5 and 6 would\n scroll nowhere. With a `peek` the last of them parks the scroller at the\n END of the track rather than on a slide's start edge. Either way the label\n stays slide-based (\"4 of 6\"), naming the slide that LEADS there — which is\n what the control does — and it then agrees with the slide's own name and\n with the live region.\n -->\n <button\n v-for=\"index in pageCount\"\n :key=\"index\"\n type=\"button\"\n class=\"v-carousel-indicator\"\n :aria-label=\"m.carousel.slide(index, count)\"\n :aria-current=\"index - 1 === model ? 'true' : undefined\"\n @click=\"goTo(index - 1)\"\n >\n <slot name=\"indicator\" :index=\"index - 1\" :active=\"index - 1 === model\">\n <span class=\"v-carousel-dot\" />\n </slot>\n </button>\n </div>\n </slot>\n\n <span class=\"v-visually-hidden\" role=\"status\">{{ liveMessage }}</span>\n </div>\n</template>\n\n<style>\n@layer vectis.components {\n .v-carousel {\n /*\n * Geometry vector and direction sign. The effect keyframes are written on\n * them ONCE instead of being duplicated per orientation and per direction:\n * `translate` and `rotate3d()` are physical, and `calc(0 * -100%)` is a valid\n * zero.\n */\n --carousel-axis-x: 1;\n --carousel-axis-y: 0;\n --carousel-dir: 1;\n\n /*\n * Effect constants: private, non-contractual geometry with no theming story,\n * hence no --vectis-* token (the qualification rule still applies).\n */\n --carousel-tilt: 32deg;\n --carousel-depth: -6rem;\n --carousel-perspective: 60rem;\n --carousel-scale-min: 0.86;\n\n /* A true gutter, which is what --vectis-space-* is for. */\n --carousel-gap: var(--vectis-space-3);\n /* No floor by default: the itemsPerView share alone decides. */\n --carousel-item-min: 0px;\n --carousel-peek: 0px;\n --carousel-viewport-block: var(--vectis-control-size-carousel-block);\n /*\n * Room reserved on the SCROLL axis for the `outside` controls. `0px` and never\n * `0`: it feeds a `padding-*`, where a unitless zero is invalid — the\n * `--carousel-peek` precedent three lines up.\n */\n --carousel-outset: 0px;\n\n /* Positioning context of the `inside` indicator bar, which is deliberately NOT\n a child of the stage — see .v-carousel-stage. */\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-3);\n font-family: var(--vectis-text-family);\n }\n\n /*\n * The gutter is PADDING on the root: the component's footprint is unchanged and\n * the viewport narrows instead, so the slides' percentage flex-basis follows with\n * no branch and no second measurement.\n *\n * INVARIANT — always on the scroll axis, always SYMMETRIC. That is what lets every\n * `inside` inset below be written against the stage's edges with no compensation:\n * an absolutely positioned box resolves against the PADDING box, the edges those\n * insets pin to are on the cross axis (which this never touches), and the axis they\n * centre on stays symmetric. Make this one-sided and the `inside` indicator bar\n * goes off-centre with nothing to report it.\n */\n .v-carousel[data-orientation='horizontal'] {\n padding-inline: var(--carousel-outset);\n }\n\n .v-carousel[data-orientation='vertical'] {\n --carousel-axis-x: 0;\n --carousel-axis-y: 1;\n\n /* The indicator bar sits BESIDE the stage here, so the root's own axis follows\n the scroll axis. */\n flex-direction: row;\n padding-block: var(--carousel-outset);\n }\n\n /*\n * TRAP — `control-height-md` is the size the two VIconButtons actually render at:\n * they pass no `size`, so they take VIconButton's own `md` default and their width\n * is `--control-height`. The gutter is that button plus one gap, so the pair lands\n * flush inside the root's border box and never covers a slide. Give the buttons a\n * `size` and this line has to follow, or the pair either overlaps the first slide\n * or floats away from it — with no error anywhere.\n *\n * The `:has()` is not decoration: a consumer `#controls` slot replaces the whole\n * bar, and reserving two buttons' worth of padding for a bar nobody rendered would\n * inset the slides for nothing.\n */\n .v-carousel[data-controls='outside']:has(> .v-carousel-stage > .v-carousel-controls) {\n --carousel-outset: calc(var(--vectis-control-height-md) + var(--vectis-space-2));\n }\n\n /*\n * The scroll axis is physical, so RTL mirrors the transforms — and ONLY the\n * transforms: flex-basis and the logical `scroll-snap-type` keyword handle\n * themselves. One sign flips both the fade counter-translate and the coverflow\n * tilt. Scoped to `horizontal`: the block axis does not flip.\n */\n [dir='rtl'] .v-carousel[data-orientation='horizontal'] {\n --carousel-dir: -1;\n }\n\n /*\n * Positioning context of the controls and of the autoplay control — and of NOTHING\n * else. The indicator bar is a SIBLING on purpose: inside this box it would join\n * the height the controls are centred on, and an `inside` pair would sit visibly\n * below the middle of the slides. Kept a flex column so a consumer `#controls` slot\n * still stacks under the viewport with a gutter.\n */\n .v-carousel-stage {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--vectis-space-3);\n min-inline-size: 0;\n min-block-size: 0;\n }\n\n /*\n * Vertical ONLY. The root is a `row` there, so the inline axis is the flex MAIN\n * axis and the stage would shrink-wrap the widest slide's content — an `inside`\n * bar's `inset-inline-end` would then land on the ROOT's edge instead of the\n * slides'. Deliberately NOT applied in horizontal: the main axis is the block one\n * there, and growing into a consumer-set height would push the stage past the\n * viewport and re-centre the controls on empty space — the very bug this split\n * fixes.\n *\n * `flex-grow` and not `flex: 1`: the shorthand's `0` basis, together with the\n * min-size floors above, lets an auto-sized flex container collapse it.\n */\n .v-carousel[data-orientation='vertical'] .v-carousel-stage {\n flex-grow: 1;\n }\n\n .v-carousel-viewport {\n display: flex;\n gap: var(--carousel-gap);\n /*\n * `auto` on BOTH axes, never `auto hidden`: clipping the cross axis would crop\n * the focus ring of any focusable slide content.\n */\n overflow: auto;\n overscroll-behavior: contain;\n /* Logical keyword: RTL and vertical need no second declaration. */\n scroll-snap-type: inline mandatory;\n scroll-behavior: smooth;\n scrollbar-width: none;\n /* A flex item's automatic minimum would stop the viewport shrinking, hence scrolling. */\n min-inline-size: 0;\n min-block-size: 0;\n border-radius: var(--vectis-radius-surface);\n }\n\n .v-carousel-viewport::-webkit-scrollbar {\n display: none;\n }\n\n .v-carousel-viewport: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-carousel[data-orientation='vertical'] .v-carousel-viewport {\n flex-direction: column;\n scroll-snap-type: block mandatory;\n /*\n * A percentage flex-basis resolves against the container's MAIN size, which on\n * the block axis has nothing intrinsic here: without a definite one the basis\n * falls back to `auto` and every slide collapses onto its content.\n */\n block-size: var(--carousel-viewport-block);\n }\n\n .v-carousel-slide {\n /*\n * `flex-basis` and NOT `inline-size`: it is the one dimension that resolves on\n * the flex MAIN axis, hence on the scroll axis, in both orientations and both\n * directions — a logical property would still need a rule per orientation,\n * since `inline` follows the writing mode and not `flex-direction`.\n *\n * Arithmetic: N slides fully visible cost N-1 INNER gaps. `peek` is the whole\n * strip reserved past the Nth slide, its leading gap included (its JSDoc says\n * so) — that is what keeps the formula branch-free, `peek: 0` collapsing it\n * exactly to (100% - (N-1)·gap) / N. `max()` makes itemMinSize a floor, never\n * a cap, and IS the responsiveness: no breakpoint, no @container.\n */\n /*\n * LONGHANDS, never the `flex` shorthand — the `animation` rule further down, for\n * the same reason. A shorthand whose value contains `var()` becomes a PENDING\n * SUBSTITUTION value: it cannot be expanded until computed-value time, and if any\n * one of the four custom properties then resolves to something invalid the WHOLE\n * declaration is dropped and `flex` reverts to its initial `0 1 auto` — shrink 1\n * and basis auto, which sizes every slide on its content and destroys the snap\n * grid. As longhands a bad value can only cost the basis. It also stops devtools\n * showing the declaration struck through, since a pending shorthand is what it\n * cannot expand.\n */\n flex-grow: 0;\n flex-shrink: 0;\n flex-basis: max(\n var(--carousel-item-min),\n calc(\n (100% - (var(--carousel-per-view) - 1) * var(--carousel-gap) - var(--carousel-peek)) /\n var(--carousel-per-view)\n )\n );\n /* `auto` is a CONTENT-based floor that can push a flex item past its basis:\n one unbreakable word would desynchronize the whole snap grid. */\n min-inline-size: 0;\n min-block-size: 0;\n scroll-snap-align: start;\n position: relative;\n }\n\n /*\n * TRAP — the LAST slide is aligned on its END edge, and that is what declares the end\n * of the track as a snap position in its own right. As soon as a `peek` or an active\n * `itemMinSize` makes the fit fractional, that slide's START-aligned position lies\n * past `scrollWidth - clientWidth`, so the only position left near the end is a strip\n * short of it and the last slide is never fully revealed. `measure()` counts the end\n * of the track as its final page: delete this rule and the JS keeps offering a page\n * the scroller is no longer told it may hold.\n *\n * It is INSURANCE rather than the mechanism — Chromium clamps an out-of-range snap\n * position into the scrollable range anyway, which is what lets a `center`-aligned\n * carousel reach both of its extremes — but a measurement that depends on a clamping\n * artefact instead of on a declared position is exactly the kind of implicit contract\n * that breaks silently in another engine.\n *\n * It costs nothing in the two other regimes, and both are worth knowing before\n * touching it: when a slide is exactly the size of the port (one item per view, no\n * peek) the start-aligned and end-aligned offsets are the SAME number, and when a\n * slide is LARGER than the port the alignment is ignored altogether — an oversized\n * snap area makes every position covering the port valid.\n *\n * `end` is logical, like `scroll-snap-type: inline mandatory` above: RTL and the\n * vertical orientation need no second declaration, and the cross-axis half of the\n * shorthand is inert, only one axis carrying a snap type.\n */\n .v-carousel-slide:last-child {\n scroll-snap-align: end;\n }\n\n .v-carousel-effect {\n block-size: 100%;\n }\n\n /*\n * Effects — progressive enhancement. Without scroll-driven animations nothing\n * below is declared and the carousel is a plain `slide`; Firefox lands there.\n *\n * The TIMELINE is declared on the slide and the ANIMATION on its inner box, and\n * that split is load-bearing: a scroll-snap area is the element's TRANSFORMED\n * border box, so animating the slide itself would make its snap position depend\n * on the scroll position — a circular dependency whose symptom is jitter, with\n * no error anywhere. A named timeline is resolved by walking up the tree, so\n * each inner finds ITS OWN slide although they all share the ident.\n */\n @supports (view-timeline-name: --v) and (animation-range: cover) {\n .v-carousel:not([data-effect='slide']) .v-carousel-slide {\n view-timeline: --carousel-view inline;\n }\n\n .v-carousel[data-orientation='vertical']:not([data-effect='slide']) .v-carousel-slide {\n view-timeline: --carousel-view block;\n }\n\n .v-carousel:not([data-effect='slide']) .v-carousel-effect {\n /*\n * TRAP — longhands, never the `animation` shorthand: `animation-timeline`\n * and `animation-duration` are reset-only sub-properties, so a shorthand\n * written afterwards would silently put the timeline back to `auto` and the\n * duration to 0s, and every effect would vanish with no error.\n *\n * `cover` is the only range that spans the full viewport+slide traversal and\n * stays defined for a slide narrower, equal to or wider than the scrollport:\n * `contain` has length |V - S|, hence exactly ZERO at one item per view.\n *\n * `linear` is load-bearing too: the default `ease` re-maps the progress and\n * the fade counter-translate would no longer cancel the scroll travel.\n */\n animation-timeline: --carousel-view;\n animation-range: cover;\n animation-fill-mode: both;\n animation-timing-function: linear;\n /* `auto` is the whole timeline. A duration in seconds would be taken as a\n PROPORTION of it, and the effect would end a fraction of the way in. */\n animation-duration: auto;\n }\n\n .v-carousel[data-effect='fade'] .v-carousel-effect {\n animation-name: v-carousel-fade;\n }\n\n .v-carousel[data-effect='scale'] .v-carousel-effect {\n animation-name: v-carousel-scale;\n }\n\n .v-carousel[data-effect='cover'] .v-carousel-effect {\n animation-name: v-carousel-cover;\n }\n }\n\n /*\n * Over the `cover` range a slide's origin travels the whole viewport+slide\n * distance, so a counter-translate of ±100% of the slide's OWN size pins it on\n * the scrollport when the two are equal — which is why `fade` is defined at one\n * item per view only. The result is a true dissolve in place, gap included.\n */\n @keyframes v-carousel-fade {\n 0% {\n opacity: 0;\n translate: calc(var(--carousel-axis-x) * var(--carousel-dir) * -100%)\n calc(var(--carousel-axis-y) * -100%);\n }\n 50% {\n opacity: 1;\n translate: 0 0;\n }\n 100% {\n opacity: 0;\n translate: calc(var(--carousel-axis-x) * var(--carousel-dir) * 100%)\n calc(var(--carousel-axis-y) * 100%);\n }\n }\n\n /*\n * Geometry ONLY, no opacity dimming — and that is an accessibility decision, not\n * a taste one: a slide off the centre still holds real text, and fading it is a\n * measurable contrast loss that axe rightly reports. The scale (and the tilt of\n * `cover`) already carries the depth. `fade` keeps its opacity, which IS the\n * effect.\n */\n @keyframes v-carousel-scale {\n 0%,\n 100% {\n scale: var(--carousel-scale-min);\n }\n 50% {\n scale: 1;\n }\n }\n\n /*\n * `transform` and not the individual rotate/translate properties: perspective()\n * has to sit in the function list. A `perspective` PROPERTY on the viewport\n * would be inert — an `overflow: auto` box is forced to `transform-style: flat`,\n * so it can never be its children's 3D context.\n *\n * The rotation axis is deliberately swapped: a horizontal carousel (axis-x: 1)\n * tilts about Y, a vertical one about X.\n */\n @keyframes v-carousel-cover {\n 0% {\n transform: perspective(var(--carousel-perspective)) translateZ(var(--carousel-depth))\n rotate3d(\n var(--carousel-axis-y),\n var(--carousel-axis-x),\n 0,\n calc(var(--carousel-dir) * var(--carousel-tilt))\n );\n }\n 50% {\n transform: perspective(var(--carousel-perspective)) translateZ(0) rotate3d(0, 1, 0, 0deg);\n }\n 100% {\n transform: perspective(var(--carousel-perspective)) translateZ(var(--carousel-depth))\n rotate3d(\n var(--carousel-axis-y),\n var(--carousel-axis-x),\n 0,\n calc(var(--carousel-dir) * var(--carousel-tilt) * -1)\n );\n }\n }\n\n .v-carousel-controls {\n display: flex;\n /* A floor, not the layout — `space-between` places the pair. It only ever shows\n on a stage narrow enough to bring the two buttons together. */\n gap: var(--vectis-space-2);\n transition: opacity var(--vectis-duration-fast) var(--vectis-ease-default);\n }\n\n .v-carousel[data-orientation='vertical'] .v-carousel-controls {\n flex-direction: column;\n }\n\n /*\n * An arrow points at a physical direction, so the icon flips in RTL (the VTabs and\n * VPagination rule, word for word — what they share is the rule, not the glyph).\n * Horizontal only: the block axis does not mirror, so the vertical arrows are\n * already right.\n */\n [dir='rtl'] .v-carousel[data-orientation='horizontal'] .v-carousel-control .v-icon {\n scale: -1 1;\n }\n\n /*\n * BOTH placements are laid out of flow against the STAGE, and that is the whole\n * requirement: the pair is then centred on the slides alone, whatever the indicator\n * bar does. One `align-items: center` serves both orientations — it is the cross\n * axis in each. `pointer-events` is handed back to the buttons alone, so the strip\n * does not swallow a drag over the slides.\n *\n * Enumerated rather than a bare `[data-controls]`: a third placement has to opt in\n * by hand (the VTabs `:is()` rule). ORDER IS LOAD-BEARING — the per-placement blocks\n * below are (0,3,0) like this one.\n */\n .v-carousel:is([data-controls='inside'], [data-controls='outside']) .v-carousel-controls {\n position: absolute;\n inset: 0;\n align-items: center;\n justify-content: space-between;\n pointer-events: none;\n }\n\n .v-carousel[data-controls='inside'] .v-carousel-controls {\n inset: var(--vectis-space-2);\n }\n\n /*\n * `outside`: the pair is pulled out of the stage by exactly the gutter the root\n * reserved, so each button sits in that padding, one gap clear of the slides, still\n * centred on the stage's cross axis.\n *\n * RTL is FREE and needs no `--carousel-dir`: `inset-inline` is logical, the two\n * insets are equal so the box is direction-symmetric, and `space-between` puts\n * `previous` at the inline START — the right-hand side in RTL, where it belongs.\n */\n .v-carousel[data-controls='outside'] .v-carousel-controls {\n inset-inline: calc(-1 * var(--carousel-outset));\n }\n\n .v-carousel[data-orientation='vertical'][data-controls='outside'] .v-carousel-controls {\n inset-inline: 0;\n inset-block: calc(-1 * var(--carousel-outset));\n }\n\n /*\n * `hover` REVEALS the pair, it never removes it. `display: none` and\n * `visibility: hidden` would drop the buttons from the tab order AND from the\n * accessibility tree, where `opacity: 0` keeps both — the hidden-input rule. The\n * reveal costs no layout, so nothing shifts.\n *\n * The focus branch is read on the ROOT, so a keyboard user who has tabbed to the\n * track — or into a link inside a slide — sees the navigation before deciding\n * whether to use it. It is the same boundary autoplay pauses on, and both are read\n * the same way.\n *\n * `:has(:focus-visible)` and NOT `:focus-within`, which was a trap: clicking `next`\n * leaves the focus on it, so the pair stayed revealed until the user clicked\n * somewhere outside the carousel — the pointer had long since left. A pointer click\n * does not match `:focus-visible`, a Tab does, and that is precisely the case the\n * focus branch exists for.\n *\n * Behind `@media (hover: hover)`: a coarse pointer has no hover to give, so the\n * whole block is inert there and the pair stays permanently visible. NOT\n * `any-hover`, which is true as soon as any pointer capable of hovering is attached\n * and would strand exactly the users this protects.\n */\n @media (hover: hover) {\n .v-carousel[data-controls-visibility='hover'] .v-carousel-controls {\n opacity: 0;\n }\n\n .v-carousel[data-controls-visibility='hover']:hover .v-carousel-controls,\n .v-carousel[data-controls-visibility='hover']:has(:focus-visible) .v-carousel-controls {\n opacity: 1;\n }\n }\n\n .v-carousel-control {\n pointer-events: auto;\n }\n\n .v-carousel-indicators {\n display: flex;\n gap: var(--vectis-space-1);\n align-items: center;\n justify-content: center;\n }\n\n .v-carousel[data-orientation='vertical'] .v-carousel-indicators {\n flex-direction: column;\n }\n\n /*\n * `inside`: centred on the block-end edge, with NO surface of its own — a pill\n * behind the dots covers a slice of the slide the whole time, which is a lot of\n * media to spend on six 8px marks. The legibility moves into the dots instead\n * (see below), where it costs their own footprint and nothing more.\n */\n .v-carousel[data-indicators='inside'] .v-carousel-indicators {\n position: absolute;\n inset-block-end: var(--vectis-space-3);\n inset-inline: 0;\n margin-inline: auto;\n inline-size: fit-content;\n }\n\n .v-carousel[data-orientation='vertical'][data-indicators='inside'] .v-carousel-indicators {\n inset-block: 0;\n inset-inline: auto var(--vectis-space-3);\n block-size: fit-content;\n margin-block: auto;\n margin-inline: 0;\n }\n\n /*\n * The dot is 8px but the control is not: a 24px transparent hit area is what\n * satisfies `target-size` without inflating the visual.\n */\n .v-carousel-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n min-inline-size: var(--vectis-control-height-xs);\n min-block-size: var(--vectis-control-height-xs);\n padding: 0;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: var(--vectis-radius-pill);\n }\n\n .v-carousel-indicator:focus-visible {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(-1 * var(--vectis-focus-ring-width));\n }\n\n .v-carousel-dot {\n display: block;\n inline-size: var(--vectis-control-size-carousel-indicator);\n block-size: var(--vectis-control-size-carousel-indicator);\n background: var(--vectis-color-border-strong);\n border-radius: var(--vectis-radius-pill);\n transition:\n inline-size var(--vectis-duration-base) var(--vectis-ease-default),\n block-size var(--vectis-duration-base) var(--vectis-ease-default),\n background var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n .v-carousel-indicator:hover .v-carousel-dot {\n background: var(--vectis-color-text-subtle);\n }\n\n /* The current dot stretches into a pill ALONG THE SCROLL AXIS. */\n .v-carousel-indicator[aria-current] .v-carousel-dot {\n inline-size: var(--vectis-control-size-carousel-indicator-active);\n background: var(--vectis-color-accent);\n }\n\n .v-carousel[data-orientation='vertical'] .v-carousel-indicator[aria-current] .v-carousel-dot {\n inline-size: var(--vectis-control-size-carousel-indicator);\n block-size: var(--vectis-control-size-carousel-indicator-active);\n }\n\n /*\n * `inside` dots sit on the SLIDE, not on the page, so they are deliberately\n * theme-independent: their backdrop is arbitrary media, and `text-on-accent` is\n * the DS's \"drawn on top of a coloured surface\" colour — white in both themes,\n * exactly like the label on an accent button.\n *\n * The ring is what replaces the pill. A flat colour cannot be guaranteed against\n * an unknown image, so the dot carries BOTH halves of the classic pair: a white\n * fill for dark media and a dark hairline for light media. Drawn with\n * `box-shadow`, so it costs no layout and the dots stay 8px.\n *\n * `surface-inverse` for the ring rather than a colour primitive: it is dark in\n * BOTH themes (neutral-900 / neutral-800), which is the property the ring needs,\n * and it keeps this sheet on semantic tokens like every other component.\n *\n * Translucency is safe here where it was not on the bar: a dot holds no text, so\n * `color-contrast` never runs on it — the rule that made the bar opaque was about\n * text drawn OVER the bar, and there is none. What the ring answers is WCAG\n * 1.4.11, and it answers it on any backdrop rather than on a judged one.\n */\n .v-carousel[data-indicators='inside'] .v-carousel-dot {\n background: color-mix(in oklab, var(--vectis-color-text-on-accent) 55%, transparent);\n box-shadow: 0 0 0 1px color-mix(in oklab, var(--vectis-color-surface-inverse) 45%, transparent);\n }\n\n .v-carousel[data-indicators='inside'] .v-carousel-indicator:hover .v-carousel-dot,\n .v-carousel[data-indicators='inside'] .v-carousel-indicator[aria-current] .v-carousel-dot {\n background: var(--vectis-color-text-on-accent);\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * `animation: none` and not `animation-name: none`: it also drops the timeline\n * binding, so the effect stops sampling the scroller altogether.\n */\n .v-carousel-effect {\n animation: none;\n }\n\n .v-carousel-viewport {\n scroll-behavior: auto;\n }\n\n .v-carousel-controls,\n .v-carousel-dot {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|