@telefonica/mistica 17.3.0 → 17.5.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/css/blau.css +29 -16
- package/css/esimflag.css +40 -18
- package/css/mistica-common.css +5 -0
- package/css/mistica.css +1 -1
- package/css/movistar.css +34 -18
- package/css/o2.css +31 -18
- package/css/telefonica.css +43 -18
- package/css/vivo-evolution.css +71 -20
- package/css/vivo.css +31 -18
- package/dist/accordion.css-mistica.js +10 -10
- package/dist/align.css-mistica.js +1 -1
- package/dist/autocomplete.css-mistica.js +4 -4
- package/dist/avatar.css-mistica.js +1 -1
- package/dist/badge.css-mistica.js +1 -1
- package/dist/box.css-mistica.js +13 -13
- package/dist/boxed.css-mistica.js +24 -24
- package/dist/boxed.d.ts +9 -0
- package/dist/boxed.js +18 -15
- package/dist/button-group.css-mistica.js +1 -1
- package/dist/button-layout.css-mistica.js +19 -19
- package/dist/button.css-mistica.js +51 -51
- package/dist/callout.css-mistica.js +13 -13
- package/dist/card-internal.css-mistica.js +22 -22
- package/dist/carousel.css-mistica.js +30 -30
- package/dist/checkbox.css-mistica.js +15 -15
- package/dist/chip.css-mistica.js +18 -18
- package/dist/circle.css-mistica.js +2 -2
- package/dist/community/advanced-data-card.css-mistica.js +19 -19
- package/dist/community/ai-card.css-mistica.js +11 -11
- package/dist/community/blocks.css-mistica.js +1 -1
- package/dist/community/cyber/example-component.css-mistica.js +1 -1
- package/dist/community/example-component.css-mistica.js +1 -1
- package/dist/community/skins/cyber-skin.js +19 -17
- package/dist/counter.css-mistica.js +6 -6
- package/dist/cover-hero.css-mistica.js +7 -7
- package/dist/credit-card-number-field.css-mistica.js +3 -3
- package/dist/date-field.css-mistica.js +1 -1
- package/dist/date-time-picker.css-mistica.js +1 -1
- package/dist/dialog.css-mistica.js +10 -10
- package/dist/divider.css-mistica.js +5 -5
- package/dist/double-field.css-mistica.js +2 -2
- package/dist/drawer.css-mistica.js +4 -4
- package/dist/empty-state-card.css-mistica.js +1 -1
- package/dist/empty-state.css-mistica.js +8 -8
- package/dist/fade-in.css-mistica.js +1 -1
- package/dist/fade-out.css-mistica.js +11 -0
- package/dist/fade-out.css.d.ts +1 -0
- package/dist/fade-out.d.ts +11 -0
- package/dist/fade-out.js +88 -0
- package/dist/feedback.css-mistica.js +5 -5
- package/dist/file-upload.css-mistica.js +10 -10
- package/dist/fixed-footer-layout.css-mistica.js +6 -6
- package/dist/form.css-mistica.js +1 -1
- package/dist/generated/mistica-icons/icon-antenna-filled.js +40 -12
- package/dist/generated/mistica-icons/icon-antenna-light.js +37 -17
- package/dist/generated/mistica-icons/icon-antenna-regular.js +42 -14
- package/dist/generated/mistica-icons/icon-arrow-up-down-filled.js +26 -16
- package/dist/generated/mistica-icons/icon-arrow-up-down-light.js +22 -12
- package/dist/generated/mistica-icons/icon-arrow-up-down-regular.js +30 -20
- package/dist/generated/mistica-icons/icon-arrows-left-and-right-filled.js +26 -16
- package/dist/generated/mistica-icons/icon-arrows-left-and-right-light.js +24 -14
- package/dist/generated/mistica-icons/icon-arrows-left-and-right-regular.js +26 -16
- package/dist/generated/mistica-icons/icon-authentication-success-filled.js +31 -11
- package/dist/generated/mistica-icons/icon-authentication-success-light.js +33 -17
- package/dist/generated/mistica-icons/icon-authentication-success-regular.js +29 -13
- package/dist/generated/mistica-icons/icon-blog-filled.js +36 -16
- package/dist/generated/mistica-icons/icon-blog-light.js +34 -14
- package/dist/generated/mistica-icons/icon-blog-regular.js +32 -16
- package/dist/generated/mistica-icons/icon-book-filled.js +19 -9
- package/dist/generated/mistica-icons/icon-book-light.js +25 -15
- package/dist/generated/mistica-icons/icon-book-regular.js +16 -6
- package/dist/generated/mistica-icons/icon-box-filled.js +35 -19
- package/dist/generated/mistica-icons/icon-box-light.js +28 -18
- package/dist/generated/mistica-icons/icon-box-regular.js +26 -16
- package/dist/generated/mistica-icons/icon-box-star-filled.js +37 -17
- package/dist/generated/mistica-icons/icon-box-star-light.js +22 -6
- package/dist/generated/mistica-icons/icon-box-star-regular.js +30 -14
- package/dist/generated/mistica-icons/icon-briefcase-filled.js +28 -12
- package/dist/generated/mistica-icons/icon-briefcase-light.js +21 -11
- package/dist/generated/mistica-icons/icon-briefcase-regular.js +29 -19
- package/dist/generated/mistica-icons/icon-calendar-event-filled.js +23 -12
- package/dist/generated/mistica-icons/icon-calendar-event-light.js +28 -11
- package/dist/generated/mistica-icons/icon-calendar-event-regular.js +30 -13
- package/dist/generated/mistica-icons/icon-calendar-filled.js +32 -22
- package/dist/generated/mistica-icons/icon-calendar-light.js +39 -23
- package/dist/generated/mistica-icons/icon-calendar-month-filled.js +23 -12
- package/dist/generated/mistica-icons/icon-calendar-month-light.js +30 -13
- package/dist/generated/mistica-icons/icon-calendar-month-regular.js +30 -13
- package/dist/generated/mistica-icons/icon-calendar-regular.js +33 -17
- package/dist/generated/mistica-icons/icon-car-filled.js +25 -9
- package/dist/generated/mistica-icons/icon-car-light.js +24 -14
- package/dist/generated/mistica-icons/icon-car-regular.js +24 -14
- package/dist/generated/mistica-icons/icon-care-briefcase-filled.js +23 -12
- package/dist/generated/mistica-icons/icon-care-briefcase-light.js +25 -14
- package/dist/generated/mistica-icons/icon-care-briefcase-regular.js +18 -8
- package/dist/generated/mistica-icons/icon-care-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-care-home-filled.js +24 -13
- package/dist/generated/mistica-icons/icon-care-home-light.js +24 -13
- package/dist/generated/mistica-icons/icon-care-home-regular.js +26 -16
- package/dist/generated/mistica-icons/icon-care-laptop-filled.js +22 -11
- package/dist/generated/mistica-icons/icon-care-laptop-light.js +24 -13
- package/dist/generated/mistica-icons/icon-care-laptop-regular.js +28 -18
- package/dist/generated/mistica-icons/icon-care-light.js +22 -12
- package/dist/generated/mistica-icons/icon-care-mobile-filled.js +22 -11
- package/dist/generated/mistica-icons/icon-care-mobile-light.js +29 -12
- package/dist/generated/mistica-icons/icon-care-mobile-regular.js +33 -17
- package/dist/generated/mistica-icons/icon-care-regular.js +23 -13
- package/dist/generated/mistica-icons/icon-care-shield-filled.js +24 -14
- package/dist/generated/mistica-icons/icon-care-shield-light.js +23 -13
- package/dist/generated/mistica-icons/icon-care-shield-regular.js +26 -16
- package/dist/generated/mistica-icons/icon-change-plan-filled.js +36 -16
- package/dist/generated/mistica-icons/icon-change-plan-light.js +38 -18
- package/dist/generated/mistica-icons/icon-change-plan-regular.js +30 -14
- package/dist/generated/mistica-icons/icon-chip-device-filled.js +32 -16
- package/dist/generated/mistica-icons/icon-chip-device-light.js +33 -17
- package/dist/generated/mistica-icons/icon-chip-device-regular.js +36 -20
- package/dist/generated/mistica-icons/icon-chip-sim-card-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-chip-sim-card-light.js +36 -20
- package/dist/generated/mistica-icons/icon-chip-sim-card-regular.js +42 -26
- package/dist/generated/mistica-icons/icon-credit-card-filled.js +20 -10
- package/dist/generated/mistica-icons/icon-credit-card-light.js +18 -8
- package/dist/generated/mistica-icons/icon-credit-card-regular.js +23 -13
- package/dist/generated/mistica-icons/icon-document-information-filled.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-document-information-light.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-document-information-regular.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-document-other-filled.js +25 -9
- package/dist/generated/mistica-icons/icon-document-other-light.js +33 -17
- package/dist/generated/mistica-icons/icon-document-other-regular.js +25 -9
- package/dist/generated/mistica-icons/icon-dollar-symbol-circle-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-dollar-symbol-circle-light.js +30 -14
- package/dist/generated/mistica-icons/icon-dollar-symbol-circle-regular.js +29 -13
- package/dist/generated/mistica-icons/icon-error-filled.js +33 -17
- package/dist/generated/mistica-icons/icon-error-light.js +29 -13
- package/dist/generated/mistica-icons/icon-error-regular.js +32 -16
- package/dist/generated/mistica-icons/icon-esim-filled.js +33 -17
- package/dist/generated/mistica-icons/icon-esim-light.js +43 -23
- package/dist/generated/mistica-icons/icon-esim-regular.js +29 -9
- package/dist/generated/mistica-icons/icon-eye-filled.js +18 -8
- package/dist/generated/mistica-icons/icon-eye-light.js +31 -15
- package/dist/generated/mistica-icons/icon-eye-regular.js +29 -13
- package/dist/generated/mistica-icons/icon-file-ok-filled.js +30 -14
- package/dist/generated/mistica-icons/icon-file-ok-light.js +29 -13
- package/dist/generated/mistica-icons/icon-file-ok-regular.js +31 -15
- package/dist/generated/mistica-icons/icon-fingerprint-filled.js +36 -15
- package/dist/generated/mistica-icons/icon-fingerprint-light.js +35 -14
- package/dist/generated/mistica-icons/icon-fingerprint-regular.js +29 -9
- package/dist/generated/mistica-icons/icon-home-filled.js +17 -7
- package/dist/generated/mistica-icons/icon-home-light.js +21 -11
- package/dist/generated/mistica-icons/icon-home-regular.js +29 -19
- package/dist/generated/mistica-icons/icon-home-wifi-filled.js +39 -19
- package/dist/generated/mistica-icons/icon-home-wifi-light.js +30 -14
- package/dist/generated/mistica-icons/icon-home-wifi-regular.js +37 -17
- package/dist/generated/mistica-icons/icon-id-card-filled.js +32 -16
- package/dist/generated/mistica-icons/icon-id-card-light.js +27 -11
- package/dist/generated/mistica-icons/icon-id-card-regular.js +31 -15
- package/dist/generated/mistica-icons/icon-information-user-filled.js +32 -12
- package/dist/generated/mistica-icons/icon-information-user-light.js +37 -21
- package/dist/generated/mistica-icons/icon-information-user-regular.js +44 -28
- package/dist/generated/mistica-icons/icon-internet-filled.js +18 -8
- package/dist/generated/mistica-icons/icon-internet-light.js +21 -11
- package/dist/generated/mistica-icons/icon-internet-regular.js +19 -9
- package/dist/generated/mistica-icons/icon-internet-roaming-filled.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-internet-roaming-light.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-internet-roaming-regular.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-key-filled.js +21 -11
- package/dist/generated/mistica-icons/icon-key-light.js +31 -15
- package/dist/generated/mistica-icons/icon-key-regular.js +32 -16
- package/dist/generated/mistica-icons/icon-list-filled.js +23 -12
- package/dist/generated/mistica-icons/icon-list-light.js +31 -15
- package/dist/generated/mistica-icons/icon-list-regular.js +34 -18
- package/dist/generated/mistica-icons/icon-location-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-location-light.js +30 -14
- package/dist/generated/mistica-icons/icon-location-regular.js +30 -14
- package/dist/generated/mistica-icons/icon-lock-closed-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-lock-closed-light.js +31 -15
- package/dist/generated/mistica-icons/icon-lock-closed-regular.js +35 -19
- package/dist/generated/mistica-icons/icon-message-filled.js +23 -12
- package/dist/generated/mistica-icons/icon-message-light.js +28 -11
- package/dist/generated/mistica-icons/icon-message-regular.js +27 -10
- package/dist/generated/mistica-icons/icon-mobile-device-filled.js +25 -15
- package/dist/generated/mistica-icons/icon-mobile-device-light.js +26 -10
- package/dist/generated/mistica-icons/icon-mobile-device-regular.js +32 -16
- package/dist/generated/mistica-icons/icon-mobile-information-filled.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-mobile-information-light.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-mobile-information-regular.d.ts +3 -0
- package/dist/generated/mistica-icons/icon-panel-collapse-regular.js +165 -0
- package/dist/generated/mistica-icons/icon-panel-expand-regular.js +159 -0
- package/dist/generated/mistica-icons/icons-keywords.js +57 -0
- package/dist/grid-layout.css-mistica.js +3 -3
- package/dist/grid.css-mistica.js +120 -120
- package/dist/header.css-mistica.js +1 -1
- package/dist/header.d.ts +3 -1
- package/dist/header.js +81 -73
- package/dist/hero.css-mistica.js +4 -4
- package/dist/horizontal-scroll.css-mistica.js +1 -1
- package/dist/icon-button.css-mistica.js +53 -53
- package/dist/icons/icon-chevron.css-mistica.js +2 -2
- package/dist/icons/icon-error.css-mistica.js +1 -1
- package/dist/image.css-mistica.js +6 -6
- package/dist/index.d.ts +6 -0
- package/dist/index.js +14 -1
- package/dist/inline.css-mistica.js +11 -11
- package/dist/list.css-mistica.js +40 -28
- package/dist/list.css.d.ts +2 -0
- package/dist/list.d.ts +3 -1
- package/dist/list.js +176 -165
- package/dist/loading-bar.css-mistica.js +1 -1
- package/dist/loading-screen.css-mistica.js +12 -12
- package/dist/logo.css-mistica.js +5 -5
- package/dist/menu.css-mistica.js +13 -13
- package/dist/mobile-navigation-menu.d.ts +26 -0
- package/dist/mobile-navigation-menu.js +145 -0
- package/dist/mosaic.css-mistica.js +1 -1
- package/dist/navigation-bar.css-mistica.js +31 -97
- package/dist/navigation-bar.css.d.ts +0 -24
- package/dist/navigation-bar.d.ts +3 -38
- package/dist/navigation-bar.js +399 -586
- package/dist/navigation-breadcrumbs.css-mistica.js +1 -1
- package/dist/navigation-shared.css-mistica.js +79 -0
- package/dist/navigation-shared.css.d.ts +26 -0
- package/dist/navigation-shared.d.ts +66 -0
- package/dist/navigation-shared.js +264 -0
- package/dist/package-version.js +1 -1
- package/dist/pagination.css-mistica.js +22 -22
- package/dist/pin-field.css-mistica.js +4 -4
- package/dist/popover.css-mistica.js +1 -1
- package/dist/portal.d.ts +1 -1
- package/dist/progress-bar.css-mistica.js +7 -7
- package/dist/radio-button.css-mistica.js +27 -27
- package/dist/rating.css-mistica.js +4 -4
- package/dist/responsive-layout.css-mistica.js +6 -6
- package/dist/screen-reader-only.css-mistica.js +1 -1
- package/dist/select.css-mistica.js +21 -21
- package/dist/sheet-action-row.css-mistica.js +1 -1
- package/dist/sheet-common.css-mistica.js +7 -7
- package/dist/sheet-info.css-mistica.js +1 -1
- package/dist/sidenav-bar-context.d.ts +25 -0
- package/dist/sidenav-bar-context.js +72 -0
- package/dist/sidenav-bar-data.d.ts +15 -0
- package/dist/sidenav-bar-data.js +38 -0
- package/dist/sidenav-bar-first-level-item.d.ts +42 -0
- package/dist/sidenav-bar-first-level-item.js +174 -0
- package/dist/sidenav-bar-keyboard.d.ts +13 -0
- package/dist/sidenav-bar-keyboard.js +314 -0
- package/dist/sidenav-bar-layout.css-mistica.js +28 -0
- package/dist/sidenav-bar-layout.css.d.ts +5 -0
- package/dist/sidenav-bar-layout.d.ts +22 -0
- package/dist/sidenav-bar-layout.js +103 -0
- package/dist/sidenav-bar-mobile.d.ts +24 -0
- package/dist/sidenav-bar-mobile.js +332 -0
- package/dist/sidenav-bar-motion.d.ts +32 -0
- package/dist/sidenav-bar-motion.js +84 -0
- package/dist/sidenav-bar-panel.d.ts +31 -0
- package/dist/sidenav-bar-panel.js +208 -0
- package/dist/sidenav-bar-row.d.ts +82 -0
- package/dist/sidenav-bar-row.js +230 -0
- package/dist/sidenav-bar-second-level-item.d.ts +43 -0
- package/dist/sidenav-bar-second-level-item.js +89 -0
- package/dist/sidenav-bar-section.d.ts +23 -0
- package/dist/sidenav-bar-section.js +167 -0
- package/dist/sidenav-bar-types.d.ts +192 -0
- package/dist/sidenav-bar-types.js +11 -0
- package/dist/sidenav-bar.css-mistica.js +325 -0
- package/dist/sidenav-bar.css.d.ts +93 -0
- package/dist/sidenav-bar.d.ts +102 -0
- package/dist/sidenav-bar.js +492 -0
- package/dist/skeletons.css-mistica.js +8 -8
- package/dist/skins/blau.js +23 -8
- package/dist/skins/defaults.js +11 -0
- package/dist/skins/esimflag.js +24 -9
- package/dist/skins/movistar.js +24 -9
- package/dist/skins/o2.js +24 -9
- package/dist/skins/skin-contract.css-mistica.js +740 -731
- package/dist/skins/skin-contract.css.d.ts +9 -0
- package/dist/skins/telefonica.js +24 -9
- package/dist/skins/types/colors.d.ts +2 -0
- package/dist/skins/types/index.d.ts +1 -0
- package/dist/skins/vivo-evolution.js +25 -10
- package/dist/skins/vivo.js +24 -9
- package/dist/skip-link.css-mistica.js +2 -2
- package/dist/slider.css-mistica.js +24 -24
- package/dist/snackbar.css-mistica.js +14 -14
- package/dist/spinner.css-mistica.js +1 -1
- package/dist/square.css-mistica.js +1 -1
- package/dist/stack.css-mistica.js +5 -5
- package/dist/stacking-group.css-mistica.js +1 -1
- package/dist/stepper.css-mistica.js +9 -9
- package/dist/switch-component.css-mistica.js +48 -42
- package/dist/switch-component.css.d.ts +2 -0
- package/dist/switch-component.js +18 -18
- package/dist/table.css-mistica.js +9 -9
- package/dist/tabs.css-mistica.js +22 -22
- package/dist/tag.css-mistica.js +3 -3
- package/dist/text-field-base.css-mistica.js +20 -20
- package/dist/text-field-components.css-mistica.js +10 -10
- package/dist/text-link.css-mistica.js +6 -6
- package/dist/text-tokens.d.ts +6 -0
- package/dist/text-tokens.js +157 -133
- package/dist/text.css-mistica.js +6 -6
- package/dist/timeline.css-mistica.js +11 -11
- package/dist/timer.css-mistica.js +6 -6
- package/dist/tooltip.css-mistica.js +2 -2
- package/dist/touchable.css-mistica.js +4 -4
- package/dist/utils/aspect-ratio-support.css-mistica.js +2 -2
- package/dist/video.css-mistica.js +1 -1
- package/dist/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
- package/dist-es/accordion.css-mistica.js +7 -7
- package/dist-es/align.css-mistica.js +1 -1
- package/dist-es/autocomplete.css-mistica.js +2 -2
- package/dist-es/avatar.css-mistica.js +1 -1
- package/dist-es/badge.css-mistica.js +1 -1
- package/dist-es/box.css-mistica.js +13 -13
- package/dist-es/boxed.css-mistica.js +23 -23
- package/dist-es/boxed.js +25 -25
- package/dist-es/button-group.css-mistica.js +1 -1
- package/dist-es/button-layout.css-mistica.js +16 -16
- package/dist-es/button.css-mistica.js +38 -38
- package/dist-es/callout.css-mistica.js +12 -12
- package/dist-es/card-internal.css-mistica.js +17 -17
- package/dist-es/carousel.css-mistica.js +10 -10
- package/dist-es/checkbox.css-mistica.js +13 -13
- package/dist-es/chip.css-mistica.js +17 -17
- package/dist-es/circle.css-mistica.js +2 -2
- package/dist-es/community/advanced-data-card.css-mistica.js +7 -7
- package/dist-es/community/ai-card.css-mistica.js +4 -4
- package/dist-es/community/blocks.css-mistica.js +1 -1
- package/dist-es/community/cyber/example-component.css-mistica.js +1 -1
- package/dist-es/community/example-component.css-mistica.js +1 -1
- package/dist-es/community/skins/cyber-skin.js +19 -17
- package/dist-es/counter.css-mistica.js +2 -2
- package/dist-es/cover-hero.css-mistica.js +4 -4
- package/dist-es/credit-card-number-field.css-mistica.js +3 -3
- package/dist-es/date-field.css-mistica.js +1 -1
- package/dist-es/date-time-picker.css-mistica.js +1 -1
- package/dist-es/dialog.css-mistica.js +5 -5
- package/dist-es/divider.css-mistica.js +5 -5
- package/dist-es/double-field.css-mistica.js +2 -2
- package/dist-es/drawer.css-mistica.js +2 -2
- package/dist-es/empty-state-card.css-mistica.js +1 -1
- package/dist-es/empty-state.css-mistica.js +7 -7
- package/dist-es/fade-in.css-mistica.js +1 -1
- package/dist-es/fade-out.css-mistica.js +2 -0
- package/dist-es/fade-out.js +79 -0
- package/dist-es/feedback.css-mistica.js +2 -2
- package/dist-es/file-upload.css-mistica.js +8 -8
- package/dist-es/fixed-footer-layout.css-mistica.js +3 -3
- package/dist-es/form.css-mistica.js +1 -1
- package/dist-es/generated/mistica-icons/icon-antenna-filled.js +50 -22
- package/dist-es/generated/mistica-icons/icon-antenna-light.js +47 -27
- package/dist-es/generated/mistica-icons/icon-antenna-regular.js +52 -24
- package/dist-es/generated/mistica-icons/icon-arrow-up-down-filled.js +29 -19
- package/dist-es/generated/mistica-icons/icon-arrow-up-down-light.js +26 -16
- package/dist-es/generated/mistica-icons/icon-arrow-up-down-regular.js +34 -24
- package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-filled.js +30 -20
- package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-light.js +32 -22
- package/dist-es/generated/mistica-icons/icon-arrows-left-and-right-regular.js +34 -24
- package/dist-es/generated/mistica-icons/icon-authentication-success-filled.js +42 -22
- package/dist-es/generated/mistica-icons/icon-authentication-success-light.js +44 -28
- package/dist-es/generated/mistica-icons/icon-authentication-success-regular.js +42 -26
- package/dist-es/generated/mistica-icons/icon-blog-filled.js +44 -24
- package/dist-es/generated/mistica-icons/icon-blog-light.js +45 -25
- package/dist-es/generated/mistica-icons/icon-blog-regular.js +45 -29
- package/dist-es/generated/mistica-icons/icon-book-filled.js +23 -13
- package/dist-es/generated/mistica-icons/icon-book-light.js +33 -23
- package/dist-es/generated/mistica-icons/icon-book-regular.js +22 -12
- package/dist-es/generated/mistica-icons/icon-box-filled.js +38 -22
- package/dist-es/generated/mistica-icons/icon-box-light.js +38 -28
- package/dist-es/generated/mistica-icons/icon-box-regular.js +37 -27
- package/dist-es/generated/mistica-icons/icon-box-star-filled.js +49 -29
- package/dist-es/generated/mistica-icons/icon-box-star-light.js +29 -13
- package/dist-es/generated/mistica-icons/icon-box-star-regular.js +33 -17
- package/dist-es/generated/mistica-icons/icon-briefcase-filled.js +32 -16
- package/dist-es/generated/mistica-icons/icon-briefcase-light.js +24 -14
- package/dist-es/generated/mistica-icons/icon-briefcase-regular.js +32 -22
- package/dist-es/generated/mistica-icons/icon-calendar-event-filled.js +28 -17
- package/dist-es/generated/mistica-icons/icon-calendar-event-light.js +34 -17
- package/dist-es/generated/mistica-icons/icon-calendar-event-regular.js +36 -19
- package/dist-es/generated/mistica-icons/icon-calendar-filled.js +42 -32
- package/dist-es/generated/mistica-icons/icon-calendar-light.js +45 -29
- package/dist-es/generated/mistica-icons/icon-calendar-month-filled.js +31 -20
- package/dist-es/generated/mistica-icons/icon-calendar-month-light.js +38 -21
- package/dist-es/generated/mistica-icons/icon-calendar-month-regular.js +38 -21
- package/dist-es/generated/mistica-icons/icon-calendar-regular.js +45 -29
- package/dist-es/generated/mistica-icons/icon-car-filled.js +26 -10
- package/dist-es/generated/mistica-icons/icon-car-light.js +33 -23
- package/dist-es/generated/mistica-icons/icon-car-regular.js +29 -19
- package/dist-es/generated/mistica-icons/icon-care-briefcase-filled.js +30 -19
- package/dist-es/generated/mistica-icons/icon-care-briefcase-light.js +28 -17
- package/dist-es/generated/mistica-icons/icon-care-briefcase-regular.js +24 -14
- package/dist-es/generated/mistica-icons/icon-care-filled.js +29 -19
- package/dist-es/generated/mistica-icons/icon-care-home-filled.js +32 -21
- package/dist-es/generated/mistica-icons/icon-care-home-light.js +31 -20
- package/dist-es/generated/mistica-icons/icon-care-home-regular.js +40 -30
- package/dist-es/generated/mistica-icons/icon-care-laptop-filled.js +29 -18
- package/dist-es/generated/mistica-icons/icon-care-laptop-light.js +31 -20
- package/dist-es/generated/mistica-icons/icon-care-laptop-regular.js +33 -23
- package/dist-es/generated/mistica-icons/icon-care-light.js +24 -14
- package/dist-es/generated/mistica-icons/icon-care-mobile-filled.js +30 -19
- package/dist-es/generated/mistica-icons/icon-care-mobile-light.js +35 -18
- package/dist-es/generated/mistica-icons/icon-care-mobile-regular.js +50 -34
- package/dist-es/generated/mistica-icons/icon-care-regular.js +38 -28
- package/dist-es/generated/mistica-icons/icon-care-shield-filled.js +33 -23
- package/dist-es/generated/mistica-icons/icon-care-shield-light.js +27 -17
- package/dist-es/generated/mistica-icons/icon-care-shield-regular.js +33 -23
- package/dist-es/generated/mistica-icons/icon-change-plan-filled.js +41 -21
- package/dist-es/generated/mistica-icons/icon-change-plan-light.js +42 -22
- package/dist-es/generated/mistica-icons/icon-change-plan-regular.js +35 -19
- package/dist-es/generated/mistica-icons/icon-chip-device-filled.js +37 -21
- package/dist-es/generated/mistica-icons/icon-chip-device-light.js +46 -30
- package/dist-es/generated/mistica-icons/icon-chip-device-regular.js +48 -32
- package/dist-es/generated/mistica-icons/icon-chip-sim-card-filled.js +26 -16
- package/dist-es/generated/mistica-icons/icon-chip-sim-card-light.js +43 -27
- package/dist-es/generated/mistica-icons/icon-chip-sim-card-regular.js +59 -43
- package/dist-es/generated/mistica-icons/icon-credit-card-filled.js +24 -14
- package/dist-es/generated/mistica-icons/icon-credit-card-light.js +19 -9
- package/dist-es/generated/mistica-icons/icon-credit-card-regular.js +26 -16
- package/dist-es/generated/mistica-icons/icon-document-other-filled.js +31 -15
- package/dist-es/generated/mistica-icons/icon-document-other-light.js +42 -26
- package/dist-es/generated/mistica-icons/icon-document-other-regular.js +32 -16
- package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-filled.js +28 -18
- package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-light.js +41 -25
- package/dist-es/generated/mistica-icons/icon-dollar-symbol-circle-regular.js +42 -26
- package/dist-es/generated/mistica-icons/icon-error-filled.js +44 -28
- package/dist-es/generated/mistica-icons/icon-error-light.js +37 -21
- package/dist-es/generated/mistica-icons/icon-error-regular.js +40 -24
- package/dist-es/generated/mistica-icons/icon-esim-filled.js +48 -32
- package/dist-es/generated/mistica-icons/icon-esim-light.js +58 -38
- package/dist-es/generated/mistica-icons/icon-esim-regular.js +35 -15
- package/dist-es/generated/mistica-icons/icon-eye-filled.js +24 -14
- package/dist-es/generated/mistica-icons/icon-eye-light.js +43 -27
- package/dist-es/generated/mistica-icons/icon-eye-regular.js +33 -17
- package/dist-es/generated/mistica-icons/icon-file-ok-filled.js +41 -25
- package/dist-es/generated/mistica-icons/icon-file-ok-light.js +37 -21
- package/dist-es/generated/mistica-icons/icon-file-ok-regular.js +41 -25
- package/dist-es/generated/mistica-icons/icon-fingerprint-filled.js +45 -24
- package/dist-es/generated/mistica-icons/icon-fingerprint-light.js +39 -18
- package/dist-es/generated/mistica-icons/icon-fingerprint-regular.js +32 -12
- package/dist-es/generated/mistica-icons/icon-home-filled.js +19 -9
- package/dist-es/generated/mistica-icons/icon-home-light.js +24 -14
- package/dist-es/generated/mistica-icons/icon-home-regular.js +30 -20
- package/dist-es/generated/mistica-icons/icon-home-wifi-filled.js +51 -31
- package/dist-es/generated/mistica-icons/icon-home-wifi-light.js +36 -20
- package/dist-es/generated/mistica-icons/icon-home-wifi-regular.js +51 -31
- package/dist-es/generated/mistica-icons/icon-id-card-filled.js +40 -24
- package/dist-es/generated/mistica-icons/icon-id-card-light.js +38 -22
- package/dist-es/generated/mistica-icons/icon-id-card-regular.js +42 -26
- package/dist-es/generated/mistica-icons/icon-information-user-filled.js +36 -16
- package/dist-es/generated/mistica-icons/icon-information-user-light.js +51 -35
- package/dist-es/generated/mistica-icons/icon-information-user-regular.js +58 -42
- package/dist-es/generated/mistica-icons/icon-internet-filled.js +22 -12
- package/dist-es/generated/mistica-icons/icon-internet-light.js +25 -15
- package/dist-es/generated/mistica-icons/icon-internet-regular.js +22 -12
- package/dist-es/generated/mistica-icons/icon-key-filled.js +23 -13
- package/dist-es/generated/mistica-icons/icon-key-light.js +40 -24
- package/dist-es/generated/mistica-icons/icon-key-regular.js +40 -24
- package/dist-es/generated/mistica-icons/icon-list-filled.js +29 -18
- package/dist-es/generated/mistica-icons/icon-list-light.js +38 -22
- package/dist-es/generated/mistica-icons/icon-list-regular.js +42 -26
- package/dist-es/generated/mistica-icons/icon-location-filled.js +29 -19
- package/dist-es/generated/mistica-icons/icon-location-light.js +37 -21
- package/dist-es/generated/mistica-icons/icon-location-regular.js +37 -21
- package/dist-es/generated/mistica-icons/icon-lock-closed-filled.js +28 -18
- package/dist-es/generated/mistica-icons/icon-lock-closed-light.js +35 -19
- package/dist-es/generated/mistica-icons/icon-lock-closed-regular.js +40 -24
- package/dist-es/generated/mistica-icons/icon-message-filled.js +29 -18
- package/dist-es/generated/mistica-icons/icon-message-light.js +36 -19
- package/dist-es/generated/mistica-icons/icon-message-regular.js +35 -18
- package/dist-es/generated/mistica-icons/icon-mobile-device-filled.js +30 -20
- package/dist-es/generated/mistica-icons/icon-mobile-device-light.js +34 -18
- package/dist-es/generated/mistica-icons/icon-mobile-device-regular.js +37 -21
- package/dist-es/generated/mistica-icons/icon-panel-collapse-regular.js +115 -0
- package/dist-es/generated/mistica-icons/icon-panel-expand-regular.js +109 -0
- package/dist-es/generated/mistica-icons/icons-keywords.js +57 -0
- package/dist-es/grid-layout.css-mistica.js +3 -3
- package/dist-es/grid.css-mistica.js +120 -120
- package/dist-es/header.css-mistica.js +1 -1
- package/dist-es/header.js +113 -105
- package/dist-es/hero.css-mistica.js +3 -3
- package/dist-es/horizontal-scroll.css-mistica.js +1 -1
- package/dist-es/icon-button.css-mistica.js +53 -53
- package/dist-es/icons/icon-chevron.css-mistica.js +2 -2
- package/dist-es/icons/icon-error.css-mistica.js +1 -1
- package/dist-es/image.css-mistica.js +4 -4
- package/dist-es/index.js +2349 -2345
- package/dist-es/inline.css-mistica.js +11 -11
- package/dist-es/list.css-mistica.js +8 -2
- package/dist-es/list.js +275 -264
- package/dist-es/loading-bar.css-mistica.js +1 -1
- package/dist-es/loading-screen.css-mistica.js +5 -5
- package/dist-es/logo.css-mistica.js +5 -5
- package/dist-es/menu.css-mistica.js +13 -13
- package/dist-es/mobile-navigation-menu.js +90 -0
- package/dist-es/mosaic.css-mistica.js +1 -1
- package/dist-es/navigation-bar.css-mistica.js +11 -20
- package/dist-es/navigation-bar.js +469 -656
- package/dist-es/navigation-breadcrumbs.css-mistica.js +1 -1
- package/dist-es/navigation-shared.css-mistica.js +11 -0
- package/dist-es/navigation-shared.js +192 -0
- package/dist-es/package-version.js +1 -1
- package/dist-es/pagination.css-mistica.js +19 -19
- package/dist-es/pin-field.css-mistica.js +2 -2
- package/dist-es/popover.css-mistica.js +1 -1
- package/dist-es/progress-bar.css-mistica.js +7 -7
- package/dist-es/radio-button.css-mistica.js +22 -22
- package/dist-es/rating.css-mistica.js +3 -3
- package/dist-es/responsive-layout.css-mistica.js +6 -6
- package/dist-es/screen-reader-only.css-mistica.js +1 -1
- package/dist-es/select.css-mistica.js +18 -18
- package/dist-es/sheet-action-row.css-mistica.js +1 -1
- package/dist-es/sheet-common.css-mistica.js +2 -2
- package/dist-es/sheet-info.css-mistica.js +1 -1
- package/dist-es/sidenav-bar-context.js +14 -0
- package/dist-es/sidenav-bar-data.js +12 -0
- package/dist-es/sidenav-bar-first-level-item.js +124 -0
- package/dist-es/sidenav-bar-keyboard.js +253 -0
- package/dist-es/sidenav-bar-layout.css-mistica.js +2 -0
- package/dist-es/sidenav-bar-layout.js +86 -0
- package/dist-es/sidenav-bar-mobile.js +277 -0
- package/dist-es/sidenav-bar-motion.js +26 -0
- package/dist-es/sidenav-bar-panel.js +146 -0
- package/dist-es/sidenav-bar-row.js +208 -0
- package/dist-es/sidenav-bar-second-level-item.js +72 -0
- package/dist-es/sidenav-bar-section.js +112 -0
- package/dist-es/sidenav-bar-types.js +2 -0
- package/dist-es/sidenav-bar.css-mistica.js +74 -0
- package/dist-es/sidenav-bar.js +429 -0
- package/dist-es/skeletons.css-mistica.js +7 -7
- package/dist-es/skins/blau.js +23 -8
- package/dist-es/skins/defaults.js +11 -0
- package/dist-es/skins/esimflag.js +24 -9
- package/dist-es/skins/movistar.js +24 -9
- package/dist-es/skins/o2.js +24 -9
- package/dist-es/skins/skin-contract.css-mistica.js +740 -731
- package/dist-es/skins/telefonica.js +24 -9
- package/dist-es/skins/vivo-evolution.js +25 -10
- package/dist-es/skins/vivo.js +24 -9
- package/dist-es/skip-link.css-mistica.js +2 -2
- package/dist-es/slider.css-mistica.js +20 -20
- package/dist-es/snackbar.css-mistica.js +5 -5
- package/dist-es/spinner.css-mistica.js +1 -1
- package/dist-es/square.css-mistica.js +1 -1
- package/dist-es/stack.css-mistica.js +5 -5
- package/dist-es/stacking-group.css-mistica.js +1 -1
- package/dist-es/stepper.css-mistica.js +3 -3
- package/dist-es/style.css +1 -1
- package/dist-es/switch-component.css-mistica.js +37 -37
- package/dist-es/switch-component.js +26 -26
- package/dist-es/table.css-mistica.js +9 -9
- package/dist-es/tabs.css-mistica.js +19 -19
- package/dist-es/tag.css-mistica.js +2 -2
- package/dist-es/text-field-base.css-mistica.js +17 -17
- package/dist-es/text-field-components.css-mistica.js +4 -4
- package/dist-es/text-link.css-mistica.js +6 -6
- package/dist-es/text-tokens.js +82 -67
- package/dist-es/text.css-mistica.js +6 -6
- package/dist-es/timeline.css-mistica.js +10 -10
- package/dist-es/timer.css-mistica.js +6 -6
- package/dist-es/tooltip.css-mistica.js +2 -2
- package/dist-es/touchable.css-mistica.js +2 -2
- package/dist-es/utils/aspect-ratio-support.css-mistica.js +2 -2
- package/dist-es/video.css-mistica.js +1 -1
- package/dist-es/vivinho-loading-animation/vivinho-loading-animation.css-mistica.js +1 -1
- package/package.json +2 -1
- package/src/boxed.css.ts +1 -0
- package/src/boxed.tsx +18 -5
- package/src/callout.css.ts +4 -2
- package/src/community/skins/cyber-skin.tsx +19 -16
- package/src/fade-out.css.ts +12 -0
- package/src/fade-out.tsx +50 -0
- package/src/header.tsx +39 -17
- package/src/index.tsx +15 -0
- package/src/list.css.ts +36 -1
- package/src/list.tsx +370 -344
- package/src/mobile-navigation-menu.tsx +168 -0
- package/src/navigation-bar.css.ts +2 -267
- package/src/navigation-bar.tsx +77 -370
- package/src/navigation-shared.css.ts +289 -0
- package/src/navigation-shared.tsx +262 -0
- package/src/package-version.tsx +1 -1
- package/src/portal.tsx +1 -1
- package/src/sidenav-bar-context.tsx +41 -0
- package/src/sidenav-bar-data.ts +49 -0
- package/src/sidenav-bar-first-level-item.tsx +203 -0
- package/src/sidenav-bar-keyboard.tsx +393 -0
- package/src/sidenav-bar-layout.css.ts +89 -0
- package/src/sidenav-bar-layout.tsx +61 -0
- package/src/sidenav-bar-mobile.tsx +302 -0
- package/src/sidenav-bar-motion.tsx +70 -0
- package/src/sidenav-bar-panel.tsx +269 -0
- package/src/sidenav-bar-row.tsx +272 -0
- package/src/sidenav-bar-second-level-item.tsx +99 -0
- package/src/sidenav-bar-section.tsx +98 -0
- package/src/sidenav-bar-types.ts +224 -0
- package/src/sidenav-bar.css.ts +1018 -0
- package/src/sidenav-bar.tsx +821 -0
- package/src/skins/blau.tsx +17 -8
- package/src/skins/defaults.tsx +5 -0
- package/src/skins/esimflag.tsx +18 -9
- package/src/skins/movistar.tsx +18 -9
- package/src/skins/o2.tsx +18 -9
- package/src/skins/skin-contract.css.ts +3 -0
- package/src/skins/telefonica.tsx +18 -9
- package/src/skins/types/colors.tsx +2 -0
- package/src/skins/types/index.tsx +1 -0
- package/src/skins/vivo-evolution.tsx +19 -10
- package/src/skins/vivo.tsx +18 -9
- package/src/switch-component.css.ts +20 -0
- package/src/switch-component.tsx +9 -1
- package/src/text-tokens.tsx +24 -0
|
@@ -0,0 +1,1018 @@
|
|
|
1
|
+
import {createVar, globalStyle, style, styleVariants} from '@vanilla-extract/css';
|
|
2
|
+
import {sprinkles} from './sprinkles.css';
|
|
3
|
+
import {vars as skinVars} from './skins/skin-contract.css';
|
|
4
|
+
|
|
5
|
+
import type {NonDeprecatedVariant} from './theme-variant-context';
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_WIDTH = 240;
|
|
8
|
+
export const COLLAPSED_WIDTH = 72;
|
|
9
|
+
const BOXED_INSET = 8;
|
|
10
|
+
// Left padding of a second-level row. It adds to the 8px left margin of the row (which clears the selected
|
|
11
|
+
// indicator on the rail), so the content of a second-level row lands 24px from the rail, as the Figma spec asks
|
|
12
|
+
// (16 + 8). The full 24 here would count the 8px margin twice.
|
|
13
|
+
const SECOND_LEVEL_INDENT = 16;
|
|
14
|
+
export const LOGO_SIZE = 32;
|
|
15
|
+
// Horizontal inset of the items rail on each side of a section (see `sectionContent`). The selected
|
|
16
|
+
// indicator of an item sits on that inset, at the left edge of the rail.
|
|
17
|
+
const RAIL_INSET = 10;
|
|
18
|
+
// Margin of the row of an item, on each side of the items rail. On the left it is measured from the left
|
|
19
|
+
// edge of the selected indicator, which is 2px wide, so the row keeps a gap of 6px from that indicator.
|
|
20
|
+
// The expanded sidenav and the collapsed rail share this number: the row of an item stands in the same
|
|
21
|
+
// place in both states, 18px from each edge of the sidenav.
|
|
22
|
+
const ITEM_ROW_INSET = 8;
|
|
23
|
+
const ITEM_ROW_GAP = 8;
|
|
24
|
+
const ITEM_ROW_HEIGHT = 44;
|
|
25
|
+
// Vertical padding of a row. A label that wraps keeps this room above and below its text, and a label of
|
|
26
|
+
// one line keeps the row at `ITEM_ROW_HEIGHT`: `Text2` measures 24px on the skin that gives it the most
|
|
27
|
+
// room, and 24 plus the two paddings is exactly that height.
|
|
28
|
+
const ITEM_ROW_PADDING_Y = 10;
|
|
29
|
+
const SECTION_TITLE_INSET = 24;
|
|
30
|
+
// Horizontal inset of the floating dialog panel. The row of each item adds `ITEM_ROW_INSET` on top of it,
|
|
31
|
+
// so the content of a child item lands at `SECTION_TITLE_INSET` from the edge of the panel.
|
|
32
|
+
const DIALOG_PANEL_INSET = 8;
|
|
33
|
+
const DIALOG_PANEL_PADDING_Y = 16;
|
|
34
|
+
// Vertical space that every entry of the first level of the body (a section or a stand-alone item) owns
|
|
35
|
+
// above and below itself. Two neighbours therefore stand twice this apart, and the first and the last
|
|
36
|
+
// entries keep it towards the header and the footer.
|
|
37
|
+
const ENTRY_SPACE_Y = 8;
|
|
38
|
+
// Vertical space between a section divider and the items that it faces. The outward side of the divider
|
|
39
|
+
// owns nothing: the entries around it already stand `ENTRY_SPACE_Y` apart on each side.
|
|
40
|
+
const SECTION_DIVIDER_MARGIN_Y = 16;
|
|
41
|
+
const SECTION_DIVIDER_MARGIN_X = 8;
|
|
42
|
+
const HEADER_SCROLL_SPACER_HEIGHT = 24;
|
|
43
|
+
const SLOT_INSET_X = 24;
|
|
44
|
+
// The collapsed rail draws both slots on the rail of the items, so they take `RAIL_INSET` there. The
|
|
45
|
+
// expanded inset would leave a slot only 24px of the 72px rail.
|
|
46
|
+
const COLLAPSED_SLOT_INSET_X = RAIL_INSET;
|
|
47
|
+
// Vertical insets of the footer slot, which are not equal to each other: the Figma anatomy frame of the
|
|
48
|
+
// footer region gives its slot 8px above and 32px below.
|
|
49
|
+
const FOOTER_PADDING_TOP = 8;
|
|
50
|
+
const FOOTER_PADDING_BOTTOM = 32;
|
|
51
|
+
const FOCUS_RING_ROOM = 4;
|
|
52
|
+
|
|
53
|
+
export const sidenavWidthVar = createVar();
|
|
54
|
+
// The second column always takes the `width` of the expanded sidenav, so it needs its own variable: the
|
|
55
|
+
// variable above carries the width of the collapsed rail while the sidenav is collapsed.
|
|
56
|
+
export const sidenavPanelWidthVar = createVar();
|
|
57
|
+
|
|
58
|
+
// Animation ------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
export const COLLAPSE_DURATION_MS = 350;
|
|
61
|
+
export const CONTENT_DURATION_MS = 400;
|
|
62
|
+
|
|
63
|
+
const COLLAPSE_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';
|
|
64
|
+
const CONTENT_EASING = 'ease';
|
|
65
|
+
|
|
66
|
+
// `SidenavBar` fills both durations on its root element, and every rule below reads them from there.
|
|
67
|
+
// An acceptance run receives 0ms, so a test that presses a control and reads the result at once never
|
|
68
|
+
// catches a frame of the movement.
|
|
69
|
+
export const collapseDurationVar = createVar();
|
|
70
|
+
export const contentDurationVar = createVar();
|
|
71
|
+
|
|
72
|
+
// Every animated rule of this file carries this block: the spec asks for an instant change when the
|
|
73
|
+
// user turns motion down in the operating system.
|
|
74
|
+
const reducedMotion = {
|
|
75
|
+
'@media': {
|
|
76
|
+
['(prefers-reduced-motion)']: {
|
|
77
|
+
transition: 'none',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
} as const;
|
|
81
|
+
|
|
82
|
+
// Tokens ----------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
// The spec paints the header, the body and the footer of every variant with an existing background token,
|
|
85
|
+
// one member per variant. A boxed sidenav paints the same colours as a full-height one, with one exception:
|
|
86
|
+
// the negative boxed header (see `headerNegativeBoxedBackground`).
|
|
87
|
+
const regionBackgroundColor: Record<NonDeprecatedVariant, string> = {
|
|
88
|
+
default: skinVars.colors.background,
|
|
89
|
+
brand: skinVars.colors.navigationBarBackground,
|
|
90
|
+
alternative: skinVars.colors.backgroundAlternative,
|
|
91
|
+
negative: skinVars.colors.backgroundNegative,
|
|
92
|
+
media: skinVars.colors.backgroundNegative,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// The negative variant is the only one whose boxed header takes a different token: the spec gives it
|
|
96
|
+
// `backgroundContainerNegative`, while its body and footer keep `backgroundNegative`. The header cannot be
|
|
97
|
+
// transparent, because the content scrolls underneath it while it is fixed.
|
|
98
|
+
export const headerNegativeBoxedBackground = style({
|
|
99
|
+
backgroundColor: skinVars.colors.backgroundContainerNegative,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Every divider of the sidenav (the right divider, the two overscroll dividers, the section dividers and the
|
|
103
|
+
// separator of the double panel column) takes the same token for a given variant.
|
|
104
|
+
const dividerColor: Record<NonDeprecatedVariant, string> = {
|
|
105
|
+
default: skinVars.colors.divider,
|
|
106
|
+
brand: skinVars.colors.dividerBrand,
|
|
107
|
+
alternative: skinVars.colors.divider,
|
|
108
|
+
negative: skinVars.colors.dividerNegative,
|
|
109
|
+
media: skinVars.colors.dividerNegative,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const sectionTitleColor: Record<NonDeprecatedVariant, string> = {
|
|
113
|
+
default: skinVars.colors.textSecondary,
|
|
114
|
+
brand: skinVars.colors.textSecondaryBrand,
|
|
115
|
+
alternative: skinVars.colors.textSecondary,
|
|
116
|
+
negative: skinVars.colors.textSecondaryNegative,
|
|
117
|
+
media: skinVars.colors.textSecondaryNegative,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type ItemColors = {
|
|
121
|
+
label: string;
|
|
122
|
+
asset: string;
|
|
123
|
+
chevron: string;
|
|
124
|
+
indicator: string;
|
|
125
|
+
hover: string;
|
|
126
|
+
pressed: string;
|
|
127
|
+
selected: string;
|
|
128
|
+
selectedHover: string;
|
|
129
|
+
selectedPressed: string;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// The resting background of an item is transparent in every variant, so the region behind it shows through.
|
|
133
|
+
const itemColors: Record<NonDeprecatedVariant, ItemColors> = {
|
|
134
|
+
default: {
|
|
135
|
+
label: skinVars.colors.textPrimary,
|
|
136
|
+
asset: 'currentColor',
|
|
137
|
+
chevron: skinVars.colors.chevronIndicator,
|
|
138
|
+
indicator: skinVars.colors.controlActivated,
|
|
139
|
+
hover: skinVars.colors.backgroundContainerHover,
|
|
140
|
+
pressed: skinVars.colors.backgroundContainerPressed,
|
|
141
|
+
selected: skinVars.colors.backgroundSelected,
|
|
142
|
+
selectedHover: skinVars.colors.backgroundSelectedHover,
|
|
143
|
+
selectedPressed: skinVars.colors.backgroundSelectedPressed,
|
|
144
|
+
},
|
|
145
|
+
brand: {
|
|
146
|
+
label: skinVars.colors.textPrimaryBrand,
|
|
147
|
+
asset: 'currentColor',
|
|
148
|
+
chevron: skinVars.colors.neutralHighBrand,
|
|
149
|
+
indicator: skinVars.colors.controlActivatedBrand,
|
|
150
|
+
hover: skinVars.colors.backgroundContainerBrandHover,
|
|
151
|
+
pressed: skinVars.colors.backgroundContainerBrandPressed,
|
|
152
|
+
selected: skinVars.colors.backgroundSelectedBrand,
|
|
153
|
+
selectedHover: skinVars.colors.backgroundSelectedBrandHover,
|
|
154
|
+
selectedPressed: skinVars.colors.backgroundSelectedBrandPressed,
|
|
155
|
+
},
|
|
156
|
+
alternative: {
|
|
157
|
+
label: skinVars.colors.textPrimary,
|
|
158
|
+
asset: 'currentColor',
|
|
159
|
+
chevron: skinVars.colors.chevronIndicator,
|
|
160
|
+
indicator: skinVars.colors.controlActivated,
|
|
161
|
+
hover: skinVars.colors.backgroundContainerHover,
|
|
162
|
+
pressed: skinVars.colors.backgroundContainerPressed,
|
|
163
|
+
selected: skinVars.colors.backgroundSelected,
|
|
164
|
+
selectedHover: skinVars.colors.backgroundSelectedHover,
|
|
165
|
+
selectedPressed: skinVars.colors.backgroundSelectedPressed,
|
|
166
|
+
},
|
|
167
|
+
negative: {
|
|
168
|
+
label: skinVars.colors.textPrimaryNegative,
|
|
169
|
+
asset: 'currentColor',
|
|
170
|
+
chevron: skinVars.colors.neutralHighNegative,
|
|
171
|
+
indicator: skinVars.colors.controlActivatedNegative,
|
|
172
|
+
hover: skinVars.colors.backgroundContainerHover,
|
|
173
|
+
pressed: skinVars.colors.backgroundContainerPressed,
|
|
174
|
+
selected: skinVars.colors.backgroundSelectedNegative,
|
|
175
|
+
selectedHover: skinVars.colors.backgroundSelectedNegativeHover,
|
|
176
|
+
selectedPressed: skinVars.colors.backgroundSelectedNegativePressed,
|
|
177
|
+
},
|
|
178
|
+
media: {
|
|
179
|
+
label: skinVars.colors.textPrimaryNegative,
|
|
180
|
+
asset: 'currentColor',
|
|
181
|
+
chevron: skinVars.colors.neutralHighNegative,
|
|
182
|
+
indicator: skinVars.colors.controlActivatedNegative,
|
|
183
|
+
hover: skinVars.colors.backgroundContainerHover,
|
|
184
|
+
pressed: skinVars.colors.backgroundContainerPressed,
|
|
185
|
+
selected: skinVars.colors.backgroundSelected,
|
|
186
|
+
selectedHover: skinVars.colors.backgroundSelectedHover,
|
|
187
|
+
selectedPressed: skinVars.colors.backgroundSelectedPressed,
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// The container is a row of columns: the main column, and the double panel column when it is open. Its
|
|
192
|
+
// width is intrinsic, so an open panel widens the sidenav and pushes the main content of the layout.
|
|
193
|
+
// It paints no background of its own: each region owns its token, and the body of the default variant
|
|
194
|
+
// is transparent, so the page shows through it.
|
|
195
|
+
// The three heights below replace the plain `100%` that a rail of `SidenavLayout` would need on its own.
|
|
196
|
+
// A percentage height resolves to `auto` under a parent that takes the height of its content, and the
|
|
197
|
+
// sidenav then shrinks to the height of its items, which is what a consumer sees when it renders the bar
|
|
198
|
+
// outside of the layout. A percentage `min-height` reads as `0` under that same parent, and a percentage
|
|
199
|
+
// `max-height` reads as `none`, so the two of them pin the sidenav to the height of its parent wherever
|
|
200
|
+
// that height exists, and they leave the height of the viewport wherever it does not.
|
|
201
|
+
export const container = style([
|
|
202
|
+
sprinkles({
|
|
203
|
+
display: 'flex',
|
|
204
|
+
flexDirection: 'row',
|
|
205
|
+
}),
|
|
206
|
+
{
|
|
207
|
+
position: 'relative',
|
|
208
|
+
boxSizing: 'border-box',
|
|
209
|
+
// The width belongs to the columns, so the root takes the width that they ask for. A block-level
|
|
210
|
+
// box otherwise fills the width of its parent, and the edge of a boxed sidenav, which the root
|
|
211
|
+
// paints, then stood far to the right of the items of a narrower `width`. A flex item resolves
|
|
212
|
+
// its width the same way, so a rail of `SidenavLayout` measured the columns already.
|
|
213
|
+
width: 'fit-content',
|
|
214
|
+
height: '100vh',
|
|
215
|
+
minHeight: '100%',
|
|
216
|
+
maxHeight: '100%',
|
|
217
|
+
overflow: 'hidden',
|
|
218
|
+
},
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
// The column that carries the header, the body, and the footer regions.
|
|
222
|
+
// `sidenavWidthVar` carries the width of the expanded sidenav or the width of the collapsed rail, so the
|
|
223
|
+
// transition below runs whenever the user toggles the sidenav.
|
|
224
|
+
export const mainColumn = style([
|
|
225
|
+
sprinkles({
|
|
226
|
+
display: 'flex',
|
|
227
|
+
flexDirection: 'column',
|
|
228
|
+
}),
|
|
229
|
+
{
|
|
230
|
+
position: 'relative',
|
|
231
|
+
boxSizing: 'border-box',
|
|
232
|
+
height: '100%',
|
|
233
|
+
width: sidenavWidthVar,
|
|
234
|
+
flexShrink: 0,
|
|
235
|
+
minWidth: 0,
|
|
236
|
+
transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
237
|
+
...reducedMotion,
|
|
238
|
+
},
|
|
239
|
+
]);
|
|
240
|
+
|
|
241
|
+
// A vertical divider paints over the last pixel column of the box that owns it, as an absolutely
|
|
242
|
+
// positioned overlay. A real border grows the intrinsic width of the container instead, so the whole
|
|
243
|
+
// sidenav (and the content next to it) shifted by 1px when the consumer toggled the divider. With the
|
|
244
|
+
// overlay, `width` is a total width, dividers included, for both columns, and no child moves. An
|
|
245
|
+
// outline is not an option either: the container has `overflow: hidden`, which clips it.
|
|
246
|
+
const verticalDividerOverlay = {
|
|
247
|
+
content: '',
|
|
248
|
+
position: 'absolute',
|
|
249
|
+
top: 0,
|
|
250
|
+
right: 0,
|
|
251
|
+
bottom: 0,
|
|
252
|
+
width: 1,
|
|
253
|
+
pointerEvents: 'none',
|
|
254
|
+
// Above the sticky scroll dividers of the body, above the header, and above the edge of a boxed
|
|
255
|
+
// sidenav (see `boxedBorder`), so this line reaches the top and the bottom of the box.
|
|
256
|
+
zIndex: 4,
|
|
257
|
+
} as const;
|
|
258
|
+
|
|
259
|
+
export const withRightDivider = styleVariants(dividerColor, (color) => ({
|
|
260
|
+
'::after': {...verticalDividerOverlay, backgroundColor: color},
|
|
261
|
+
}));
|
|
262
|
+
|
|
263
|
+
// The header, the body and the footer share one background per variant, so the three bands of the sidenav
|
|
264
|
+
// stay uniform, and a boxed sidenav paints the same colours as a full-height one.
|
|
265
|
+
export const regionBackground = styleVariants(regionBackgroundColor, (color) => ({
|
|
266
|
+
backgroundColor: color,
|
|
267
|
+
}));
|
|
268
|
+
|
|
269
|
+
// While the rail moves, every column of the sidenav stops answering the pointer: the row that the user
|
|
270
|
+
// aims at is travelling, and a floating panel opened here would measure an edge that has not arrived yet.
|
|
271
|
+
// The rule lands on the columns, and not on the container, so the container still takes the press: a press
|
|
272
|
+
// that fell through to the page behind would read as a press outside of the bar, and it would close the
|
|
273
|
+
// second column.
|
|
274
|
+
export const columnsWhileMoving = style({});
|
|
275
|
+
|
|
276
|
+
globalStyle(`${columnsWhileMoving} > *`, {
|
|
277
|
+
pointerEvents: 'none',
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// The margins of the box belong to the height, so a boxed sidenav and a full-height one take the same
|
|
281
|
+
// room. The three heights follow the rule of `container` above.
|
|
282
|
+
export const boxed = style({
|
|
283
|
+
margin: BOXED_INSET,
|
|
284
|
+
height: `calc(100vh - ${BOXED_INSET * 2}px)`,
|
|
285
|
+
minHeight: `calc(100% - ${BOXED_INSET * 2}px)`,
|
|
286
|
+
maxHeight: `calc(100% - ${BOXED_INSET * 2}px)`,
|
|
287
|
+
borderRadius: skinVars.borderRadii.popup,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// The edge of the box is an overlay, not a real border. A real border takes 1px of the container on
|
|
291
|
+
// each side, and `overflow: hidden` clips every child to the padding box, so the separator of the
|
|
292
|
+
// double panel could not reach the top and the bottom edge of the box: it stopped one pixel short of
|
|
293
|
+
// them, and that pixel reads as a gap wherever the border token matches the background of the sidenav,
|
|
294
|
+
// which every dark mode does. The overlay keeps the border out of the intrinsic size too, so a boxed
|
|
295
|
+
// sidenav of `width` pixels measures exactly that width. An outline is not an option: `overflow:
|
|
296
|
+
// hidden` clips a negatively-offset outline.
|
|
297
|
+
// `shouldShowBoxedBorder` decides when this class applies: the border only reads over a default or an
|
|
298
|
+
// alternative page, and a skin can switch it off.
|
|
299
|
+
// todo https://github.com/Telefonica/mistica-design/issues/2827 review Boxed border rendering logic
|
|
300
|
+
export const boxedBorder = style({
|
|
301
|
+
'::before': {
|
|
302
|
+
content: '',
|
|
303
|
+
position: 'absolute',
|
|
304
|
+
inset: 0,
|
|
305
|
+
boxSizing: 'border-box',
|
|
306
|
+
border: `1px solid ${skinVars.colors.border}`,
|
|
307
|
+
// The container owns the radius (see `boxed`), and the edge follows it.
|
|
308
|
+
borderRadius: 'inherit',
|
|
309
|
+
pointerEvents: 'none',
|
|
310
|
+
// Above the background of both columns, the sticky scroll dividers of the body and the header,
|
|
311
|
+
// and below the vertical dividers, which cross it (see `verticalDividerOverlay`).
|
|
312
|
+
zIndex: 3,
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// Header region ---------------------------------------------------------------
|
|
317
|
+
|
|
318
|
+
// The 24px inset above the logo belongs to the header, so the header band reaches the top edge of the
|
|
319
|
+
// sidenav in every variant.
|
|
320
|
+
// The 32px gap separates the collapse action from the header slot, and the collapsed rail keeps it: the
|
|
321
|
+
// spec gives one value for both states.
|
|
322
|
+
export const headerBase = style({
|
|
323
|
+
display: 'flex',
|
|
324
|
+
flexDirection: 'column',
|
|
325
|
+
alignItems: 'center',
|
|
326
|
+
gap: 24,
|
|
327
|
+
flexShrink: 0,
|
|
328
|
+
paddingTop: 24,
|
|
329
|
+
// Above the background of the body and above the painted scroll spacer, which follow it. Without a
|
|
330
|
+
// header slot, the collapse control ends the header, and its focus ring draws a few pixels below it,
|
|
331
|
+
// over the body: the body background, or the band of the spacer while the user scrolls, would
|
|
332
|
+
// otherwise cover that part of the ring. Below the boxed edge (zIndex 3) and the vertical dividers
|
|
333
|
+
// (zIndex 4).
|
|
334
|
+
position: 'relative',
|
|
335
|
+
zIndex: 2,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// The logo and the collapse control stack, both 32px tall. Their left edge is placed with
|
|
339
|
+
// explicit padding rather than by centering, so that it stays at 20px in both states
|
|
340
|
+
// regardless of the right divider border and of whether the consumer loads css/reset.css.
|
|
341
|
+
export const headerControls = style({
|
|
342
|
+
boxSizing: 'border-box',
|
|
343
|
+
display: 'flex',
|
|
344
|
+
flexDirection: 'column',
|
|
345
|
+
alignItems: 'flex-start',
|
|
346
|
+
gap: 8,
|
|
347
|
+
width: '100%',
|
|
348
|
+
paddingLeft: 20,
|
|
349
|
+
paddingRight: 24,
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// The collapsed rail keeps the same left padding, and it keeps `flex-start` too. Centring the controls
|
|
353
|
+
// gives the same result at rest, because the rail leaves the logo exactly its 32px, but it moves them
|
|
354
|
+
// while the rail moves: a centre travels with the box that holds it, and a left edge does not.
|
|
355
|
+
export const headerControlsCollapsed = style({
|
|
356
|
+
paddingRight: 20,
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// The default isotype is a square as wide as its height in both states. The collapsed rail still clamps
|
|
360
|
+
// the width, because a logo of the consumer, or the function form of the prop, can be wider than the rail.
|
|
361
|
+
// The spec fades the label of the header 50ms after the rail starts to move. Our default header carries no
|
|
362
|
+
// label, because the default logo is the isotype in both states, so what this rule gives is the smooth
|
|
363
|
+
// clamp of the width, and a smooth fade for a consumer that drives the opacity of its own logo.
|
|
364
|
+
export const logo = style({
|
|
365
|
+
display: 'flex',
|
|
366
|
+
alignItems: 'center',
|
|
367
|
+
flexShrink: 0,
|
|
368
|
+
// The spot grows with a logo of the consumer that is taller than the default isotype. The minimum
|
|
369
|
+
// keeps the 32px band of the spec, so the header rhythm does not change with the default logo.
|
|
370
|
+
height: 'auto',
|
|
371
|
+
minHeight: LOGO_SIZE,
|
|
372
|
+
// The clamp below is a `max-width`, and not a `width`, so that it interpolates: `auto` has no value to
|
|
373
|
+
// animate from.
|
|
374
|
+
maxWidth: '100%',
|
|
375
|
+
// A logo of the consumer that is larger than this box is clipped, so it never paints over the
|
|
376
|
+
// controls of the header or past the edge of the collapsed rail.
|
|
377
|
+
overflow: 'hidden',
|
|
378
|
+
transition: `max-width ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING} 50ms`,
|
|
379
|
+
...reducedMotion,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// The child keeps its own width while the clamp narrows the box. A flex item shrinks to its minimum
|
|
383
|
+
// otherwise, and a text inside it then re-wraps letter by letter, which makes the spot grow with every
|
|
384
|
+
// line. This way the edge of the box cuts the child, which stands still (see `itemLabelFrozenWidth`).
|
|
385
|
+
globalStyle(`${logo} > *`, {
|
|
386
|
+
flexShrink: 0,
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// The svg of the default logo draws a few pixels taller than the size that it receives, and the amount
|
|
390
|
+
// depends on the skin. The default spot holds the 32px of the spec, so the header keeps its rhythm in
|
|
391
|
+
// every skin.
|
|
392
|
+
export const logoDefault = style({
|
|
393
|
+
height: LOGO_SIZE,
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
export const logoCollapsed = style({
|
|
397
|
+
maxWidth: LOGO_SIZE,
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// The slot follows the same rule as the logo above. It never rests at opacity 0, because the collapsed
|
|
401
|
+
// rail keeps the slot: the fade serves a consumer that drives the opacity of its own header content.
|
|
402
|
+
// The padding travels with the rail, so the slot never snaps to its collapsed inset while the rail moves.
|
|
403
|
+
export const headerSlot = style({
|
|
404
|
+
boxSizing: 'border-box',
|
|
405
|
+
width: '100%',
|
|
406
|
+
minWidth: 0,
|
|
407
|
+
paddingLeft: SLOT_INSET_X,
|
|
408
|
+
paddingRight: SLOT_INSET_X,
|
|
409
|
+
transition: `opacity ${collapseDurationVar} ${COLLAPSE_EASING} 50ms, padding ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
410
|
+
...reducedMotion,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
export const headerSlotCollapsed = style({
|
|
414
|
+
paddingLeft: COLLAPSED_SLOT_INSET_X,
|
|
415
|
+
paddingRight: COLLAPSED_SLOT_INSET_X,
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Body region -----------------------------------------------------------------
|
|
419
|
+
|
|
420
|
+
// The body scrolls up and down, never sideways. The rule below is not the default: a box that scrolls on
|
|
421
|
+
// one axis takes `auto` on the other one as well, and the title of a section, which keeps the width of its
|
|
422
|
+
// text while the sidenav moves, would then give the collapsed rail a horizontal scrollbar.
|
|
423
|
+
export const bodyBase = style({
|
|
424
|
+
flex: 1,
|
|
425
|
+
minHeight: 0,
|
|
426
|
+
overflowX: 'hidden',
|
|
427
|
+
overflowY: 'auto',
|
|
428
|
+
display: 'flex',
|
|
429
|
+
flexDirection: 'column',
|
|
430
|
+
position: 'relative',
|
|
431
|
+
// When the keyboard moves the focus to a row outside of the view, the browser scrolls that row just
|
|
432
|
+
// to the edge of the scrollport. At the top, that edge sits under the painted spacer, which would
|
|
433
|
+
// cover the top of the focus ring. The scroll padding makes the browser leave the spacer and the
|
|
434
|
+
// ring their room. `FOCUS_RING_ROOM` is the room of the ring alone, top and bottom.
|
|
435
|
+
scrollPaddingTop: HEADER_SCROLL_SPACER_HEIGHT + FOCUS_RING_ROOM,
|
|
436
|
+
scrollPaddingBottom: FOCUS_RING_ROOM,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// The inset between the header and the first row lives inside the scrollport, as this sticky
|
|
440
|
+
// spacer, and not as a padding of the header or of the body. A padding of the header sits outside the
|
|
441
|
+
// scrollport, and the seam clips the focus ring of the first row; a padding of the body sits inside it,
|
|
442
|
+
// and the rows stay visible under the header while the user scrolls. The spacer gives both behaviours:
|
|
443
|
+
// transparent at rest, it leaves the ring its room, and while the content scrolls it paints the
|
|
444
|
+
// background of the body over the rows that pass beneath, with the divider on its bottom edge. It is
|
|
445
|
+
// always in the flow, so nothing jumps on the scroll threshold: only its paint changes.
|
|
446
|
+
// The flex places the line of the spacer on its outer edge: the last child lands on the bottom edge of
|
|
447
|
+
// the header spacer, and the first child on the top edge of the footer spacer. An absolutely positioned
|
|
448
|
+
// line is not an option: it does not anchor to the sticky box reliably, and it lands at the bottom of
|
|
449
|
+
// the scroll content instead.
|
|
450
|
+
const scrollSpacerBase = {
|
|
451
|
+
flexShrink: 0,
|
|
452
|
+
position: 'sticky',
|
|
453
|
+
zIndex: 1,
|
|
454
|
+
pointerEvents: 'none',
|
|
455
|
+
display: 'flex',
|
|
456
|
+
flexDirection: 'column',
|
|
457
|
+
} as const;
|
|
458
|
+
|
|
459
|
+
export const headerScrollSpacer = style({
|
|
460
|
+
...scrollSpacerBase,
|
|
461
|
+
height: HEADER_SCROLL_SPACER_HEIGHT,
|
|
462
|
+
top: 0,
|
|
463
|
+
justifyContent: 'flex-end',
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
// The mirror of `headerScrollSpacer` for a fixed footer, which sits outside of the scrollport like the
|
|
467
|
+
// header does. The band covers the rows that pass beneath it toward the footer. It is shorter than the
|
|
468
|
+
// header spacer, because it carries the top inset of the footer, which the spec makes smaller.
|
|
469
|
+
export const footerScrollSpacer = style({
|
|
470
|
+
...scrollSpacerBase,
|
|
471
|
+
height: FOOTER_PADDING_TOP,
|
|
472
|
+
bottom: 0,
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// The line of a spacer. It stops 1px before the right edge, so it never crosses the vertical divider
|
|
476
|
+
// that sits there (see the comment of `scrollDivider` below), and a boxed sidenav insets it on the left
|
|
477
|
+
// (see the `boxed` rule below).
|
|
478
|
+
export const scrollSpacerDivider = style({
|
|
479
|
+
height: 1,
|
|
480
|
+
marginRight: 1,
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// A keyboard-focused row must stop clear of the band of the fixed footer: the height of the band plus the
|
|
484
|
+
// room of the ring, like `scrollPaddingTop` above. The inline footer keeps the `FOCUS_RING_ROOM` of
|
|
485
|
+
// `bodyBase`, because it scrolls with the content and needs no band.
|
|
486
|
+
export const bodyWithFixedFooter = style({
|
|
487
|
+
scrollPaddingBottom: FOOTER_PADDING_TOP + FOCUS_RING_ROOM,
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// List of first-level entries (sections and stand-alone items). Every entry owns `ENTRY_SPACE_Y` above and
|
|
491
|
+
// below itself, whatever its kind: the gap carries the two spaces that meet between two neighbours, and the
|
|
492
|
+
// padding carries the space of the first entry and of the last one. The space lives on this list, so the
|
|
493
|
+
// scroll sentinels and the footer, which are its siblings, stay untouched.
|
|
494
|
+
export const bodyContent = style({
|
|
495
|
+
display: 'flex',
|
|
496
|
+
flexDirection: 'column',
|
|
497
|
+
gap: ENTRY_SPACE_Y * 2,
|
|
498
|
+
paddingTop: ENTRY_SPACE_Y,
|
|
499
|
+
paddingBottom: ENTRY_SPACE_Y,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
// Scroll-intersection divider of the footer (appears when content scrolls past the footer).
|
|
503
|
+
// It stops 1px before the right edge, so it never crosses the vertical divider that sits there (the right
|
|
504
|
+
// divider, or the separator of the double panel). The divider token is translucent in dark mode, so two
|
|
505
|
+
// lines that overlap paint a brighter pixel at the crossing. The gap is invisible when no vertical divider
|
|
506
|
+
// is there, because the right edge of the sidenav is transparent then. A boxed sidenav also insets it on
|
|
507
|
+
// the left (see the `boxed` rule below), where its edge draws a border too.
|
|
508
|
+
export const scrollDivider = style({
|
|
509
|
+
height: 1,
|
|
510
|
+
flexShrink: 0,
|
|
511
|
+
pointerEvents: 'none',
|
|
512
|
+
position: 'sticky',
|
|
513
|
+
zIndex: 1,
|
|
514
|
+
marginRight: 1,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
export const footerScrollDivider = style({
|
|
518
|
+
bottom: 0,
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
export const scrollDividerVariant = styleVariants(dividerColor, (color) => ({backgroundColor: color}));
|
|
522
|
+
|
|
523
|
+
// Footer region ---------------------------------------------------------------
|
|
524
|
+
|
|
525
|
+
// The horizontal padding travels with the rail, like the one of `headerSlot`: the two slots keep the same
|
|
526
|
+
// two edges through the whole movement, and neither of them snaps to its collapsed inset.
|
|
527
|
+
export const footerBase = style({
|
|
528
|
+
flexShrink: 0,
|
|
529
|
+
paddingTop: FOOTER_PADDING_TOP,
|
|
530
|
+
paddingBottom: FOOTER_PADDING_BOTTOM,
|
|
531
|
+
paddingLeft: SLOT_INSET_X,
|
|
532
|
+
paddingRight: SLOT_INSET_X,
|
|
533
|
+
transition: `padding ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
534
|
+
...reducedMotion,
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
export const footerCollapsed = style({
|
|
538
|
+
paddingLeft: COLLAPSED_SLOT_INSET_X,
|
|
539
|
+
paddingRight: COLLAPSED_SLOT_INSET_X,
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// A fixed footer hands its top inset to `footerScrollSpacer`, which owns that space inside the
|
|
543
|
+
// scrollport, so the focus ring of the last row has room to draw. The footer content does not move: it
|
|
544
|
+
// anchors to the bottom, and only the boundary of its band shifts. The stacking mirrors `headerBase`:
|
|
545
|
+
// a control on the top edge of the footer slot draws its ring a few pixels above the footer, and the
|
|
546
|
+
// painted band would cover that part of the ring otherwise.
|
|
547
|
+
export const footerFixed = style({
|
|
548
|
+
paddingTop: 0,
|
|
549
|
+
position: 'relative',
|
|
550
|
+
zIndex: 2,
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
// Section ---------------------------------------------------------------------
|
|
554
|
+
|
|
555
|
+
// No vertical padding here: a section owns no space of its own. Its dividers own the space that faces the
|
|
556
|
+
// items (see `sectionDividerTop`), and the body list owns the space between the entries.
|
|
557
|
+
export const section = style({
|
|
558
|
+
display: 'flex',
|
|
559
|
+
flexDirection: 'column',
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
// The box of the title closes while the rail narrows, so the items move up with it. A grid row goes from
|
|
563
|
+
// `1fr` to `0fr` with a transition, which a height in `auto` cannot do (the same pattern as the panel of the
|
|
564
|
+
// Accordion). The CI Chromium predates that interpolation and snaps the row, which its screenshots accept.
|
|
565
|
+
// The text fades apart from the fold, so the fade shows instead of the clip of the row: it fades out over
|
|
566
|
+
// the first half of a collapse, before the row cuts it, and it fades in over the second half of an
|
|
567
|
+
// expansion, once the row has room for it. A transition runs with the timing of the state that it goes
|
|
568
|
+
// to, so this rule times the expansion and `sectionTitleCollapsed` times the collapse.
|
|
569
|
+
const TITLE_FADE_DURATION = `calc(${collapseDurationVar} / 2)`;
|
|
570
|
+
|
|
571
|
+
export const sectionTitle = style({
|
|
572
|
+
display: 'grid',
|
|
573
|
+
gridTemplateRows: '1fr',
|
|
574
|
+
marginBottom: 8,
|
|
575
|
+
transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, margin-bottom ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${TITLE_FADE_DURATION} ${COLLAPSE_EASING} ${TITLE_FADE_DURATION}`,
|
|
576
|
+
...reducedMotion,
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
// The row of the grid clips its content, so the text disappears with the row and never paints over the
|
|
580
|
+
// items while the row closes.
|
|
581
|
+
export const sectionTitleContent = style({
|
|
582
|
+
minHeight: 0,
|
|
583
|
+
overflow: 'hidden',
|
|
584
|
+
padding: `0 ${SECTION_TITLE_INSET}px`,
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
// The title text inherits this colour (see the `color="inherit"` of its `Text3`), so every title of the
|
|
588
|
+
// sidenav takes its token from one place.
|
|
589
|
+
export const sectionTitleVariant = styleVariants(sectionTitleColor, (color) => ({color}));
|
|
590
|
+
|
|
591
|
+
// Collapsed: the title gives its space back, so the first item of a section moves up to where the title
|
|
592
|
+
// stood. The element stays in the document, out of the reading order with `aria-hidden`, because the
|
|
593
|
+
// list of the section takes its name from it (see `sidenav-bar-section.tsx`). No `visibility: hidden`: a
|
|
594
|
+
// box without height takes no click, and jsdom would drop the name of the list with it.
|
|
595
|
+
export const sectionTitleCollapsed = style({
|
|
596
|
+
gridTemplateRows: '0fr',
|
|
597
|
+
marginBottom: 0,
|
|
598
|
+
opacity: 0,
|
|
599
|
+
transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, margin-bottom ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${TITLE_FADE_DURATION} ${COLLAPSE_EASING}`,
|
|
600
|
+
...reducedMotion,
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
// A title that the consumer hides (`title={{text, hidden: true}}`) never paints, in any state, and it
|
|
604
|
+
// takes no space. It stays in the document because the list of the section takes its name from it, as in
|
|
605
|
+
// the collapsed state above. No `display: none`: that drops the element from the accessibility tree, and
|
|
606
|
+
// the name of the list would go with it.
|
|
607
|
+
export const sectionTitleHidden = style({
|
|
608
|
+
gridTemplateRows: '0fr',
|
|
609
|
+
marginBottom: 0,
|
|
610
|
+
opacity: 0,
|
|
611
|
+
transition: 'none',
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
// While the sidenav moves, the title keeps the width that it had at rest (an inline `width`, see
|
|
615
|
+
// `useRestWidth`), for the same reason as the label of an item (see `itemLabelFrozenWidth`). Without
|
|
616
|
+
// this, the title would wrap over several lines as the rail narrows, and the whole body of the sidenav
|
|
617
|
+
// would move down with it. A title with no width at rest yet takes the width of its text on one line.
|
|
618
|
+
export const sectionTitleKeepsWidth = style({
|
|
619
|
+
width: 'max-content',
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
// The rail that carries the items of a section. A first-level stand-alone item reuses it, so that
|
|
623
|
+
// it lands on the same rail as the items that belong to a section (see `standaloneItem`).
|
|
624
|
+
// The left inset hosts the selected indicator, and the row of each item adds `ITEM_ROW_INSET` on top of
|
|
625
|
+
// it, which gives the 18px that the spec measures from the edge of the sidenav to the row.
|
|
626
|
+
export const sectionContent = style({
|
|
627
|
+
display: 'flex',
|
|
628
|
+
flexDirection: 'column',
|
|
629
|
+
paddingLeft: RAIL_INSET,
|
|
630
|
+
paddingRight: RAIL_INSET,
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// A stand-alone item is not wrapped in a section, so it carries the items rail itself. It is a class of
|
|
634
|
+
// its own, so that a selector can tell it from the rail inside a section.
|
|
635
|
+
export const standaloneItem = style([sectionContent]);
|
|
636
|
+
|
|
637
|
+
// The dividers sit outside `sectionContent`, on the edges of the section. The anatomy of a section reads,
|
|
638
|
+
// top to bottom: top divider, 16px, title, 8px, items, 16px, bottom divider. Each divider carries its 16px
|
|
639
|
+
// as a margin on the side of the items only. The outward side is the edge of the entry, and the body list
|
|
640
|
+
// keeps every entry 16px from its neighbour there, so a line reads 16px on each side, shared or not. The
|
|
641
|
+
// collapsed rail keeps the same distances, because the title closes without a trace. The horizontal margin
|
|
642
|
+
// also keeps the line off the vertical divider on the right edge, for the same reason as `scrollDivider`
|
|
643
|
+
// above.
|
|
644
|
+
const sectionDividerBase = style({
|
|
645
|
+
marginLeft: SECTION_DIVIDER_MARGIN_X,
|
|
646
|
+
marginRight: SECTION_DIVIDER_MARGIN_X,
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
export const sectionDividerTop = style([sectionDividerBase, {marginBottom: SECTION_DIVIDER_MARGIN_Y}]);
|
|
650
|
+
export const sectionDividerBottom = style([sectionDividerBase, {marginTop: SECTION_DIVIDER_MARGIN_Y}]);
|
|
651
|
+
|
|
652
|
+
// A boxed sidenav draws a border on its left edge too (see `boxedBorder`), so the scroll dividers keep off
|
|
653
|
+
// that edge as well. A non-boxed sidenav has no divider on the left, so the lines reach that edge. A section
|
|
654
|
+
// divider needs no rule here: its 8px margin already clears both edges.
|
|
655
|
+
globalStyle(`${boxed} ${scrollDivider}, ${boxed} ${scrollSpacerDivider}`, {
|
|
656
|
+
marginLeft: 1,
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
// Item ------------------------------------------------------------------------
|
|
660
|
+
|
|
661
|
+
export const itemRow = style({
|
|
662
|
+
position: 'relative',
|
|
663
|
+
display: 'flex',
|
|
664
|
+
alignItems: 'center',
|
|
665
|
+
gap: 6,
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// The row of an item takes the same box in both states: `ITEM_ROW_INSET` on each side of the items rail.
|
|
669
|
+
// Its width is a percentage of the rail, so it follows the rail while the rail moves, and it needs no
|
|
670
|
+
// transition of its own. The collapsed rail leaves it 36px, which holds the icon and its two paddings.
|
|
671
|
+
// The overflow keeps the label, the right slot and the chevron inside the row while it narrows.
|
|
672
|
+
// The height is a minimum, and not a fixed number: the spec asks for a label that wraps over several
|
|
673
|
+
// lines instead of one that truncates, and the row grows with it. A row that holds a single line keeps the
|
|
674
|
+
// 44px of the spec, because `ITEM_ROW_PADDING_Y` leaves that line the room that it needs: one line of
|
|
675
|
+
// `Text2` measures 24px on the widest skin, and 44px hold it with the two paddings.
|
|
676
|
+
export const itemTouchable = style({
|
|
677
|
+
boxSizing: 'border-box',
|
|
678
|
+
display: 'flex',
|
|
679
|
+
alignItems: 'center',
|
|
680
|
+
gap: ITEM_ROW_GAP,
|
|
681
|
+
flex: 'none',
|
|
682
|
+
width: `calc(100% - ${ITEM_ROW_INSET * 2}px)`,
|
|
683
|
+
minWidth: 0,
|
|
684
|
+
minHeight: ITEM_ROW_HEIGHT,
|
|
685
|
+
padding: `${ITEM_ROW_PADDING_Y}px 8px`,
|
|
686
|
+
marginLeft: ITEM_ROW_INSET,
|
|
687
|
+
marginRight: ITEM_ROW_INSET,
|
|
688
|
+
borderRadius: 8,
|
|
689
|
+
backgroundColor: 'transparent',
|
|
690
|
+
overflow: 'hidden',
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// The label inherits the `color` of the row (see the `color="inherit"` of its `Text2`). The asset inherits it
|
|
694
|
+
// too (the spec paints it with `currentColor`), while the chevron overrides it with its own token (see
|
|
695
|
+
// `itemChevronVariant`).
|
|
696
|
+
export const itemTouchableVariant = styleVariants(itemColors, (colors) => ({
|
|
697
|
+
color: colors.label,
|
|
698
|
+
selectors: {
|
|
699
|
+
'&:hover': {backgroundColor: colors.hover},
|
|
700
|
+
'&:focus-visible': {backgroundColor: colors.hover},
|
|
701
|
+
'&:active': {backgroundColor: colors.pressed},
|
|
702
|
+
},
|
|
703
|
+
}));
|
|
704
|
+
|
|
705
|
+
// The collapsed rail keeps the box of the row untouched, so that the row never moves between the two
|
|
706
|
+
// states. The 36px that the rail leaves hold the icon and its two paddings exactly, which places the icon
|
|
707
|
+
// at the centre of the rail. The label and the gap that precedes it overflow that box, and the row clips
|
|
708
|
+
// them, so the icon keeps its place from the first frame of the movement to the last one.
|
|
709
|
+
export const itemTouchableCollapsed = style({
|
|
710
|
+
border: 'none',
|
|
711
|
+
lineHeight: 1,
|
|
712
|
+
textDecoration: 'none',
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
// It follows `itemTouchableVariant` in this file on purpose: both rules have the same specificity, so the
|
|
716
|
+
// selected background wins over the resting one by source order.
|
|
717
|
+
export const itemTouchableSelected = styleVariants(itemColors, (colors) => ({
|
|
718
|
+
backgroundColor: colors.selected,
|
|
719
|
+
selectors: {
|
|
720
|
+
'&:hover': {backgroundColor: colors.selectedHover},
|
|
721
|
+
'&:focus-visible': {backgroundColor: colors.selectedHover},
|
|
722
|
+
'&:active': {backgroundColor: colors.selectedPressed},
|
|
723
|
+
},
|
|
724
|
+
}));
|
|
725
|
+
|
|
726
|
+
// The accent stays on the collapsed rail: a selected first-level item keeps its bar in both states. Only
|
|
727
|
+
// a parent whose descendant is selected marks the selection with the background alone, because the bar
|
|
728
|
+
// belongs to the selected child (see `showAccent` in `sidenav-bar-first-level-item.tsx`).
|
|
729
|
+
export const itemAccent = style({
|
|
730
|
+
position: 'absolute',
|
|
731
|
+
left: 0,
|
|
732
|
+
top: '50%',
|
|
733
|
+
transform: 'translateY(-50%)',
|
|
734
|
+
width: 2,
|
|
735
|
+
height: 20,
|
|
736
|
+
borderRadius: 8,
|
|
737
|
+
pointerEvents: 'none',
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
export const itemAccentVariant = styleVariants(itemColors, (colors) => ({
|
|
741
|
+
backgroundColor: colors.indicator,
|
|
742
|
+
}));
|
|
743
|
+
|
|
744
|
+
export const itemAsset = style({
|
|
745
|
+
display: 'flex',
|
|
746
|
+
flexShrink: 0,
|
|
747
|
+
width: 20,
|
|
748
|
+
height: 20,
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
export const itemAssetVariant = styleVariants(itemColors, (colors) => ({color: colors.asset}));
|
|
752
|
+
|
|
753
|
+
// The label keeps its box in the DOM on the collapsed rail, so a screen reader still reads it, and so the
|
|
754
|
+
// fade of the spec has something to fade. Its own box needs no width animation: it grows and shrinks with
|
|
755
|
+
// the row that holds it, because it takes the space that the row leaves.
|
|
756
|
+
// The box is a grid row that folds from `1fr` to the height of one line while the rail collapses, the same
|
|
757
|
+
// pattern as the section title: a label that wraps over several lines then shrinks its row with the rail,
|
|
758
|
+
// instead of making it jump to one line at the first frame. The CI Chromium snaps that row (see
|
|
759
|
+
// `sectionTitle`).
|
|
760
|
+
export const itemLabel = style({
|
|
761
|
+
flex: 1,
|
|
762
|
+
minWidth: 0,
|
|
763
|
+
display: 'grid',
|
|
764
|
+
gridTemplateRows: '1fr',
|
|
765
|
+
transition: `grid-template-rows ${collapseDurationVar} ${COLLAPSE_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
766
|
+
...reducedMotion,
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
// The folded row stops at one line of text, which is what a row of 44px holds, so a label of one line
|
|
770
|
+
// never changes its box. The clip hides the lines below the first one while the row folds.
|
|
771
|
+
export const itemLabelContent = style({
|
|
772
|
+
minHeight: skinVars.textPresets.text2.lineHeight,
|
|
773
|
+
overflow: 'hidden',
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// The label keeps its place beside the icon, so the text stands still while it fades. A margin or a width
|
|
777
|
+
// of its own would drag the text toward the icon instead.
|
|
778
|
+
export const itemLabelCollapsed = style({
|
|
779
|
+
gridTemplateRows: '0fr',
|
|
780
|
+
opacity: 0,
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
// While the sidenav moves, the label keeps the width that it had at rest (an inline `width`, see
|
|
784
|
+
// `useRestWidth`), instead of taking the share of the row that the flex layout would give it. The row
|
|
785
|
+
// narrows under a text that does not move, and the edge of the sidenav passes over that text: without
|
|
786
|
+
// this, the label would wrap over more and more lines as the rail narrows, and every row of the body would
|
|
787
|
+
// grow and then shrink again. The expanded sidenav at rest drops this rule, so a label longer than the
|
|
788
|
+
// row wraps there, which is what the spec asks for.
|
|
789
|
+
export const itemLabelFrozenWidth = style({
|
|
790
|
+
flex: 'none',
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
// Fallback for a label with no width at rest yet (a sidenav that mounted collapsed): the width that its
|
|
794
|
+
// text asks for, on one line. The label then wraps when the rail settles, which is one jump at the end.
|
|
795
|
+
export const itemLabelKeepsWidth = style({
|
|
796
|
+
minWidth: 'max-content',
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
// The right slot and the chevron stay in the DOM on the collapsed rail and fade with the label of their
|
|
800
|
+
// item, so that nothing of the row pops while the rail moves. The `visibility` step ends with the fade,
|
|
801
|
+
// which takes the slot out of the accessibility tree and the tab order once the rail stopped.
|
|
802
|
+
export const itemRightSlot = style({
|
|
803
|
+
display: 'flex',
|
|
804
|
+
alignItems: 'center',
|
|
805
|
+
flexShrink: 0,
|
|
806
|
+
transition: `opacity ${collapseDurationVar} ${COLLAPSE_EASING}, visibility ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
807
|
+
...reducedMotion,
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
export const itemRightSlotCollapsed = style({
|
|
811
|
+
opacity: 0,
|
|
812
|
+
visibility: 'hidden',
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
export const itemChevron = style({
|
|
816
|
+
display: 'flex',
|
|
817
|
+
alignItems: 'center',
|
|
818
|
+
flexShrink: 0,
|
|
819
|
+
width: 16,
|
|
820
|
+
height: 16,
|
|
821
|
+
transition: `transform ${contentDurationVar} ${CONTENT_EASING}, opacity ${collapseDurationVar} ${COLLAPSE_EASING}, visibility ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
822
|
+
...reducedMotion,
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
export const itemChevronCollapsed = style({
|
|
826
|
+
opacity: 0,
|
|
827
|
+
visibility: 'hidden',
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
// The chevron of an open parent item turns half a turn counterclockwise, the same direction as the chevron
|
|
831
|
+
// of `Accordion` (see `icons/icon-chevron.tsx`), so that it reports the state of its group. It applies to
|
|
832
|
+
// the chevron that points down, which the sidenav uses for a group that opens in place. The double panel
|
|
833
|
+
// keeps the chevron that points right, and never turns it: half a turn would make it point away from the
|
|
834
|
+
// column that it opens.
|
|
835
|
+
export const itemChevronRotated = style({
|
|
836
|
+
transform: 'rotate(-180deg)',
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
export const itemChevronVariant = styleVariants(itemColors, (colors) => ({color: colors.chevron}));
|
|
840
|
+
|
|
841
|
+
// The children of a parent item grow and shrink as one group. A grid row of `0fr` collapses the group
|
|
842
|
+
// without a measured height, which is the pattern that `Accordion` uses (see `accordion.css.ts`).
|
|
843
|
+
export const accordionContainer = style({
|
|
844
|
+
display: 'grid',
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// The group also fades while it folds: the fold clips its rows, and a selected row would otherwise leave
|
|
848
|
+
// at full opacity, with its accent and its background.
|
|
849
|
+
export const accordionTransitionClasses = {
|
|
850
|
+
enter: style({
|
|
851
|
+
gridTemplateRows: '0fr',
|
|
852
|
+
opacity: 0,
|
|
853
|
+
}),
|
|
854
|
+
enterActive: style({
|
|
855
|
+
gridTemplateRows: '1fr',
|
|
856
|
+
opacity: 1,
|
|
857
|
+
transition: `grid-template-rows ${contentDurationVar} ${CONTENT_EASING}, opacity ${contentDurationVar} ${CONTENT_EASING}`,
|
|
858
|
+
...reducedMotion,
|
|
859
|
+
}),
|
|
860
|
+
exit: style({
|
|
861
|
+
gridTemplateRows: '1fr',
|
|
862
|
+
opacity: 1,
|
|
863
|
+
}),
|
|
864
|
+
exitActive: style({
|
|
865
|
+
gridTemplateRows: '0fr',
|
|
866
|
+
opacity: 0,
|
|
867
|
+
transition: `grid-template-rows ${contentDurationVar} ${CONTENT_EASING}, opacity ${contentDurationVar} ${CONTENT_EASING}`,
|
|
868
|
+
...reducedMotion,
|
|
869
|
+
}),
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
export const accordion = style({
|
|
873
|
+
display: 'flex',
|
|
874
|
+
flexDirection: 'column',
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
// accordionContainer display: grid ← the only grid; its row animates 0fr ↔ 1fr
|
|
878
|
+
// └─ accordion flex column ← clips its rows while the track moves
|
|
879
|
+
// └─ accordionRows flex column, role="list"
|
|
880
|
+
// └─ item rows
|
|
881
|
+
// the selection would be clipped (borders) when not animating. this fixes it.
|
|
882
|
+
globalStyle(
|
|
883
|
+
`:is(${accordionTransitionClasses.enter}, ${accordionTransitionClasses.enterActive}, ${accordionTransitionClasses.exit}, ${accordionTransitionClasses.exitActive}) > ${accordion}`,
|
|
884
|
+
{overflow: 'hidden'}
|
|
885
|
+
);
|
|
886
|
+
|
|
887
|
+
// One node carries one role, so the group of the children and the list of their rows are two nodes. This
|
|
888
|
+
// one repeats the column of the group above it, and the rows keep the box that they had.
|
|
889
|
+
export const accordionRows = style({
|
|
890
|
+
display: 'flex',
|
|
891
|
+
flexDirection: 'column',
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
// The rows of a panel list the children at the edge, like a first-level row, so only the accordion
|
|
895
|
+
// rows take the indent.
|
|
896
|
+
globalStyle(`${accordionRows} ${itemRow}`, {
|
|
897
|
+
paddingLeft: SECOND_LEVEL_INDENT,
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
// Panel (the dialog panel and the second column) -------------------------------
|
|
901
|
+
|
|
902
|
+
// The rows of a panel, under the group that names it. It repeats the column of that group, for the
|
|
903
|
+
// same reason as `accordionRows`.
|
|
904
|
+
export const panelRows = style({
|
|
905
|
+
display: 'flex',
|
|
906
|
+
flexDirection: 'column',
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
export const dialogPanel = style({
|
|
910
|
+
display: 'flex',
|
|
911
|
+
flexDirection: 'column',
|
|
912
|
+
backgroundColor: skinVars.colors.backgroundContainer,
|
|
913
|
+
borderRadius: skinVars.borderRadii.popup,
|
|
914
|
+
border: `1px solid ${skinVars.colors.border}`,
|
|
915
|
+
minWidth: DEFAULT_WIDTH,
|
|
916
|
+
maxHeight: '70vh',
|
|
917
|
+
overflowY: 'auto',
|
|
918
|
+
paddingTop: DIALOG_PANEL_PADDING_Y,
|
|
919
|
+
paddingBottom: DIALOG_PANEL_PADDING_Y,
|
|
920
|
+
paddingLeft: DIALOG_PANEL_INSET,
|
|
921
|
+
paddingRight: DIALOG_PANEL_INSET,
|
|
922
|
+
boxShadow: '0px 4px 12px rgba(0,0,0,0.15)',
|
|
923
|
+
position: 'relative',
|
|
924
|
+
zIndex: 1001,
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
// The inset of the panel plus this padding place the title where a section title stands, at
|
|
928
|
+
// `SECTION_TITLE_INSET` from the edge of the panel, on the rail of the content of the items below it.
|
|
929
|
+
export const dialogPanelTitle = style({
|
|
930
|
+
paddingBottom: 8,
|
|
931
|
+
paddingLeft: SECTION_TITLE_INSET - DIALOG_PANEL_INSET,
|
|
932
|
+
paddingRight: SECTION_TITLE_INSET - DIALOG_PANEL_INSET,
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
// The second column of the sidenav. It holds the children of the open parent item, spans the whole
|
|
936
|
+
// height of the sidenav, and scrolls on its own. Its horizontal inset (8px) is the same as the items
|
|
937
|
+
// rail of a section, so the children land on the same rail as the items of the main column.
|
|
938
|
+
export const doublePanelColumn = style({
|
|
939
|
+
boxSizing: 'border-box',
|
|
940
|
+
display: 'flex',
|
|
941
|
+
flexDirection: 'column',
|
|
942
|
+
// The content hangs from the right edge of the column, so it slides out from under the main column
|
|
943
|
+
// while the column opens, and slides back under it while the column closes. Anchored to the left edge,
|
|
944
|
+
// the content stood still and the edge wiped it instead, in one direction only: on opening, the focus
|
|
945
|
+
// of the first item scrolled the narrow column, which dragged the content by accident.
|
|
946
|
+
alignItems: 'flex-end',
|
|
947
|
+
width: sidenavPanelWidthVar,
|
|
948
|
+
height: '100%',
|
|
949
|
+
flexShrink: 0,
|
|
950
|
+
// The column only clips. The content scrolls (see `doublePanelContent`), so a classic scrollbar
|
|
951
|
+
// takes its room inside the content instead of pushing the content, which hangs from the right edge,
|
|
952
|
+
// out of the left edge of the column.
|
|
953
|
+
overflow: 'hidden',
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// The column slides out of the main column and slides back into it, with the movement of the rail. Its
|
|
957
|
+
// children keep the width of the open column while it moves, so the text never reflows: the column clips
|
|
958
|
+
// them instead (see the `overflow` above, and `doublePanelContent` below).
|
|
959
|
+
const doublePanelClosed = style({
|
|
960
|
+
width: 0,
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
const doublePanelOpening = style({
|
|
964
|
+
width: sidenavPanelWidthVar,
|
|
965
|
+
transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
966
|
+
...reducedMotion,
|
|
967
|
+
});
|
|
968
|
+
|
|
969
|
+
// The first column that a sidenav opens arrives with the item that owns it, so it enters the tree while it
|
|
970
|
+
// is already open. `appear` gives that first column the same movement as every later one.
|
|
971
|
+
export const doublePanelTransitionClasses = {
|
|
972
|
+
appear: doublePanelClosed,
|
|
973
|
+
appearActive: doublePanelOpening,
|
|
974
|
+
enter: doublePanelClosed,
|
|
975
|
+
enterActive: doublePanelOpening,
|
|
976
|
+
exit: style({
|
|
977
|
+
width: sidenavPanelWidthVar,
|
|
978
|
+
}),
|
|
979
|
+
exitActive: style({
|
|
980
|
+
width: 0,
|
|
981
|
+
transition: `width ${collapseDurationVar} ${COLLAPSE_EASING}`,
|
|
982
|
+
...reducedMotion,
|
|
983
|
+
}),
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
// The paddings of the column belong to this box, so the column itself can reach a width of zero. Its
|
|
987
|
+
// horizontal inset is the inset of the items rail, so the children of the column land on the same rail as
|
|
988
|
+
// the items of the main column. It scrolls up and down on its own, never sideways.
|
|
989
|
+
export const doublePanelContent = style({
|
|
990
|
+
boxSizing: 'border-box',
|
|
991
|
+
display: 'flex',
|
|
992
|
+
flexDirection: 'column',
|
|
993
|
+
width: sidenavPanelWidthVar,
|
|
994
|
+
height: '100%',
|
|
995
|
+
flexShrink: 0,
|
|
996
|
+
overflowX: 'hidden',
|
|
997
|
+
overflowY: 'auto',
|
|
998
|
+
paddingTop: 24,
|
|
999
|
+
paddingBottom: 24,
|
|
1000
|
+
paddingLeft: RAIL_INSET,
|
|
1001
|
+
paddingRight: RAIL_INSET,
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
// The inset of the column plus this padding place the title where a section title stands, at
|
|
1005
|
+
// `SECTION_TITLE_INSET` from the edge of the column. The 16px bottom margin is the title-to-items gap of
|
|
1006
|
+
// the spec.
|
|
1007
|
+
export const doublePanelTitle = style({
|
|
1008
|
+
padding: `0 ${SECTION_TITLE_INSET - RAIL_INSET}px`,
|
|
1009
|
+
marginBottom: 16,
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
// Separates the main column from the double panel column. It renders whenever the panel is open, even
|
|
1013
|
+
// when the sidenav hides its right divider, because the two columns always need a visible boundary.
|
|
1014
|
+
// It is an overlay too (see `verticalDividerOverlay`), so the items of the main column keep the same
|
|
1015
|
+
// width when the panel opens.
|
|
1016
|
+
export const columnSeparator = styleVariants(dividerColor, (color) => ({
|
|
1017
|
+
'::after': {...verticalDividerOverlay, backgroundColor: color},
|
|
1018
|
+
}));
|