@12-apps/ui 6.71.0 → 6.73.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/components-catalog.md +1 -1
- package/dist/_internal/components/data-display/CardKit/card-actions-context.js +1 -1
- package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +2 -2
- package/dist/_internal/components/index.js +7 -7
- package/dist/_internal/components/navigation/SectionNav/SectionNav.bar.js +5 -4
- package/dist/_internal/components/navigation/SectionNav/SectionNav.js +8 -7
- package/dist/_internal/components/navigation/SectionNav/SectionNav.parts.js +8 -3
- package/dist/_internal/components/navigation/SectionNav/SectionNav.primary.js +3 -2
- package/dist/_internal/components/navigation/SectionNav/SectionNav.rail.js +4 -3
- package/dist/_internal/components/navigation/SectionNav/SectionNav.railCreate.js +3 -2
- package/dist/_internal/components/navigation/SectionNav/SectionNav.sheet.js +3 -2
- package/dist/_internal/components/navigation/index.js +8 -7
- package/dist/{chunk-XS4NQ6LD.js → chunk-23LPXHR2.js} +61 -35
- package/dist/chunk-23LPXHR2.js.map +1 -0
- package/dist/{chunk-WP7KPWCP.js → chunk-24HHUCWB.js} +14 -2
- package/dist/chunk-24HHUCWB.js.map +1 -0
- package/dist/{chunk-62BY4ZUQ.js → chunk-7KAZ3B5B.js} +2 -2
- package/dist/{chunk-WY7FR7I4.js → chunk-ILJ3FXIC.js} +17 -8
- package/dist/chunk-ILJ3FXIC.js.map +1 -0
- package/dist/{chunk-VI2IXBOO.js → chunk-KPEKD5SG.js} +24 -13
- package/dist/chunk-KPEKD5SG.js.map +1 -0
- package/dist/{chunk-N7KWWIF7.js → chunk-LY7PBZ3Z.js} +7 -3
- package/dist/chunk-LY7PBZ3Z.js.map +1 -0
- package/dist/{chunk-2STYL5PF.js → chunk-NM46HQSW.js} +2 -2
- package/dist/{chunk-LWQGIN2M.js → chunk-NQP72RTD.js} +9 -6
- package/dist/chunk-NQP72RTD.js.map +1 -0
- package/dist/{chunk-OBGUD2PG.js → chunk-SNWCT6JN.js} +91 -42
- package/dist/chunk-SNWCT6JN.js.map +1 -0
- package/dist/data-display/CardKit.js +2 -2
- package/dist/navigation/SectionNav.js +8 -7
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts +10 -1
- package/dist/types/components/data-display/CardKit/card-actions-context.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.bar.d.ts +6 -2
- package/dist/types/components/navigation/SectionNav/SectionNav.bar.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.d.ts +4 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.parts.d.ts +12 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.parts.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.primary.d.ts +7 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.primary.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.rail.d.ts +3 -2
- package/dist/types/components/navigation/SectionNav/SectionNav.rail.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.railCreate.d.ts +3 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.railCreate.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.types.d.ts +12 -0
- package/dist/types/components/navigation/SectionNav/SectionNav.types.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/index.d.ts +1 -0
- package/dist/types/components/navigation/SectionNav/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/CardKit/CardKit.md +3 -0
- package/src/components/data-display/CardKit/card-actions-context.tsx +16 -1
- package/src/components/navigation/SectionNav/SectionNav.bar.tsx +77 -29
- package/src/components/navigation/SectionNav/SectionNav.md +24 -3
- package/src/components/navigation/SectionNav/SectionNav.parts.tsx +19 -1
- package/src/components/navigation/SectionNav/SectionNav.primary.tsx +39 -11
- package/src/components/navigation/SectionNav/SectionNav.rail.tsx +90 -35
- package/src/components/navigation/SectionNav/SectionNav.railCreate.tsx +23 -5
- package/src/components/navigation/SectionNav/SectionNav.tsx +6 -0
- package/src/components/navigation/SectionNav/SectionNav.types.ts +12 -0
- package/src/components/navigation/SectionNav/index.ts +1 -0
- package/dist/chunk-LWQGIN2M.js.map +0 -1
- package/dist/chunk-N7KWWIF7.js.map +0 -1
- package/dist/chunk-OBGUD2PG.js.map +0 -1
- package/dist/chunk-VI2IXBOO.js.map +0 -1
- package/dist/chunk-WP7KPWCP.js.map +0 -1
- package/dist/chunk-WY7FR7I4.js.map +0 -1
- package/dist/chunk-XS4NQ6LD.js.map +0 -1
- /package/dist/{chunk-62BY4ZUQ.js.map → chunk-7KAZ3B5B.js.map} +0 -0
- /package/dist/{chunk-2STYL5PF.js.map → chunk-NM46HQSW.js.map} +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type ElementType } from 'react';
|
|
2
2
|
import { rem } from '../../../tokens/scales';
|
|
3
3
|
import type { SectionNavProps } from './SectionNav.types';
|
|
4
|
+
/** How the bar is drawn — `compact` is `SectionNavProps.compact`. */
|
|
5
|
+
export interface SectionNavBarOptions {
|
|
6
|
+
compact?: boolean;
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* The bar's full height on screen, the safe area included — where its sheets
|
|
6
10
|
* stop, and what a host reserves at the foot of its content so nothing it
|
|
7
11
|
* floats (a toast, a receipt) lands under the bar.
|
|
8
12
|
*/
|
|
9
|
-
export declare function sectionNavBarInset(theme: Parameters<typeof rem>[0]): string;
|
|
13
|
+
export declare function sectionNavBarInset(theme: Parameters<typeof rem>[0], options?: SectionNavBarOptions): string;
|
|
10
14
|
/** The phone layout: a bottom bar, with its menus as bottom sheets. */
|
|
11
|
-
export declare function SectionNavBar({ label, destinations, primary, more, linkComponent, copy, dataTestId, }: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> & Pick<SectionNavProps, 'primary' | 'more'> & {
|
|
15
|
+
export declare function SectionNavBar({ label, destinations, primary, more, linkComponent, copy, dataTestId, compact, }: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> & Pick<SectionNavProps, 'primary' | 'more' | 'compact'> & {
|
|
12
16
|
linkComponent: ElementType | undefined;
|
|
13
17
|
}): React.JSX.Element;
|
|
14
18
|
//# sourceMappingURL=SectionNav.bar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.bar.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.bar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,WAAW,EAAkB,MAAM,OAAO,CAAC;AAInE,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"SectionNav.bar.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.bar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,WAAW,EAAkB,MAAM,OAAO,CAAC;AAInE,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAgB7C,OAAO,KAAK,EAA4E,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAWpI,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAE/G;AA6RD,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,aAAa,EACb,IAAI,EACJ,UAAU,EACV,OAAe,GAChB,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,YAAY,CAAC,CAAC,GAClF,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG;IAAE,aAAa,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAkDvH"}
|
|
@@ -8,9 +8,12 @@ import type { SectionNavProps } from './SectionNav.types';
|
|
|
8
8
|
* (`linkComponent`). The nav decides only how they are drawn: the order of the
|
|
9
9
|
* bar's slots, the raised primary action, the sheets, the rail's sections.
|
|
10
10
|
*
|
|
11
|
+
* `compact` draws either layout as icons only, a size down, for a host that
|
|
12
|
+
* folds its chrome; the labels stay the controls' names.
|
|
13
|
+
*
|
|
11
14
|
* Which layout to use is the host's call too, because the host knows what
|
|
12
15
|
* else is on screen: a bar next to a sidebar is two navigations competing for
|
|
13
16
|
* one glance.
|
|
14
17
|
*/
|
|
15
|
-
export declare function SectionNav({ layout, label, destinations, primary, more, back, heading, linkComponent, copy, dataTestId, }: SectionNavProps): React.JSX.Element;
|
|
18
|
+
export declare function SectionNav({ layout, label, destinations, primary, more, back, heading, linkComponent, copy, dataTestId, compact, }: SectionNavProps): React.JSX.Element;
|
|
16
19
|
//# sourceMappingURL=SectionNav.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"SectionNav.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,aAAa,EACb,IAAI,EACJ,UAA0B,EAC1B,OAAe,GAChB,EAAE,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA6BrC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Box from '@mui/material/Box/index.js';
|
|
2
2
|
import type { SxProps, Theme } from '@mui/material/styles/index.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type ElementType, type ReactNode } from 'react';
|
|
4
4
|
import type { SectionNavBadge, SectionNavDestination } from './SectionNav.types';
|
|
5
5
|
/**
|
|
6
6
|
* An icon with its count on the shoulder.
|
|
@@ -74,5 +74,16 @@ export declare const CONTROL_RESET: {
|
|
|
74
74
|
readonly cursor: "default";
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* Out of sight, still read: a compact nav keeps each label as its control's
|
|
79
|
+
* accessible name. The same box `Label`'s `srOnly` draws.
|
|
80
|
+
*/
|
|
81
|
+
export declare const VISUALLY_HIDDEN: SxProps<Theme>;
|
|
82
|
+
/**
|
|
83
|
+
* False on the first render, true from then on — so a fold animates when the
|
|
84
|
+
* host CHANGES `compact`, never when a page simply opens folded (which drew
|
|
85
|
+
* the labels sliding out over the neighbouring badges on every load).
|
|
86
|
+
*/
|
|
87
|
+
export declare function useMounted(): boolean;
|
|
77
88
|
export { Box };
|
|
78
89
|
//# sourceMappingURL=SectionNav.parts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.parts.tsx"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAE7C,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"SectionNav.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.parts.tsx"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAE7C,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAuB,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAO9E,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEjF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,KAAK,EACL,KAAK,EACL,MAAM,EACN,cAAc,GACf,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,eAAe,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAyBpB;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAOtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,OAAO,EACP,aAAa,EACb,KAAa,EACb,IAAY,EACZ,MAAc,GACf,EAAE;IACD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM1B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,qBAAqB,EAClC,aAAa,EAAE,WAAW,GAAG,SAAS,EACtC,OAAO,EAAE,MAAM,IAAI,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,0CAAwC,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAGpG;AAED,wFAAwF;AACxF,eAAO,MAAM,aAAa;;;;;;;;;;;CAShB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,eAAe,gBAAa,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAIpC;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
|
|
@@ -21,6 +21,12 @@ export interface RaisedActionButtonProps {
|
|
|
21
21
|
* bar of places can leave its one action to the icon.
|
|
22
22
|
*/
|
|
23
23
|
captioned?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* A size down — 40px rather than 52, lifted less — for a compact bar. It
|
|
26
|
+
* draws no caption: a compact bar is icons only, and the name stays the
|
|
27
|
+
* button's `aria-label`.
|
|
28
|
+
*/
|
|
29
|
+
compact?: boolean;
|
|
24
30
|
/** Dimmed and not operable: a native `disabled` button. */
|
|
25
31
|
disabled?: boolean;
|
|
26
32
|
/**
|
|
@@ -43,5 +49,5 @@ export interface RaisedActionButtonProps {
|
|
|
43
49
|
* `SectionNav` draws it for its `primary` menu. It is exported on its own for
|
|
44
50
|
* a bar the host already draws — drop it between two tabs, in a flex row.
|
|
45
51
|
*/
|
|
46
|
-
export declare function RaisedActionButton({ label, icon, onClick, open, closeLabel, captioned, disabled, loading, dataTestId, }: RaisedActionButtonProps): React.JSX.Element;
|
|
52
|
+
export declare function RaisedActionButton({ label, icon, onClick, open, closeLabel, captioned, compact, disabled, loading, dataTestId, }: RaisedActionButtonProps): React.JSX.Element;
|
|
47
53
|
//# sourceMappingURL=SectionNav.primary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.primary.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.primary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,UAAU,EACV,SAAiB,EACjB,QAAgB,EAChB,OAAe,EACf,UAA4B,GAC7B,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4B7C"}
|
|
1
|
+
{"version":3,"file":"SectionNav.primary.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.primary.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,UAAU,EACV,SAAiB,EACjB,OAAe,EACf,QAAgB,EAChB,OAAe,EACf,UAA4B,GAC7B,EAAE,uBAAuB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4B7C"}
|
|
@@ -6,9 +6,10 @@ import type { SectionNavProps } from './SectionNav.types';
|
|
|
6
6
|
* `primary` action as a row, then `more` listed in full.
|
|
7
7
|
*
|
|
8
8
|
* It fills the column the host gives it and scrolls on its own, like the
|
|
9
|
-
* sidebar it stands in for.
|
|
9
|
+
* sidebar it stands in for. `compact` draws every row as its icon for a
|
|
10
|
+
* column 64px wide; the words stay the rows' names.
|
|
10
11
|
*/
|
|
11
|
-
export declare function SectionNavRail({ label, destinations, primary, more, back, heading, linkComponent, copy, dataTestId, }: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> & Pick<SectionNavProps, 'primary' | 'more' | 'back' | 'heading'> & {
|
|
12
|
+
export declare function SectionNavRail({ label, destinations, primary, more, back, heading, linkComponent, copy, dataTestId, compact, }: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> & Pick<SectionNavProps, 'primary' | 'more' | 'back' | 'heading' | 'compact'> & {
|
|
12
13
|
linkComponent: ElementType | undefined;
|
|
13
14
|
}): React.JSX.Element;
|
|
14
15
|
//# sourceMappingURL=SectionNav.rail.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.rail.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.rail.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SectionNav.rail.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.rail.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,OAAO,CAAC;AAkBpD,OAAO,KAAK,EAKV,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAoR5B;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,aAAa,EACb,IAAI,EACJ,UAAU,EACV,OAAe,GAChB,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,YAAY,CAAC,CAAC,GAClF,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC,GAAG;IAC3E,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC;CACxC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsDtB"}
|
|
@@ -15,10 +15,12 @@ import type { SectionNavMenu } from './SectionNav.types';
|
|
|
15
15
|
* outside click. Choosing an entry closes it too, and the entry's link or act
|
|
16
16
|
* takes over.
|
|
17
17
|
*/
|
|
18
|
-
export declare function RailCreateMenu({ menu, linkComponent, copy, testId, }: {
|
|
18
|
+
export declare function RailCreateMenu({ menu, linkComponent, copy, testId, compact, }: {
|
|
19
19
|
menu: SectionNavMenu;
|
|
20
20
|
linkComponent: ElementType | undefined;
|
|
21
21
|
copy: SectionNavCopy;
|
|
22
22
|
testId: string;
|
|
23
|
+
/** The button as its icon only — the label stays its name and its tooltip. */
|
|
24
|
+
compact?: boolean;
|
|
23
25
|
}): React.JSX.Element;
|
|
24
26
|
//# sourceMappingURL=SectionNav.railCreate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.railCreate.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.railCreate.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAmB,KAAK,WAAW,EAAkB,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"SectionNav.railCreate.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.railCreate.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAmB,KAAK,WAAW,EAAkB,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAkE1E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,aAAa,EACb,IAAI,EACJ,MAAM,EACN,OAAe,GAChB,EAAE;IACD,IAAI,EAAE,cAAc,CAAC;IACrB,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4DpB"}
|
|
@@ -178,5 +178,17 @@ export interface SectionNavProps {
|
|
|
178
178
|
copy: SectionNavCopy;
|
|
179
179
|
/** Prefix for every `data-testid`. Defaults to `"section-nav"`. */
|
|
180
180
|
dataTestId?: string;
|
|
181
|
+
/**
|
|
182
|
+
* Icons only, a size down — for a host that folds its chrome so the content
|
|
183
|
+
* gets the screen (a "focus mode"). Every label stays its control's
|
|
184
|
+
* accessible name and `title`; nothing is removed, only drawn smaller.
|
|
185
|
+
*
|
|
186
|
+
* `bar` — 48px instead of 60, the raised button 40px instead of 52, no
|
|
187
|
+
* captions; `sectionNavBarInset(theme, { compact: true })` is its inset.
|
|
188
|
+
* `rail` — every row, the way back and the create button as their icon only,
|
|
189
|
+
* headings out of sight, for a column 64px wide (the host sets the width).
|
|
190
|
+
* Defaults to `false`.
|
|
191
|
+
*/
|
|
192
|
+
compact?: boolean;
|
|
181
193
|
}
|
|
182
194
|
//# sourceMappingURL=SectionNav.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SectionNav.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { SectionNav } from './SectionNav';
|
|
2
2
|
export { sectionNavBarInset } from './SectionNav.bar';
|
|
3
|
+
export type { SectionNavBarOptions } from './SectionNav.bar';
|
|
3
4
|
export { RaisedActionButton } from './SectionNav.primary';
|
|
4
5
|
export type { RaisedActionButtonProps } from './SectionNav.primary';
|
|
5
6
|
export type { SectionNavAction, SectionNavBack, SectionNavBadge, SectionNavDestination, SectionNavEntry, SectionNavGroup, SectionNavMenu, SectionNavProps, } from './SectionNav.types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -33,6 +33,9 @@ language shipped as a finished-looking silence:
|
|
|
33
33
|
verbatim by a screen reader.
|
|
34
34
|
- `CardActionsProvider`'s **`errorTitle`** — the one sentence the provider
|
|
35
35
|
renders on its own. The message beside it comes from whatever failed.
|
|
36
|
+
An app with one toast channel passes **`onError(title, message)`** instead of
|
|
37
|
+
living with the provider's bottom snackbar: given, the provider draws
|
|
38
|
+
nothing of its own and the failure lands with every other toast.
|
|
36
39
|
- Both hooks' **`confirmText`** — the verb. `ConfirmOptions` already refuses to
|
|
37
40
|
default one, for the same reason: a confirm button reading "OK" tells the
|
|
38
41
|
operator nothing about what is about to happen.
|
|
@@ -39,6 +39,7 @@ export function CardActionsProvider({
|
|
|
39
39
|
errorTitle,
|
|
40
40
|
errorDismissLabel,
|
|
41
41
|
autoHideMs = 6_000,
|
|
42
|
+
onError,
|
|
42
43
|
children,
|
|
43
44
|
}: {
|
|
44
45
|
tenantSlug: string;
|
|
@@ -55,14 +56,27 @@ export function CardActionsProvider({
|
|
|
55
56
|
errorDismissLabel: string;
|
|
56
57
|
/** How long the snackbar stays up. */
|
|
57
58
|
autoHideMs?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Hand a failure to the HOST's own toast channel instead of this provider's
|
|
61
|
+
* snackbar. Given, the provider draws nothing of its own: an app with one
|
|
62
|
+
* toast column (every toast in one place, in one look) passes its `toast`
|
|
63
|
+
* here, so a card's failure lands with every other toast rather than in a
|
|
64
|
+
* corner of its own. It receives the same heading and message the snackbar
|
|
65
|
+
* would have shown.
|
|
66
|
+
*/
|
|
67
|
+
onError?: (title: string, message: string) => void;
|
|
58
68
|
children: ReactNode;
|
|
59
69
|
}): JSX.Element {
|
|
60
70
|
const [error, setError] = useState<string | null>(null);
|
|
61
|
-
const notifyError = useCallback(
|
|
71
|
+
const notifyError = useCallback(
|
|
72
|
+
(message: string) => (onError ? onError(errorTitle, message) : setError(message)),
|
|
73
|
+
[onError, errorTitle],
|
|
74
|
+
);
|
|
62
75
|
|
|
63
76
|
return (
|
|
64
77
|
<CardActionsContext.Provider value={{ tenantSlug, onRefresh, notifyError }}>
|
|
65
78
|
{children}
|
|
79
|
+
{onError === undefined && (
|
|
66
80
|
<Snackbar
|
|
67
81
|
open={error !== null}
|
|
68
82
|
autoHideDuration={autoHideMs}
|
|
@@ -81,6 +95,7 @@ export function CardActionsProvider({
|
|
|
81
95
|
/>
|
|
82
96
|
</span>
|
|
83
97
|
</Snackbar>
|
|
98
|
+
)}
|
|
84
99
|
</CardActionsContext.Provider>
|
|
85
100
|
);
|
|
86
101
|
}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
NOT_LIVE,
|
|
15
15
|
SlotIcon,
|
|
16
16
|
controlProps,
|
|
17
|
+
useMounted,
|
|
17
18
|
destinationControl,
|
|
18
19
|
focusRing,
|
|
19
20
|
} from './SectionNav.parts';
|
|
@@ -24,16 +25,24 @@ import type { SectionNavAction, SectionNavBadge, SectionNavDestination, SectionN
|
|
|
24
25
|
/** Which of the bar's two menus is open, if any. */
|
|
25
26
|
type OpenMenu = 'primary' | 'more' | null;
|
|
26
27
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* The bar's height above the safe area — tall enough for an icon over a label;
|
|
30
|
+
* a compact bar holds the icon alone.
|
|
31
|
+
*/
|
|
32
|
+
const barHeight = (theme: Parameters<typeof rem>[0], compact = false): string => rem(theme, compact ? 48 : 60);
|
|
33
|
+
|
|
34
|
+
/** How the bar is drawn — `compact` is `SectionNavProps.compact`. */
|
|
35
|
+
export interface SectionNavBarOptions {
|
|
36
|
+
compact?: boolean;
|
|
37
|
+
}
|
|
29
38
|
|
|
30
39
|
/**
|
|
31
40
|
* The bar's full height on screen, the safe area included — where its sheets
|
|
32
41
|
* stop, and what a host reserves at the foot of its content so nothing it
|
|
33
42
|
* floats (a toast, a receipt) lands under the bar.
|
|
34
43
|
*/
|
|
35
|
-
export function sectionNavBarInset(theme: Parameters<typeof rem>[0]): string {
|
|
36
|
-
return `calc(${barHeight(theme)} + env(safe-area-inset-bottom))`;
|
|
44
|
+
export function sectionNavBarInset(theme: Parameters<typeof rem>[0], options: SectionNavBarOptions = {}): string {
|
|
45
|
+
return `calc(${barHeight(theme, options.compact === true)} + env(safe-area-inset-bottom))`;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/**
|
|
@@ -62,6 +71,7 @@ function Slot({
|
|
|
62
71
|
control,
|
|
63
72
|
expanded,
|
|
64
73
|
loading = false,
|
|
74
|
+
compact = false,
|
|
65
75
|
}: {
|
|
66
76
|
label: string;
|
|
67
77
|
icon: ReactNode;
|
|
@@ -73,17 +83,21 @@ function Slot({
|
|
|
73
83
|
control: Record<string, unknown>;
|
|
74
84
|
expanded?: boolean;
|
|
75
85
|
loading?: boolean;
|
|
86
|
+
/** Icon only: the label stays the slot's name, out of sight, and its tooltip. */
|
|
87
|
+
compact?: boolean;
|
|
76
88
|
}): React.JSX.Element {
|
|
77
89
|
const theme = useTheme();
|
|
90
|
+
const animate = useMounted();
|
|
78
91
|
return (
|
|
79
92
|
<Box
|
|
80
93
|
{...control}
|
|
94
|
+
title={compact ? label : undefined}
|
|
81
95
|
aria-current={current ? 'page' : undefined}
|
|
82
96
|
aria-expanded={expanded}
|
|
83
97
|
aria-busy={loading || undefined}
|
|
84
98
|
data-lit={lit ? 'true' : undefined}
|
|
85
99
|
data-testid={testId}
|
|
86
|
-
sx={slotSx(theme, lit)}
|
|
100
|
+
sx={slotSx(theme, lit, compact)}
|
|
87
101
|
>
|
|
88
102
|
<CountedIcon
|
|
89
103
|
icon={
|
|
@@ -107,6 +121,7 @@ function Slot({
|
|
|
107
121
|
lineHeight: 1.3,
|
|
108
122
|
fontWeight: lit ? 700 : 600,
|
|
109
123
|
color: lit ? 'text.primary' : 'inherit',
|
|
124
|
+
...labelFoldSx(theme, compact, animate),
|
|
110
125
|
}}
|
|
111
126
|
>
|
|
112
127
|
{label}
|
|
@@ -115,6 +130,23 @@ function Slot({
|
|
|
115
130
|
);
|
|
116
131
|
}
|
|
117
132
|
|
|
133
|
+
/**
|
|
134
|
+
* The label folding away in a compact bar: it shrinks to no height and fades
|
|
135
|
+
* while the bar shrinks, rather than leaving in one frame. Never `display:
|
|
136
|
+
* none` — it is still the slot's accessible name. With reduced motion it
|
|
137
|
+
* simply goes.
|
|
138
|
+
*/
|
|
139
|
+
function labelFoldSx(theme: Theme, compact: boolean, animate: boolean): Record<string, unknown> {
|
|
140
|
+
return {
|
|
141
|
+
maxHeight: compact ? 0 : rem(theme, 24),
|
|
142
|
+
opacity: compact ? 0 : 1,
|
|
143
|
+
transition: animate
|
|
144
|
+
? theme.transitions.create(['max-height', 'opacity'], { duration: theme.transitions.duration.shorter })
|
|
145
|
+
: 'none',
|
|
146
|
+
'@media (prefers-reduced-motion: reduce)': { transition: 'none' },
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
118
150
|
/** The pill behind a slot's icon — tinted while the slot is lit. */
|
|
119
151
|
function pillSx(theme: Theme): SxProps<Theme> {
|
|
120
152
|
return {
|
|
@@ -129,7 +161,7 @@ function pillSx(theme: Theme): SxProps<Theme> {
|
|
|
129
161
|
}
|
|
130
162
|
|
|
131
163
|
/** A slot's look: icon over label, a pill behind the lit icon, dimmed when disabled. */
|
|
132
|
-
function slotSx(theme: Theme, lit: boolean): SxProps<Theme> {
|
|
164
|
+
function slotSx(theme: Theme, lit: boolean, compact: boolean): SxProps<Theme> {
|
|
133
165
|
return {
|
|
134
166
|
...CONTROL_RESET,
|
|
135
167
|
...focusRing(theme),
|
|
@@ -139,7 +171,7 @@ function slotSx(theme: Theme, lit: boolean): SxProps<Theme> {
|
|
|
139
171
|
flexDirection: 'column',
|
|
140
172
|
alignItems: 'center',
|
|
141
173
|
justifyContent: 'center',
|
|
142
|
-
gap: 0.25,
|
|
174
|
+
gap: compact ? 0 : 0.25,
|
|
143
175
|
position: 'relative',
|
|
144
176
|
color: lit ? 'primary.main' : 'text.secondary',
|
|
145
177
|
// The current slot is marked by more than its colour: a tinted pill behind
|
|
@@ -158,6 +190,7 @@ interface SlotContext {
|
|
|
158
190
|
linkComponent: ElementType | undefined;
|
|
159
191
|
copy: SectionNavCopy;
|
|
160
192
|
dataTestId: string;
|
|
193
|
+
compact: boolean;
|
|
161
194
|
}
|
|
162
195
|
|
|
163
196
|
/** The raised button: an action runs on tap; a menu opens its sheet. */
|
|
@@ -175,6 +208,7 @@ function PrimarySlot({
|
|
|
175
208
|
label={primary.label}
|
|
176
209
|
icon={primary.icon}
|
|
177
210
|
captioned
|
|
211
|
+
compact={context.compact}
|
|
178
212
|
disabled={primary.disabled}
|
|
179
213
|
loading={primary.loading}
|
|
180
214
|
dataTestId={testId}
|
|
@@ -191,6 +225,7 @@ function PrimarySlot({
|
|
|
191
225
|
icon={primary.icon}
|
|
192
226
|
open={context.open === 'primary'}
|
|
193
227
|
closeLabel={context.copy.close}
|
|
228
|
+
compact={context.compact}
|
|
194
229
|
disabled={primary.disabled}
|
|
195
230
|
dataTestId={testId}
|
|
196
231
|
onClick={() => context.toggle('primary')}
|
|
@@ -211,6 +246,7 @@ function MoreSlot({ more, context }: { more: SectionNavMenu; context: SlotContex
|
|
|
211
246
|
expanded={open === 'more'}
|
|
212
247
|
copy={context.copy}
|
|
213
248
|
testId={more.dataTestId ?? `${context.dataTestId}-more`}
|
|
249
|
+
compact={context.compact}
|
|
214
250
|
control={controlProps({
|
|
215
251
|
href: undefined,
|
|
216
252
|
linkComponent: context.linkComponent,
|
|
@@ -240,6 +276,7 @@ function DestinationSlot({
|
|
|
240
276
|
copy={context.copy}
|
|
241
277
|
testId={destination.dataTestId ?? `${context.dataTestId}-dest-${destination.id}`}
|
|
242
278
|
loading={destination.loading === true}
|
|
279
|
+
compact={context.compact}
|
|
243
280
|
control={destinationControl(destination, context.linkComponent, () => {
|
|
244
281
|
context.close();
|
|
245
282
|
destination.onSelect?.();
|
|
@@ -265,6 +302,32 @@ function BarSlotView({
|
|
|
265
302
|
return <DestinationSlot destination={slot.destination} context={context} />;
|
|
266
303
|
}
|
|
267
304
|
|
|
305
|
+
/** The bar's own box: docked, a hairline on top, raised over the backdrop only while its sheet is open. */
|
|
306
|
+
function barSx(theme: Theme, sheetOpen: boolean, compact: boolean, animate: boolean): SxProps<Theme> {
|
|
307
|
+
return {
|
|
308
|
+
flex: 'none',
|
|
309
|
+
display: 'flex',
|
|
310
|
+
alignItems: 'stretch',
|
|
311
|
+
boxSizing: 'border-box',
|
|
312
|
+
height: sectionNavBarInset(theme, { compact }),
|
|
313
|
+
// Folding to icons and back is a change of height the eye follows;
|
|
314
|
+
// with reduced motion it simply happens.
|
|
315
|
+
transition: animate ? theme.transitions.create('height', { duration: theme.transitions.duration.shorter }) : 'none',
|
|
316
|
+
'@media (prefers-reduced-motion: reduce)': { transition: 'none' },
|
|
317
|
+
paddingBottom: 'env(safe-area-inset-bottom)',
|
|
318
|
+
borderTop: `1px solid ${theme.palette.divider}`,
|
|
319
|
+
bgcolor: 'background.paper',
|
|
320
|
+
// Above the backdrop ONLY while one of its own sheets is open, so the
|
|
321
|
+
// primary button can close what it opened. Raised all the time it
|
|
322
|
+
// would sit over every dialog the page opens, and on a small phone a
|
|
323
|
+
// dialog's own footer is exactly where the bar is. `stackedOverlayZIndex`,
|
|
324
|
+
// not `zIndex.modal + 1`: a host lifting a bottom Drawer clear of a
|
|
325
|
+
// stacked sheet catches this bar's OWN sheets too.
|
|
326
|
+
position: 'relative',
|
|
327
|
+
zIndex: sheetOpen ? stackedOverlayZIndex(theme) + 1 : 'auto',
|
|
328
|
+
} as SxProps<Theme>;
|
|
329
|
+
}
|
|
330
|
+
|
|
268
331
|
/** The phone layout: a bottom bar, with its menus as bottom sheets. */
|
|
269
332
|
export function SectionNavBar({
|
|
270
333
|
label,
|
|
@@ -274,10 +337,12 @@ export function SectionNavBar({
|
|
|
274
337
|
linkComponent,
|
|
275
338
|
copy,
|
|
276
339
|
dataTestId,
|
|
340
|
+
compact = false,
|
|
277
341
|
}: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> &
|
|
278
|
-
Pick<SectionNavProps, 'primary' | 'more'> & { linkComponent: ElementType | undefined }): React.JSX.Element {
|
|
342
|
+
Pick<SectionNavProps, 'primary' | 'more' | 'compact'> & { linkComponent: ElementType | undefined }): React.JSX.Element {
|
|
279
343
|
const sheetMenu = isMenu(primary) ? primary : undefined;
|
|
280
344
|
const theme = useTheme();
|
|
345
|
+
const animate = useMounted();
|
|
281
346
|
const [open, setOpen] = useState<OpenMenu>(null);
|
|
282
347
|
const toggle = (menu: Exclude<OpenMenu, null>): void => setOpen((current) => (current === menu ? null : menu));
|
|
283
348
|
const close = (): void => setOpen(null);
|
|
@@ -288,24 +353,7 @@ export function SectionNavBar({
|
|
|
288
353
|
component="nav"
|
|
289
354
|
aria-label={label}
|
|
290
355
|
data-testid={dataTestId}
|
|
291
|
-
sx={
|
|
292
|
-
flex: 'none',
|
|
293
|
-
display: 'flex',
|
|
294
|
-
alignItems: 'stretch',
|
|
295
|
-
boxSizing: 'border-box',
|
|
296
|
-
height: sectionNavBarInset(theme),
|
|
297
|
-
paddingBottom: 'env(safe-area-inset-bottom)',
|
|
298
|
-
borderTop: `1px solid ${theme.palette.divider}`,
|
|
299
|
-
bgcolor: 'background.paper',
|
|
300
|
-
// Above the backdrop ONLY while one of its own sheets is open, so the
|
|
301
|
-
// primary button can close what it opened. Raised all the time it
|
|
302
|
-
// would sit over every dialog the page opens, and on a small phone a
|
|
303
|
-
// dialog's own footer is exactly where the bar is. `stackedOverlayZIndex`,
|
|
304
|
-
// not `zIndex.modal + 1`: a host lifting a bottom Drawer clear of a
|
|
305
|
-
// stacked sheet catches this bar's OWN sheets too.
|
|
306
|
-
position: 'relative',
|
|
307
|
-
zIndex: open === null ? 'auto' : stackedOverlayZIndex(theme) + 1,
|
|
308
|
-
}}
|
|
356
|
+
sx={barSx(theme, open !== null, compact, animate)}
|
|
309
357
|
>
|
|
310
358
|
{barSlots(destinations, more !== undefined, primary !== undefined).map((slot) => (
|
|
311
359
|
<BarSlotView
|
|
@@ -313,7 +361,7 @@ export function SectionNavBar({
|
|
|
313
361
|
slot={slot}
|
|
314
362
|
primary={primary}
|
|
315
363
|
more={more}
|
|
316
|
-
context={{ open, toggle, close, linkComponent, copy, dataTestId }}
|
|
364
|
+
context={{ open, toggle, close, linkComponent, copy, dataTestId, compact }}
|
|
317
365
|
/>
|
|
318
366
|
))}
|
|
319
367
|
</Box>
|
|
@@ -325,7 +373,7 @@ export function SectionNavBar({
|
|
|
325
373
|
linkComponent={linkComponent}
|
|
326
374
|
copy={copy}
|
|
327
375
|
testId={`${dataTestId}-primary-sheet`}
|
|
328
|
-
bottomOffset={sectionNavBarInset(theme)}
|
|
376
|
+
bottomOffset={sectionNavBarInset(theme, { compact })}
|
|
329
377
|
/>
|
|
330
378
|
) : null}
|
|
331
379
|
{more ? (
|
|
@@ -336,7 +384,7 @@ export function SectionNavBar({
|
|
|
336
384
|
linkComponent={linkComponent}
|
|
337
385
|
copy={copy}
|
|
338
386
|
testId={`${dataTestId}-more-sheet`}
|
|
339
|
-
bottomOffset={sectionNavBarInset(theme)}
|
|
387
|
+
bottomOffset={sectionNavBarInset(theme, { compact })}
|
|
340
388
|
/>
|
|
341
389
|
) : null}
|
|
342
390
|
</>
|
|
@@ -50,6 +50,26 @@ screen.
|
|
|
50
50
|
carries no words. `PT_BR_SECTION_NAV_COPY` and `EN_US_SECTION_NAV_COPY` are
|
|
51
51
|
named packs; `SECTION_NAV_COPY` is the locale pack.
|
|
52
52
|
- **dataTestId**: the prefix for every test id (`section-nav`).
|
|
53
|
+
- **compact**: `boolean`, default `false`. Icons only, a size down, for a host
|
|
54
|
+
that folds its chrome so the content gets the screen. See *Compact*.
|
|
55
|
+
|
|
56
|
+
## Compact
|
|
57
|
+
|
|
58
|
+
`compact` draws the same navigation as icons only. Nothing is removed: every
|
|
59
|
+
label stays its control's accessible name (out of sight) and its `title`
|
|
60
|
+
tooltip, every count stays on its icon, every menu still opens.
|
|
61
|
+
|
|
62
|
+
| `layout` | compact draws |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `bar` | 48px instead of 60; each slot its icon, its label folding away (shrinking and fading) as the bar shrinks; the raised button 40px instead of 52, lifted less, with its label as a tooltip and no caption under an action. Height and labels animate (200ms) unless the reader asked for reduced motion. |
|
|
65
|
+
| `rail` | each row, the way back (an arrow when it brings no icon) and a `primary` menu's button as their icon, centred; the heading, `more`'s title and its group titles out of sight. Made for a column 64px wide; the host sets the width. |
|
|
66
|
+
|
|
67
|
+
`sectionNavBarInset(theme, { compact: true })` is the compact bar's full
|
|
68
|
+
height, so a host's reserved foot follows the bar as it folds.
|
|
69
|
+
|
|
70
|
+
A slot's name includes its count ("Board, 3 pending") while its tooltip is the
|
|
71
|
+
label alone, so a screen reader may read the label a second time as the
|
|
72
|
+
description; the tooltip is there for a pointer, which sees no words otherwise.
|
|
53
73
|
|
|
54
74
|
## A bar of verbs
|
|
55
75
|
|
|
@@ -103,8 +123,8 @@ every label is semibold.
|
|
|
103
123
|
|
|
104
124
|
## Docking the bar
|
|
105
125
|
|
|
106
|
-
Dock the bar at the foot of a flex column. `sectionNavBarInset(theme)`
|
|
107
|
-
full height, the phone's safe area included. Reserve it at the foot of the
|
|
126
|
+
Dock the bar at the foot of a flex column. `sectionNavBarInset(theme)` (with
|
|
127
|
+
`{ compact: true }` for the compact bar) is its full height, the phone's safe area included. Reserve it at the foot of the
|
|
108
128
|
content, so nothing the page floats (a toast, a receipt) lands under the bar.
|
|
109
129
|
|
|
110
130
|
The bar rises above a modal backdrop only while one of its OWN sheets is open,
|
|
@@ -123,7 +143,8 @@ the slot reports the sheet through `aria-expanded`.
|
|
|
123
143
|
The raised round button on its own, for a host that already draws its own bar:
|
|
124
144
|
drop it between two tabs in a flex row. Without `open` it is a plain action.
|
|
125
145
|
With `captioned` its label is drawn under it, hidden from assistive tech so
|
|
126
|
-
the button is named once. `
|
|
146
|
+
the button is named once. `compact` draws it 40px rather than 52, with no
|
|
147
|
+
caption. `disabled` is native; `loading` keeps it focusable
|
|
127
148
|
with `aria-busy` and `aria-disabled`, and drops the click.
|
|
128
149
|
With `open` it reports `aria-expanded`, takes `closeLabel` as its name, and its
|
|
129
150
|
icon turns 45° while open.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import Box from '@mui/material/Box/index.js';
|
|
2
2
|
import CircularProgress from '@mui/material/CircularProgress/index.js';
|
|
3
3
|
import type { SxProps, Theme } from '@mui/material/styles/index.js';
|
|
4
|
-
import type
|
|
4
|
+
import { useEffect, useState, type ElementType, type ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
import { rem } from '../../../tokens/scales';
|
|
7
|
+
import { SR_ONLY_SX } from '../../form/Label/Label.styles';
|
|
7
8
|
import { Badge } from '../../data-display/Badge';
|
|
8
9
|
|
|
9
10
|
import { shownCount } from './SectionNav.helpers';
|
|
@@ -153,4 +154,21 @@ export const CONTROL_RESET = {
|
|
|
153
154
|
[NOT_LIVE]: { cursor: 'default' },
|
|
154
155
|
} as const;
|
|
155
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Out of sight, still read: a compact nav keeps each label as its control's
|
|
159
|
+
* accessible name. The same box `Label`'s `srOnly` draws.
|
|
160
|
+
*/
|
|
161
|
+
export const VISUALLY_HIDDEN = SR_ONLY_SX;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* False on the first render, true from then on — so a fold animates when the
|
|
165
|
+
* host CHANGES `compact`, never when a page simply opens folded (which drew
|
|
166
|
+
* the labels sliding out over the neighbouring badges on every load).
|
|
167
|
+
*/
|
|
168
|
+
export function useMounted(): boolean {
|
|
169
|
+
const [mounted, setMounted] = useState(false);
|
|
170
|
+
useEffect(() => setMounted(true), []);
|
|
171
|
+
return mounted;
|
|
172
|
+
}
|
|
173
|
+
|
|
156
174
|
export { Box };
|