@telefonica/mistica 17.2.0 → 17.4.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 +30 -16
- package/css/community/cyber.css +1491 -0
- package/css/esimflag.css +41 -18
- package/css/mistica-common.css +6 -0
- package/css/mistica.css +1 -1
- package/css/movistar.css +35 -18
- package/css/o2.css +32 -18
- package/css/telefonica.css +44 -18
- package/css/vivo-evolution.css +72 -20
- package/css/vivo.css +32 -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 +50 -50
- 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 +9 -9
- package/dist/community/blocks.css-mistica.js +3 -3
- 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.d.ts +5 -0
- package/dist/community/skins/cyber-skin.js +289 -256
- 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/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-panel-collapse-regular.js +165 -0
- package/dist/generated/mistica-icons/icon-panel-expand-regular.js +159 -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/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 +8 -8
- package/dist/index.d.ts +5 -0
- package/dist/index.js +10 -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-movistar.js +1 -1
- 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.d.ts +5 -0
- package/dist/skins/blau.js +12 -8
- package/dist/skins/esimflag.d.ts +5 -0
- package/dist/skins/esimflag.js +13 -9
- package/dist/skins/movistar.d.ts +5 -0
- package/dist/skins/movistar.js +13 -9
- package/dist/skins/o2.d.ts +5 -0
- package/dist/skins/o2.js +13 -9
- package/dist/skins/skin-contract.css-mistica.js +735 -731
- package/dist/skins/skin-contract.css.d.ts +16 -12
- package/dist/skins/telefonica.d.ts +5 -0
- package/dist/skins/telefonica.js +13 -9
- package/dist/skins/types/colors.d.ts +13 -6
- package/dist/skins/vivo-evolution.d.ts +5 -0
- package/dist/skins/vivo-evolution.js +14 -10
- package/dist/skins/vivo.d.ts +5 -0
- package/dist/skins/vivo.js +13 -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 +19 -19
- 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 +3 -3
- package/dist-es/community/blocks.css-mistica.js +2 -2
- 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 +289 -256
- 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/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-panel-collapse-regular.js +115 -0
- package/dist-es/generated/mistica-icons/icon-panel-expand-regular.js +109 -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/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 +2279 -2276
- 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-movistar.js +1 -1
- 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 +12 -8
- package/dist-es/skins/esimflag.js +13 -9
- package/dist-es/skins/movistar.js +13 -9
- package/dist-es/skins/o2.js +13 -9
- package/dist-es/skins/skin-contract.css-mistica.js +735 -731
- package/dist-es/skins/telefonica.js +13 -9
- package/dist-es/skins/vivo-evolution.js +14 -10
- package/dist-es/skins/vivo.js +13 -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 +3 -2
- 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 +127 -439
- package/src/index.tsx +14 -0
- package/src/list.css.ts +36 -1
- package/src/list.tsx +370 -344
- package/src/logo-movistar.tsx +1 -1
- 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 +18 -8
- package/src/skins/esimflag.tsx +19 -9
- package/src/skins/movistar.tsx +19 -9
- package/src/skins/o2.tsx +19 -9
- package/src/skins/skin-contract.css.ts +2 -0
- package/src/skins/telefonica.tsx +19 -9
- package/src/skins/types/colors.tsx +14 -6
- package/src/skins/vivo-evolution.tsx +20 -10
- package/src/skins/vivo.tsx +19 -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,98 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import * as styles from './sidenav-bar.css';
|
|
5
|
+
import {useThemeVariant} from './theme-variant-context';
|
|
6
|
+
import {getPrefixedDataAttributes} from './utils/dom';
|
|
7
|
+
import Divider from './divider';
|
|
8
|
+
import {Text2} from './text';
|
|
9
|
+
import {useSidenavBarContext} from './sidenav-bar-context';
|
|
10
|
+
import {useRestWidth} from './sidenav-bar-motion';
|
|
11
|
+
import {getSidenavSectionTitle} from './sidenav-bar-data';
|
|
12
|
+
|
|
13
|
+
import type {SidenavSectionTitle} from './sidenav-bar-types';
|
|
14
|
+
import type {DataAttributes} from './utils/types';
|
|
15
|
+
|
|
16
|
+
type SidenavSectionProps = {
|
|
17
|
+
/**
|
|
18
|
+
* Section heading, and accessible name of the list of the section. It is mandatory: a screen reader
|
|
19
|
+
* needs it to tell one section from another. When the sidenav is collapsed the heading closes and the
|
|
20
|
+
* items move up, but it still names the list. Give `{text, hidden: true}` to keep the name and paint
|
|
21
|
+
* no heading.
|
|
22
|
+
*/
|
|
23
|
+
title: SidenavSectionTitle;
|
|
24
|
+
/** Renders a divider above the section. @default false */
|
|
25
|
+
dividerTop?: boolean;
|
|
26
|
+
/** Renders a divider below the section. @default false */
|
|
27
|
+
dividerBottom?: boolean;
|
|
28
|
+
/** Navigation items (`SidenavItem` elements).
|
|
29
|
+
* @see SidenavItem
|
|
30
|
+
*/
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
dataAttributes?: DataAttributes;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const SidenavSection = ({
|
|
36
|
+
title,
|
|
37
|
+
dividerTop,
|
|
38
|
+
dividerBottom,
|
|
39
|
+
children,
|
|
40
|
+
dataAttributes,
|
|
41
|
+
}: SidenavSectionProps): JSX.Element => {
|
|
42
|
+
const {collapsed, collapseState} = useSidenavBarContext();
|
|
43
|
+
const variant = useThemeVariant();
|
|
44
|
+
const {text: titleText, isHeadingVisible} = getSidenavSectionTitle(title);
|
|
45
|
+
// The title names the list of the section, so the name a screen reader speaks is always the text of
|
|
46
|
+
// the heading, visible or not. The section itself carries no role and no name: the named list is the
|
|
47
|
+
// whole structure, as in the second level (see `sidenav-bar-panel.tsx`).
|
|
48
|
+
const titleId = React.useId();
|
|
49
|
+
// The title holds the width that it had at rest while the sidenav moves, in both directions, so its
|
|
50
|
+
// lines stay where they are while its box folds. See `sectionTitleKeepsWidth` for the fallback. A
|
|
51
|
+
// hidden heading never moves, so it needs no measurement.
|
|
52
|
+
const isTitleWidthKept = isHeadingVisible && collapseState !== 'expanded';
|
|
53
|
+
const {ref: titleRef, frozenWidth: titleWidth} = useRestWidth(isTitleWidthKept);
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
className={styles.section}
|
|
58
|
+
{...getPrefixedDataAttributes({testid: 'SidenavSection', ...dataAttributes})}
|
|
59
|
+
>
|
|
60
|
+
{dividerTop && (
|
|
61
|
+
<div className={styles.sectionDividerTop}>
|
|
62
|
+
<Divider />
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
65
|
+
<div
|
|
66
|
+
ref={titleRef}
|
|
67
|
+
id={titleId}
|
|
68
|
+
// The list already speaks this text as its name, so the title steps out of the
|
|
69
|
+
// reading order. The name survives: `aria-labelledby` reads a hidden element that
|
|
70
|
+
// it references directly.
|
|
71
|
+
aria-hidden="true"
|
|
72
|
+
className={classnames(styles.sectionTitle, styles.sectionTitleVariant[variant], {
|
|
73
|
+
[styles.sectionTitleHidden]: !isHeadingVisible,
|
|
74
|
+
[styles.sectionTitleCollapsed]: isHeadingVisible && collapsed,
|
|
75
|
+
[styles.sectionTitleKeepsWidth]: isTitleWidthKept && titleWidth === undefined,
|
|
76
|
+
})}
|
|
77
|
+
style={titleWidth !== undefined ? {width: titleWidth} : undefined}
|
|
78
|
+
>
|
|
79
|
+
<div className={styles.sectionTitleContent}>
|
|
80
|
+
<Text2 medium color="inherit">
|
|
81
|
+
{titleText}
|
|
82
|
+
</Text2>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
{/* The title names the list, and the list gives the count of its items. */}
|
|
86
|
+
<div className={styles.sectionContent} role="list" aria-labelledby={titleId}>
|
|
87
|
+
{children}
|
|
88
|
+
</div>
|
|
89
|
+
{dividerBottom && (
|
|
90
|
+
<div className={styles.sectionDividerBottom}>
|
|
91
|
+
<Divider />
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export {SidenavSection};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import type {ExclusifyUnion} from './utils/utility-types';
|
|
2
|
+
import type {IconProps} from './utils/types';
|
|
3
|
+
import type {InteractiveProps} from './navigation-shared';
|
|
4
|
+
|
|
5
|
+
type SidenavAsset = ((props: IconProps) => JSX.Element) | React.ReactElement;
|
|
6
|
+
|
|
7
|
+
/** Props shared by every navigation item, at any level. */
|
|
8
|
+
type SidenavItemBaseProps = {
|
|
9
|
+
/** Unique identifier within the sidenav for selection tracking and panel state. */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Display text (truncated if too long). */
|
|
12
|
+
label: string;
|
|
13
|
+
/** Custom content on right side (e.g., Badge). */
|
|
14
|
+
rightSlot?: React.ReactNode;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parent item: it owns the items of the second level, it only opens and closes them, and it cannot
|
|
19
|
+
* navigate (`href`, `to`, and `onPress` are not allowed).
|
|
20
|
+
*/
|
|
21
|
+
type SidenavParentItemProps = {
|
|
22
|
+
/** Second-level items (max 1 level, level 0 items only). A parent item cannot navigate. */
|
|
23
|
+
children: ReadonlyArray<SidenavSecondLevelItem>;
|
|
24
|
+
/** Initial open state of the children. @default false */
|
|
25
|
+
defaultOpen?: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Navigable item: it navigates with exactly one of `href`, `to`, or `onPress`, and it cannot have
|
|
30
|
+
* children.
|
|
31
|
+
*/
|
|
32
|
+
type SidenavNavigableItemProps = InteractiveProps & {
|
|
33
|
+
/** Called after navigation (when item has href, to, or onPress). */
|
|
34
|
+
onNavigate?: () => void | Promise<void>;
|
|
35
|
+
/** Open link in new tab. Only applies when href or to is set. @default false */
|
|
36
|
+
newTab?: boolean;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Navigation item data for SidenavBar.
|
|
41
|
+
*
|
|
42
|
+
* Supports 2-level nesting:
|
|
43
|
+
* - **Level 0 items** can have children. They always carry an `asset`, because the collapsed rail shows
|
|
44
|
+
* nothing else of them.
|
|
45
|
+
* - **Level 1 items** (children) cannot have children (leaf nodes). See `SidenavSecondLevelItem`.
|
|
46
|
+
*
|
|
47
|
+
* Each item is exactly one of:
|
|
48
|
+
* - **Parent** — has `children` and only opens/closes them. It cannot navigate, so
|
|
49
|
+
* `href`, `to`, and `onPress` are not allowed (enforced by the type).
|
|
50
|
+
* - **Navigable** — has `href`, `to`, or `onPress`. It cannot have `children`.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Navigable item (leaf)
|
|
54
|
+
* {id: 'home', label: 'Home', asset: IconHome, href: '/', onNavigate: () => {}}
|
|
55
|
+
*
|
|
56
|
+
* // Parent item (only opens/closes its children, no navigation prop allowed)
|
|
57
|
+
* {
|
|
58
|
+
* id: 'projects',
|
|
59
|
+
* label: 'Projects',
|
|
60
|
+
* asset: IconFolder,
|
|
61
|
+
* children: [
|
|
62
|
+
* {id: 'active', label: 'Active', href: '/projects/active'},
|
|
63
|
+
* {id: 'archived', label: 'Archived', href: '/projects/archived'}
|
|
64
|
+
* ]
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* // Item with right slot (e.g., badge)
|
|
68
|
+
* {id: 'notifications', label: 'Notifications', asset: IconBell, href: '#', rightSlot: <Badge value={5} />}
|
|
69
|
+
*/
|
|
70
|
+
type SidenavFirstLevelItem = SidenavItemBaseProps & {
|
|
71
|
+
/** Icon component or element. It is the only visible part of the item on the collapsed rail. */
|
|
72
|
+
asset: SidenavAsset;
|
|
73
|
+
/** Show asset when expanded (not collapsed). @default true */
|
|
74
|
+
showAssetWhenExpanded?: boolean;
|
|
75
|
+
} & ExclusifyUnion<SidenavParentItemProps | SidenavNavigableItemProps>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Second-level item data: a child of a parent item. It is always navigable, and it cannot have children of its
|
|
79
|
+
* own. See `SidenavFirstLevelItem`.
|
|
80
|
+
*
|
|
81
|
+
* The collapsed rail never shows a second-level item, so the asset is optional and `showAssetWhenExpanded` has
|
|
82
|
+
* no meaning. The `undefined` members let a consumer read both item types through one union.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* {id: 'active', label: 'Active', href: '/projects/active'}
|
|
86
|
+
*/
|
|
87
|
+
type SidenavSecondLevelItem = SidenavItemBaseProps &
|
|
88
|
+
SidenavNavigableItemProps & {
|
|
89
|
+
/** Icon component or element. */
|
|
90
|
+
asset?: SidenavAsset;
|
|
91
|
+
showAssetWhenExpanded?: undefined;
|
|
92
|
+
children?: undefined;
|
|
93
|
+
defaultOpen?: undefined;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Title of a section. Every section declares one, because it names the list of the section for a screen
|
|
98
|
+
* reader. A plain string also paints the heading. The object form with `hidden: true` keeps the name and
|
|
99
|
+
* paints no heading, so only assistive technology reads it.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* // Visible heading, and name of the list
|
|
103
|
+
* 'Workspace'
|
|
104
|
+
*
|
|
105
|
+
* // Name of the list only: no heading appears
|
|
106
|
+
* {text: 'Workspace', hidden: true}
|
|
107
|
+
*/
|
|
108
|
+
type SidenavSectionTitle =
|
|
109
|
+
| string
|
|
110
|
+
| {
|
|
111
|
+
/** Text of the heading, and name of the list of the section. */
|
|
112
|
+
text: string;
|
|
113
|
+
/** Hide the heading. The list keeps this text as its name. @default false */
|
|
114
|
+
hidden?: boolean;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Section data that groups navigation items under a title, with optional dividers.
|
|
119
|
+
*
|
|
120
|
+
* Sections provide visual organization of items within a SidenavBar.
|
|
121
|
+
* The title is mandatory, because the list of the section takes its accessible name from it. When the
|
|
122
|
+
* sidenav is collapsed, the title is hidden visually but remains available to screen readers.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Section with a visible title and items
|
|
126
|
+
* {
|
|
127
|
+
* title: 'Workspace',
|
|
128
|
+
* dividerTop: true,
|
|
129
|
+
* items: [
|
|
130
|
+
* {id: 'projects', label: 'Projects', asset: IconFolder, href: '/projects'},
|
|
131
|
+
* {id: 'teams', label: 'Teams', asset: IconPeople, href: '/teams'}
|
|
132
|
+
* ]
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* // Section that groups items without a visible heading. Only a screen reader reads the title.
|
|
136
|
+
* {
|
|
137
|
+
* title: {text: 'Workspace', hidden: true},
|
|
138
|
+
* items: [{id: 'teams', label: 'Teams', asset: IconPeople, href: '/teams'}]
|
|
139
|
+
* }
|
|
140
|
+
*/
|
|
141
|
+
type SidenavSection = {
|
|
142
|
+
/**
|
|
143
|
+
* Section heading, and accessible name of the list of the section. It is mandatory, because a list
|
|
144
|
+
* without a name leaves a screen reader with no way to tell one section from another. Give
|
|
145
|
+
* `{text, hidden: true}` to keep the name and paint no heading.
|
|
146
|
+
*/
|
|
147
|
+
title: SidenavSectionTitle;
|
|
148
|
+
/** Show divider above section. The first entry of the body draws none: a line parts two entries. */
|
|
149
|
+
dividerTop?: boolean;
|
|
150
|
+
/** Show divider below section. The last entry of the body draws none: a line parts two entries. */
|
|
151
|
+
dividerBottom?: boolean;
|
|
152
|
+
/** Navigation items in this section. */
|
|
153
|
+
items: ReadonlyArray<SidenavFirstLevelItem>;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* First-level entry of the sidenav body. The first level admits sections and stand-alone items,
|
|
158
|
+
* in any order, so an item does not need a section around it.
|
|
159
|
+
*
|
|
160
|
+
* Each entry is exactly one of:
|
|
161
|
+
* - **Section** — has `items` and groups them under a title and optional dividers.
|
|
162
|
+
* - **Stand-alone item** — a `SidenavFirstLevelItem` placed directly at the first level. It carries no
|
|
163
|
+
* title, so it is the entry to use when a group of one item needs no name.
|
|
164
|
+
*
|
|
165
|
+
* A stand-alone item aligns with the items of a section, and every first-level entry is
|
|
166
|
+
* separated from the next one by the same vertical space.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* // A stand-alone item, then a section, then another stand-alone item
|
|
170
|
+
* [
|
|
171
|
+
* {id: 'home', label: 'Home', asset: IconHome, href: '/'},
|
|
172
|
+
* {title: 'Workspace', items: [{id: 'teams', label: 'Teams', asset: IconPeople, href: '/teams'}]},
|
|
173
|
+
* {id: 'settings', label: 'Settings', asset: IconSettings, href: '/settings'}
|
|
174
|
+
* ]
|
|
175
|
+
*/
|
|
176
|
+
type SidenavEntry = ExclusifyUnion<SidenavSection | SidenavFirstLevelItem>;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Phase of the collapse motion of the desktop rail. `collapsing` and `expanding` last for the movement of
|
|
180
|
+
* the rail, and they never appear when motion is off. The mobile top bar always reports `expanded`.
|
|
181
|
+
*/
|
|
182
|
+
type SidenavCollapseState = 'expanded' | 'collapsing' | 'collapsed' | 'expanding';
|
|
183
|
+
|
|
184
|
+
const isSidenavMoving = (state: SidenavCollapseState): boolean =>
|
|
185
|
+
state === 'collapsing' || state === 'expanding';
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Props of the slots that render per state: the logo, the header slot, the footer slot, and the collapse
|
|
189
|
+
* action. `collapsed` flips at the first frame of the motion, and `state` tells the phase, so a slot can
|
|
190
|
+
* keep its content while the rail moves and swap it when the rail rests.
|
|
191
|
+
*/
|
|
192
|
+
type SidenavSlotRenderProps = {
|
|
193
|
+
/** Target collapsed state. The mobile top bar reports false, because it is not a rail. */
|
|
194
|
+
collapsed: boolean;
|
|
195
|
+
/** Phase of the collapse motion. */
|
|
196
|
+
state: SidenavCollapseState;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/** Props of the logo of the header. The default logo keeps the isotype in both states. */
|
|
200
|
+
type SidenavLogoRenderProps = SidenavSlotRenderProps;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Logo of the header. It takes true for the logo of the skin, false to hide the logo, an element of your
|
|
204
|
+
* own, or a function that receives the collapse state and returns one logo for each state.
|
|
205
|
+
*/
|
|
206
|
+
type SidenavLogo = React.ReactElement | boolean | ((props: SidenavLogoRenderProps) => React.ReactNode);
|
|
207
|
+
|
|
208
|
+
/** Content of the header slot or of the footer slot: an element, or a function of the collapse state. */
|
|
209
|
+
type SidenavSlot = React.ReactNode | ((props: SidenavSlotRenderProps) => React.ReactNode);
|
|
210
|
+
|
|
211
|
+
export type {
|
|
212
|
+
SidenavAsset,
|
|
213
|
+
SidenavFirstLevelItem,
|
|
214
|
+
SidenavSecondLevelItem,
|
|
215
|
+
SidenavSection,
|
|
216
|
+
SidenavSectionTitle,
|
|
217
|
+
SidenavEntry,
|
|
218
|
+
SidenavLogo,
|
|
219
|
+
SidenavLogoRenderProps,
|
|
220
|
+
SidenavSlot,
|
|
221
|
+
SidenavSlotRenderProps,
|
|
222
|
+
SidenavCollapseState,
|
|
223
|
+
};
|
|
224
|
+
export {isSidenavMoving};
|