@12-apps/ui 6.50.0 → 6.51.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 +2 -2
- package/dist/_internal/components/data-display/Badge/Badge.js +4 -4
- package/dist/_internal/components/data-display/Badge/Badge.styles.js +4 -4
- package/dist/_internal/components/data-display/Badge/BadgeContent.js +4 -4
- package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +4 -4
- package/dist/_internal/components/data-display/Carousel/Carousel.js +4 -4
- package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +4 -4
- package/dist/_internal/components/data-display/Carousel/Carousel.styles.js +4 -4
- package/dist/_internal/components/data-display/Chart/Chart.js +4 -4
- package/dist/_internal/components/data-display/Chart/SpecChart.js +4 -4
- package/dist/_internal/components/data-display/Chart/chart-context.js +4 -4
- package/dist/_internal/components/data-display/Chart/chart-internals.js +4 -4
- package/dist/_internal/components/data-display/Chart/chart-renderers.js +4 -4
- package/dist/_internal/components/data-display/DataGrid/DataGrid.js +6 -6
- package/dist/_internal/components/data-display/DataGrid/DataGrid.model.js +5 -5
- package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +16 -16
- package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +17 -17
- package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +8 -8
- package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +7 -7
- package/dist/_internal/components/data-display/DataViews/base-list-card.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +7 -7
- package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +15 -15
- package/dist/_internal/components/data-display/DataViews/data-views-layout-context.js +5 -5
- package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +6 -6
- package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +9 -9
- package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +8 -8
- package/dist/_internal/components/data-display/DataViews/list-card-rails.js +6 -6
- package/dist/_internal/components/data-display/FleetMap/FleetMap.js +4 -4
- package/dist/_internal/components/data-display/Sheet/Sheet.body.js +4 -4
- package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -4
- package/dist/_internal/components/data-display/Sheet/Sheet.styles.js +4 -4
- package/dist/_internal/components/data-display/Table/Table.js +5 -5
- package/dist/_internal/components/data-display/index.js +7 -7
- package/dist/_internal/components/form/Command/Command.js +4 -4
- package/dist/_internal/components/form/Command/Command.styles.js +4 -4
- package/dist/_internal/components/form/Label/Label.js +4 -4
- package/dist/_internal/components/form/Label/Label.styles.js +4 -4
- package/dist/_internal/components/form/Menubar/Menubar.item.js +4 -4
- package/dist/_internal/components/form/Menubar/Menubar.js +4 -4
- package/dist/_internal/components/form/Menubar/Menubar.styles.js +4 -4
- package/dist/_internal/components/form/Menubar/Menubar.toolbar.js +4 -4
- package/dist/_internal/components/form/index.js +4 -4
- package/dist/_internal/components/index.js +23 -23
- package/dist/_internal/components/layout/Box/Box.js +7 -7
- package/dist/_internal/components/layout/SettingCard/SettingCard.js +9 -9
- package/dist/_internal/components/layout/SettingCard/SettingCard.parts.js +8 -8
- package/dist/_internal/components/layout/SettingCard/SettingGrid.js +9 -9
- package/dist/_internal/components/layout/SettingCard/SettingGroup.js +10 -10
- package/dist/_internal/components/layout/SettingCard/SettingSwitch.js +9 -9
- package/dist/_internal/components/layout/SettingCard/SettingToggle.js +10 -10
- package/dist/_internal/components/layout/Stack/Stack.js +8 -8
- package/dist/_internal/components/layout/index.js +13 -13
- package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +4 -4
- package/dist/_internal/components/navigation/AppHeader/AppHeader.identity.js +4 -4
- package/dist/_internal/components/navigation/SectionNav/SectionNav.bar.js +9 -9
- package/dist/_internal/components/navigation/SectionNav/SectionNav.helpers.js +5 -1
- package/dist/_internal/components/navigation/SectionNav/SectionNav.js +11 -11
- package/dist/_internal/components/navigation/SectionNav/SectionNav.parts.js +12 -6
- package/dist/_internal/components/navigation/SectionNav/SectionNav.primary.js +7 -7
- package/dist/_internal/components/navigation/SectionNav/SectionNav.rail.js +7 -7
- package/dist/_internal/components/navigation/SectionNav/SectionNav.sheet.js +7 -7
- package/dist/_internal/components/navigation/SectionNav/__stories__/fixtures.js +16 -4
- package/dist/_internal/components/navigation/SectionNav/__stories__/fixtures.js.map +1 -1
- package/dist/_internal/components/navigation/index.js +11 -11
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.helpers.js +4 -4
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.js +4 -4
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStep.parts.js +4 -4
- package/dist/_internal/components/utility/WorkflowStep/WorkflowStepRow.js +4 -4
- package/dist/_internal/components/utility/index.js +4 -4
- package/dist/_internal/icons/Icon.js +7 -7
- package/dist/_internal/provider/UiProvider.js +6 -6
- package/dist/_internal/provider/mui-bridge.js +5 -5
- package/dist/_internal/provider/use-ui-theme.js +6 -6
- package/dist/_internal/tokens/density-overrides.js +3 -3
- package/dist/_internal/tokens/density-overrides.navigation.js +1 -1
- package/dist/_internal/tokens/density-overrides.selection.js +1 -1
- package/dist/_internal/tokens/density.js +4 -4
- package/dist/charts.js +4 -4
- package/dist/{chunk-XK77FY42.js → chunk-25MSGLNU.js} +4 -3
- package/dist/chunk-25MSGLNU.js.map +1 -0
- package/dist/{chunk-7VC6YBD3.js → chunk-3U45DRNS.js} +2 -2
- package/dist/{chunk-ZQCZMSLO.js → chunk-4B5WSVS7.js} +2 -2
- package/dist/{chunk-F4FOBTLJ.js → chunk-4BI5PCOM.js} +2 -2
- package/dist/{chunk-HVZ4HF4M.js → chunk-5N2UJOCT.js} +2 -2
- package/dist/{chunk-DFCX3FNB.js → chunk-5ZBFADBL.js} +2 -2
- package/dist/{chunk-GLKQT2DS.js → chunk-A436VORP.js} +33 -4
- package/dist/chunk-A436VORP.js.map +1 -0
- package/dist/{chunk-LWBR5U6V.js → chunk-ABPTS3XK.js} +2 -2
- package/dist/{chunk-43EQITNF.js → chunk-BHPLHGZP.js} +4 -4
- package/dist/{chunk-YMW2VYGU.js → chunk-DLO5V4AV.js} +2 -2
- package/dist/{chunk-7FQF5BC2.js → chunk-ESW4Z5I7.js} +2 -2
- package/dist/{chunk-ZPD6MGAO.js → chunk-FDJLYYDA.js} +4 -4
- package/dist/{chunk-LZL6HDTZ.js → chunk-FM5RBGG7.js} +2 -2
- package/dist/{chunk-V2SAZOT2.js → chunk-FYTC4LOD.js} +2 -2
- package/dist/{chunk-4ELI2MM3.js → chunk-GAXHYRX6.js} +9 -6
- package/dist/chunk-GAXHYRX6.js.map +1 -0
- package/dist/{chunk-CT45KNCT.js → chunk-GPTICJVN.js} +3 -3
- package/dist/{chunk-URGH4673.js → chunk-H556NMKE.js} +4 -4
- package/dist/{chunk-VOF6QVCF.js → chunk-HF7V3RI5.js} +2 -2
- package/dist/{chunk-NKJMOWY3.js → chunk-HJUR6ZY6.js} +2 -2
- package/dist/{chunk-RX7J6VRI.js → chunk-HKEBTPKY.js} +119 -42
- package/dist/chunk-HKEBTPKY.js.map +1 -0
- package/dist/{chunk-ZC3NEUNQ.js → chunk-I2LF53MJ.js} +2 -2
- package/dist/{chunk-ZFQVT6HZ.js → chunk-II7Z5UB6.js} +2 -2
- package/dist/{chunk-K65NSHQI.js → chunk-L3CQTVFU.js} +4 -4
- package/dist/{chunk-EY4GPLMF.js → chunk-MT7XMJUJ.js} +5 -5
- package/dist/{chunk-TELVW2OI.js → chunk-MYCR7FMI.js} +2 -2
- package/dist/{chunk-56TGECKZ.js → chunk-NP6SHLQ3.js} +4 -3
- package/dist/chunk-NP6SHLQ3.js.map +1 -0
- package/dist/{chunk-WB6BTUXQ.js → chunk-OWILUXWM.js} +2 -2
- package/dist/{chunk-VHVI3D4R.js → chunk-P3GBXE73.js} +11 -2
- package/dist/chunk-P3GBXE73.js.map +1 -0
- package/dist/{chunk-WSBTMZJM.js → chunk-P7YUOH2E.js} +2 -2
- package/dist/{chunk-VOP2BXKL.js → chunk-QWTPK3FT.js} +2 -2
- package/dist/{chunk-XQ6Y5Z7R.js → chunk-RCJOTNIW.js} +2 -2
- package/dist/{chunk-32JMSHEA.js → chunk-S4ZUZ6DS.js} +10 -6
- package/dist/chunk-S4ZUZ6DS.js.map +1 -0
- package/dist/{chunk-SWDDXMV7.js → chunk-SJ4IAZ3V.js} +4 -4
- package/dist/{chunk-FHWBOOS3.js → chunk-TH7RBREI.js} +2 -2
- package/dist/{chunk-SA2ERYVV.js → chunk-VAO63IIP.js} +3 -3
- package/dist/{chunk-43Q6CVPB.js → chunk-VELGOFCL.js} +127 -78
- package/dist/chunk-VELGOFCL.js.map +1 -0
- package/dist/{chunk-RCJYLDXV.js → chunk-VJBTFWDK.js} +4 -4
- package/dist/chunk-WNKRFMSI.js +113 -0
- package/dist/chunk-WNKRFMSI.js.map +1 -0
- package/dist/{chunk-LM2YOONY.js → chunk-XYHNXO6Q.js} +2 -2
- package/dist/{chunk-FT7BNFGS.js → chunk-YK4ZG5Y4.js} +2 -2
- package/dist/data-display/Badge.js +4 -4
- package/dist/data-display/Carousel.js +4 -4
- package/dist/data-display/Chart.js +4 -4
- package/dist/data-display/DataGrid.js +6 -6
- package/dist/data-display/DataViews.js +20 -20
- package/dist/data-display/FleetMap.js +4 -4
- package/dist/data-display/Sheet.js +4 -4
- package/dist/data-display/Table.js +5 -5
- package/dist/form/Command.js +4 -4
- package/dist/form/Label.js +4 -4
- package/dist/form/Menubar.js +4 -4
- package/dist/icons.js +7 -7
- package/dist/layout/Box.js +7 -7
- package/dist/layout/SettingCard.js +13 -13
- package/dist/layout/Stack.js +8 -8
- package/dist/navigation/AppHeader.js +4 -4
- package/dist/navigation/SectionNav.js +11 -11
- package/dist/provider.js +7 -7
- package/dist/tokens.js +4 -4
- package/dist/types/components/navigation/SectionNav/SectionNav.bar.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.helpers.d.ts +12 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.helpers.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.parts.d.ts +36 -2
- package/dist/types/components/navigation/SectionNav/SectionNav.parts.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.primary.d.ts +22 -4
- package/dist/types/components/navigation/SectionNav/SectionNav.primary.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.rail.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.sheet.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/SectionNav.types.d.ts +81 -5
- package/dist/types/components/navigation/SectionNav/SectionNav.types.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/__stories__/fixtures.d.ts +11 -1
- package/dist/types/components/navigation/SectionNav/__stories__/fixtures.d.ts.map +1 -1
- package/dist/types/components/navigation/SectionNav/index.d.ts +1 -1
- package/dist/types/components/navigation/SectionNav/index.d.ts.map +1 -1
- package/dist/types/tokens/density-overrides.d.ts.map +1 -1
- package/dist/types/tokens/density-overrides.navigation.d.ts.map +1 -1
- package/dist/types/tokens/density-overrides.selection.d.ts.map +1 -1
- package/dist/utility/WorkflowStep.js +4 -4
- package/package.json +1 -1
- package/src/components/navigation/SectionNav/SectionNav.bar.tsx +161 -88
- package/src/components/navigation/SectionNav/SectionNav.helpers.ts +16 -1
- package/src/components/navigation/SectionNav/SectionNav.md +40 -4
- package/src/components/navigation/SectionNav/SectionNav.parts.tsx +59 -1
- package/src/components/navigation/SectionNav/SectionNav.primary.tsx +107 -30
- package/src/components/navigation/SectionNav/SectionNav.rail.tsx +154 -41
- package/src/components/navigation/SectionNav/SectionNav.sheet.tsx +6 -2
- package/src/components/navigation/SectionNav/SectionNav.types.ts +82 -5
- package/src/components/navigation/SectionNav/__stories__/fixtures.tsx +21 -1
- package/src/components/navigation/SectionNav/index.ts +1 -0
- package/src/tokens/density-overrides.navigation.ts +15 -2
- package/src/tokens/density-overrides.selection.ts +31 -14
- package/src/tokens/density-overrides.ts +27 -11
- package/dist/chunk-32JMSHEA.js.map +0 -1
- package/dist/chunk-43Q6CVPB.js.map +0 -1
- package/dist/chunk-4ELI2MM3.js.map +0 -1
- package/dist/chunk-56TGECKZ.js.map +0 -1
- package/dist/chunk-GLKQT2DS.js.map +0 -1
- package/dist/chunk-RX7J6VRI.js.map +0 -1
- package/dist/chunk-RZ4SBSLP.js +0 -62
- package/dist/chunk-RZ4SBSLP.js.map +0 -1
- package/dist/chunk-VHVI3D4R.js.map +0 -1
- package/dist/chunk-XK77FY42.js.map +0 -1
- /package/dist/{chunk-7VC6YBD3.js.map → chunk-3U45DRNS.js.map} +0 -0
- /package/dist/{chunk-ZQCZMSLO.js.map → chunk-4B5WSVS7.js.map} +0 -0
- /package/dist/{chunk-F4FOBTLJ.js.map → chunk-4BI5PCOM.js.map} +0 -0
- /package/dist/{chunk-HVZ4HF4M.js.map → chunk-5N2UJOCT.js.map} +0 -0
- /package/dist/{chunk-DFCX3FNB.js.map → chunk-5ZBFADBL.js.map} +0 -0
- /package/dist/{chunk-LWBR5U6V.js.map → chunk-ABPTS3XK.js.map} +0 -0
- /package/dist/{chunk-43EQITNF.js.map → chunk-BHPLHGZP.js.map} +0 -0
- /package/dist/{chunk-YMW2VYGU.js.map → chunk-DLO5V4AV.js.map} +0 -0
- /package/dist/{chunk-7FQF5BC2.js.map → chunk-ESW4Z5I7.js.map} +0 -0
- /package/dist/{chunk-ZPD6MGAO.js.map → chunk-FDJLYYDA.js.map} +0 -0
- /package/dist/{chunk-LZL6HDTZ.js.map → chunk-FM5RBGG7.js.map} +0 -0
- /package/dist/{chunk-V2SAZOT2.js.map → chunk-FYTC4LOD.js.map} +0 -0
- /package/dist/{chunk-CT45KNCT.js.map → chunk-GPTICJVN.js.map} +0 -0
- /package/dist/{chunk-URGH4673.js.map → chunk-H556NMKE.js.map} +0 -0
- /package/dist/{chunk-VOF6QVCF.js.map → chunk-HF7V3RI5.js.map} +0 -0
- /package/dist/{chunk-NKJMOWY3.js.map → chunk-HJUR6ZY6.js.map} +0 -0
- /package/dist/{chunk-ZC3NEUNQ.js.map → chunk-I2LF53MJ.js.map} +0 -0
- /package/dist/{chunk-ZFQVT6HZ.js.map → chunk-II7Z5UB6.js.map} +0 -0
- /package/dist/{chunk-K65NSHQI.js.map → chunk-L3CQTVFU.js.map} +0 -0
- /package/dist/{chunk-EY4GPLMF.js.map → chunk-MT7XMJUJ.js.map} +0 -0
- /package/dist/{chunk-TELVW2OI.js.map → chunk-MYCR7FMI.js.map} +0 -0
- /package/dist/{chunk-WB6BTUXQ.js.map → chunk-OWILUXWM.js.map} +0 -0
- /package/dist/{chunk-WSBTMZJM.js.map → chunk-P7YUOH2E.js.map} +0 -0
- /package/dist/{chunk-VOP2BXKL.js.map → chunk-QWTPK3FT.js.map} +0 -0
- /package/dist/{chunk-XQ6Y5Z7R.js.map → chunk-RCJOTNIW.js.map} +0 -0
- /package/dist/{chunk-SWDDXMV7.js.map → chunk-SJ4IAZ3V.js.map} +0 -0
- /package/dist/{chunk-FHWBOOS3.js.map → chunk-TH7RBREI.js.map} +0 -0
- /package/dist/{chunk-SA2ERYVV.js.map → chunk-VAO63IIP.js.map} +0 -0
- /package/dist/{chunk-RCJYLDXV.js.map → chunk-VJBTFWDK.js.map} +0 -0
- /package/dist/{chunk-LM2YOONY.js.map → chunk-XYHNXO6Q.js.map} +0 -0
- /package/dist/{chunk-FT7BNFGS.js.map → chunk-YK4ZG5Y4.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.sheet.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAMzC,OAAO,KAAK,EAAoC,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"SectionNav.sheet.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAMzC,OAAO,KAAK,EAAoC,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAqIpD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,aAAa,EACb,IAAI,EACJ,MAAM,EACN,YAAY,GACb,EAAE;IACD,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,WAAW,GAAG,SAAS,CAAC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,0GAA0G;IAC1G,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4CpB"}
|
|
@@ -1,21 +1,61 @@
|
|
|
1
1
|
import type { ElementType, ReactNode } from 'react';
|
|
2
2
|
import type { SectionNavCopy } from '../../../copy';
|
|
3
3
|
/**
|
|
4
|
-
* One
|
|
4
|
+
* One slot of the section — a bar slot on a phone, a row in the rail.
|
|
5
|
+
*
|
|
6
|
+
* A slot either LEADS somewhere (`href`, rendered through `linkComponent`) or
|
|
7
|
+
* DOES something (`onSelect`), the way a menu entry does. A bar of places is a
|
|
8
|
+
* section's navigation; a bar of verbs is a screen's actions pinned at its
|
|
9
|
+
* foot, and it is the same bar, so the two cannot be drawn two ways. Give a
|
|
10
|
+
* slot one or the other.
|
|
5
11
|
*/
|
|
6
12
|
export interface SectionNavDestination {
|
|
7
13
|
/** Stable key. Also the suffix of the slot's `data-testid`. */
|
|
8
14
|
id: string;
|
|
9
15
|
label: string;
|
|
10
16
|
icon: ReactNode;
|
|
11
|
-
href
|
|
17
|
+
href?: string;
|
|
18
|
+
/**
|
|
19
|
+
* What the slot does, for an action slot. Ignored while `disabled` or
|
|
20
|
+
* `loading`; still called while `dimmed`.
|
|
21
|
+
*/
|
|
22
|
+
onSelect?: () => void;
|
|
23
|
+
/**
|
|
24
|
+
* Drawn dimmed and not operable: the act exists here, and cannot be done
|
|
25
|
+
* now. A native `disabled` button — a tap does nothing, and `onSelect` is
|
|
26
|
+
* not called.
|
|
27
|
+
*/
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Drawn exactly like `disabled`, but still TAPPABLE: for an act the screen
|
|
31
|
+
* cannot do now and should EXPLAIN when tapped. It reports
|
|
32
|
+
* `aria-disabled="true"`, stays focusable, never lights up, and its
|
|
33
|
+
* `onSelect` still fires so the host can answer with a message (why not,
|
|
34
|
+
* and what would make it possible).
|
|
35
|
+
*/
|
|
36
|
+
dimmed?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* A write this slot started is in flight — a spinner replaces the icon, the
|
|
39
|
+
* slot reports `aria-busy` and `aria-disabled`, and a tap is ignored. It
|
|
40
|
+
* stays focusable, so the keyboard does not lose its place mid-write.
|
|
41
|
+
*/
|
|
42
|
+
loading?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The control's own `data-testid`, in place of the one the nav derives. For
|
|
45
|
+
* a host whose suites already drive an id of their own shape.
|
|
46
|
+
*/
|
|
47
|
+
dataTestId?: string;
|
|
12
48
|
/**
|
|
13
49
|
* How many things behind this destination wait on the viewer. `0` and
|
|
14
50
|
* `undefined` render no badge — "nothing waiting" and "not known yet" are
|
|
15
51
|
* different claims and neither is a number.
|
|
16
52
|
*/
|
|
17
53
|
badge?: number;
|
|
18
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* For a link: the destination the viewer is on (`aria-current="page"`). For
|
|
56
|
+
* an action slot: a toggle that is ON (`aria-pressed`). The host decides;
|
|
57
|
+
* the nav never reads the URL.
|
|
58
|
+
*/
|
|
19
59
|
active?: boolean;
|
|
20
60
|
}
|
|
21
61
|
/**
|
|
@@ -34,6 +74,13 @@ export interface SectionNavEntry {
|
|
|
34
74
|
onSelect?: () => void;
|
|
35
75
|
badge?: number;
|
|
36
76
|
active?: boolean;
|
|
77
|
+
/** Drawn dimmed and not operable — a print already on its way, an act this state refuses. */
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The control's own `data-testid`, in place of the one the nav derives. For
|
|
81
|
+
* a host whose suites already drive an id of their own shape.
|
|
82
|
+
*/
|
|
83
|
+
dataTestId?: string;
|
|
37
84
|
}
|
|
38
85
|
/** A titled run of entries inside a menu. */
|
|
39
86
|
export interface SectionNavGroup {
|
|
@@ -62,6 +109,32 @@ export interface SectionNavMenu {
|
|
|
62
109
|
/** The sheet's heading, and the rail section's. */
|
|
63
110
|
title: string;
|
|
64
111
|
groups: SectionNavGroup[];
|
|
112
|
+
/** The trigger is drawn dimmed and does not open; in the rail every row of it is inert. */
|
|
113
|
+
disabled?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* The control's own `data-testid`, in place of the one the nav derives. For
|
|
116
|
+
* a host whose suites already drive an id of their own shape.
|
|
117
|
+
*/
|
|
118
|
+
dataTestId?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The raised primary as a plain ACTION rather than a menu: one act, done on
|
|
122
|
+
* tap. Its label is drawn under the button, because a bar of verbs names the
|
|
123
|
+
* act it is for rather than leaving it to an icon.
|
|
124
|
+
*/
|
|
125
|
+
export interface SectionNavAction {
|
|
126
|
+
label: string;
|
|
127
|
+
icon: ReactNode;
|
|
128
|
+
onSelect: () => void;
|
|
129
|
+
/** A native `disabled` button: a tap does nothing. */
|
|
130
|
+
disabled?: boolean;
|
|
131
|
+
/** In flight: a spinner, `aria-busy`, `aria-disabled`; focusable, and a tap is ignored. */
|
|
132
|
+
loading?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* The control's own `data-testid`, in place of the one the nav derives. For
|
|
135
|
+
* a host whose suites already drive an id of their own shape.
|
|
136
|
+
*/
|
|
137
|
+
dataTestId?: string;
|
|
65
138
|
}
|
|
66
139
|
/** The way out of the section, drawn at the top of the rail. */
|
|
67
140
|
export interface SectionNavBack {
|
|
@@ -81,8 +154,11 @@ export interface SectionNavProps {
|
|
|
81
154
|
/** The navigation landmark's accessible name. */
|
|
82
155
|
label: string;
|
|
83
156
|
destinations: SectionNavDestination[];
|
|
84
|
-
/**
|
|
85
|
-
|
|
157
|
+
/**
|
|
158
|
+
* The raised button in the middle of the bar: a menu it opens as a sheet,
|
|
159
|
+
* or an action it does on tap (drawn with its label under it).
|
|
160
|
+
*/
|
|
161
|
+
primary?: SectionNavMenu | SectionNavAction;
|
|
86
162
|
/** The last slot of the bar. Its badge is the sum of its entries' badges. */
|
|
87
163
|
more?: SectionNavMenu;
|
|
88
164
|
/** Rail only: the way back out of the section. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionNav.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/navigation/SectionNav/SectionNav.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD
|
|
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,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { SectionNavDestination, SectionNavMenu } from '../SectionNav.types';
|
|
2
|
+
import type { SectionNavAction, SectionNavDestination, SectionNavMenu } from '../SectionNav.types';
|
|
3
3
|
/**
|
|
4
4
|
* The stories' example section, shared by the showcase and the interaction
|
|
5
5
|
* tests. Kept out of the `*.stories.tsx` files because Storybook reads every
|
|
@@ -17,4 +17,14 @@ export declare function PhoneFrame({ children }: {
|
|
|
17
17
|
export declare function RailFrame({ children }: {
|
|
18
18
|
children: React.ReactNode;
|
|
19
19
|
}): React.ReactElement;
|
|
20
|
+
/**
|
|
21
|
+
* A screen's ACTIONS pinned at its foot — the same bar, drawn with verbs: a
|
|
22
|
+
* bill being settled, one person at a time.
|
|
23
|
+
*
|
|
24
|
+
* `split` is DIMMED — it cannot be done yet, and a tap still reaches the host
|
|
25
|
+
* so it can say why. `equal` is a TOGGLE that is on: `aria-pressed`, never
|
|
26
|
+
* `aria-current`, because an action is not a page.
|
|
27
|
+
*/
|
|
28
|
+
export declare const ACTIONS: SectionNavDestination[];
|
|
29
|
+
export declare const PAY_ALL: SectionNavAction;
|
|
20
30
|
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../../../../src/components/navigation/SectionNav/__stories__/fixtures.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../../../../src/components/navigation/SectionNav/__stories__/fixtures.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnG;;;;GAIG;AAEH,8FAA8F;AAC9F,eAAO,MAAM,YAAY,EAAE,qBAAqB,EAI/C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,cA6BrB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,cAiBlB,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAoB1F;AAGD,iDAAiD;AACjD,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAEzF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,qBAAqB,EAI1C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,gBAIrB,CAAC"}
|
|
@@ -2,6 +2,6 @@ export { SectionNav } from './SectionNav';
|
|
|
2
2
|
export { sectionNavBarInset } from './SectionNav.bar';
|
|
3
3
|
export { RaisedActionButton } from './SectionNav.primary';
|
|
4
4
|
export type { RaisedActionButtonProps } from './SectionNav.primary';
|
|
5
|
-
export type { SectionNavBack, SectionNavDestination, SectionNavEntry, SectionNavGroup, SectionNavMenu, SectionNavProps, } from './SectionNav.types';
|
|
5
|
+
export type { SectionNavAction, SectionNavBack, SectionNavDestination, SectionNavEntry, SectionNavGroup, SectionNavMenu, SectionNavProps, } from './SectionNav.types';
|
|
6
6
|
export type { SectionNavCopy } from '../../../copy';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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,cAAc,EACd,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,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"density-overrides.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAQlF,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"density-overrides.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAQlF,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,6BAA6B,EAC7B,yBAAyB,EACzB,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AA4HtG,4DAA4D;AAC5D,wBAAgB,0BAA0B,IAAI,UAAU,CAAC,KAAK,CAAC,CAU9D;AA0CD,2FAA2F;AAC3F,wBAAgB,oBAAoB,IAAI,UAAU,CAAC,KAAK,CAAC,CAWxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"density-overrides.navigation.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.navigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;AA+ElF,8DAA8D;AAC9D,wBAAgB,4BAA4B,IAAI,UAAU,CAAC,KAAK,CAAC,CAUhE;AAYD,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI,UAAU,CAAC,KAAK,CAAC,CASvD;
|
|
1
|
+
{"version":3,"file":"density-overrides.navigation.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.navigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;AA+ElF,8DAA8D;AAC9D,wBAAgB,4BAA4B,IAAI,UAAU,CAAC,KAAK,CAAC,CAUhE;AAYD,iFAAiF;AACjF,wBAAgB,mBAAmB,IAAI,UAAU,CAAC,KAAK,CAAC,CASvD;AAiCD,oEAAoE;AACpE,wBAAgB,yBAAyB,IAAI,UAAU,CAAC,KAAK,CAAC,CAS7D;AA0BD;;;GAGG;AACH,wBAAgB,8BAA8B,IAAI,UAAU,CAAC,KAAK,CAAC,CAUlE;AAwBD,8FAA8F;AAC9F,wBAAgB,sBAAsB,IAAI,UAAU,CAAC,KAAK,CAAC,CAW1D;AAsBD,0DAA0D;AAC1D,wBAAgB,6BAA6B,IAAI,UAAU,CAAC,KAAK,CAAC,CAQjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"density-overrides.selection.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"density-overrides.selection.d.ts","sourceRoot":"","sources":["../../../src/tokens/density-overrides.selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAuIlF;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,UAAU,CAAC,KAAK,CAAC,CAKjE;AA8DD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,UAAU,CAAC,KAAK,CAAC,CAW1D"}
|
|
@@ -7,10 +7,10 @@ import "../chunk-KNWG77FB.js";
|
|
|
7
7
|
import "../chunk-TM5QQJTF.js";
|
|
8
8
|
import "../chunk-3IPPMWUA.js";
|
|
9
9
|
import "../chunk-7ZPUN7TV.js";
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-SJ4IAZ3V.js";
|
|
11
|
+
import "../chunk-25MSGLNU.js";
|
|
12
|
+
import "../chunk-GAXHYRX6.js";
|
|
13
|
+
import "../chunk-NP6SHLQ3.js";
|
|
14
14
|
import "../chunk-PT6TCWIW.js";
|
|
15
15
|
import "../chunk-2TZ6X265.js";
|
|
16
16
|
import "../chunk-7FDU3FIN.js";
|
package/package.json
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import Typography from '@mui/material/Typography/index.js';
|
|
2
|
-
import { useTheme } from '@mui/material/styles/index.js';
|
|
2
|
+
import { useTheme, type SxProps, type Theme } from '@mui/material/styles/index.js';
|
|
3
3
|
import { useState, type ElementType, type ReactNode } from 'react';
|
|
4
4
|
|
|
5
5
|
import type { SectionNavCopy } from '../../../copy';
|
|
6
6
|
import { rem } from '../../../tokens/scales';
|
|
7
7
|
|
|
8
|
-
import { barSlots, menuActive, menuCount, type BarSlot } from './SectionNav.helpers';
|
|
9
|
-
import {
|
|
8
|
+
import { barSlots, destinationState, isMenu, menuActive, menuCount, type BarSlot } from './SectionNav.helpers';
|
|
9
|
+
import {
|
|
10
|
+
Box,
|
|
11
|
+
CONTROL_RESET,
|
|
12
|
+
CountedIcon,
|
|
13
|
+
NOT_LIVE,
|
|
14
|
+
SlotIcon,
|
|
15
|
+
controlProps,
|
|
16
|
+
destinationControl,
|
|
17
|
+
focusRing,
|
|
18
|
+
} from './SectionNav.parts';
|
|
10
19
|
import { RaisedActionButton } from './SectionNav.primary';
|
|
11
20
|
import { SectionNavSheet } from './SectionNav.sheet';
|
|
12
|
-
import type { SectionNavMenu, SectionNavProps } from './SectionNav.types';
|
|
21
|
+
import type { SectionNavAction, SectionNavDestination, SectionNavMenu, SectionNavProps } from './SectionNav.types';
|
|
13
22
|
|
|
14
23
|
/** Which of the bar's two menus is open, if any. */
|
|
15
24
|
type OpenMenu = 'primary' | 'more' | null;
|
|
@@ -29,13 +38,17 @@ export function sectionNavBarInset(theme: Parameters<typeof rem>[0]): string {
|
|
|
29
38
|
/**
|
|
30
39
|
* One slot: icon over label, a count on the icon.
|
|
31
40
|
*
|
|
32
|
-
* `current` is the page the viewer is on and is what `aria-current` reports
|
|
33
|
-
*
|
|
34
|
-
*
|
|
41
|
+
* `current` is the page the viewer is on and is what `aria-current` reports —
|
|
42
|
+
* a link's claim only; an action slot that is ON says so with `aria-pressed`,
|
|
43
|
+
* which arrives in `control`. `lit` is only how the slot looks, and goes out
|
|
44
|
+
* while a sheet is open so the bar shows where the thumb is. Opening a sheet
|
|
45
|
+
* is `aria-expanded`'s to say.
|
|
35
46
|
*
|
|
36
|
-
* A destination is a link; the "more" slot is a button that
|
|
37
|
-
* Either way the whole slot is the target, so a thumb landing
|
|
38
|
-
* lands on the control.
|
|
47
|
+
* A destination is a link or an action; the "more" slot is a button that
|
|
48
|
+
* opens its sheet. Either way the whole slot is the target, so a thumb landing
|
|
49
|
+
* on the label lands on the control. A `disabled` slot is a disabled button,
|
|
50
|
+
* dimmed — the act is still where the hand expects it. A `loading` or
|
|
51
|
+
* `dimmed` slot is drawn the same and stays focusable (`aria-disabled`).
|
|
39
52
|
*/
|
|
40
53
|
function Slot({
|
|
41
54
|
label,
|
|
@@ -47,6 +60,7 @@ function Slot({
|
|
|
47
60
|
testId,
|
|
48
61
|
control,
|
|
49
62
|
expanded,
|
|
63
|
+
loading = false,
|
|
50
64
|
}: {
|
|
51
65
|
label: string;
|
|
52
66
|
icon: ReactNode;
|
|
@@ -57,6 +71,7 @@ function Slot({
|
|
|
57
71
|
testId: string;
|
|
58
72
|
control: Record<string, unknown>;
|
|
59
73
|
expanded?: boolean;
|
|
74
|
+
loading?: boolean;
|
|
60
75
|
}): React.JSX.Element {
|
|
61
76
|
const theme = useTheme();
|
|
62
77
|
return (
|
|
@@ -64,36 +79,17 @@ function Slot({
|
|
|
64
79
|
{...control}
|
|
65
80
|
aria-current={current ? 'page' : undefined}
|
|
66
81
|
aria-expanded={expanded}
|
|
82
|
+
aria-busy={loading || undefined}
|
|
67
83
|
data-lit={lit ? 'true' : undefined}
|
|
68
84
|
data-testid={testId}
|
|
69
|
-
sx={
|
|
70
|
-
...CONTROL_RESET,
|
|
71
|
-
...focusRing(theme),
|
|
72
|
-
flex: 1,
|
|
73
|
-
minWidth: 0,
|
|
74
|
-
display: 'flex',
|
|
75
|
-
flexDirection: 'column',
|
|
76
|
-
alignItems: 'center',
|
|
77
|
-
justifyContent: 'center',
|
|
78
|
-
gap: 0.25,
|
|
79
|
-
position: 'relative',
|
|
80
|
-
color: lit ? 'primary.main' : 'text.secondary',
|
|
81
|
-
// The current slot is marked by more than its colour: a short rule on
|
|
82
|
-
// its top edge, so the state survives a colour-blind reading.
|
|
83
|
-
'&[data-lit="true"]::before': {
|
|
84
|
-
content: '""',
|
|
85
|
-
position: 'absolute',
|
|
86
|
-
top: 0,
|
|
87
|
-
insetInline: '22%',
|
|
88
|
-
height: rem(theme, 3),
|
|
89
|
-
borderBottomLeftRadius: rem(theme, 3),
|
|
90
|
-
borderBottomRightRadius: rem(theme, 3),
|
|
91
|
-
bgcolor: 'primary.main',
|
|
92
|
-
},
|
|
93
|
-
'& svg': { fontSize: rem(theme, 22) },
|
|
94
|
-
}}
|
|
85
|
+
sx={slotSx(theme, lit)}
|
|
95
86
|
>
|
|
96
|
-
<CountedIcon
|
|
87
|
+
<CountedIcon
|
|
88
|
+
icon={<SlotIcon icon={icon} loading={loading} />}
|
|
89
|
+
count={count}
|
|
90
|
+
label={copy.badge}
|
|
91
|
+
testId={`${testId}-badge`}
|
|
92
|
+
/>
|
|
97
93
|
<Typography
|
|
98
94
|
component="span"
|
|
99
95
|
variant="caption"
|
|
@@ -112,71 +108,152 @@ function Slot({
|
|
|
112
108
|
);
|
|
113
109
|
}
|
|
114
110
|
|
|
115
|
-
/**
|
|
116
|
-
function
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
111
|
+
/** A slot's look: icon over label, the lit rule on its top edge, dimmed when disabled. */
|
|
112
|
+
function slotSx(theme: Theme, lit: boolean): SxProps<Theme> {
|
|
113
|
+
return {
|
|
114
|
+
...CONTROL_RESET,
|
|
115
|
+
...focusRing(theme),
|
|
116
|
+
flex: 1,
|
|
117
|
+
minWidth: 0,
|
|
118
|
+
display: 'flex',
|
|
119
|
+
flexDirection: 'column',
|
|
120
|
+
alignItems: 'center',
|
|
121
|
+
justifyContent: 'center',
|
|
122
|
+
gap: 0.25,
|
|
123
|
+
position: 'relative',
|
|
124
|
+
color: lit ? 'primary.main' : 'text.secondary',
|
|
125
|
+
// The current slot is marked by more than its colour: a short rule on
|
|
126
|
+
// its top edge, so the state survives a colour-blind reading.
|
|
127
|
+
'&[data-lit="true"]::before': {
|
|
128
|
+
content: '""',
|
|
129
|
+
position: 'absolute',
|
|
130
|
+
top: 0,
|
|
131
|
+
insetInline: '22%',
|
|
132
|
+
height: rem(theme, 3),
|
|
133
|
+
borderBottomLeftRadius: rem(theme, 3),
|
|
134
|
+
borderBottomRightRadius: rem(theme, 3),
|
|
135
|
+
bgcolor: 'primary.main',
|
|
136
|
+
},
|
|
137
|
+
'& svg': { fontSize: rem(theme, 22) },
|
|
138
|
+
[NOT_LIVE]: { color: 'text.disabled' },
|
|
139
|
+
} as SxProps<Theme>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** What every slot kind is handed: the bar's open state and how to change it. */
|
|
143
|
+
interface SlotContext {
|
|
130
144
|
open: OpenMenu;
|
|
131
145
|
toggle: (menu: Exclude<OpenMenu, null>) => void;
|
|
132
146
|
close: () => void;
|
|
133
147
|
linkComponent: ElementType | undefined;
|
|
134
148
|
copy: SectionNavCopy;
|
|
135
149
|
dataTestId: string;
|
|
136
|
-
}
|
|
137
|
-
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** The raised button: an action runs on tap; a menu opens its sheet. */
|
|
153
|
+
function PrimarySlot({
|
|
154
|
+
primary,
|
|
155
|
+
context,
|
|
156
|
+
}: {
|
|
157
|
+
primary: SectionNavMenu | SectionNavAction;
|
|
158
|
+
context: SlotContext;
|
|
159
|
+
}): React.JSX.Element {
|
|
160
|
+
const testId = primary.dataTestId ?? `${context.dataTestId}-primary`;
|
|
161
|
+
if (!isMenu(primary)) {
|
|
138
162
|
return (
|
|
139
163
|
<RaisedActionButton
|
|
140
164
|
label={primary.label}
|
|
141
165
|
icon={primary.icon}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<Slot
|
|
152
|
-
label={more.label}
|
|
153
|
-
icon={more.icon}
|
|
154
|
-
count={menuCount(more)}
|
|
155
|
-
current={false}
|
|
156
|
-
lit={open === 'more' || (open === null && menuActive(more))}
|
|
157
|
-
expanded={open === 'more'}
|
|
158
|
-
copy={copy}
|
|
159
|
-
testId={`${dataTestId}-more`}
|
|
160
|
-
control={controlProps({ href: undefined, linkComponent, onClick: () => toggle('more') })}
|
|
166
|
+
captioned
|
|
167
|
+
disabled={primary.disabled}
|
|
168
|
+
loading={primary.loading}
|
|
169
|
+
dataTestId={testId}
|
|
170
|
+
onClick={() => {
|
|
171
|
+
context.close();
|
|
172
|
+
primary.onSelect();
|
|
173
|
+
}}
|
|
161
174
|
/>
|
|
162
175
|
);
|
|
163
176
|
}
|
|
164
|
-
|
|
165
|
-
|
|
177
|
+
return (
|
|
178
|
+
<RaisedActionButton
|
|
179
|
+
label={primary.label}
|
|
180
|
+
icon={primary.icon}
|
|
181
|
+
open={context.open === 'primary'}
|
|
182
|
+
closeLabel={context.copy.close}
|
|
183
|
+
disabled={primary.disabled}
|
|
184
|
+
dataTestId={testId}
|
|
185
|
+
onClick={() => context.toggle('primary')}
|
|
186
|
+
/>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** The "more" slot: a button that opens its sheet, carrying its entries' counts. */
|
|
191
|
+
function MoreSlot({ more, context }: { more: SectionNavMenu; context: SlotContext }): React.JSX.Element {
|
|
192
|
+
const { open } = context;
|
|
193
|
+
return (
|
|
194
|
+
<Slot
|
|
195
|
+
label={more.label}
|
|
196
|
+
icon={more.icon}
|
|
197
|
+
count={menuCount(more)}
|
|
198
|
+
current={false}
|
|
199
|
+
lit={open === 'more' || (open === null && menuActive(more))}
|
|
200
|
+
expanded={open === 'more'}
|
|
201
|
+
copy={context.copy}
|
|
202
|
+
testId={more.dataTestId ?? `${context.dataTestId}-more`}
|
|
203
|
+
control={controlProps({
|
|
204
|
+
href: undefined,
|
|
205
|
+
linkComponent: context.linkComponent,
|
|
206
|
+
inert: more.disabled === true,
|
|
207
|
+
onClick: () => context.toggle('more'),
|
|
208
|
+
})}
|
|
209
|
+
/>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** A destination: a link, or an action slot (a toggle when it carries `active`). */
|
|
214
|
+
function DestinationSlot({
|
|
215
|
+
destination,
|
|
216
|
+
context,
|
|
217
|
+
}: {
|
|
218
|
+
destination: SectionNavDestination;
|
|
219
|
+
context: SlotContext;
|
|
220
|
+
}): React.JSX.Element {
|
|
221
|
+
const { current, lit } = destinationState(destination);
|
|
166
222
|
return (
|
|
167
223
|
<Slot
|
|
168
224
|
label={destination.label}
|
|
169
225
|
icon={destination.icon}
|
|
170
226
|
count={destination.badge}
|
|
171
|
-
current={
|
|
172
|
-
lit={open === null &&
|
|
173
|
-
copy={copy}
|
|
174
|
-
testId={`${dataTestId}-dest-${destination.id}`}
|
|
175
|
-
|
|
227
|
+
current={current}
|
|
228
|
+
lit={context.open === null && lit}
|
|
229
|
+
copy={context.copy}
|
|
230
|
+
testId={destination.dataTestId ?? `${context.dataTestId}-dest-${destination.id}`}
|
|
231
|
+
loading={destination.loading === true}
|
|
232
|
+
control={destinationControl(destination, context.linkComponent, () => {
|
|
233
|
+
context.close();
|
|
234
|
+
destination.onSelect?.();
|
|
235
|
+
})}
|
|
176
236
|
/>
|
|
177
237
|
);
|
|
178
238
|
}
|
|
179
239
|
|
|
240
|
+
/** One slot of the bar, whichever kind it is. */
|
|
241
|
+
function BarSlotView({
|
|
242
|
+
slot,
|
|
243
|
+
primary,
|
|
244
|
+
more,
|
|
245
|
+
context,
|
|
246
|
+
}: {
|
|
247
|
+
slot: BarSlot;
|
|
248
|
+
primary: SectionNavMenu | SectionNavAction | undefined;
|
|
249
|
+
more: SectionNavMenu | undefined;
|
|
250
|
+
context: SlotContext;
|
|
251
|
+
}): React.JSX.Element | null {
|
|
252
|
+
if (slot.kind === 'primary') return primary ? <PrimarySlot primary={primary} context={context} /> : null;
|
|
253
|
+
if (slot.kind === 'more') return more ? <MoreSlot more={more} context={context} /> : null;
|
|
254
|
+
return <DestinationSlot destination={slot.destination} context={context} />;
|
|
255
|
+
}
|
|
256
|
+
|
|
180
257
|
/** The phone layout: a bottom bar, with its menus as bottom sheets. */
|
|
181
258
|
export function SectionNavBar({
|
|
182
259
|
label,
|
|
@@ -188,6 +265,7 @@ export function SectionNavBar({
|
|
|
188
265
|
dataTestId,
|
|
189
266
|
}: Required<Pick<SectionNavProps, 'label' | 'destinations' | 'copy' | 'dataTestId'>> &
|
|
190
267
|
Pick<SectionNavProps, 'primary' | 'more'> & { linkComponent: ElementType | undefined }): React.JSX.Element {
|
|
268
|
+
const sheetMenu = isMenu(primary) ? primary : undefined;
|
|
191
269
|
const theme = useTheme();
|
|
192
270
|
const [open, setOpen] = useState<OpenMenu>(null);
|
|
193
271
|
const toggle = (menu: Exclude<OpenMenu, null>): void => setOpen((current) => (current === menu ? null : menu));
|
|
@@ -222,18 +300,13 @@ export function SectionNavBar({
|
|
|
222
300
|
slot={slot}
|
|
223
301
|
primary={primary}
|
|
224
302
|
more={more}
|
|
225
|
-
|
|
226
|
-
toggle={toggle}
|
|
227
|
-
close={close}
|
|
228
|
-
linkComponent={linkComponent}
|
|
229
|
-
copy={copy}
|
|
230
|
-
dataTestId={dataTestId}
|
|
303
|
+
context={{ open, toggle, close, linkComponent, copy, dataTestId }}
|
|
231
304
|
/>
|
|
232
305
|
))}
|
|
233
306
|
</Box>
|
|
234
|
-
{
|
|
307
|
+
{sheetMenu ? (
|
|
235
308
|
<SectionNavSheet
|
|
236
|
-
menu={
|
|
309
|
+
menu={sheetMenu}
|
|
237
310
|
open={open === 'primary'}
|
|
238
311
|
onClose={close}
|
|
239
312
|
linkComponent={linkComponent}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SectionNavDestination, SectionNavMenu } from './SectionNav.types';
|
|
1
|
+
import type { SectionNavAction, SectionNavDestination, SectionNavMenu } from './SectionNav.types';
|
|
2
2
|
|
|
3
3
|
/** A count worth drawing: positive and finite. Zero and "unknown" draw nothing. */
|
|
4
4
|
export function shownCount(count: number | undefined): number | undefined {
|
|
@@ -49,3 +49,18 @@ export function barSlots(
|
|
|
49
49
|
if (hasPrimary) slots.splice(Math.floor(slots.length / 2), 0, { kind: 'primary' });
|
|
50
50
|
return slots;
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
/** A primary that opens a sheet, as opposed to one that acts on tap. */
|
|
54
|
+
export function isMenu(primary: SectionNavMenu | SectionNavAction | undefined): primary is SectionNavMenu {
|
|
55
|
+
return primary !== undefined && 'groups' in primary;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* How a destination reads. `current` is `aria-current="page"` and belongs to a
|
|
60
|
+
* LINK only — an action slot that is ON reports `aria-pressed` instead. `lit`
|
|
61
|
+
* is the look, and a `dimmed` slot is never lit: it says "not now".
|
|
62
|
+
*/
|
|
63
|
+
export function destinationState(destination: SectionNavDestination): { current: boolean; lit: boolean } {
|
|
64
|
+
const active = destination.active === true;
|
|
65
|
+
return { current: active && destination.href !== undefined, lit: active && destination.dimmed !== true };
|
|
66
|
+
}
|