vectis-ui 0.1.0 → 0.8.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/README.md +40 -6
- package/dist/components/VAccordion/VAccordion.css +1 -1
- package/dist/components/VAccordion/VAccordion.d.ts +9 -16
- package/dist/components/VAccordion/VAccordion.js.map +1 -1
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/VAccordion/VAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.css +1 -1
- package/dist/components/VAccordion/VAccordionItem.d.ts +33 -19
- package/dist/components/VAccordion/VAccordionItem.js.map +1 -1
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js +50 -38
- package/dist/components/VAccordion/VAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAccordion/context.d.ts +1 -8
- package/dist/components/VAccordion/context.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.css +1 -1
- package/dist/components/VAvatar/VAvatar.d.ts +44 -29
- package/dist/components/VAvatar/VAvatar.js.map +1 -1
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js +38 -35
- package/dist/components/VAvatar/VAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.d.ts +5 -16
- package/dist/components/VAvatar/VAvatarGroup.js.map +1 -1
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/VAvatar/VAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VAvatar/context.d.ts +6 -10
- package/dist/components/VAvatar/context.js.map +1 -1
- package/dist/components/VBadge/VBadge.css +1 -1
- package/dist/components/VBadge/VBadge.d.ts +31 -10
- package/dist/components/VBadge/VBadge.js.map +1 -1
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js +39 -24
- package/dist/components/VBadge/VBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.css +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.d.ts +4 -17
- package/dist/components/VBreadcrumb/VBreadcrumb.js.map +1 -1
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js +23 -25
- package/dist/components/VBreadcrumb/VBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButton.css +1 -1
- package/dist/components/VButton/VButton.d.ts +30 -10
- package/dist/components/VButton/VButton.js.map +1 -1
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js +39 -30
- package/dist/components/VButton/VButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.css +1 -1
- package/dist/components/VButton/VButtonGroup.d.ts +76 -13
- package/dist/components/VButton/VButtonGroup.js.map +1 -1
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js +74 -8
- package/dist/components/VButton/VButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VButton/context.d.ts +30 -0
- package/dist/components/VButton/context.js +6 -0
- package/dist/components/VButton/context.js.map +1 -0
- package/dist/components/VCalendar/VCalendar.css +1 -1
- package/dist/components/VCalendar/VCalendar.d.ts +50 -36
- package/dist/components/VCalendar/VCalendar.js.map +1 -1
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js +99 -85
- package/dist/components/VCalendar/VCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.css +1 -1
- package/dist/components/VCalendar/VCalendarEvent.d.ts +5 -11
- package/dist/components/VCalendar/VCalendarEvent.js.map +1 -1
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/components/VCalendar/VCalendarEvent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.css +1 -1
- package/dist/components/VCalendar/VCalendarMonth.d.ts +10 -13
- package/dist/components/VCalendar/VCalendarMonth.js.map +1 -1
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js +183 -244
- package/dist/components/VCalendar/VCalendarMonth.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.css +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.d.ts +15 -20
- package/dist/components/VCalendar/VCalendarTimeGrid.js.map +1 -1
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js +385 -448
- package/dist/components/VCalendar/VCalendarTimeGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.css +1 -1
- package/dist/components/VCalendar/VCalendarYear.js.map +1 -1
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js +53 -49
- package/dist/components/VCalendar/VCalendarYear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCalendar/gesture.d.ts +158 -0
- package/dist/components/VCalendar/gesture.js +170 -0
- package/dist/components/VCalendar/gesture.js.map +1 -0
- package/dist/components/VCalendar/keyboard.d.ts +9 -3
- package/dist/components/VCalendar/keyboard.js +2 -6
- package/dist/components/VCalendar/keyboard.js.map +1 -1
- package/dist/components/VCalendar/layout.d.ts +67 -54
- package/dist/components/VCalendar/layout.js +77 -69
- package/dist/components/VCalendar/layout.js.map +1 -1
- package/dist/components/VCalendar/timeGrid.d.ts +55 -0
- package/dist/components/VCalendar/timeGrid.js +71 -0
- package/dist/components/VCalendar/timeGrid.js.map +1 -0
- package/dist/components/VCalendar/types.d.ts +41 -16
- package/dist/components/VCarousel/VCarousel.css +1 -1
- package/dist/components/VCarousel/VCarousel.d.ts +21 -41
- package/dist/components/VCarousel/VCarousel.js.map +1 -1
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js +157 -129
- package/dist/components/VCarousel/VCarousel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.d.ts +0 -17
- package/dist/components/VCarousel/VCarouselItem.js.map +1 -1
- package/dist/components/VCarousel/VCarouselItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCarousel/context.d.ts +0 -12
- package/dist/components/VCarousel/context.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.css +1 -1
- package/dist/components/VCheckbox/VCheckbox.d.ts +31 -16
- package/dist/components/VCheckbox/VCheckbox.js.map +1 -1
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js +62 -29
- package/dist/components/VCheckbox/VCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VChip/VChip.css +1 -1
- package/dist/components/VChip/VChip.d.ts +36 -26
- package/dist/components/VChip/VChip.js.map +1 -1
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js +57 -48
- package/dist/components/VChip/VChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.css +1 -1
- package/dist/components/VCombobox/VCombobox.d.ts +127 -31
- package/dist/components/VCombobox/VCombobox.js.map +1 -1
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js +336 -247
- package/dist/components/VCombobox/VCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.css +1 -1
- package/dist/components/VCombobox/VComboboxGroup.d.ts +0 -9
- package/dist/components/VCombobox/VComboboxGroup.js.map +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/VCombobox/VComboboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxOption.css +1 -1
- package/dist/components/VCombobox/VComboboxOption.d.ts +0 -15
- package/dist/components/VCombobox/VComboboxOption.js.map +1 -1
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VCombobox/VComboboxOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/VComboboxSeparator.js.map +1 -1
- package/dist/components/VCombobox/VComboboxSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VCombobox/infiniteScroll.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.css +1 -1
- package/dist/components/VDataTable/VDataTable.d.ts +50 -28
- package/dist/components/VDataTable/VDataTable.js.map +1 -1
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js +183 -194
- package/dist/components/VDataTable/VDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.css +1 -1
- package/dist/components/VDateInput/VDateInput.d.ts +90 -42
- package/dist/components/VDateInput/VDateInput.js.map +1 -1
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js +159 -191
- package/dist/components/VDateInput/VDateInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.css +1 -1
- package/dist/components/VDatePicker/VDatePicker.d.ts +61 -30
- package/dist/components/VDatePicker/VDatePicker.js.map +1 -1
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js +243 -221
- package/dist/components/VDatePicker/VDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDialog/VDialog.css +1 -1
- package/dist/components/VDialog/VDialog.d.ts +45 -33
- package/dist/components/VDialog/VDialog.js.map +1 -1
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js +65 -64
- package/dist/components/VDialog/VDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VDialog/VDialogAlert.d.ts +24 -20
- package/dist/components/VDialog/VDialogAlert.js.map +1 -1
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js +36 -25
- package/dist/components/VDialog/VDialogAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.css +1 -1
- package/dist/components/VFileInput/VFileInput.d.ts +78 -26
- package/dist/components/VFileInput/VFileInput.js.map +1 -1
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js +144 -132
- package/dist/components/VFileInput/VFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.css +1 -1
- package/dist/components/VFilePicker/VFilePicker.d.ts +47 -30
- package/dist/components/VFilePicker/VFilePicker.js.map +1 -1
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js +166 -163
- package/dist/components/VFilePicker/VFilePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VFilePicker/fileKind.d.ts +2 -27
- package/dist/components/VFilePicker/fileKind.js +9 -8
- package/dist/components/VFilePicker/fileKind.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.css +1 -1
- package/dist/components/VHotkeys/VHotkeys.d.ts +8 -30
- package/dist/components/VHotkeys/VHotkeys.js.map +1 -1
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VHotkeys/VHotkeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VHotkeys/platform.js.map +1 -1
- package/dist/components/VIcon/VIcon.css +1 -1
- package/dist/components/VIcon/VIcon.d.ts +15 -6
- package/dist/components/VIcon/VIcon.js.map +1 -1
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js +45 -37
- package/dist/components/VIcon/VIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VIcon/iconProps.js.map +1 -1
- package/dist/components/VIcon/icons/index.d.ts +1 -1
- package/dist/components/VIcon/icons/index.js.map +1 -1
- package/dist/components/VIcon/icons/names.d.ts +1 -1
- package/dist/components/VIcon/icons/names.js.map +1 -1
- package/dist/components/VIcon/resolver.d.ts +3 -3
- package/dist/components/VIcon/resolver.js.map +1 -1
- package/dist/components/VIcon/types.d.ts +12 -12
- package/dist/components/VIconButton/VIconButton.css +1 -1
- package/dist/components/VIconButton/VIconButton.d.ts +28 -11
- package/dist/components/VIconButton/VIconButton.js.map +1 -1
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js +26 -20
- package/dist/components/VIconButton/VIconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInput.css +1 -1
- package/dist/components/VInput/VInput.d.ts +26 -7
- package/dist/components/VInput/VInput.js.map +1 -1
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js +86 -75
- package/dist/components/VInput/VInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VInput/VInputGroup.css +2 -0
- package/dist/components/VInput/VInputGroup.d.ts +47 -0
- package/dist/components/VInput/VInputGroup.js +9 -0
- package/dist/components/VInput/VInputGroup.js.map +1 -0
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js +80 -0
- package/dist/components/VInput/VInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/VInput/context.d.ts +11 -0
- package/dist/components/VInput/context.js +6 -0
- package/dist/components/VInput/context.js.map +1 -0
- package/dist/components/VInputOTP/VInputOTP.css +1 -1
- package/dist/components/VInputOTP/VInputOTP.d.ts +37 -22
- package/dist/components/VInputOTP/VInputOTP.js.map +1 -1
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js +98 -61
- package/dist/components/VInputOTP/VInputOTP.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenu.d.ts +23 -30
- package/dist/components/VMenu/VMenu.js.map +1 -1
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js +31 -27
- package/dist/components/VMenu/VMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.css +1 -1
- package/dist/components/VMenu/VMenuGroup.d.ts +12 -8
- package/dist/components/VMenu/VMenuGroup.js.map +1 -1
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js +11 -11
- package/dist/components/VMenu/VMenuGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.css +1 -1
- package/dist/components/VMenu/VMenuItem.d.ts +11 -19
- package/dist/components/VMenu/VMenuItem.js.map +1 -1
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js +65 -57
- package/dist/components/VMenu/VMenuItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.d.ts +14 -30
- package/dist/components/VMenu/VMenuPanel.js.map +1 -1
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js +43 -44
- package/dist/components/VMenu/VMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VMenu/context.d.ts +2 -6
- package/dist/components/VMenu/context.js.map +1 -1
- package/dist/components/VPagination/VPagination.css +1 -1
- package/dist/components/VPagination/VPagination.d.ts +60 -22
- package/dist/components/VPagination/VPagination.js.map +1 -1
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js +113 -161
- package/dist/components/VPagination/VPagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VPopover/VPopover.css +1 -1
- package/dist/components/VPopover/VPopover.d.ts +26 -7
- package/dist/components/VPopover/VPopover.js.map +1 -1
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js +43 -37
- package/dist/components/VPopover/VPopover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.css +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.d.ts +15 -4
- package/dist/components/VProgressCircular/VProgressCircular.js.map +1 -1
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js +32 -30
- package/dist/components/VProgressCircular/VProgressCircular.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.css +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.d.ts +23 -8
- package/dist/components/VProgressLinear/VProgressLinear.js.map +1 -1
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js +34 -32
- package/dist/components/VProgressLinear/VProgressLinear.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VRadio/VRadio.css +1 -1
- package/dist/components/VRadio/VRadio.d.ts +36 -18
- package/dist/components/VRadio/VRadio.js.map +1 -1
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js +55 -26
- package/dist/components/VRadio/VRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.d.ts +4 -2
- package/dist/components/VSeparator/VSeparator.js.map +1 -1
- package/dist/components/VSeparator/VSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.d.ts +5 -19
- package/dist/components/VSideNavigation/VSideNavigation.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/VSideNavigation/VSideNavigation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.d.ts +9 -17
- package/dist/components/VSideNavigation/VSideNavigationGroup.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/VSideNavigation/VSideNavigationGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.css +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.d.ts +22 -30
- package/dist/components/VSideNavigation/VSideNavigationItem.js.map +1 -1
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js +77 -87
- package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSideNavigation/context.d.ts +0 -14
- package/dist/components/VSideNavigation/context.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.css +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.d.ts +9 -9
- package/dist/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
- package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSlider/VSlider.css +1 -1
- package/dist/components/VSlider/VSlider.d.ts +52 -27
- package/dist/components/VSlider/VSlider.js.map +1 -1
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js +202 -118
- package/dist/components/VSlider/VSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.css +1 -1
- package/dist/components/VSnackbar/VSnackbar.d.ts +0 -23
- package/dist/components/VSnackbar/VSnackbar.js.map +1 -1
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js +38 -38
- package/dist/components/VSnackbar/VSnackbar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSnackbar/state.d.ts +0 -27
- package/dist/components/VSnackbar/state.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.css +1 -1
- package/dist/components/VSpinner/VSpinner.d.ts +6 -6
- package/dist/components/VSpinner/VSpinner.js.map +1 -1
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js +10 -9
- package/dist/components/VSpinner/VSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.css +1 -1
- package/dist/components/VSwitch/VSwitch.d.ts +35 -13
- package/dist/components/VSwitch/VSwitch.js.map +1 -1
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js +62 -21
- package/dist/components/VSwitch/VSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTab.css +1 -1
- package/dist/components/VTabs/VTab.d.ts +12 -12
- package/dist/components/VTabs/VTab.js.map +1 -1
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js +36 -24
- package/dist/components/VTabs/VTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTabPanel.d.ts +2 -10
- package/dist/components/VTabs/VTabPanel.js.map +1 -1
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/VTabs/VTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/VTabs.css +1 -1
- package/dist/components/VTabs/VTabs.d.ts +27 -18
- package/dist/components/VTabs/VTabs.js.map +1 -1
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js +92 -81
- package/dist/components/VTabs/VTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTabs/context.d.ts +9 -19
- package/dist/components/VTabs/context.js +1 -1
- package/dist/components/VTabs/context.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.css +1 -1
- package/dist/components/VTextarea/VTextarea.d.ts +34 -6
- package/dist/components/VTextarea/VTextarea.js.map +1 -1
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js +91 -74
- package/dist/components/VTextarea/VTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.css +1 -1
- package/dist/components/VTimeInput/VTimeInput.d.ts +123 -33
- package/dist/components/VTimeInput/VTimeInput.js.map +1 -1
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js +294 -291
- package/dist/components/VTimeInput/VTimeInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimeInput/search.d.ts +24 -0
- package/dist/components/VTimeInput/search.js +22 -0
- package/dist/components/VTimeInput/search.js.map +1 -0
- package/dist/components/VTimePicker/VTimePicker.css +1 -1
- package/dist/components/VTimePicker/VTimePicker.d.ts +51 -30
- package/dist/components/VTimePicker/VTimePicker.js.map +1 -1
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js +216 -151
- package/dist/components/VTimePicker/VTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTimePicker/limits.d.ts +88 -0
- package/dist/components/VTimePicker/limits.js +70 -0
- package/dist/components/VTimePicker/limits.js.map +1 -0
- package/dist/components/VToast/VToast.css +1 -1
- package/dist/components/VToast/VToast.d.ts +0 -10
- package/dist/components/VToast/VToast.js.map +1 -1
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js +10 -10
- package/dist/components/VToast/VToast.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/VToaster.css +1 -1
- package/dist/components/VToast/VToaster.d.ts +0 -17
- package/dist/components/VToast/VToaster.js.map +1 -1
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js +29 -28
- package/dist/components/VToast/VToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToast/state.d.ts +10 -19
- package/dist/components/VToast/state.js +1 -1
- package/dist/components/VToast/state.js.map +1 -1
- package/dist/components/VToggle/VToggle.css +1 -1
- package/dist/components/VToggle/VToggle.d.ts +56 -11
- package/dist/components/VToggle/VToggle.js.map +1 -1
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js +80 -46
- package/dist/components/VToggle/VToggle.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.d.ts +16 -2
- package/dist/components/VToggle/VToggleItem.js +0 -2
- package/dist/components/VToggle/VToggleItem.js.map +1 -1
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js +23 -15
- package/dist/components/VToggle/VToggleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VToggle/context.d.ts +4 -24
- package/dist/components/VToggle/context.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.css +1 -1
- package/dist/components/VTooltip/VTooltip.d.ts +9 -33
- package/dist/components/VTooltip/VTooltip.js.map +1 -1
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js +28 -24
- package/dist/components/VTooltip/VTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/VTypography/VTypography.js.map +1 -1
- package/dist/components/VTypography/VTypography.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/useAriaLabel.d.ts +0 -17
- package/dist/composables/useAriaLabel.js.map +1 -1
- package/dist/composables/useClearable.d.ts +42 -0
- package/dist/composables/useClearable.js +19 -0
- package/dist/composables/useClearable.js.map +1 -0
- package/dist/composables/useControlShape.d.ts +22 -0
- package/dist/composables/useControlShape.js +13 -0
- package/dist/composables/useControlShape.js.map +1 -0
- package/dist/composables/useDetailsOpen.d.ts +22 -0
- package/dist/composables/useDetailsOpen.js +21 -0
- package/dist/composables/useDetailsOpen.js.map +1 -0
- package/dist/composables/useFieldIds.d.ts +0 -15
- package/dist/composables/useFieldIds.js +8 -7
- package/dist/composables/useFieldIds.js.map +1 -1
- package/dist/composables/useFieldPanel.d.ts +21 -18
- package/dist/composables/useFieldPanel.js +43 -23
- package/dist/composables/useFieldPanel.js.map +1 -1
- package/dist/composables/useFileDrop.d.ts +0 -22
- package/dist/composables/useFileDrop.js.map +1 -1
- package/dist/composables/useFileField.d.ts +45 -17
- package/dist/composables/useFileField.js +40 -20
- package/dist/composables/useFileField.js.map +1 -1
- package/dist/composables/useFocusoutDismiss.d.ts +0 -15
- package/dist/composables/useFocusoutDismiss.js.map +1 -1
- package/dist/composables/useIconClickHandlers.d.ts +29 -14
- package/dist/composables/useIconClickHandlers.js +15 -5
- package/dist/composables/useIconClickHandlers.js.map +1 -1
- package/dist/composables/useInertLink.d.ts +20 -0
- package/dist/composables/useInertLink.js +23 -0
- package/dist/composables/useInertLink.js.map +1 -0
- package/dist/composables/useMaskedField.d.ts +33 -10
- package/dist/composables/useMaskedField.js +45 -1
- package/dist/composables/useMaskedField.js.map +1 -1
- package/dist/composables/usePopover.d.ts +15 -1
- package/dist/composables/usePopover.js +23 -8
- package/dist/composables/usePopover.js.map +1 -1
- package/dist/composables/useProgressValue.d.ts +5 -8
- package/dist/composables/useProgressValue.js +6 -3
- package/dist/composables/useProgressValue.js.map +1 -1
- package/dist/composables/useRootAttrs.d.ts +12 -19
- package/dist/composables/useRootAttrs.js.map +1 -1
- package/dist/composables/useTimer.d.ts +8 -10
- package/dist/composables/useTimer.js.map +1 -1
- package/dist/i18n/en.d.ts +2 -10
- package/dist/i18n/en.js +18 -19
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.d.ts +2 -18
- package/dist/i18n/fr.js +18 -19
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/state.d.ts +44 -47
- package/dist/i18n/state.js +20 -17
- package/dist/i18n/state.js.map +1 -1
- package/dist/i18n/types.d.ts +53 -44
- package/dist/icons.d.ts +3 -3
- package/dist/index.d.ts +43 -17
- package/dist/index.js +45 -44
- package/dist/styles.css +1 -1
- package/dist/tokens/css.js.map +1 -1
- package/dist/tokens/index.d.ts +5 -1
- package/dist/tokens/primitives.js.map +1 -1
- package/dist/tokens/semantic.d.ts +5 -1
- package/dist/tokens/semantic.js +6 -2
- package/dist/tokens/semantic.js.map +1 -1
- package/dist/tokens/themes/dark.js.map +1 -1
- package/dist/tokens/types.d.ts +7 -15
- package/dist/tokens/types.js.map +1 -1
- package/dist/tokens.json +25 -5
- package/dist/types.d.ts +24 -0
- package/dist/utils/array.d.ts +3 -6
- package/dist/utils/array.js.map +1 -1
- package/dist/utils/arrowNav.d.ts +17 -17
- package/dist/utils/arrowNav.js +5 -3
- package/dist/utils/arrowNav.js.map +1 -1
- package/dist/utils/chip.d.ts +11 -15
- package/dist/utils/chip.js.map +1 -1
- package/dist/utils/css.d.ts +22 -11
- package/dist/utils/css.js +5 -2
- package/dist/utils/css.js.map +1 -1
- package/dist/utils/date.d.ts +42 -19
- package/dist/utils/date.js +97 -98
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/direction.d.ts +6 -12
- package/dist/utils/direction.js.map +1 -1
- package/dist/utils/env.d.ts +5 -6
- package/dist/utils/file.d.ts +46 -58
- package/dist/utils/file.js +43 -36
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/focus.d.ts +8 -17
- package/dist/utils/focus.js.map +1 -1
- package/dist/utils/hostWarns.d.ts +12 -0
- package/dist/utils/hostWarns.js +6 -0
- package/dist/utils/hostWarns.js.map +1 -0
- package/dist/utils/ids.d.ts +10 -0
- package/dist/utils/ids.js +8 -0
- package/dist/utils/ids.js.map +1 -0
- package/dist/utils/matcher.d.ts +5 -9
- package/dist/utils/matcher.js.map +1 -1
- package/dist/utils/memo.d.ts +12 -0
- package/dist/utils/memo.js +9 -0
- package/dist/utils/memo.js.map +1 -0
- package/dist/utils/number.d.ts +3 -4
- package/dist/utils/number.js.map +1 -1
- package/dist/utils/text.d.ts +20 -9
- package/dist/utils/text.js +17 -3
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/time.d.ts +53 -61
- package/dist/utils/time.js +49 -45
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/vnode.d.ts +8 -15
- package/dist/utils/vnode.js.map +1 -1
- package/package.json +6 -6
- package/dist/components/VToggle/VToggleItem.css +0 -2
package/dist/components/VSideNavigation/VSideNavigationItem.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,37 +1,33 @@
|
|
|
1
|
-
import e from "../VIcon/
|
|
2
|
-
import
|
|
1
|
+
import { iconProps as e } from "../VIcon/iconProps.js";
|
|
2
|
+
import t from "../VIcon/VIcon.js";
|
|
3
3
|
import { expand_more as n } from "../VIcon/icons/expand_more.js";
|
|
4
4
|
import { useRootAttrs as r } from "../../composables/useRootAttrs.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { useDetailsOpen as i } from "../../composables/useDetailsOpen.js";
|
|
6
|
+
import { sideNavigationKey as a } from "./context.js";
|
|
7
|
+
import { computed as o, createBlock as s, createCommentVNode as c, createElementBlock as l, createElementVNode as u, createVNode as d, defineComponent as f, h as p, inject as m, mergeModels as h, mergeProps as g, normalizeClass as _, normalizeStyle as v, openBlock as y, provide as b, renderSlot as x, resolveDynamicComponent as S, unref as C, useId as w, useModel as T, useSlots as E, withCtx as D } from "vue";
|
|
7
8
|
//#region src/components/VSideNavigation/VSideNavigationItem.vue?vue&type=script&setup=true&lang.ts
|
|
8
|
-
var
|
|
9
|
+
var O = [
|
|
9
10
|
"name",
|
|
10
11
|
"open",
|
|
11
12
|
"data-swap"
|
|
12
|
-
],
|
|
13
|
-
"data-
|
|
13
|
+
], k = [
|
|
14
|
+
"data-current",
|
|
14
15
|
"data-disabled",
|
|
15
16
|
"aria-current",
|
|
16
17
|
"aria-disabled",
|
|
17
18
|
"tabindex"
|
|
18
|
-
],
|
|
19
|
-
key: 0,
|
|
20
|
-
class: "v-side-nav-sublabel"
|
|
21
|
-
}, M = { class: "v-side-nav-children" }, N = ["data-active", "data-disabled"], P = { class: "v-side-nav-content" }, F = { class: "v-side-nav-label" }, I = {
|
|
22
|
-
key: 0,
|
|
23
|
-
class: "v-side-nav-sublabel"
|
|
24
|
-
}, L = {
|
|
19
|
+
], A = { class: "v-side-nav-children" }, j = ["data-current", "data-disabled"], M = {
|
|
25
20
|
key: 0,
|
|
26
21
|
class: "v-side-nav-end"
|
|
27
|
-
},
|
|
22
|
+
}, N = /*@__PURE__*/ f({
|
|
28
23
|
inheritAttrs: !1,
|
|
29
24
|
__name: "VSideNavigationItem",
|
|
30
|
-
props: /*@__PURE__*/
|
|
25
|
+
props: /*@__PURE__*/ h({
|
|
26
|
+
label: { default: void 0 },
|
|
31
27
|
sublabel: { default: void 0 },
|
|
32
28
|
icon: { default: void 0 },
|
|
33
29
|
href: { default: void 0 },
|
|
34
|
-
|
|
30
|
+
current: {
|
|
35
31
|
type: Boolean,
|
|
36
32
|
default: !1
|
|
37
33
|
},
|
|
@@ -50,105 +46,99 @@ var D = [
|
|
|
50
46
|
},
|
|
51
47
|
openModifiers: {}
|
|
52
48
|
}),
|
|
53
|
-
emits: /*@__PURE__*/
|
|
54
|
-
setup(f, { emit:
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
let t = e.target.open;
|
|
73
|
-
z.value !== t && (z.value = t);
|
|
49
|
+
emits: /*@__PURE__*/ h(["select"], ["update:open"]),
|
|
50
|
+
setup(f, { emit: h }) {
|
|
51
|
+
let N = f, P = T(f, "open"), F = h, { rootClass: I, rootStyle: L, forwardedAttrs: R } = r(), z = E(), B = o(() => !!z.children), V = o(() => !B.value && N.href !== void 0 ? "a" : "button"), H = m(a, null), U = o(() => H?.expandIcon ?? n), W = o(() => H?.collapseIcon);
|
|
52
|
+
if (z.children) {
|
|
53
|
+
let e = w();
|
|
54
|
+
b(a, {
|
|
55
|
+
get name() {
|
|
56
|
+
return H?.exclusive ? e : void 0;
|
|
57
|
+
},
|
|
58
|
+
get exclusive() {
|
|
59
|
+
return H?.exclusive ?? !1;
|
|
60
|
+
},
|
|
61
|
+
get expandIcon() {
|
|
62
|
+
return U.value;
|
|
63
|
+
},
|
|
64
|
+
get collapseIcon() {
|
|
65
|
+
return W.value;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
74
68
|
}
|
|
75
|
-
let
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
69
|
+
let { openAttr: G, onToggle: K, onSummaryClick: q } = i(P, {
|
|
70
|
+
defaultOpen: () => N.defaultOpen,
|
|
71
|
+
disabled: () => N.disabled
|
|
72
|
+
}), J = o(() => N.current ? V.value === "a" ? "page" : "true" : void 0), Y = () => [x(z, "icon", {}, () => N.icon ? [p(t, {
|
|
73
|
+
class: "v-side-nav-icon",
|
|
74
|
+
...e(N.icon)
|
|
75
|
+
})] : []), p("span", { class: "v-side-nav-content" }, [p("span", { class: "v-side-nav-label" }, [x(z, "default", {}, () => [N.label])]), N.sublabel !== void 0 || z.sublabel ? p("span", { class: "v-side-nav-sublabel" }, [x(z, "sublabel", {}, () => [N.sublabel])]) : null])];
|
|
76
|
+
function X(e) {
|
|
80
77
|
e.target?.closest("button, a, input, select, textarea, [tabindex]") || e.preventDefault();
|
|
81
78
|
}
|
|
82
|
-
function
|
|
83
|
-
if (
|
|
79
|
+
function Z(e) {
|
|
80
|
+
if (N.disabled) {
|
|
84
81
|
e.preventDefault();
|
|
85
82
|
return;
|
|
86
83
|
}
|
|
87
|
-
|
|
84
|
+
F("select");
|
|
88
85
|
}
|
|
89
|
-
return (n, r) => (
|
|
90
|
-
class:
|
|
91
|
-
style:
|
|
92
|
-
}, [
|
|
86
|
+
return (n, r) => (y(), l("li", {
|
|
87
|
+
class: _(["v-side-nav-item", C(I)]),
|
|
88
|
+
style: v(C(L))
|
|
89
|
+
}, [B.value ? (y(), l("details", {
|
|
93
90
|
key: 0,
|
|
94
|
-
class: "v-side-nav-branch",
|
|
95
|
-
name: C(
|
|
96
|
-
open:
|
|
97
|
-
"data-swap":
|
|
98
|
-
onToggle:
|
|
99
|
-
}, [
|
|
91
|
+
class: "v-side-nav-branch v-disclosure",
|
|
92
|
+
name: C(H)?.name,
|
|
93
|
+
open: C(G),
|
|
94
|
+
"data-swap": W.value ? "" : void 0,
|
|
95
|
+
onToggle: r[1] ||= (...e) => C(K) && C(K)(...e)
|
|
96
|
+
}, [u("summary", g(C(R), {
|
|
100
97
|
class: "v-side-nav-row",
|
|
101
|
-
"data-
|
|
98
|
+
"data-current": f.current ? "" : void 0,
|
|
102
99
|
"data-disabled": f.disabled ? "" : void 0,
|
|
103
|
-
"aria-current":
|
|
100
|
+
"aria-current": J.value,
|
|
104
101
|
"aria-disabled": f.disabled || void 0,
|
|
105
102
|
tabindex: f.disabled ? -1 : void 0,
|
|
106
|
-
onClick:
|
|
103
|
+
onClick: r[0] ||= (...e) => C(q) && C(q)(...e)
|
|
107
104
|
}), [
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
class: "v-side-nav-icon"
|
|
111
|
-
}, C(t)(f.icon)), null, 16)) : s("", !0)]),
|
|
112
|
-
l("span", k, [l("span", A, [b(n.$slots, "default")]), f.sublabel !== void 0 || n.$slots.sublabel ? (v(), c("span", j, [b(n.$slots, "sublabel", {}, () => [u(S(f.sublabel), 1)])])) : s("", !0)]),
|
|
113
|
-
n.$slots.end ? (v(), c("span", {
|
|
105
|
+
d(Y),
|
|
106
|
+
n.$slots.end ? (y(), l("span", {
|
|
114
107
|
key: 0,
|
|
115
108
|
class: "v-side-nav-end",
|
|
116
|
-
onClick:
|
|
117
|
-
}, [
|
|
118
|
-
d(
|
|
119
|
-
|
|
109
|
+
onClick: X
|
|
110
|
+
}, [x(n.$slots, "end")])) : c("", !0),
|
|
111
|
+
d(t, g({ class: "v-side-nav-chevron v-disclosure-chevron" }, C(e)(U.value)), null, 16),
|
|
112
|
+
W.value ? (y(), s(t, g({
|
|
120
113
|
key: 1,
|
|
121
|
-
class: "v-side-nav-chevron v-side-nav-chevron-open"
|
|
122
|
-
}, C(
|
|
123
|
-
], 16,
|
|
114
|
+
class: "v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open"
|
|
115
|
+
}, C(e)(W.value)), null, 16)) : c("", !0)
|
|
116
|
+
], 16, k), u("ul", A, [x(n.$slots, "children")])], 40, O)) : (y(), l("div", {
|
|
124
117
|
key: 1,
|
|
125
118
|
class: "v-side-nav-row",
|
|
126
|
-
"data-
|
|
119
|
+
"data-current": f.current ? "" : void 0,
|
|
127
120
|
"data-disabled": f.disabled ? "" : void 0
|
|
128
|
-
}, [(
|
|
121
|
+
}, [(y(), s(S(V.value), g(C(R), {
|
|
129
122
|
class: "v-side-nav-action",
|
|
130
|
-
type:
|
|
131
|
-
disabled:
|
|
132
|
-
href:
|
|
133
|
-
"aria-disabled":
|
|
134
|
-
"aria-current":
|
|
135
|
-
onClick:
|
|
123
|
+
type: V.value === "button" ? "button" : void 0,
|
|
124
|
+
disabled: V.value === "button" ? f.disabled : void 0,
|
|
125
|
+
href: V.value === "a" && !f.disabled ? f.href : void 0,
|
|
126
|
+
"aria-disabled": V.value === "a" && f.disabled ? "true" : void 0,
|
|
127
|
+
"aria-current": J.value,
|
|
128
|
+
onClick: Z
|
|
136
129
|
}), {
|
|
137
|
-
default:
|
|
138
|
-
|
|
139
|
-
class: "v-side-nav-icon"
|
|
140
|
-
}, C(t)(f.icon)), null, 16)) : s("", !0)]), l("span", P, [l("span", F, [b(n.$slots, "default")]), f.sublabel !== void 0 || n.$slots.sublabel ? (v(), c("span", I, [b(n.$slots, "sublabel", {}, () => [u(S(f.sublabel), 1)])])) : s("", !0)])]),
|
|
141
|
-
_: 3
|
|
130
|
+
default: D(() => [d(Y)]),
|
|
131
|
+
_: 1
|
|
142
132
|
}, 16, [
|
|
143
133
|
"type",
|
|
144
134
|
"disabled",
|
|
145
135
|
"href",
|
|
146
136
|
"aria-disabled",
|
|
147
137
|
"aria-current"
|
|
148
|
-
])), n.$slots.end ? (
|
|
138
|
+
])), n.$slots.end ? (y(), l("span", M, [x(n.$slots, "end")])) : c("", !0)], 8, j))], 6));
|
|
149
139
|
}
|
|
150
140
|
});
|
|
151
141
|
//#endregion
|
|
152
|
-
export {
|
|
142
|
+
export { N as default };
|
|
153
143
|
|
|
154
144
|
//# sourceMappingURL=VSideNavigationItem.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VSideNavigationItem.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, inject, provide, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\n/**\n * One row of a sidebar navigation. It takes one of two shapes, depending on whether it\n * was given subitems, and the difference runs deeper than it looks.\n *\n * A BRANCH is a native disclosure element, so its open state, the keyboard that\n * toggles it, the closing of a neighbouring section and the animation all come from\n * the browser. Its row IS the header of that element, which must contain everything\n * shown on the line — the `#end` slot included, which is why a click there has to be\n * cancelled: otherwise anything put in it would fold the branch. The consequence,\n * documented for integrators, is that only NON-focusable content belongs there — a\n * badge, a counter. A control inside would be a control nested inside another, and the\n * header's whole subtree also serves as its name for assistive technology, which some\n * screen readers flatten into one string.\n *\n * A LEAF is the opposite arrangement: the row is a plain container, and the link is\n * stretched over it invisibly so the entire row is clickable. The `#end` slot then\n * stays a SIBLING of that link rather than sitting inside it, which keeps a real\n * control there legitimate.\n */\ninterface SideNavigationItemProps {\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#start` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page.\n */\n active?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /**\n * Renders a branch already open. It sets the initial state only; the browser owns it\n * from then on.\n */\n defaultOpen?: boolean\n}\n\n// The root element is a list item, which is structure and not the control. Without\n// redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n active: false,\n disabled: false,\n defaultOpen: false,\n})\n\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it.\n *\n * Left unbound, the browser keeps that state entirely to itself, `defaultOpen` giving\n * only the initial value: the bound value never changes, so Vue never patches the\n * element back, and the native toggling stays sovereign.\n *\n * TRAP — \"not bound\" is written as `null` and not `undefined`. A model typed as a\n * plain boolean is declared as such at runtime, and Vue casts an ABSENT boolean prop\n * to `false`, which would silently overwrite `defaultOpen` on every branch. Giving it\n * an explicit default disarms that cast.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n /**\n * A row WITHOUT subitems was activated, by click or by keyboard.\n *\n * TRAP — never declare a `click` emit alongside it. Vue removes a declared event\n * from the forwarded attributes, and a consumer's own `@click` would then stop\n * reaching the link entirely.\n */\n select: []\n}>()\n\ndefineSlots<{\n /** The label of the row. It is REQUIRED: a navigation row must say where it goes. */\n default(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n start?(): unknown\n /**\n * Free content at the end of the row, before the chevron — a counter, a badge. On a\n * BRANCH it must not be focusable (see the introduction).\n */\n end?(): unknown\n /** The subitems, which turn this row into a branch. Nesting is not limited. */\n items?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\n/**\n * Whether this row has subitems, read from the mere PRESENCE of the slot — the same\n * device VMenuItem and VTabs use. The answer is the same on the server and in the\n * browser, so there is no registry to fill in and no hydration mismatch.\n *\n * The trade-off is that a slot present but empty still makes the row a branch, chevron\n * included, over an empty list.\n */\nconst hasChildren = computed(() => !!slots.items)\nconst tag = computed(() =>\n !hasChildren.value && props.href !== undefined ? ('a' as const) : ('button' as const),\n)\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// The name shared by THIS row's children. It is minted afresh at every level, and that\n// is what keeps \"one section open at a time\" local to a level instead of applying\n// across the whole document.\nconst childrenName = useId()\n\nprovide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n})\n\nconst openAttr = computed(() => (open.value ?? props.defaultOpen) || undefined)\n\n// The element is the source of truth and the model is fed BY it, never the other way\n// round. The event it fires does not bubble, which is convenient here: listening on\n// the element itself cannot pick up a nested branch opening inside it.\nfunction onToggle(event: Event) {\n const value = (event.target as HTMLDetailsElement).open\n if (open.value !== value) open.value = value\n}\n\nconst ariaCurrent = computed(() =>\n props.active ? (tag.value === 'a' && !hasChildren.value ? 'page' : 'true') : undefined,\n)\n\n/*\n * A branch header has no `disabled` attribute of its own, so cancelling the click is\n * the only way to stop it from folding. The keyboard needs nothing here: taking the\n * header out of the tab order already covers it.\n *\n * The same solution as VAccordionItem, and deliberately not `pointer-events: none`,\n * which would also remove the forbidden cursor telling the reader why nothing happens.\n */\nfunction onSummaryClick(event: MouseEvent) {\n if (props.disabled) event.preventDefault()\n}\n\n/*\n * A branch's end slot sits INSIDE the header, so a click there would fold the branch.\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's DEFAULT action, and only cancelling that prevents it.\n *\n * The exception is a click that already landed on something activable. There the click\n * belongs to that control, the branch is not concerned, and cancelling the default\n * would break its own behaviour — a link would stop navigating. The same filter as in\n * `useFieldPanel`, for the same reason.\n */\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; a link made inert by hand does,\n // so it is cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"hasChildren\"\n class=\"v-side-nav-branch\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n v-bind=\"forwardedAttrs\"\n class=\"v-side-nav-row\"\n :data-active=\"active ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"ariaCurrent\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click=\"onSummaryClick\"\n >\n <slot name=\"start\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"><slot /></span>\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <!-- Both chevrons are always in the DOM; the open state decides which one\n shows, in CSS alone — the VAccordion idiom -->\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"items\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-active=\"active ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n v-bind=\"forwardedAttrs\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :href=\"tag === 'a' && !disabled ? href : undefined\"\n :aria-disabled=\"tag === 'a' && disabled ? 'true' : undefined\"\n :aria-current=\"ariaCurrent\"\n @click=\"onActionClick\"\n >\n <slot name=\"start\">\n <VIcon v-if=\"icon\" class=\"v-side-nav-icon\" v-bind=\"iconProps(icon)\" />\n </slot>\n <span class=\"v-side-nav-content\">\n <span class=\"v-side-nav-label\"><slot /></span>\n <span v-if=\"sublabel !== undefined || $slots.sublabel\" class=\"v-side-nav-sublabel\">\n <slot name=\"sublabel\">{{ sublabel }}</slot>\n </span>\n </span>\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * How deep an item sits, counted entirely in CSS: no registry, nothing provided down\n * the tree, no inline style, and no `level` prop for the consumer to keep track of.\n * The markup gives two elements per level — the item, then the list of its children —\n * and each of them reads a name the other DECLARES.\n *\n * TRAP — the obvious one-name form, incrementing a variable by reading itself, is a\n * CYCLE as far as CSS is concerned, even though the value being read is the inherited\n * one. The property then falls to invalid, every read falls back to zero, and the\n * whole tree renders FLAT — with nothing in the console to say why. The two\n * alternating names are what avoid it.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-branch {\n /* Lets a long label wrap rather than widening the whole sidebar. The folding\n animation itself is further down. */\n min-inline-size: 0;\n }\n\n .v-side-nav-row {\n /*\n * Every dimension comes from the variables the nav sets and this row inherits — it\n * is the only element carrying the shared size class. The icons follow with nothing\n * written for them, their own variables belonging to that same block.\n *\n * The type is composite, as in a menu row: the SIZE comes from the scale, but the\n * line height stays that of body text — a unitless ratio, so it still follows the\n * size — and the weight stays regular. The full `control` type role would suit a\n * single-line label, and a navigation row may wrap and carry a second line.\n *\n * TRAP — the indent is computed HERE and not stored in a variable set higher up. A\n * custom property is substituted on the element that DECLARES it, so a padding\n * computed on the nav would be frozen at level zero for the whole tree.\n */\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--vectis-radius-sm);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n list-style: none;\n cursor: pointer;\n }\n\n /* Removing the browser's own disclosure triangle: setting the list style is not\n enough in WebKit, which draws it through this pseudo-element. */\n .v-side-nav-row::-webkit-details-marker {\n display: none;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the WHOLE row without having to wrap the end\n * slot inside it. It is an invisible box, positioned, so it is painted above the\n * chevron — which is not positioned — while passing UNDER the end slot, which is\n * positioned too and comes later in the document. That layering is exactly what\n * makes the whole row clickable while leaving a control in the end slot usable.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--vectis-radius-sm);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n /* The chevron points down when the branch is closed and flips when it opens. It\n turns around a horizontal axis, so unlike VMenu's sideways chevron it needs no\n mirroring in a right-to-left page. */\n .v-side-nav-chevron {\n flex: none;\n color: var(--vectis-color-text-muted);\n transition: rotate var(--vectis-duration-base) var(--vectis-ease-default);\n }\n\n .v-side-nav-branch[open]:not([data-swap]) > .v-side-nav-row > .v-side-nav-chevron {\n rotate: 180deg;\n }\n\n /* When the navigation supplied a second chevron, each state hides one of the two\n rendered icons instead of rotating a single one. */\n .v-side-nav-branch[data-swap][open]\n > .v-side-nav-row\n > .v-side-nav-chevron:not(.v-side-nav-chevron-open),\n .v-side-nav-branch[data-swap]:not([open]) > .v-side-nav-row > .v-side-nav-chevron-open {\n display: none;\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\n outline: var(--vectis-focus-ring-width) solid var(--vectis-focus-ring-color);\n outline-offset: calc(var(--vectis-focus-ring-offset) * -1);\n }\n\n .v-side-nav-action:focus-visible {\n outline: none;\n }\n\n /* The row of the page currently being viewed. */\n .v-side-nav-row[data-active] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-active] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-active] .v-side-nav-icon,\n .v-side-nav-row[data-active] .v-side-nav-sublabel,\n .v-side-nav-row[data-active] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-active]:hover {\n /* The current row is already tinted, so its hover deepens that tint rather than\n replacing it with the neutral highlight — the VMenuItem idiom. */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-active]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon, the second line and the chevron default to a colour DARKER than the one\n a disabled label takes: left alone they would come out stronger than the label\n itself, so they inherit it instead. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel,\n .v-side-nav-row[data-disabled] .v-side-nav-chevron {\n color: inherit;\n }\n\n /* The opening animates in pure CSS, on the box the browser wraps a branch's content\n in. A browser without support opens the branch instantly, which is the intended\n fallback. */\n .v-side-nav-branch::details-content {\n block-size: 0;\n overflow: clip;\n transition:\n block-size var(--vectis-duration-base) var(--vectis-ease-default),\n content-visibility var(--vectis-duration-base) allow-discrete;\n }\n\n .v-side-nav-branch[open]::details-content {\n block-size: auto;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .v-side-nav-chevron,\n .v-side-nav-branch::details-content {\n transition: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEA,IAAM,IAAQ,GAqBR,IAAO,EAA2B,GAAC,MAAyB,GAE5D,IAAO,GA2BP,EAAE,cAAW,cAAW,sBAAmB,EAAa,GAExD,IAAQ,GAAS,GASjB,IAAc,QAAe,CAAC,CAAC,EAAM,KAAK,GAC1C,IAAM,QACV,CAAC,EAAY,SAAS,EAAM,SAAS,KAAA,IAAa,MAAiB,QACrE,GAEM,IAAS,EAAO,GAAmB,IAAI,GAMvC,IAAa,QAAe,GAAQ,cAAc,CAAc,GAChE,IAAe,QAAe,GAAQ,YAAY,GAKlD,IAAe,EAAM;EAE3B,EAAQ,GAAmB;GACzB,IAAI,OAAO;IACT,OAAO,GAAQ,YAAY,IAAe,KAAA;GAC5C;GACA,IAAI,YAAY;IACd,OAAO,GAAQ,aAAa;GAC9B;GACA,IAAI,aAAa;IACf,OAAO,EAAW;GACpB;GACA,IAAI,eAAe;IACjB,OAAO,EAAa;GACtB;EACF,CAAC;EAED,IAAM,IAAW,SAAgB,EAAK,SAAS,EAAM,gBAAgB,KAAA,CAAS;EAK9E,SAAS,EAAS,GAAc;GAC9B,IAAM,IAAS,EAAM,OAA8B;GACnD,AAAI,EAAK,UAAU,MAAO,EAAK,QAAQ;EACzC;EAEA,IAAM,IAAc,QAClB,EAAM,SAAU,EAAI,UAAU,OAAO,CAAC,EAAY,QAAQ,SAAS,SAAU,KAAA,CAC/E;EAUA,SAAS,GAAe,GAAmB;GACzC,AAAI,EAAM,YAAU,EAAM,eAAe;EAC3C;EAYA,SAAS,GAAW,GAAmB;GAErC,AADe,EAAM,QACR,QAAQ,gDAAgD,KAAG,EAAM,eAAe;EAC/F;EAEA,SAAS,GAAc,GAAmB;GAGxC,IAAI,EAAM,UAAU;IAClB,EAAM,eAAe;IACrB;GACF;GACA,EAAK,QAAQ;EACf;yBAIE,EA6EK,MAAA;GA7ED,OAAK,EAAA,CAAC,mBAA0B,EAAA,CAAA,CAAS,CAAA;GAAG,OAAK,EAAE,EAAA,CAAA,CAAS;MAEtD,EAAA,SAAA,EAAA,GADR,EA6CU,WAAA;;GA3CR,OAAM;GACL,MAAM,EAAA,CAAA,CAAM,EAAE;GACd,MAAM,EAAA;GACN,aAAW,EAAA,QAAY,KAAQ,KAAA;GACvB;MAET,EAiCU,WAjCV,EACU,EAgCA,CAAA,GAhCc;GACtB,OAAM;GACL,eAAa,EAAA,SAAM,KAAQ,KAAA;GAC3B,iBAAe,EAAA,WAAQ,KAAQ,KAAA;GAC/B,gBAAc,EAAA;GACd,iBAAe,EAAA,YAAY,KAAA;GAC3B,UAAU,EAAA,WAAQ,KAAQ,KAAA;GAC1B,SAAO;;GAER,EAEO,EAAA,QAAA,SAAA,CAAA,SAAA,CADQ,EAAA,QAAA,EAAA,GAAb,EAAsE,GAAtE,EAAsE;;IAAnD,OAAM;MAA0B,EAAA,CAAA,CAAS,CAAC,EAAA,IAAI,CAAA,GAAA,MAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA;GAEnE,EAKO,QALP,GAKO,CAJL,EAA8C,QAA9C,GAA8C,CAAf,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA,GAC3B,EAAA,aAAa,KAAA,KAAaA,EAAAA,OAAO,YAAA,EAAA,GAA7C,EAEO,QAFP,GAEO,CADL,EAA2C,EAAA,QAAA,YAAA,CAAA,SAAA,CAAA,EAAA,EAAlB,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA;GAMzBA,EAAAA,OAAO,OAAA,EAAA,GAAnB,EAES,QAAA;;IAFe,OAAM;IAAkB,SAAO;OACpD,EACD,EAAA,QAAA,KAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GACF,EAAmE,GAAnE,EAAmE,EAA5D,OAAM,qBAAoB,GAAS,EAAA,CAAA,CAAS,CAAC,EAAA,KAAU,CAAA,GAAA,MAAA,EAAA;GAItD,EAAA,SAAA,EAAA,GADR,EAIE,GAJF,EAIE;;IAFA,OAAM;MACE,EAAA,CAAA,CAAS,CAAC,EAAA,KAAY,CAAA,GAAA,MAAA,EAAA,KAAA,EAAA,IAAA,EAAA;aAGlC,EAEK,MAFL,GAEK,CADH,EAAqB,EAAA,QAAA,OAAA,CAAA,CAAA,CAAA,GAAA,IAAA,CAAA,MAAA,EAAA,GAIzB,EA4BM,OAAA;;GA1BJ,OAAM;GACL,eAAa,EAAA,SAAM,KAAQ,KAAA;GAC3B,iBAAe,EAAA,WAAQ,KAAQ,KAAA;YAEhC,EAoBY,EAnBL,EAAA,KAAG,GADV,EAEU,EAkBE,CAAA,GAlBY;GACtB,OAAM;GACL,MAAM,EAAA,UAAG,WAAA,WAA2B,KAAA;GACpC,UAAU,EAAA,UAAG,WAAgB,EAAA,WAAW,KAAA;GACxC,MAAM,EAAA,UAAG,OAAA,CAAa,EAAA,WAAW,EAAA,OAAO,KAAA;GACxC,iBAAe,EAAA,UAAG,OAAY,EAAA,WAAQ,SAAY,KAAA;GAClD,gBAAc,EAAA;GACd,SAAO;;oBAID,CAFP,EAEO,EAAA,QAAA,SAAA,CAAA,SAAA,CADQ,EAAA,QAAA,EAAA,GAAb,EAAsE,GAAtE,EAAsE;;IAAnD,OAAM;MAA0B,EAAA,CAAA,CAAS,CAAC,EAAA,IAAI,CAAA,GAAA,MAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,GAEnE,EAKO,QALP,GAKO,CAJL,EAA8C,QAA9C,GAA8C,CAAf,EAAQ,EAAA,QAAA,SAAA,CAAA,CAAA,GAC3B,EAAA,aAAa,KAAA,KAAaA,EAAAA,OAAO,YAAA,EAAA,GAA7C,EAEO,QAFP,GAEO,CADL,EAA2C,EAAA,QAAA,YAAA,CAAA,SAAA,CAAA,EAAA,EAAlB,EAAA,QAAQ,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA;;;;;;;;OAI3BA,EAAAA,OAAO,OAAA,EAAA,GAAnB,EAAyE,QAAzE,GAAyE,CAA1B,EAAmB,EAAA,QAAA,KAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,GAAA,CAAA,EAAA,GAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"VSideNavigationItem.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/VSideNavigation/VSideNavigationItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * One row of a sidebar navigation, in one of two shapes depending on whether it was given\n * subitems — and the difference runs deeper than it looks.\n *\n * A BRANCH is a `<details>`, so its open state, the toggle keyboard, the exclusivity with a\n * neighbouring section and the animation all come from the browser. Its row IS the\n * `<summary>`, which must contain the whole line, `#end` included — hence the click handler\n * there, or anything put in it would fold the branch. The documented consequence is that\n * only NON-focusable content belongs in it: a control would be nested inside a control (WCAG\n * 4.1.2, axe `nested-interactive`), and a `<summary>`'s subtree also serves as its\n * accessible name, which some screen readers flatten.\n *\n * A LEAF is the opposite: the row is a plain container with the action stretched over it by\n * an absolute `::after`, so the whole row is clickable while `#end` stays a SIBLING of the\n * action rather than inside it — which is what keeps a real control there legitimate.\n *\n * The branch's open state and its disabled summary go through `useDetailsOpen`, shared with\n * VAccordionItem.\n */\n\nimport { computed, h, inject, provide, renderSlot, useId, useSlots } from 'vue'\n\nimport VIcon from '../VIcon/VIcon.vue'\nimport { iconProps } from '../VIcon/iconProps'\nimport { expand_more as expandMoreIcon } from '../VIcon/icons/expand_more'\nimport type { IconSource } from '../VIcon/types'\nimport { sideNavigationKey } from './context'\n\nimport { useDetailsOpen } from '../../composables/useDetailsOpen'\nimport { useRootAttrs } from '../../composables/useRootAttrs'\n\ninterface SideNavigationItemProps {\n /** What the row says, and where it goes. The default slot replaces it. */\n label?: string\n /** A second line under the label, for a status or a short explanation. */\n sublabel?: string\n /**\n * An icon before the label: an icon name, or an explicit render. The `#icon` slot\n * replaces it.\n */\n icon?: IconSource\n /**\n * Where this row leads, which makes it a link. It is IGNORED on a row that has\n * subitems: such a row opens and closes rather than navigating.\n */\n href?: string\n /**\n * Marks this row as the page currently being viewed. It is highlighted, and\n * announced as the current page (`aria-current`).\n */\n current?: boolean\n /**\n * Makes the row unusable: it greys out through the colour tokens and leaves the\n * keyboard path.\n */\n disabled?: boolean\n /**\n * Renders a branch already open. Only its initial value is read: the browser owns the\n * state from then on, so changing this prop later will not fold a branch the reader\n * has opened. Bind `v-model:open` to drive it instead.\n */\n defaultOpen?: boolean\n}\n\n// The root element is a list item, which is structure and not the control. Without\n// redirecting them, `target`, `rel`, `download` and the aria-* would land on that list\n// item instead of on the link or the branch header.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SideNavigationItemProps>(), {\n label: undefined,\n sublabel: undefined,\n icon: undefined,\n href: undefined,\n current: false,\n disabled: false,\n defaultOpen: false,\n})\n\n/**\n * Whether the branch is open, when the consumer wants to drive or observe it.\n *\n * Left unbound, the browser keeps that state entirely to itself, `defaultOpen` giving\n * only the initial value: the bound value never changes, so Vue never patches the\n * element back, and the native toggling stays sovereign.\n *\n * TRAP — \"not bound\" is written as `null` and not `undefined`. A model typed as a\n * plain boolean is declared as such at runtime, and Vue casts an ABSENT boolean prop\n * to `false`, which would silently overwrite `defaultOpen` on every branch. Giving it\n * an explicit default disarms that cast.\n */\nconst open = defineModel<boolean | null>('open', { default: null })\n\nconst emit = defineEmits<{\n /**\n * A row WITHOUT subitems was activated, by click or by keyboard.\n *\n * TRAP — never declare a `click` emit alongside it. Vue removes a declared event\n * from the forwarded attributes, and a consumer's own `@click` would then stop\n * reaching the link entirely.\n */\n select: []\n}>()\n\ndefineSlots<{\n /**\n * The label of the row, replacing the `label` prop. One of the two is REQUIRED: a\n * navigation row must say where it goes.\n */\n default?(): unknown\n /** A second line made of markup, replacing the `sublabel` prop. */\n sublabel?(): unknown\n /** Free content before the label, which takes the place of `icon`. */\n icon?(): unknown\n /**\n * Free content at the end of the row, before the chevron — a counter, a badge. On a\n * BRANCH it must not be focusable (see the introduction).\n */\n end?(): unknown\n /**\n * The subitems, which turn this row into a branch. Nesting is not limited. The slot\n * must be statically present or absent: whether a row is a branch is decided when it\n * is created.\n */\n children?(): unknown\n}>()\n\nconst { rootClass, rootStyle, forwardedAttrs } = useRootAttrs()\n\nconst slots = useSlots()\n/**\n * Whether this row has subitems, read from the mere PRESENCE of the slot — the same\n * device VMenuItem and VTabs use. The answer is the same on the server and in the\n * browser, so there is no registry to fill in and no hydration mismatch.\n *\n * The trade-off is that a slot present but empty still makes the row a branch, chevron\n * included, over an empty list.\n */\nconst hasChildren = computed(() => !!slots.children)\nconst tag = computed(() =>\n !hasChildren.value && props.href !== undefined ? ('a' as const) : ('button' as const),\n)\n\nconst parent = inject(sideNavigationKey, null)\n\n/**\n * Both chevrons are chosen on the navigation as a whole. The fallback is what keeps an\n * item rendering correctly when it is used outside one.\n */\nconst expandIcon = computed(() => parent?.expandIcon ?? expandMoreIcon)\nconst collapseIcon = computed(() => parent?.collapseIcon)\n\n// @ssr @core\n// Only a BRANCH has children to hand a context to, so a leaf — most rows of a sidebar —\n// mints no id and provides nothing. The test runs once, at setup: the server and the\n// client take the same path because they see the same slot, which is what keeps `useId`\n// in step across hydration, and also why the slot must not come and go later.\nif (slots.children) {\n // The name shared by THIS row's children. It is minted afresh at every level, and that\n // is what keeps \"one section open at a time\" local to a level instead of applying\n // across the whole document.\n const childrenName = useId()\n\n provide(sideNavigationKey, {\n get name() {\n return parent?.exclusive ? childrenName : undefined\n },\n get exclusive() {\n return parent?.exclusive ?? false\n },\n get expandIcon() {\n return expandIcon.value\n },\n get collapseIcon() {\n return collapseIcon.value\n },\n })\n}\n\nconst { openAttr, onToggle, onSummaryClick } = useDetailsOpen(open, {\n defaultOpen: () => props.defaultOpen,\n disabled: () => props.disabled,\n})\n\n// A link says \"page\"; a button, a branch header included, can only say \"true\".\nconst ariaCurrent = computed(() =>\n props.current ? (tag.value === 'a' ? 'page' : 'true') : undefined,\n)\n\n/*\n * The icon and the label column, identical in both row shapes. A functional component\n * rather than two copies of the markup, a Vue template having no reusable fragment.\n * `renderSlot` is what a compiled `<slot>` calls, so each fallback behaves exactly as it\n * would in the template.\n */\nconst RowBody = () => [\n renderSlot(slots, 'icon', {}, () =>\n props.icon ? [h(VIcon, { class: 'v-side-nav-icon', ...iconProps(props.icon) })] : [],\n ),\n h('span', { class: 'v-side-nav-content' }, [\n h('span', { class: 'v-side-nav-label' }, [\n renderSlot(slots, 'default', {}, () => [props.label]),\n ]),\n props.sublabel !== undefined || slots.sublabel\n ? h('span', { class: 'v-side-nav-sublabel' }, [\n renderSlot(slots, 'sublabel', {}, () => [props.sublabel]),\n ])\n : null,\n ]),\n]\n\n/*\n * A branch's end slot sits INSIDE the header, so a click there would fold the branch.\n * Stopping the event from travelling would not help: folding is not a listener anyone\n * registered, it is the click's DEFAULT action, and only cancelling that prevents it.\n *\n * The exception is a click that already landed on something activable. There the click\n * belongs to that control, the branch is not concerned, and cancelling the default\n * would break its own behaviour — a link would stop navigating. The same filter as in\n * `useFieldPanel`, for the same reason.\n */\nfunction onEndClick(event: MouseEvent) {\n const target = event.target as Element | null\n if (!target?.closest('button, a, input, select, textarea, [tabindex]')) event.preventDefault()\n}\n\nfunction onActionClick(event: MouseEvent) {\n // A disabled button never receives the click at all; a link made inert by hand does,\n // so it is cancelled here.\n if (props.disabled) {\n event.preventDefault()\n return\n }\n emit('select')\n}\n</script>\n\n<template>\n <li class=\"v-side-nav-item\" :class=\"rootClass\" :style=\"rootStyle\">\n <details\n v-if=\"hasChildren\"\n class=\"v-side-nav-branch v-disclosure\"\n :name=\"parent?.name\"\n :open=\"openAttr\"\n :data-swap=\"collapseIcon ? '' : undefined\"\n @toggle=\"onToggle\"\n >\n <summary\n v-bind=\"forwardedAttrs\"\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :aria-current=\"ariaCurrent\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click=\"onSummaryClick\"\n >\n <RowBody />\n <!-- This slot sits INSIDE the branch header, where ANY click folds the\n branch: without the handler, clicking a badge would close the section\n under it -->\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\" @click=\"onEndClick\"\n ><slot name=\"end\"\n /></span>\n <VIcon class=\"v-side-nav-chevron v-disclosure-chevron\" v-bind=\"iconProps(expandIcon)\" />\n <!-- Both chevrons are always in the DOM; the open state decides which one\n shows, in CSS alone -->\n <VIcon\n v-if=\"collapseIcon\"\n class=\"v-side-nav-chevron v-side-nav-chevron-open v-disclosure-chevron v-disclosure-chevron-open\"\n v-bind=\"iconProps(collapseIcon)\"\n />\n </summary>\n <ul class=\"v-side-nav-children\">\n <slot name=\"children\" />\n </ul>\n </details>\n\n <div\n v-else\n class=\"v-side-nav-row\"\n :data-current=\"current ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n >\n <component\n :is=\"tag\"\n v-bind=\"forwardedAttrs\"\n class=\"v-side-nav-action\"\n :type=\"tag === 'button' ? 'button' : undefined\"\n :disabled=\"tag === 'button' ? disabled : undefined\"\n :href=\"tag === 'a' && !disabled ? href : undefined\"\n :aria-disabled=\"tag === 'a' && disabled ? 'true' : undefined\"\n :aria-current=\"ariaCurrent\"\n @click=\"onActionClick\"\n >\n <RowBody />\n </component>\n <span v-if=\"$slots.end\" class=\"v-side-nav-end\"><slot name=\"end\" /></span>\n </div>\n </li>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * How deep an item sits, counted entirely in CSS: no registry, nothing provided down\n * the tree, no inline style, and no `level` prop for the consumer to keep track of.\n * The markup gives two elements per level — the item, then the list of its children —\n * and each of them reads a name the other DECLARES.\n *\n * TRAP — the obvious one-name form, incrementing a variable by reading itself, is a\n * CYCLE as far as CSS is concerned, even though the value being read is the inherited\n * one. The property then falls to invalid, every read falls back to zero, and the\n * whole tree renders FLAT — with nothing in the console to say why. The two\n * alternating names are what avoid it.\n */\n .v-side-nav-item {\n --side-nav-parent-level: var(--side-nav-level, 0);\n }\n\n .v-side-nav-children {\n --side-nav-level: calc(var(--side-nav-parent-level) + 1);\n }\n\n .v-side-nav-row {\n /*\n * Every dimension comes from the variables the nav sets and this row inherits — it\n * is the only element carrying the shared size class. The icons follow with nothing\n * written for them, their own variables belonging to that same block.\n *\n * The type is composite, as in a menu row: the SIZE comes from the scale, but the\n * line height stays that of body text — a unitless ratio, so it still follows the\n * size — and the weight stays regular. The full `control` type role would set its\n * lines tight against each other, and a row may carry a second line under the label.\n *\n * The label and that second line TRUNCATE rather than wrap: a sidebar has a fixed\n * width, and a row that grew a line would break the rhythm of the list. VMenuItem\n * follows the same recipe.\n *\n * TRAP — the indent is computed HERE and not stored in a variable set higher up. A\n * custom property is substituted on the element that DECLARES it, so a padding\n * computed on the nav would be frozen at level zero for the whole tree.\n */\n\n /*\n * The corner takes the role every clickable box in the DS takes, so a brand that\n * squares its controls or rounds them into pills carries the sidebar along in the\n * one override.\n *\n * TRAP — the cap has to stay derived from --control-height. A browser scales down\n * any radius it cannot fit, so a row exactly one control tall already paints half\n * that height under a pill override; min() applies the same reduction to a row that\n * grew past it. Written bare, a row carrying a second line paints half of ITS OWN\n * height instead, and two rows of the same list come out with different corners. At\n * the shipped 6px this resolves to 6px on both sizes and under compact, so nothing\n * at the default value can see the line go — only the PillRadius play function can.\n *\n * The variable is what keeps the row and the stretched overlay below in step: that\n * overlay is positioned against this element, so the two are the same box, and its\n * ring is drawn on the radius found here.\n */\n --side-nav-row-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n min-block-size: var(--control-height);\n padding-block: var(--vectis-space-1);\n padding-inline: calc(\n var(--control-padding-inline) + var(--side-nav-level, 0) * var(--side-nav-indent)\n )\n var(--control-padding-inline);\n border-radius: var(--side-nav-row-radius);\n color: var(--vectis-color-text);\n font-size: var(--control-font-size);\n line-height: var(--vectis-text-body-md-leading);\n cursor: pointer;\n }\n\n .v-side-nav-action {\n /* On a leaf the link is a CHILD of the row, and the indent deliberately stays on\n the row itself: what has to run the full width is the hover background, not the\n link inside it. */\n flex: 1;\n min-inline-size: 0;\n display: flex;\n align-items: center;\n gap: var(--control-gap);\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n cursor: inherit;\n }\n\n /*\n * This is what stretches the link over the WHOLE row without having to wrap the end\n * slot inside it. It is an invisible box, positioned, so it is painted above the\n * chevron — which is not positioned — while passing UNDER the end slot, which is\n * positioned too and comes later in the document. That layering is exactly what\n * makes the whole row clickable while leaving a control in the end slot usable.\n */\n .v-side-nav-action::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--side-nav-row-radius);\n }\n\n .v-side-nav-content {\n flex: 1;\n min-inline-size: 0;\n display: flex;\n flex-direction: column;\n }\n\n .v-side-nav-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-sublabel {\n overflow: hidden;\n font-size: var(--vectis-text-caption-size);\n color: var(--vectis-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .v-side-nav-icon {\n flex: none;\n color: var(--vectis-color-text-muted);\n }\n\n /* Positioned on purpose: that is what paints it above the stretched link, and\n therefore what keeps whatever it holds clickable. */\n .v-side-nav-end {\n position: relative;\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--vectis-space-1);\n }\n\n .v-side-nav-row:hover:not([data-disabled]) {\n background: var(--vectis-color-surface-muted);\n }\n\n /*\n * A branch header takes focus itself; a leaf only takes it through its link, and the\n * ring is then drawn on the stretched box so that it frames the whole row rather than\n * just the text.\n *\n * The ring is pulled INWARDS in both cases: the content of a branch is clipped so it\n * can be animated open, and a ring drawn outside the row would be cut off there.\n */\n .v-side-nav-row:focus-visible,\n .v-side-nav-action:focus-visible::after {\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-side-nav-action:focus-visible {\n outline: none;\n }\n\n /* The row of the page currently being viewed. */\n .v-side-nav-row[data-current] {\n background: var(--vectis-color-accent-surface);\n color: var(--vectis-color-accent-text);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-label {\n font-weight: var(--vectis-text-label-weight);\n }\n\n .v-side-nav-row[data-current] .v-side-nav-icon,\n .v-side-nav-row[data-current] .v-side-nav-sublabel,\n .v-side-nav-row[data-current] .v-side-nav-chevron {\n color: inherit;\n }\n\n .v-side-nav-row[data-current]:hover {\n /* The current row is already tinted, so its hover deepens that tint rather than\n replacing it with the neutral highlight — the VMenuItem idiom. */\n background: color-mix(\n in oklab,\n var(--vectis-color-accent-surface),\n var(--vectis-color-accent-text) 8%\n );\n }\n\n /* A CLOSED branch holding the current page keeps a mark of it, so the reader can see\n where they are without opening every section. The lookup is deliberately a\n descendant one: the page may be several levels down. */\n .v-side-nav-branch:not([open]):has(.v-side-nav-children [aria-current])\n > .v-side-nav-row:not([data-current]) {\n color: var(--vectis-color-accent-text);\n }\n\n /* A disabled row greys out through the colour tokens, never through opacity. */\n .v-side-nav-row[data-disabled] {\n color: var(--vectis-color-text-subtle);\n cursor: not-allowed;\n }\n\n /* The icon and the second line default to a colour DARKER than the one a disabled\n label takes: left alone they would come out stronger than the label itself, so they\n inherit it instead. The chevron gets the same treatment from `styles/disclosure.css`. */\n .v-side-nav-row[data-disabled] .v-side-nav-icon,\n .v-side-nav-row[data-disabled] .v-side-nav-sublabel {\n color: inherit;\n }\n\n /* The disclosure animation, the chevron's rotation or swap and the WebKit marker come\n from `styles/disclosure.css`, reduced-motion block included. */\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsEA,IAAM,IAAQ,GAsBR,IAAO,EAA2B,GAAC,MAAyB,GAE5D,IAAO,GAkCP,EAAE,cAAW,cAAW,sBAAmB,EAAa,GAExD,IAAQ,EAAS,GASjB,IAAc,QAAe,CAAC,CAAC,EAAM,QAAQ,GAC7C,IAAM,QACV,CAAC,EAAY,SAAS,EAAM,SAAS,KAAA,IAAa,MAAiB,QACrE,GAEM,IAAS,EAAO,GAAmB,IAAI,GAMvC,IAAa,QAAe,GAAQ,cAAc,CAAc,GAChE,IAAe,QAAe,GAAQ,YAAY;EAOxD,IAAI,EAAM,UAAU;GAIlB,IAAM,IAAe,EAAM;GAE3B,EAAQ,GAAmB;IACzB,IAAI,OAAO;KACT,OAAO,GAAQ,YAAY,IAAe,KAAA;IAC5C;IACA,IAAI,YAAY;KACd,OAAO,GAAQ,aAAa;IAC9B;IACA,IAAI,aAAa;KACf,OAAO,EAAW;IACpB;IACA,IAAI,eAAe;KACjB,OAAO,EAAa;IACtB;GACF,CAAC;EACH;EAEA,IAAM,EAAE,aAAU,aAAU,sBAAmB,EAAe,GAAM;GAClE,mBAAmB,EAAM;GACzB,gBAAgB,EAAM;EACxB,CAAC,GAGK,IAAc,QAClB,EAAM,UAAW,EAAI,UAAU,MAAM,SAAS,SAAU,KAAA,CAC1D,GAQM,UAAgB,CACpB,EAAW,GAAO,QAAQ,CAAC,SACzB,EAAM,OAAO,CAAC,EAAE,GAAO;GAAE,OAAO;GAAmB,GAAG,EAAU,EAAM,IAAI;EAAE,CAAC,CAAC,IAAI,CAAC,CACrF,GACA,EAAE,QAAQ,EAAE,OAAO,qBAAqB,GAAG,CACzC,EAAE,QAAQ,EAAE,OAAO,mBAAmB,GAAG,CACvC,EAAW,GAAO,WAAW,CAAC,SAAS,CAAC,EAAM,KAAK,CAAC,CACtD,CAAC,GACD,EAAM,aAAa,KAAA,KAAa,EAAM,WAClC,EAAE,QAAQ,EAAE,OAAO,sBAAsB,GAAG,CAC1C,EAAW,GAAO,YAAY,CAAC,SAAS,CAAC,EAAM,QAAQ,CAAC,CAC1D,CAAC,IACD,IACN,CAAC,CACH;EAYA,SAAS,EAAW,GAAmB;GAErC,AADe,EAAM,QACR,QAAQ,gDAAgD,KAAG,EAAM,eAAe;EAC/F;EAEA,SAAS,EAAc,GAAmB;GAGxC,IAAI,EAAM,UAAU;IAClB,EAAM,eAAe;IACrB;GACF;GACA,EAAK,QAAQ;EACf;yBAIE,EA6DK,MAAA;GA7DD,OAAK,EAAA,CAAC,mBAA0B,EAAA,CAAA,CAAS,CAAA;GAAG,OAAK,EAAE,EAAA,CAAA,CAAS;MAEtD,EAAA,SAAA,EAAA,GADR,EAqCU,WAAA;;GAnCR,OAAM;GACL,MAAM,EAAA,CAAA,CAAM,EAAE;GACd,MAAM,EAAA,CAAA;GACN,aAAW,EAAA,QAAY,KAAQ,KAAA;GAC/B,UAAM,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;MAET,EAyBU,WAzBV,EACU,EAwBA,CAAA,GAxBc;GACtB,OAAM;GACL,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,iBAAe,EAAA,WAAQ,KAAQ,KAAA;GAC/B,gBAAc,EAAA;GACd,iBAAe,EAAA,YAAY,KAAA;GAC3B,UAAU,EAAA,WAAQ,KAAQ,KAAA;GAC1B,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,KAAA,EAAA,CAAA,CAAA,CAAA,GAAA,CAAA;;GAER,EAAW,CAAA;GAICA,EAAAA,OAAO,OAAA,EAAA,GAAnB,EAES,QAAA;;IAFe,OAAM;IAAkB,SAAO;OACpD,EACD,EAAA,QAAA,KAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA;GACF,EAAwF,GAAxF,EAAwF,EAAjF,OAAM,0CAAyC,GAAS,EAAA,CAAA,CAAS,CAAC,EAAA,KAAU,CAAA,GAAA,MAAA,EAAA;GAI3E,EAAA,SAAA,EAAA,GADR,EAIE,GAJF,EAIE;;IAFA,OAAM;MACE,EAAA,CAAA,CAAS,CAAC,EAAA,KAAY,CAAA,GAAA,MAAA,EAAA,KAAA,EAAA,IAAA,EAAA;aAGlC,EAEK,MAFL,GAEK,CADH,EAAwB,EAAA,QAAA,UAAA,CAAA,CAAA,CAAA,GAAA,IAAA,CAAA,MAAA,EAAA,GAI5B,EAoBM,OAAA;;GAlBJ,OAAM;GACL,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,iBAAe,EAAA,WAAQ,KAAQ,KAAA;YAEhC,EAYY,EAXL,EAAA,KAAG,GADV,EAEU,EAUE,CAAA,GAVY;GACtB,OAAM;GACL,MAAM,EAAA,UAAG,WAAA,WAA2B,KAAA;GACpC,UAAU,EAAA,UAAG,WAAgB,EAAA,WAAW,KAAA;GACxC,MAAM,EAAA,UAAG,OAAA,CAAa,EAAA,WAAW,EAAA,OAAO,KAAA;GACxC,iBAAe,EAAA,UAAG,OAAY,EAAA,WAAQ,SAAY,KAAA;GAClD,gBAAc,EAAA;GACd,SAAO;;oBAEG,CAAX,EAAW,CAAA,CAAA,CAAA;;;;;;;;OAEDA,EAAAA,OAAO,OAAA,EAAA,GAAnB,EAAyE,QAAzE,GAAyE,CAA1B,EAAmB,EAAA,QAAA,KAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,GAAA,GAAA,CAAA,EAAA,GAAA,CAAA"}
|
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
import { InjectionKey } from 'vue';
|
|
2
2
|
import { IconSource } from '../VIcon/types.js';
|
|
3
|
-
/**
|
|
4
|
-
* What each level of a VSideNavigation passes down to the level below it. An item
|
|
5
|
-
* reads the context of ITS level and provides a fresh one to its own children, and
|
|
6
|
-
* that renewal is precisely what keeps "only one section open at a time" local to a
|
|
7
|
-
* level rather than global to the whole sidebar.
|
|
8
|
-
*
|
|
9
|
-
* Two things deliberately do NOT travel through here:
|
|
10
|
-
*
|
|
11
|
-
* - the size and the density, which the CSS variables carry by inheritance from the
|
|
12
|
-
* nav down; passing them here as well would be the same information in two places,
|
|
13
|
-
* free to disagree;
|
|
14
|
-
* - the DEPTH of an item, which is counted by the cascade itself (see the alternating
|
|
15
|
-
* variables in VSideNavigationItem) — no registry, and no inline style.
|
|
16
|
-
*/
|
|
17
3
|
export interface SideNavigationContext {
|
|
18
4
|
/**
|
|
19
5
|
* The name shared by the collapsible sections of this level. Sections that share one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../../../src/components/VSideNavigation/context.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../../src/components/VSideNavigation/context.ts"],"sourcesContent":["/**\n * What each level of a VSideNavigation passes down to the level below it. An item\n * reads the context of ITS level and provides a fresh one to its own children, and\n * that renewal is precisely what keeps \"only one section open at a time\" local to a\n * level rather than global to the whole sidebar.\n *\n * Two things deliberately do NOT travel through here:\n *\n * - the size and the density, which the CSS variables carry by inheritance from the\n * nav down; passing them here as well would be the same information in two places,\n * free to disagree;\n * - the DEPTH of an item, which is counted by the cascade itself (see the alternating\n * variables in VSideNavigationItem) — no registry, and no inline style.\n */\n\nimport type { InjectionKey } from 'vue'\n\nimport type { IconSource } from '../VIcon/types'\n\nexport interface SideNavigationContext {\n /**\n * The name shared by the collapsible sections of this level. Sections that share one\n * close each other, which the browser does entirely on its own. Nothing here means\n * several may stay open at once.\n */\n name: string | undefined\n /**\n * Whether the sidebar was asked for one-at-a-time behaviour. It is passed down so\n * that each level can mint a name of its own.\n */\n exclusive: boolean\n /** The chevron of a closed section: an icon name, or an explicit render. */\n expandIcon: IconSource\n /**\n * The chevron of an open section. Nothing here means the closed one is simply\n * rotated.\n */\n collapseIcon: IconSource | undefined\n}\n\nexport const sideNavigationKey: InjectionKey<SideNavigationContext> = Symbol('v-side-navigation')\n"],"mappings":";AAwCA,IAAa,IAAyD,OAAO,mBAAmB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
|
|
2
|
-
@layer vectis.components{.v-skeleton{--skeleton-base:var(--vectis-color-surface-skeleton);--skeleton-highlight:oklch(from var(--skeleton-base) calc(l + .06) c h);--skeleton-h:var(--control-height);--skeleton-radius:var(--vectis-radius-interactive);--skeleton-gap:var(--vectis-space-2);gap:var(--skeleton-gap);flex-direction:column;display:flex}.v-skeleton[data-custom]{--skeleton-base:var(--custom-color)}.v-skeleton-item{inline-size:var(--skeleton-w,100%);block-size:var(--skeleton-h);border-radius:var(--skeleton-radius);background:var(--skeleton-base);flex:auto;position:relative;overflow:clip}.v-skeleton[data-shape=text]{--skeleton-h:1em;--skeleton-radius:var(--vectis-radius-pill);--skeleton-gap:max(0px, calc(1lh - 1em));padding-block:calc(
|
|
2
|
+
@layer vectis.components{.v-skeleton{--skeleton-base:var(--vectis-color-surface-skeleton);--skeleton-highlight:oklch(from var(--skeleton-base) calc(l + .06) c h);--skeleton-h:var(--control-height);--skeleton-radius:min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));--skeleton-gap:var(--vectis-space-2);gap:var(--skeleton-gap);flex-direction:column;display:flex}.v-skeleton[data-custom]{--skeleton-base:var(--custom-color)}.v-skeleton-item{inline-size:var(--skeleton-w,100%);block-size:var(--skeleton-h);border-radius:var(--skeleton-radius);background:var(--skeleton-base);flex:auto;position:relative;overflow:clip}.v-skeleton[data-shape=text]{--skeleton-h:1em;--skeleton-radius:var(--vectis-radius-pill);--skeleton-gap:max(0px, calc(1lh - 1em));padding-block:calc(var(--skeleton-gap) / 2)}.v-skeleton[data-shape=text] .v-skeleton-item{flex:none}.v-skeleton[data-shape=text] .v-skeleton-item+.v-skeleton-item:last-child{--skeleton-last-line:.6;inline-size:calc(var(--skeleton-w,100%) * var(--skeleton-last-line))}.v-skeleton[data-shape=pill]{--skeleton-radius:var(--vectis-radius-pill)}.v-skeleton[data-shape=circle]{--skeleton-radius:var(--vectis-radius-pill);align-items:start;display:inline-flex}.v-skeleton[data-shape=circle] .v-skeleton-item{inline-size:var(--skeleton-w,auto);aspect-ratio:1}.v-skeleton[data-shape=surface]{--skeleton-h:var(--vectis-control-size-skeleton-surface);--skeleton-radius:var(--vectis-radius-surface)}.v-skeleton:is([data-animation=wave],[data-animation=pulse]) .v-skeleton-item:after{content:"";position:absolute;inset:0}.v-skeleton[data-animation=pulse] .v-skeleton-item:after{background-color:var(--skeleton-highlight);animation:v-skeleton-pulse var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite}.v-skeleton[data-animation=wave] .v-skeleton-item:after{background-image:linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);animation:v-skeleton-wave var(--vectis-duration-1500) linear infinite}.v-skeleton[data-animation=wave]:dir(rtl) .v-skeleton-item:after{animation-direction:reverse}@keyframes v-skeleton-pulse{0%,to{opacity:0}50%{opacity:1}}@keyframes v-skeleton-wave{0%{translate:-100%}to{translate:100%}}@media (prefers-reduced-motion:reduce){.v-skeleton:is([data-animation=wave],[data-animation=pulse]) .v-skeleton-item:after{background-image:none;background-color:var(--skeleton-highlight);animation:v-skeleton-pulse var(--vectis-duration-5000) var(--vectis-ease-in-out) infinite}}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export type
|
|
3
|
-
export type
|
|
1
|
+
export type SkeletonLoaderShape = 'text' | 'control' | 'pill' | 'circle' | 'surface';
|
|
2
|
+
export type SkeletonLoaderAnimation = 'wave' | 'pulse' | 'none';
|
|
3
|
+
export type SkeletonLoaderSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
4
4
|
interface SkeletonLoaderProps {
|
|
5
5
|
/**
|
|
6
6
|
* What the silhouette stands for. Each value sets both a corner radius and a way of
|
|
@@ -13,13 +13,13 @@ interface SkeletonLoaderProps {
|
|
|
13
13
|
* - `circle` is that height in both dimensions — an avatar, a round icon button;
|
|
14
14
|
* - `surface` is a card or an image, with a height of its own.
|
|
15
15
|
*/
|
|
16
|
-
shape?:
|
|
16
|
+
shape?: SkeletonLoaderShape;
|
|
17
17
|
/**
|
|
18
18
|
* The size on the scale shared by every control. It only means something for the
|
|
19
19
|
* shapes sized like a control: text follows the typography around it, and a surface
|
|
20
20
|
* has its own height.
|
|
21
21
|
*/
|
|
22
|
-
size?:
|
|
22
|
+
size?: SkeletonLoaderSize;
|
|
23
23
|
/** Takes 4px off the height, as everywhere else in the design system. */
|
|
24
24
|
compact?: boolean;
|
|
25
25
|
/**
|
|
@@ -39,7 +39,7 @@ interface SkeletonLoaderProps {
|
|
|
39
39
|
* How the silhouette shows that something is happening. Turning it off freezes it,
|
|
40
40
|
* which suits printing, a screenshot, or a parent already animating.
|
|
41
41
|
*/
|
|
42
|
-
animation?:
|
|
42
|
+
animation?: SkeletonLoaderAnimation;
|
|
43
43
|
/**
|
|
44
44
|
* A background colour of your own, replacing the token. The wave's highlight is
|
|
45
45
|
* DERIVED from it, so it stays correct with nothing else to set.
|
|
@@ -61,14 +61,14 @@ interface SkeletonLoaderProps {
|
|
|
61
61
|
}
|
|
62
62
|
declare const __VLS_export: import('vue').DefineComponent<SkeletonLoaderProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SkeletonLoaderProps> & Readonly<{}>, {
|
|
63
63
|
label: string;
|
|
64
|
-
size:
|
|
64
|
+
size: SkeletonLoaderSize;
|
|
65
65
|
compact: boolean;
|
|
66
|
-
shape:
|
|
66
|
+
shape: SkeletonLoaderShape;
|
|
67
67
|
color: string;
|
|
68
68
|
width: number | string;
|
|
69
69
|
height: number | string;
|
|
70
70
|
lines: number;
|
|
71
|
-
animation:
|
|
71
|
+
animation: SkeletonLoaderAnimation;
|
|
72
72
|
announce: boolean;
|
|
73
73
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
74
74
|
declare const _default: typeof __VLS_export;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VSkeletonLoader.js","names":[],"sources":["../../../src/components/VSkeletonLoader/VSkeletonLoader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The grey silhouette standing in for content that has not arrived yet: a line of\n * text, a button, an avatar. It is drawn entirely in CSS.\n *\n * The element rendered is a CONTAINER holding its silhouettes, and not itself the\n * painted shape — the opposite of VProgressLinear. That is what makes several lines\n * possible at no cost, and what keeps every rule below uniform: there is no\n * \"painted root\" case beside a \"painted child\" one. It carries the shared size class,\n * so a skeleton of a given size is exactly as tall as a button of that size.\n *\n * The component MEASURES nothing. It does not look at what it replaces to work out a\n * shape; the shape is declared. The three derived values are all the JavaScript there\n * is — no event, no lifecycle, no DOM.\n */\nimport { computed } from 'vue'\n\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\nexport type SkeletonShape = 'text' | 'control' | 'pill' | 'circle' | 'surface'\nexport type SkeletonAnimation = 'wave' | 'pulse' | 'none'\nexport type SkeletonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface SkeletonLoaderProps {\n /**\n * What the silhouette stands for. Each value sets both a corner radius and a way of\n * being sized:\n *\n * - `text` follows the typography around it, so several silhouettes occupy exactly\n * as many lines as the text they replace;\n * - `control` takes the height of a control of the given size — a button, a field;\n * - `pill` is that same height with fully rounded ends — a chip, a badge;\n * - `circle` is that height in both dimensions — an avatar, a round icon button;\n * - `surface` is a card or an image, with a height of its own.\n */\n shape?: SkeletonShape\n /**\n * The size on the scale shared by every control. It only means something for the\n * shapes sized like a control: text follows the typography around it, and a surface\n * has its own height.\n */\n size?: SkeletonSize\n /** Takes 4px off the height, as everywhere else in the design system. */\n compact?: boolean\n /**\n * The width: a number is read as pixels, and anything else as a CSS length of your\n * own — `'100%'`, `'12ch'`. Left out, the silhouette takes all the width available.\n */\n width?: number | string\n /** The height, read the same way. It wins over the shape and the size. */\n height?: number | string\n /**\n * How many silhouettes to stack. In the text shape the LAST one is drawn shorter\n * than the others, and that single detail is what reads as a paragraph rather than\n * as a table.\n */\n lines?: number\n /**\n * How the silhouette shows that something is happening. Turning it off freezes it,\n * which suits printing, a screenshot, or a parent already animating.\n */\n animation?: SkeletonAnimation\n /**\n * A background colour of your own, replacing the token. The wave's highlight is\n * DERIVED from it, so it stays correct with nothing else to set.\n */\n color?: string\n /**\n * Announces the loading to screen readers. It is OFF by default, because a skeleton\n * is decorative: a page holds a dozen of them, and a dozen competing announcements\n * are unreadable. What should announce the wait is the container around them,\n * marked as busy.\n */\n announce?: boolean\n /**\n * What is announced, which also IMPLIES announcing. Prefer something situated —\n * \"Loading the results\" — since a generic word is the reason the default is silence.\n * It falls back to the design system dictionary.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonLoaderProps>(), {\n shape: 'text',\n size: 'md',\n compact: false,\n width: undefined,\n height: undefined,\n lines: 1,\n animation: 'wave',\n color: undefined,\n announce: false,\n label: undefined,\n})\n\n// A guard against two silent bugs: asked for zero lines the component would render\n// NOTHING at all — an invisible skeleton nobody notices is missing — and a fractional\n// count would produce a surprising number of them.\nconst count = computed(() => Math.max(1, Math.trunc(props.lines)))\n\n// @a11y — silent by default, since a dozen silhouettes must not produce a dozen\n// announcements. Supplying a label counts as asking to be announced, otherwise that\n// prop would sit there doing nothing.\nconst announced = computed(() => props.announce || props.label !== undefined)\n\nconst m = useMessages()\n// TRAP — the dictionary must never be read directly in the body of `setup`: the value\n// would be captured once and would stop following a later change of language.\nconst resolvedLabel = computed(() => props.label ?? m.value.common.loading)\n</script>\n\n<template>\n <span\n class=\"v-skeleton v-control\"\n :data-shape=\"shape\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-animation=\"animation\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :role=\"announced ? 'status' : undefined\"\n :aria-hidden=\"announced ? undefined : 'true'\"\n :style=\"{\n '--custom-color': color,\n '--skeleton-w': cssSize(width),\n '--skeleton-h': cssSize(height),\n }\"\n >\n <!--\n TRAP — the label is rendered BEFORE the silhouettes, and that order is\n structural. The rule shortening the last line of a paragraph asks for the last\n CHILD, so a label rendered after them would quietly take that place and no line\n would be shortened. A unit test locks the order.\n\n It costs no layout: the class hiding it takes it out of the flow entirely, so it\n is never one of the stacked items. And it is rendered only when something is\n actually announced — inside a subtree hidden from screen readers it would be text\n nobody can reach.\n -->\n <span v-if=\"announced\" class=\"v-visually-hidden\">{{ resolvedLabel }}</span>\n <span v-for=\"n in count\" :key=\"n\" class=\"v-skeleton-item\" />\n </span>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The whole geometry comes down to four variables. The shape table below sets them,\n * and the dimension props overwrite them inline — which always wins over a rule\n * targeting the same element, so no specificity contest is possible.\n */\n .v-skeleton {\n /* The grey has a token of its own. No existing colour role holds the right value in\n BOTH themes: the muted surface is too pale in the light one for the pulse to be\n visible at all, and the border colour has the right tone but the wrong meaning. */\n --skeleton-base: var(--vectis-color-surface-skeleton);\n /*\n * The lighter shade the animation sweeps across is DERIVED from the grey rather\n * than named: it is that same colour, a little lighter.\n *\n * Expressing it as a lightness STEP is what makes one declaration correct in both\n * themes. Mixing towards a target colour would not: in the light theme the\n * silhouette is darker than the page, in the dark theme it is LIGHTER than it, so\n * any fixed target would lighten in one and darken in the other. A step in\n * lightness always goes the same way — and in the light theme it naturally stops at\n * white, exactly the page's colour.\n *\n * It also follows a custom colour with nothing else to set. The step itself is a\n * bare ratio, the same tolerance as the opacities.\n */\n --skeleton-highlight: oklch(from var(--skeleton-base) calc(l + 0.06) c h);\n --skeleton-h: var(--control-height);\n --skeleton-radius: var(--vectis-radius-interactive);\n --skeleton-gap: var(--vectis-space-2);\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n }\n\n /* A custom colour wins by specificity rather than by order, being one step more\n specific than the rule above — unlike VProgressLinear's tones, which all sit at the\n same level and depend on their sequence. */\n .v-skeleton[data-custom] {\n --skeleton-base: var(--custom-color);\n }\n\n .v-skeleton-item {\n /* The animation's overlay is positioned against this box. */\n position: relative;\n /* The height from the shape table is a DEFAULT: inside a parent that has a height\n of its own, the silhouette grows to fill it — a card fills its slot. */\n flex: 1 1 auto;\n inline-size: var(--skeleton-w, 100%);\n block-size: var(--skeleton-h);\n /* Clipped rather than hidden: hiding the overflow would turn every silhouette into\n a scroll container, for nothing. */\n overflow: clip;\n border-radius: var(--skeleton-radius);\n background: var(--skeleton-base);\n }\n\n /*\n * A line of text is one em tall, which means it follows the typography it INHERITS,\n * and it is centred in the line box the same way a line of text would be.\n *\n * The gap between lines and the padding around them are derived from that same line\n * height, so that N silhouettes occupy exactly N lines of text: replacing them with\n * the real content shifts nothing on the page. The floor guards against a parent\n * whose lines are set tighter than its font size, where the gap would otherwise go\n * negative.\n */\n .v-skeleton[data-shape='text'] {\n --skeleton-h: 1em;\n --skeleton-radius: var(--vectis-radius-pill);\n --skeleton-gap: max(0px, calc(1lh - 1em));\n padding-block: calc(max(0px, calc(1lh - 1em)) / 2);\n }\n\n /* A line of text keeps the height its typography gives it: unlike the other shapes it\n neither stretches in a tall parent nor squashes in a short one. */\n .v-skeleton[data-shape='text'] .v-skeleton-item {\n flex: none;\n }\n\n /*\n * The shortened last line, the one detail that makes a stack of bars read as a\n * paragraph. Asking for a line PRECEDED by another is what guarantees it only\n * applies from two lines up — a single line is not a paragraph — and the proportion\n * is taken from the EFFECTIVE width, so it still works under a `width` prop.\n */\n .v-skeleton[data-shape='text'] .v-skeleton-item + .v-skeleton-item:last-child {\n --skeleton-last-line: 0.6;\n inline-size: calc(var(--skeleton-w, 100%) * var(--skeleton-last-line));\n }\n\n .v-skeleton[data-shape='pill'] {\n --skeleton-radius: var(--vectis-radius-pill);\n }\n\n /*\n * A circle takes its width FROM its height through the ratio, so changing the size\n * alone changes the diameter and nothing has to be kept in step.\n *\n * The container sits inline, like the avatar it replaces, rather than spanning the\n * whole width, and aligning to the start stops the silhouette from being stretched\n * sideways — which is what keeps the circle round.\n */\n .v-skeleton[data-shape='circle'] {\n --skeleton-radius: var(--vectis-radius-pill);\n display: inline-flex;\n align-items: start;\n }\n\n .v-skeleton[data-shape='circle'] .v-skeleton-item {\n /* Left to the content rather than set to the full width, so that the ratio is what\n decides. An explicit `width` still takes over, and then knowingly gives an\n oval. */\n inline-size: var(--skeleton-w, auto);\n aspect-ratio: 1;\n }\n\n /*\n * A surface — a card, an image, a block — has no height anyone could guess without\n * measuring the page, which this component deliberately never does. It takes a\n * default from a token, which the `height` prop overrides, as does any consumer style\n * (theirs sits outside our layers and therefore wins).\n */\n .v-skeleton[data-shape='surface'] {\n --skeleton-h: var(--vectis-control-size-skeleton-surface);\n --skeleton-radius: var(--vectis-radius-surface);\n }\n\n /*\n * The pulse: a flat sheet of the lighter shade fades in and out OVER the silhouette.\n *\n * Fading the silhouette itself would be shorter to write, and wrong: it would fade\n * towards the PAGE, which means lightening in the light theme and DARKENING in the\n * dark one — the opposite of what the wave does. Going through an overlay in the\n * derived colour gives the same direction in both, and it is still only an opacity\n * being animated, so it costs no layout.\n */\n .v-skeleton[data-animation='pulse'] .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite;\n }\n\n /*\n * The wave: a band of light crossing the silhouette.\n *\n * The gradient is SYMMETRIC — transparent, light, transparent — so the physical angle\n * it is drawn at makes no observable difference, and there is nothing to mirror in a\n * right-to-left page. All that matters is the DIRECTION of the run, and reversing the\n * animation is enough for that. It is exact here because the run is linear, hence\n * identical read backwards; the same argument VProgressLinear uses for its\n * indeterminate bar.\n *\n * The band is moved by a transform, where VProgressLinear runs a logical property.\n * The trade-off is genuinely reversed between the two: that component has a vertical\n * orientation to serve and only ever draws one bar, whereas a page may hold a dozen\n * skeletons, and here a movement the compositor can handle without laying anything\n * out is no longer negotiable.\n */\n .v-skeleton[data-animation='wave'] .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n background-image: linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);\n animation: v-skeleton-wave var(--vectis-duration-1500) linear infinite;\n }\n\n /* Scoped to the wave: the pulse uses the same overlay, but its run is symmetric in\n time, so reversing it would change nothing at all. */\n .v-skeleton[data-animation='wave']:dir(rtl) .v-skeleton-item::after {\n animation-direction: reverse;\n }\n\n /* These keyframes serve this component alone, so they stay in its own stylesheet.\n Only the spin shared by VSpinner and VProgressCircular is declared globally, in\n styles/utilities.css. */\n @keyframes v-skeleton-pulse {\n from,\n to {\n opacity: 0;\n }\n\n 50% {\n opacity: 1;\n }\n }\n\n @keyframes v-skeleton-wave {\n from {\n translate: -100% 0;\n }\n\n to {\n translate: 100% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * The design system's rule for readers who ask for less motion is to slow down\n * rather than to stop: a motionless placeholder no longer says that anything is in\n * progress. But the wave is a TRANSLATION, which is exactly what those readers are\n * flagging, so it FALLS BACK to the pulse — which keeps the signal without moving\n * anything. Both are then slowed considerably.\n *\n * Since the two animations share the same overlay, all that is left to do is\n * replace the moving gradient with the flat colour.\n *\n * TRAP — this rule has exactly the same specificity as the two it overrides, so it\n * is its position at the END of the stylesheet that makes it win.\n */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n background-image: none;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-5000) var(--vectis-ease-in-out) infinite;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"VSkeletonLoader.js","names":[],"sources":["../../../src/components/VSkeletonLoader/VSkeletonLoader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The silhouette standing in for content that has not arrived: a line of text, a button, an\n * avatar. Drawn entirely in CSS.\n *\n * The root is a CONTAINER holding its silhouettes rather than being the painted shape — the\n * opposite of VProgressLinear. That is what makes `lines` free and keeps every rule below\n * uniform, with no \"painted root\" case beside a \"painted child\" one. It carries `v-control`,\n * so a skeleton of a given size is exactly as tall as a button of that size.\n *\n * It MEASURES nothing: the shape is declared, never inferred from what it replaces. Three\n * derived values are the whole of the JS — no event, no lifecycle, no DOM.\n */\nimport { computed } from 'vue'\n\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\nexport type SkeletonLoaderShape = 'text' | 'control' | 'pill' | 'circle' | 'surface'\nexport type SkeletonLoaderAnimation = 'wave' | 'pulse' | 'none'\nexport type SkeletonLoaderSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface SkeletonLoaderProps {\n /**\n * What the silhouette stands for. Each value sets both a corner radius and a way of\n * being sized:\n *\n * - `text` follows the typography around it, so several silhouettes occupy exactly\n * as many lines as the text they replace;\n * - `control` takes the height of a control of the given size — a button, a field;\n * - `pill` is that same height with fully rounded ends — a chip, a badge;\n * - `circle` is that height in both dimensions — an avatar, a round icon button;\n * - `surface` is a card or an image, with a height of its own.\n */\n shape?: SkeletonLoaderShape\n /**\n * The size on the scale shared by every control. It only means something for the\n * shapes sized like a control: text follows the typography around it, and a surface\n * has its own height.\n */\n size?: SkeletonLoaderSize\n /** Takes 4px off the height, as everywhere else in the design system. */\n compact?: boolean\n /**\n * The width: a number is read as pixels, and anything else as a CSS length of your\n * own — `'100%'`, `'12ch'`. Left out, the silhouette takes all the width available.\n */\n width?: number | string\n /** The height, read the same way. It wins over the shape and the size. */\n height?: number | string\n /**\n * How many silhouettes to stack. In the text shape the LAST one is drawn shorter\n * than the others, and that single detail is what reads as a paragraph rather than\n * as a table.\n */\n lines?: number\n /**\n * How the silhouette shows that something is happening. Turning it off freezes it,\n * which suits printing, a screenshot, or a parent already animating.\n */\n animation?: SkeletonLoaderAnimation\n /**\n * A background colour of your own, replacing the token. The wave's highlight is\n * DERIVED from it, so it stays correct with nothing else to set.\n */\n color?: string\n /**\n * Announces the loading to screen readers. It is OFF by default, because a skeleton\n * is decorative: a page holds a dozen of them, and a dozen competing announcements\n * are unreadable. What should announce the wait is the container around them,\n * marked as busy.\n */\n announce?: boolean\n /**\n * What is announced, which also IMPLIES announcing. Prefer something situated —\n * \"Loading the results\" — since a generic word is the reason the default is silence.\n * It falls back to the design system dictionary.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonLoaderProps>(), {\n shape: 'text',\n size: 'md',\n compact: false,\n width: undefined,\n height: undefined,\n lines: 1,\n animation: 'wave',\n color: undefined,\n announce: false,\n label: undefined,\n})\n\n// A guard against two silent bugs: asked for zero lines the component would render\n// NOTHING at all — an invisible skeleton nobody notices is missing — and a fractional\n// count would produce a surprising number of them.\nconst count = computed(() => Math.max(1, Math.trunc(props.lines)))\n\n// @a11y — silent by default, since a dozen silhouettes must not produce a dozen\n// announcements. Supplying a label counts as asking to be announced, otherwise that\n// prop would sit there doing nothing.\nconst announced = computed(() => props.announce || props.label !== undefined)\n\nconst m = useMessages()\n// TRAP — the dictionary must never be read directly in the body of `setup`: the value\n// would be captured once and would stop following a later change of language.\nconst resolvedLabel = computed(() => props.label ?? m.value.common.loading)\n</script>\n\n<template>\n <span\n class=\"v-skeleton v-control\"\n :data-shape=\"shape\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-animation=\"animation\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :role=\"announced ? 'status' : undefined\"\n :aria-hidden=\"announced ? undefined : 'true'\"\n :style=\"{\n '--custom-color': color,\n '--skeleton-w': cssSize(width),\n '--skeleton-h': cssSize(height),\n }\"\n >\n <!--\n TRAP — the label is rendered BEFORE the silhouettes, and that order is\n structural. The rule shortening the last line of a paragraph asks for the last\n CHILD, so a label rendered after them would quietly take that place and no line\n would be shortened. A unit test locks the order.\n\n It costs no layout: the class hiding it takes it out of the flow entirely, so it\n is never one of the stacked items. And it is rendered only when something is\n actually announced — inside a subtree hidden from screen readers it would be text\n nobody can reach.\n -->\n <span v-if=\"announced\" class=\"v-visually-hidden\">{{ resolvedLabel }}</span>\n <span v-for=\"n in count\" :key=\"n\" class=\"v-skeleton-item\" />\n </span>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The whole geometry comes down to four variables. The shape table below sets them,\n * and the dimension props overwrite them inline — which always wins over a rule\n * targeting the same element, so no specificity contest is possible.\n */\n .v-skeleton {\n /* The grey has a token of its own. No existing colour role holds the right value in\n BOTH themes: the muted surface is too pale in the light one for the pulse to be\n visible at all, and the border colour has the right tone but the wrong meaning. */\n --skeleton-base: var(--vectis-color-surface-skeleton);\n /*\n * The highlight is DERIVED from the grey rather than named: the same colour, a little\n * lighter. A lightness STEP is what makes one declaration correct in both themes, where\n * a `color-mix()` towards a target would not — the silhouette is darker than the page in\n * light and LIGHTER than it in dark, so a fixed target would lighten in one and darken in\n * the other. It also follows a custom `color` with nothing else to set.\n */\n --skeleton-highlight: oklch(from var(--skeleton-base) calc(l + 0.06) c h);\n --skeleton-h: var(--control-height);\n /* The corner a CONTROL-sized silhouette takes, whatever height this instance ends up\n with: a browser scales down a radius it cannot fit, so min() gives a silhouette that\n grew the same reduction a control-tall one already gets. It resolves to the token\n itself at the shipped 6px.\n\n TRAP — the cap is NOT calc(var(--skeleton-h) / 2), which looks like the closer unit\n and is the wrong one twice over: --skeleton-h is a flex BASIS on an item that grows\n to fill a taller parent (see below), and the `height` prop overwrites it inline. Two\n equally tall silhouettes would then round differently depending on how they got\n there. */\n --skeleton-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n --skeleton-gap: var(--vectis-space-2);\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n }\n\n /* A custom colour wins by specificity rather than by order, being one step more\n specific than the rule above — unlike VProgressLinear's tones, which all sit at the\n same level and depend on their sequence. */\n .v-skeleton[data-custom] {\n --skeleton-base: var(--custom-color);\n }\n\n .v-skeleton-item {\n /* The animation's overlay is positioned against this box. */\n position: relative;\n /* The height from the shape table is a DEFAULT: inside a parent that has a height\n of its own, the silhouette grows to fill it — a card fills its slot. */\n flex: 1 1 auto;\n inline-size: var(--skeleton-w, 100%);\n block-size: var(--skeleton-h);\n /* Clipped rather than hidden: hiding the overflow would turn every silhouette into\n a scroll container, for nothing. */\n overflow: clip;\n border-radius: var(--skeleton-radius);\n background: var(--skeleton-base);\n }\n\n /*\n * A line of text is one em tall, which means it follows the typography it INHERITS,\n * and it is centred in the line box the same way a line of text would be.\n *\n * The gap between lines and the padding around them are derived from that same line\n * height, so that N silhouettes occupy exactly N lines of text: replacing them with\n * the real content shifts nothing on the page. The floor guards against a parent\n * whose lines are set tighter than its font size, where the gap would otherwise go\n * negative.\n */\n .v-skeleton[data-shape='text'] {\n --skeleton-h: 1em;\n --skeleton-radius: var(--vectis-radius-pill);\n --skeleton-gap: max(0px, calc(1lh - 1em));\n padding-block: calc(var(--skeleton-gap) / 2);\n }\n\n /* A line of text keeps the height its typography gives it: unlike the other shapes it\n neither stretches in a tall parent nor squashes in a short one. */\n .v-skeleton[data-shape='text'] .v-skeleton-item {\n flex: none;\n }\n\n /*\n * The shortened last line, the one detail that makes a stack of bars read as a\n * paragraph. Asking for a line PRECEDED by another is what guarantees it only\n * applies from two lines up — a single line is not a paragraph — and the proportion\n * is taken from the EFFECTIVE width, so it still works under a `width` prop.\n */\n .v-skeleton[data-shape='text'] .v-skeleton-item + .v-skeleton-item:last-child {\n --skeleton-last-line: 0.6;\n inline-size: calc(var(--skeleton-w, 100%) * var(--skeleton-last-line));\n }\n\n .v-skeleton[data-shape='pill'] {\n --skeleton-radius: var(--vectis-radius-pill);\n }\n\n /*\n * A circle takes its width FROM its height through the ratio, so changing the size\n * alone changes the diameter and nothing has to be kept in step.\n *\n * The container sits inline, like the avatar it replaces, rather than spanning the\n * whole width, and aligning to the start stops the silhouette from being stretched\n * sideways — which is what keeps the circle round.\n */\n .v-skeleton[data-shape='circle'] {\n --skeleton-radius: var(--vectis-radius-pill);\n display: inline-flex;\n align-items: start;\n }\n\n .v-skeleton[data-shape='circle'] .v-skeleton-item {\n /* Left to the content rather than set to the full width, so that the ratio is what\n decides. An explicit `width` still takes over, and then knowingly gives an\n oval. */\n inline-size: var(--skeleton-w, auto);\n aspect-ratio: 1;\n }\n\n /*\n * A surface — a card, an image, a block — has no height anyone could guess without\n * measuring the page, which this component deliberately never does. It takes a\n * default from a token, which the `height` prop overrides, as does any consumer style\n * (theirs sits outside our layers and therefore wins).\n */\n .v-skeleton[data-shape='surface'] {\n --skeleton-h: var(--vectis-control-size-skeleton-surface);\n --skeleton-radius: var(--vectis-radius-surface);\n }\n\n /* The overlay both animations paint on, laid over the whole silhouette. */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n }\n\n /*\n * The pulse: a flat sheet of the lighter shade fades in and out OVER the silhouette.\n *\n * Fading the silhouette itself would be shorter to write, and wrong: it would fade\n * towards the PAGE, which means lightening in the light theme and DARKENING in the\n * dark one — the opposite of what the wave does. Going through an overlay in the\n * derived colour gives the same direction in both, and it is still only an opacity\n * being animated, so it costs no layout.\n */\n .v-skeleton[data-animation='pulse'] .v-skeleton-item::after {\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite;\n }\n\n /*\n * The wave: a band of light crossing the silhouette.\n *\n * The gradient is SYMMETRIC — transparent, light, transparent — so its physical angle makes\n * no observable difference and there is nothing to mirror in RTL. Only the DIRECTION of the\n * run matters, and `animation-direction: reverse` covers it exactly, the run being linear\n * and therefore identical read backwards.\n *\n * Moved by `translate`, where VProgressLinear animates a logical property: the trade-off is\n * reversed between the two, that component drawing one bar where a page may hold a dozen\n * skeletons, so a compositor-only movement is not negotiable here.\n */\n .v-skeleton[data-animation='wave'] .v-skeleton-item::after {\n background-image: linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);\n animation: v-skeleton-wave var(--vectis-duration-1500) linear infinite;\n }\n\n /* Scoped to the wave: the pulse uses the same overlay, but its run is symmetric in\n time, so reversing it would change nothing at all. */\n .v-skeleton[data-animation='wave']:dir(rtl) .v-skeleton-item::after {\n animation-direction: reverse;\n }\n\n /* These keyframes serve this component alone, so they stay in its own stylesheet.\n Only the spin shared by VSpinner and VProgressCircular is declared globally, in\n styles/utilities.css. */\n @keyframes v-skeleton-pulse {\n from,\n to {\n opacity: 0;\n }\n\n 50% {\n opacity: 1;\n }\n }\n\n @keyframes v-skeleton-wave {\n from {\n translate: -100% 0;\n }\n\n to {\n translate: 100% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * Reduced motion SLOWS rather than stops: a motionless placeholder no longer says\n * anything is in progress. But the wave is a TRANSLATION, precisely what these readers\n * flag, so it falls back to the pulse — the same signal without movement. Both are then\n * slowed considerably. The two share one overlay, so all that is left is replacing the\n * moving gradient with the flat fill.\n *\n * TRAP — this has exactly the specificity of the two rules it overrides, so its position\n * at the END of the sheet is the whole of what makes it win.\n */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n background-image: none;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-5000) var(--vectis-ease-in-out) infinite;\n }\n }\n}\n</style>\n"],"mappings":""}
|
package/dist/components/VSkeletonLoader/VSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VSkeletonLoader.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VSkeletonLoader/VSkeletonLoader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The grey silhouette standing in for content that has not arrived yet: a line of\n * text, a button, an avatar. It is drawn entirely in CSS.\n *\n * The element rendered is a CONTAINER holding its silhouettes, and not itself the\n * painted shape — the opposite of VProgressLinear. That is what makes several lines\n * possible at no cost, and what keeps every rule below uniform: there is no\n * \"painted root\" case beside a \"painted child\" one. It carries the shared size class,\n * so a skeleton of a given size is exactly as tall as a button of that size.\n *\n * The component MEASURES nothing. It does not look at what it replaces to work out a\n * shape; the shape is declared. The three derived values are all the JavaScript there\n * is — no event, no lifecycle, no DOM.\n */\nimport { computed } from 'vue'\n\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\nexport type SkeletonShape = 'text' | 'control' | 'pill' | 'circle' | 'surface'\nexport type SkeletonAnimation = 'wave' | 'pulse' | 'none'\nexport type SkeletonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface SkeletonLoaderProps {\n /**\n * What the silhouette stands for. Each value sets both a corner radius and a way of\n * being sized:\n *\n * - `text` follows the typography around it, so several silhouettes occupy exactly\n * as many lines as the text they replace;\n * - `control` takes the height of a control of the given size — a button, a field;\n * - `pill` is that same height with fully rounded ends — a chip, a badge;\n * - `circle` is that height in both dimensions — an avatar, a round icon button;\n * - `surface` is a card or an image, with a height of its own.\n */\n shape?: SkeletonShape\n /**\n * The size on the scale shared by every control. It only means something for the\n * shapes sized like a control: text follows the typography around it, and a surface\n * has its own height.\n */\n size?: SkeletonSize\n /** Takes 4px off the height, as everywhere else in the design system. */\n compact?: boolean\n /**\n * The width: a number is read as pixels, and anything else as a CSS length of your\n * own — `'100%'`, `'12ch'`. Left out, the silhouette takes all the width available.\n */\n width?: number | string\n /** The height, read the same way. It wins over the shape and the size. */\n height?: number | string\n /**\n * How many silhouettes to stack. In the text shape the LAST one is drawn shorter\n * than the others, and that single detail is what reads as a paragraph rather than\n * as a table.\n */\n lines?: number\n /**\n * How the silhouette shows that something is happening. Turning it off freezes it,\n * which suits printing, a screenshot, or a parent already animating.\n */\n animation?: SkeletonAnimation\n /**\n * A background colour of your own, replacing the token. The wave's highlight is\n * DERIVED from it, so it stays correct with nothing else to set.\n */\n color?: string\n /**\n * Announces the loading to screen readers. It is OFF by default, because a skeleton\n * is decorative: a page holds a dozen of them, and a dozen competing announcements\n * are unreadable. What should announce the wait is the container around them,\n * marked as busy.\n */\n announce?: boolean\n /**\n * What is announced, which also IMPLIES announcing. Prefer something situated —\n * \"Loading the results\" — since a generic word is the reason the default is silence.\n * It falls back to the design system dictionary.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonLoaderProps>(), {\n shape: 'text',\n size: 'md',\n compact: false,\n width: undefined,\n height: undefined,\n lines: 1,\n animation: 'wave',\n color: undefined,\n announce: false,\n label: undefined,\n})\n\n// A guard against two silent bugs: asked for zero lines the component would render\n// NOTHING at all — an invisible skeleton nobody notices is missing — and a fractional\n// count would produce a surprising number of them.\nconst count = computed(() => Math.max(1, Math.trunc(props.lines)))\n\n// @a11y — silent by default, since a dozen silhouettes must not produce a dozen\n// announcements. Supplying a label counts as asking to be announced, otherwise that\n// prop would sit there doing nothing.\nconst announced = computed(() => props.announce || props.label !== undefined)\n\nconst m = useMessages()\n// TRAP — the dictionary must never be read directly in the body of `setup`: the value\n// would be captured once and would stop following a later change of language.\nconst resolvedLabel = computed(() => props.label ?? m.value.common.loading)\n</script>\n\n<template>\n <span\n class=\"v-skeleton v-control\"\n :data-shape=\"shape\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-animation=\"animation\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :role=\"announced ? 'status' : undefined\"\n :aria-hidden=\"announced ? undefined : 'true'\"\n :style=\"{\n '--custom-color': color,\n '--skeleton-w': cssSize(width),\n '--skeleton-h': cssSize(height),\n }\"\n >\n <!--\n TRAP — the label is rendered BEFORE the silhouettes, and that order is\n structural. The rule shortening the last line of a paragraph asks for the last\n CHILD, so a label rendered after them would quietly take that place and no line\n would be shortened. A unit test locks the order.\n\n It costs no layout: the class hiding it takes it out of the flow entirely, so it\n is never one of the stacked items. And it is rendered only when something is\n actually announced — inside a subtree hidden from screen readers it would be text\n nobody can reach.\n -->\n <span v-if=\"announced\" class=\"v-visually-hidden\">{{ resolvedLabel }}</span>\n <span v-for=\"n in count\" :key=\"n\" class=\"v-skeleton-item\" />\n </span>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The whole geometry comes down to four variables. The shape table below sets them,\n * and the dimension props overwrite them inline — which always wins over a rule\n * targeting the same element, so no specificity contest is possible.\n */\n .v-skeleton {\n /* The grey has a token of its own. No existing colour role holds the right value in\n BOTH themes: the muted surface is too pale in the light one for the pulse to be\n visible at all, and the border colour has the right tone but the wrong meaning. */\n --skeleton-base: var(--vectis-color-surface-skeleton);\n /*\n * The lighter shade the animation sweeps across is DERIVED from the grey rather\n * than named: it is that same colour, a little lighter.\n *\n * Expressing it as a lightness STEP is what makes one declaration correct in both\n * themes. Mixing towards a target colour would not: in the light theme the\n * silhouette is darker than the page, in the dark theme it is LIGHTER than it, so\n * any fixed target would lighten in one and darken in the other. A step in\n * lightness always goes the same way — and in the light theme it naturally stops at\n * white, exactly the page's colour.\n *\n * It also follows a custom colour with nothing else to set. The step itself is a\n * bare ratio, the same tolerance as the opacities.\n */\n --skeleton-highlight: oklch(from var(--skeleton-base) calc(l + 0.06) c h);\n --skeleton-h: var(--control-height);\n --skeleton-radius: var(--vectis-radius-interactive);\n --skeleton-gap: var(--vectis-space-2);\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n }\n\n /* A custom colour wins by specificity rather than by order, being one step more\n specific than the rule above — unlike VProgressLinear's tones, which all sit at the\n same level and depend on their sequence. */\n .v-skeleton[data-custom] {\n --skeleton-base: var(--custom-color);\n }\n\n .v-skeleton-item {\n /* The animation's overlay is positioned against this box. */\n position: relative;\n /* The height from the shape table is a DEFAULT: inside a parent that has a height\n of its own, the silhouette grows to fill it — a card fills its slot. */\n flex: 1 1 auto;\n inline-size: var(--skeleton-w, 100%);\n block-size: var(--skeleton-h);\n /* Clipped rather than hidden: hiding the overflow would turn every silhouette into\n a scroll container, for nothing. */\n overflow: clip;\n border-radius: var(--skeleton-radius);\n background: var(--skeleton-base);\n }\n\n /*\n * A line of text is one em tall, which means it follows the typography it INHERITS,\n * and it is centred in the line box the same way a line of text would be.\n *\n * The gap between lines and the padding around them are derived from that same line\n * height, so that N silhouettes occupy exactly N lines of text: replacing them with\n * the real content shifts nothing on the page. The floor guards against a parent\n * whose lines are set tighter than its font size, where the gap would otherwise go\n * negative.\n */\n .v-skeleton[data-shape='text'] {\n --skeleton-h: 1em;\n --skeleton-radius: var(--vectis-radius-pill);\n --skeleton-gap: max(0px, calc(1lh - 1em));\n padding-block: calc(max(0px, calc(1lh - 1em)) / 2);\n }\n\n /* A line of text keeps the height its typography gives it: unlike the other shapes it\n neither stretches in a tall parent nor squashes in a short one. */\n .v-skeleton[data-shape='text'] .v-skeleton-item {\n flex: none;\n }\n\n /*\n * The shortened last line, the one detail that makes a stack of bars read as a\n * paragraph. Asking for a line PRECEDED by another is what guarantees it only\n * applies from two lines up — a single line is not a paragraph — and the proportion\n * is taken from the EFFECTIVE width, so it still works under a `width` prop.\n */\n .v-skeleton[data-shape='text'] .v-skeleton-item + .v-skeleton-item:last-child {\n --skeleton-last-line: 0.6;\n inline-size: calc(var(--skeleton-w, 100%) * var(--skeleton-last-line));\n }\n\n .v-skeleton[data-shape='pill'] {\n --skeleton-radius: var(--vectis-radius-pill);\n }\n\n /*\n * A circle takes its width FROM its height through the ratio, so changing the size\n * alone changes the diameter and nothing has to be kept in step.\n *\n * The container sits inline, like the avatar it replaces, rather than spanning the\n * whole width, and aligning to the start stops the silhouette from being stretched\n * sideways — which is what keeps the circle round.\n */\n .v-skeleton[data-shape='circle'] {\n --skeleton-radius: var(--vectis-radius-pill);\n display: inline-flex;\n align-items: start;\n }\n\n .v-skeleton[data-shape='circle'] .v-skeleton-item {\n /* Left to the content rather than set to the full width, so that the ratio is what\n decides. An explicit `width` still takes over, and then knowingly gives an\n oval. */\n inline-size: var(--skeleton-w, auto);\n aspect-ratio: 1;\n }\n\n /*\n * A surface — a card, an image, a block — has no height anyone could guess without\n * measuring the page, which this component deliberately never does. It takes a\n * default from a token, which the `height` prop overrides, as does any consumer style\n * (theirs sits outside our layers and therefore wins).\n */\n .v-skeleton[data-shape='surface'] {\n --skeleton-h: var(--vectis-control-size-skeleton-surface);\n --skeleton-radius: var(--vectis-radius-surface);\n }\n\n /*\n * The pulse: a flat sheet of the lighter shade fades in and out OVER the silhouette.\n *\n * Fading the silhouette itself would be shorter to write, and wrong: it would fade\n * towards the PAGE, which means lightening in the light theme and DARKENING in the\n * dark one — the opposite of what the wave does. Going through an overlay in the\n * derived colour gives the same direction in both, and it is still only an opacity\n * being animated, so it costs no layout.\n */\n .v-skeleton[data-animation='pulse'] .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite;\n }\n\n /*\n * The wave: a band of light crossing the silhouette.\n *\n * The gradient is SYMMETRIC — transparent, light, transparent — so the physical angle\n * it is drawn at makes no observable difference, and there is nothing to mirror in a\n * right-to-left page. All that matters is the DIRECTION of the run, and reversing the\n * animation is enough for that. It is exact here because the run is linear, hence\n * identical read backwards; the same argument VProgressLinear uses for its\n * indeterminate bar.\n *\n * The band is moved by a transform, where VProgressLinear runs a logical property.\n * The trade-off is genuinely reversed between the two: that component has a vertical\n * orientation to serve and only ever draws one bar, whereas a page may hold a dozen\n * skeletons, and here a movement the compositor can handle without laying anything\n * out is no longer negotiable.\n */\n .v-skeleton[data-animation='wave'] .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n background-image: linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);\n animation: v-skeleton-wave var(--vectis-duration-1500) linear infinite;\n }\n\n /* Scoped to the wave: the pulse uses the same overlay, but its run is symmetric in\n time, so reversing it would change nothing at all. */\n .v-skeleton[data-animation='wave']:dir(rtl) .v-skeleton-item::after {\n animation-direction: reverse;\n }\n\n /* These keyframes serve this component alone, so they stay in its own stylesheet.\n Only the spin shared by VSpinner and VProgressCircular is declared globally, in\n styles/utilities.css. */\n @keyframes v-skeleton-pulse {\n from,\n to {\n opacity: 0;\n }\n\n 50% {\n opacity: 1;\n }\n }\n\n @keyframes v-skeleton-wave {\n from {\n translate: -100% 0;\n }\n\n to {\n translate: 100% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * The design system's rule for readers who ask for less motion is to slow down\n * rather than to stop: a motionless placeholder no longer says that anything is in\n * progress. But the wave is a TRANSLATION, which is exactly what those readers are\n * flagging, so it FALLS BACK to the pulse — which keeps the signal without moving\n * anything. Both are then slowed considerably.\n *\n * Since the two animations share the same overlay, all that is left to do is\n * replace the moving gradient with the flat colour.\n *\n * TRAP — this rule has exactly the same specificity as the two it overrides, so it\n * is its position at the END of the stylesheet that makes it win.\n */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n background-image: none;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-5000) var(--vectis-ease-in-out) infinite;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmFA,IAAM,IAAQ,GAgBR,IAAQ,QAAe,KAAK,IAAI,GAAG,KAAK,MAAM,EAAM,KAAK,CAAC,CAAC,GAK3D,IAAY,QAAe,EAAM,YAAY,EAAM,UAAU,KAAA,CAAS,GAEtE,IAAI,EAAY,GAGhB,IAAgB,QAAe,EAAM,SAAS,EAAE,MAAM,OAAO,OAAO;yBAIxE,EA4BO,QAAA;GA3BL,OAAM;GACL,cAAY,EAAA;GACZ,aAAW,EAAA;GACX,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,kBAAgB,EAAA;GAChB,eAAa,EAAA,UAAU,KAAA,IAAiB,KAAA,IAAR;GAChC,MAAM,EAAA,QAAS,WAAc,KAAA;GAC7B,eAAa,EAAA,QAAY,KAAA,IAAS;GAClC,OAAK,EAAA;sBAA4B,EAAA;oBAA6B,EAAA,CAAA,CAAO,CAAC,EAAA,KAAK;oBAAyB,EAAA,CAAA,CAAO,CAAC,EAAA,MAAM;;MAiBvG,EAAA,SAAA,EAAA,GAAZ,EAA2E,QAA3E,GAA2E,EAAvB,EAAA,KAAa,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,GACjE,EAA4D,GAAA,MAAA,EAA1C,EAAA,QAAL,YAAb,EAA4D,QAAA;GAAlC,KAAK;GAAG,OAAM"}
|
|
1
|
+
{"version":3,"file":"VSkeletonLoader.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/VSkeletonLoader/VSkeletonLoader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The silhouette standing in for content that has not arrived: a line of text, a button, an\n * avatar. Drawn entirely in CSS.\n *\n * The root is a CONTAINER holding its silhouettes rather than being the painted shape — the\n * opposite of VProgressLinear. That is what makes `lines` free and keeps every rule below\n * uniform, with no \"painted root\" case beside a \"painted child\" one. It carries `v-control`,\n * so a skeleton of a given size is exactly as tall as a button of that size.\n *\n * It MEASURES nothing: the shape is declared, never inferred from what it replaces. Three\n * derived values are the whole of the JS — no event, no lifecycle, no DOM.\n */\nimport { computed } from 'vue'\n\nimport { useMessages } from '../../i18n/state'\nimport { cssSize } from '../../utils/css'\n\nexport type SkeletonLoaderShape = 'text' | 'control' | 'pill' | 'circle' | 'surface'\nexport type SkeletonLoaderAnimation = 'wave' | 'pulse' | 'none'\nexport type SkeletonLoaderSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\ninterface SkeletonLoaderProps {\n /**\n * What the silhouette stands for. Each value sets both a corner radius and a way of\n * being sized:\n *\n * - `text` follows the typography around it, so several silhouettes occupy exactly\n * as many lines as the text they replace;\n * - `control` takes the height of a control of the given size — a button, a field;\n * - `pill` is that same height with fully rounded ends — a chip, a badge;\n * - `circle` is that height in both dimensions — an avatar, a round icon button;\n * - `surface` is a card or an image, with a height of its own.\n */\n shape?: SkeletonLoaderShape\n /**\n * The size on the scale shared by every control. It only means something for the\n * shapes sized like a control: text follows the typography around it, and a surface\n * has its own height.\n */\n size?: SkeletonLoaderSize\n /** Takes 4px off the height, as everywhere else in the design system. */\n compact?: boolean\n /**\n * The width: a number is read as pixels, and anything else as a CSS length of your\n * own — `'100%'`, `'12ch'`. Left out, the silhouette takes all the width available.\n */\n width?: number | string\n /** The height, read the same way. It wins over the shape and the size. */\n height?: number | string\n /**\n * How many silhouettes to stack. In the text shape the LAST one is drawn shorter\n * than the others, and that single detail is what reads as a paragraph rather than\n * as a table.\n */\n lines?: number\n /**\n * How the silhouette shows that something is happening. Turning it off freezes it,\n * which suits printing, a screenshot, or a parent already animating.\n */\n animation?: SkeletonLoaderAnimation\n /**\n * A background colour of your own, replacing the token. The wave's highlight is\n * DERIVED from it, so it stays correct with nothing else to set.\n */\n color?: string\n /**\n * Announces the loading to screen readers. It is OFF by default, because a skeleton\n * is decorative: a page holds a dozen of them, and a dozen competing announcements\n * are unreadable. What should announce the wait is the container around them,\n * marked as busy.\n */\n announce?: boolean\n /**\n * What is announced, which also IMPLIES announcing. Prefer something situated —\n * \"Loading the results\" — since a generic word is the reason the default is silence.\n * It falls back to the design system dictionary.\n */\n label?: string\n}\n\nconst props = withDefaults(defineProps<SkeletonLoaderProps>(), {\n shape: 'text',\n size: 'md',\n compact: false,\n width: undefined,\n height: undefined,\n lines: 1,\n animation: 'wave',\n color: undefined,\n announce: false,\n label: undefined,\n})\n\n// A guard against two silent bugs: asked for zero lines the component would render\n// NOTHING at all — an invisible skeleton nobody notices is missing — and a fractional\n// count would produce a surprising number of them.\nconst count = computed(() => Math.max(1, Math.trunc(props.lines)))\n\n// @a11y — silent by default, since a dozen silhouettes must not produce a dozen\n// announcements. Supplying a label counts as asking to be announced, otherwise that\n// prop would sit there doing nothing.\nconst announced = computed(() => props.announce || props.label !== undefined)\n\nconst m = useMessages()\n// TRAP — the dictionary must never be read directly in the body of `setup`: the value\n// would be captured once and would stop following a later change of language.\nconst resolvedLabel = computed(() => props.label ?? m.value.common.loading)\n</script>\n\n<template>\n <span\n class=\"v-skeleton v-control\"\n :data-shape=\"shape\"\n :data-size=\"size\"\n :data-compact=\"compact ? '' : undefined\"\n :data-animation=\"animation\"\n :data-custom=\"color !== undefined ? '' : undefined\"\n :role=\"announced ? 'status' : undefined\"\n :aria-hidden=\"announced ? undefined : 'true'\"\n :style=\"{\n '--custom-color': color,\n '--skeleton-w': cssSize(width),\n '--skeleton-h': cssSize(height),\n }\"\n >\n <!--\n TRAP — the label is rendered BEFORE the silhouettes, and that order is\n structural. The rule shortening the last line of a paragraph asks for the last\n CHILD, so a label rendered after them would quietly take that place and no line\n would be shortened. A unit test locks the order.\n\n It costs no layout: the class hiding it takes it out of the flow entirely, so it\n is never one of the stacked items. And it is rendered only when something is\n actually announced — inside a subtree hidden from screen readers it would be text\n nobody can reach.\n -->\n <span v-if=\"announced\" class=\"v-visually-hidden\">{{ resolvedLabel }}</span>\n <span v-for=\"n in count\" :key=\"n\" class=\"v-skeleton-item\" />\n </span>\n</template>\n\n<style>\n@layer vectis.components {\n /*\n * The whole geometry comes down to four variables. The shape table below sets them,\n * and the dimension props overwrite them inline — which always wins over a rule\n * targeting the same element, so no specificity contest is possible.\n */\n .v-skeleton {\n /* The grey has a token of its own. No existing colour role holds the right value in\n BOTH themes: the muted surface is too pale in the light one for the pulse to be\n visible at all, and the border colour has the right tone but the wrong meaning. */\n --skeleton-base: var(--vectis-color-surface-skeleton);\n /*\n * The highlight is DERIVED from the grey rather than named: the same colour, a little\n * lighter. A lightness STEP is what makes one declaration correct in both themes, where\n * a `color-mix()` towards a target would not — the silhouette is darker than the page in\n * light and LIGHTER than it in dark, so a fixed target would lighten in one and darken in\n * the other. It also follows a custom `color` with nothing else to set.\n */\n --skeleton-highlight: oklch(from var(--skeleton-base) calc(l + 0.06) c h);\n --skeleton-h: var(--control-height);\n /* The corner a CONTROL-sized silhouette takes, whatever height this instance ends up\n with: a browser scales down a radius it cannot fit, so min() gives a silhouette that\n grew the same reduction a control-tall one already gets. It resolves to the token\n itself at the shipped 6px.\n\n TRAP — the cap is NOT calc(var(--skeleton-h) / 2), which looks like the closer unit\n and is the wrong one twice over: --skeleton-h is a flex BASIS on an item that grows\n to fill a taller parent (see below), and the `height` prop overwrites it inline. Two\n equally tall silhouettes would then round differently depending on how they got\n there. */\n --skeleton-radius: min(var(--vectis-radius-interactive), calc(var(--control-height) / 2));\n --skeleton-gap: var(--vectis-space-2);\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n }\n\n /* A custom colour wins by specificity rather than by order, being one step more\n specific than the rule above — unlike VProgressLinear's tones, which all sit at the\n same level and depend on their sequence. */\n .v-skeleton[data-custom] {\n --skeleton-base: var(--custom-color);\n }\n\n .v-skeleton-item {\n /* The animation's overlay is positioned against this box. */\n position: relative;\n /* The height from the shape table is a DEFAULT: inside a parent that has a height\n of its own, the silhouette grows to fill it — a card fills its slot. */\n flex: 1 1 auto;\n inline-size: var(--skeleton-w, 100%);\n block-size: var(--skeleton-h);\n /* Clipped rather than hidden: hiding the overflow would turn every silhouette into\n a scroll container, for nothing. */\n overflow: clip;\n border-radius: var(--skeleton-radius);\n background: var(--skeleton-base);\n }\n\n /*\n * A line of text is one em tall, which means it follows the typography it INHERITS,\n * and it is centred in the line box the same way a line of text would be.\n *\n * The gap between lines and the padding around them are derived from that same line\n * height, so that N silhouettes occupy exactly N lines of text: replacing them with\n * the real content shifts nothing on the page. The floor guards against a parent\n * whose lines are set tighter than its font size, where the gap would otherwise go\n * negative.\n */\n .v-skeleton[data-shape='text'] {\n --skeleton-h: 1em;\n --skeleton-radius: var(--vectis-radius-pill);\n --skeleton-gap: max(0px, calc(1lh - 1em));\n padding-block: calc(var(--skeleton-gap) / 2);\n }\n\n /* A line of text keeps the height its typography gives it: unlike the other shapes it\n neither stretches in a tall parent nor squashes in a short one. */\n .v-skeleton[data-shape='text'] .v-skeleton-item {\n flex: none;\n }\n\n /*\n * The shortened last line, the one detail that makes a stack of bars read as a\n * paragraph. Asking for a line PRECEDED by another is what guarantees it only\n * applies from two lines up — a single line is not a paragraph — and the proportion\n * is taken from the EFFECTIVE width, so it still works under a `width` prop.\n */\n .v-skeleton[data-shape='text'] .v-skeleton-item + .v-skeleton-item:last-child {\n --skeleton-last-line: 0.6;\n inline-size: calc(var(--skeleton-w, 100%) * var(--skeleton-last-line));\n }\n\n .v-skeleton[data-shape='pill'] {\n --skeleton-radius: var(--vectis-radius-pill);\n }\n\n /*\n * A circle takes its width FROM its height through the ratio, so changing the size\n * alone changes the diameter and nothing has to be kept in step.\n *\n * The container sits inline, like the avatar it replaces, rather than spanning the\n * whole width, and aligning to the start stops the silhouette from being stretched\n * sideways — which is what keeps the circle round.\n */\n .v-skeleton[data-shape='circle'] {\n --skeleton-radius: var(--vectis-radius-pill);\n display: inline-flex;\n align-items: start;\n }\n\n .v-skeleton[data-shape='circle'] .v-skeleton-item {\n /* Left to the content rather than set to the full width, so that the ratio is what\n decides. An explicit `width` still takes over, and then knowingly gives an\n oval. */\n inline-size: var(--skeleton-w, auto);\n aspect-ratio: 1;\n }\n\n /*\n * A surface — a card, an image, a block — has no height anyone could guess without\n * measuring the page, which this component deliberately never does. It takes a\n * default from a token, which the `height` prop overrides, as does any consumer style\n * (theirs sits outside our layers and therefore wins).\n */\n .v-skeleton[data-shape='surface'] {\n --skeleton-h: var(--vectis-control-size-skeleton-surface);\n --skeleton-radius: var(--vectis-radius-surface);\n }\n\n /* The overlay both animations paint on, laid over the whole silhouette. */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n content: '';\n position: absolute;\n inset: 0;\n }\n\n /*\n * The pulse: a flat sheet of the lighter shade fades in and out OVER the silhouette.\n *\n * Fading the silhouette itself would be shorter to write, and wrong: it would fade\n * towards the PAGE, which means lightening in the light theme and DARKENING in the\n * dark one — the opposite of what the wave does. Going through an overlay in the\n * derived colour gives the same direction in both, and it is still only an opacity\n * being animated, so it costs no layout.\n */\n .v-skeleton[data-animation='pulse'] .v-skeleton-item::after {\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-1500) var(--vectis-ease-in-out) infinite;\n }\n\n /*\n * The wave: a band of light crossing the silhouette.\n *\n * The gradient is SYMMETRIC — transparent, light, transparent — so its physical angle makes\n * no observable difference and there is nothing to mirror in RTL. Only the DIRECTION of the\n * run matters, and `animation-direction: reverse` covers it exactly, the run being linear\n * and therefore identical read backwards.\n *\n * Moved by `translate`, where VProgressLinear animates a logical property: the trade-off is\n * reversed between the two, that component drawing one bar where a page may hold a dozen\n * skeletons, so a compositor-only movement is not negotiable here.\n */\n .v-skeleton[data-animation='wave'] .v-skeleton-item::after {\n background-image: linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);\n animation: v-skeleton-wave var(--vectis-duration-1500) linear infinite;\n }\n\n /* Scoped to the wave: the pulse uses the same overlay, but its run is symmetric in\n time, so reversing it would change nothing at all. */\n .v-skeleton[data-animation='wave']:dir(rtl) .v-skeleton-item::after {\n animation-direction: reverse;\n }\n\n /* These keyframes serve this component alone, so they stay in its own stylesheet.\n Only the spin shared by VSpinner and VProgressCircular is declared globally, in\n styles/utilities.css. */\n @keyframes v-skeleton-pulse {\n from,\n to {\n opacity: 0;\n }\n\n 50% {\n opacity: 1;\n }\n }\n\n @keyframes v-skeleton-wave {\n from {\n translate: -100% 0;\n }\n\n to {\n translate: 100% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * Reduced motion SLOWS rather than stops: a motionless placeholder no longer says\n * anything is in progress. But the wave is a TRANSLATION, precisely what these readers\n * flag, so it falls back to the pulse — the same signal without movement. Both are then\n * slowed considerably. The two share one overlay, so all that is left is replacing the\n * moving gradient with the flat fill.\n *\n * TRAP — this has exactly the specificity of the two rules it overrides, so its position\n * at the END of the sheet is the whole of what makes it win.\n */\n .v-skeleton:is([data-animation='wave'], [data-animation='pulse']) .v-skeleton-item::after {\n background-image: none;\n background-color: var(--skeleton-highlight);\n animation: v-skeleton-pulse var(--vectis-duration-5000) var(--vectis-ease-in-out) infinite;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiFA,IAAM,IAAQ,GAgBR,IAAQ,QAAe,KAAK,IAAI,GAAG,KAAK,MAAM,EAAM,KAAK,CAAC,CAAC,GAK3D,IAAY,QAAe,EAAM,YAAY,EAAM,UAAU,KAAA,CAAS,GAEtE,IAAI,EAAY,GAGhB,IAAgB,QAAe,EAAM,SAAS,EAAE,MAAM,OAAO,OAAO;yBAIxE,EA4BO,QAAA;GA3BL,OAAM;GACL,cAAY,EAAA;GACZ,aAAW,EAAA;GACX,gBAAc,EAAA,UAAO,KAAQ,KAAA;GAC7B,kBAAgB,EAAA;GAChB,eAAa,EAAA,UAAU,KAAA,IAAiB,KAAA,IAAR;GAChC,MAAM,EAAA,QAAS,WAAc,KAAA;GAC7B,eAAa,EAAA,QAAY,KAAA,IAAS;GAClC,OAAK,EAAA;sBAA4B,EAAA;oBAA6B,EAAA,CAAA,CAAO,CAAC,EAAA,KAAK;oBAAyB,EAAA,CAAA,CAAO,CAAC,EAAA,MAAM;;MAiBvG,EAAA,SAAA,EAAA,GAAZ,EAA2E,QAA3E,GAA2E,EAAvB,EAAA,KAAa,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,GACjE,EAA4D,GAAA,MAAA,EAA1C,EAAA,QAAL,YAAb,EAA4D,QAAA;GAAlC,KAAK;GAAG,OAAM"}
|