@pnx-mixtape/mxds 0.1.0-rc.5 → 0.1.0-rc.6
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/DESIGN.md +1 -1
- package/README.md +1 -1
- package/dist/build/accordion.entry.js +1 -1
- package/dist/build/base.css +1 -1
- package/dist/build/chunks/{Accordion-D2wp8hBG.js → Accordion-Bqe8vTNR.js} +1 -1
- package/dist/build/chunks/{AccordionMobile-D3sTeiM5.js → AccordionMobile-D517oXYZ.js} +1 -1
- package/dist/build/chunks/{ClosableAlert-yy84gae6.js → ClosableAlert-CZ114JsL.js} +1 -1
- package/dist/build/chunks/{Dialog-DWoXW-7Z.js → Dialog-DoYcGqhW.js} +1 -1
- package/dist/build/chunks/{FeedbackForm-BochXEDx.js → FeedbackForm-BsL7fv8s.js} +1 -1
- package/dist/build/chunks/{Gallery-Rkfv7Mbb.js → Gallery-DqJPujX5.js} +2 -2
- package/dist/build/chunks/{GlobalToggle-CzlkpLpc.js → GlobalToggle-7H3F1Wvc.js} +1 -1
- package/dist/build/chunks/{InPageNavigation-D1Kk-rCm.js → InPageNavigation-D7m3IN89.js} +1 -1
- package/dist/build/chunks/{Navigation-CDQnN61h.js → Navigation-CRModT40.js} +13 -18
- package/dist/build/chunks/{Sticky-DoVndENm.js → Sticky-C1H8MNqK.js} +1 -1
- package/dist/build/chunks/{Tabs-BDlxCDNh.js → Tabs-BJD3kABL.js} +1 -1
- package/dist/build/chunks/{Translate-bmM38j6z.js → Translate-yAgySwet.js} +1 -1
- package/dist/build/chunks/{utilities-Dd-08SW6.js → utilities-B9mNRs7V.js} +1 -1
- package/dist/build/dialog.entry.js +1 -1
- package/dist/build/elements.js +13 -13
- package/dist/build/feedback-form.entry.js +1 -1
- package/dist/build/filters.entry.js +3 -3
- package/dist/build/form.css +1 -1
- package/dist/build/gallery.entry.js +1 -1
- package/dist/build/global-alert.entry.js +1 -1
- package/dist/build/header.entry.js +1 -1
- package/dist/build/in-page-navigation.entry.js +1 -1
- package/dist/build/navigation.css +1 -1
- package/dist/build/navigation.entry.js +1 -1
- package/dist/build/react.js +230 -209
- package/dist/build/side-navigation.css +1 -1
- package/dist/build/sidebar.css +1 -1
- package/dist/build/sticky.entry.js +1 -1
- package/dist/build/tabs.entry.js +1 -1
- package/dist/build/translate.entry.js +1 -1
- package/dist/types/Component/Navigation/Elements/Navigation.d.ts +2 -3
- package/dist/types/Component/Navigation/Elements/Navigation.d.ts.map +1 -1
- package/dist/types/Component/SideNavigation/Components/SideNavigationTree.d.ts +3 -3
- package/dist/types/Component/SideNavigation/Components/SideNavigationTree.d.ts.map +1 -1
- package/dist/types/Component/SideNavigation/SideNavigation.d.ts +3 -1
- package/dist/types/Component/SideNavigation/SideNavigation.d.ts.map +1 -1
- package/dist/types/tokens.d.ts +1 -0
- package/dist/types/tokens.d.ts.map +1 -1
- package/docs/CSSGuidelines.md +2 -0
- package/package.json +5 -5
- package/src/Atom/Link/_links.css +1 -0
- package/src/Component/Navigation/Elements/Navigation.ts +25 -29
- package/src/Component/Navigation/README.md +11 -10
- package/src/Component/Navigation/__snapshots__/Navigation.stories.ts.snap +8 -8
- package/src/Component/Navigation/_navigation-dropdown.css +9 -11
- package/src/Component/Navigation/_navigation-mega.css +5 -11
- package/src/Component/Navigation/_navigation.css +5 -3
- package/src/Component/Navigation/menu.twig +1 -1
- package/src/Component/Navigation/navigation.twig +0 -1
- package/src/Component/SideNavigation/Components/SideNavigationTree.tsx +68 -24
- package/src/Component/SideNavigation/README.md +78 -32
- package/src/Component/SideNavigation/SideNavigation.stories.ts +41 -2
- package/src/Component/SideNavigation/SideNavigation.stories.tsx +31 -0
- package/src/Component/SideNavigation/SideNavigation.tsx +13 -3
- package/src/Component/SideNavigation/__snapshots__/SideNavigation.stories.ts.snap +87 -3
- package/src/Component/SideNavigation/__snapshots__/SideNavigation.stories.tsx.snap +2 -0
- package/src/Component/SideNavigation/side-navigation.css +3 -3
- package/src/Component/SideNavigation/side-navigation.twig +10 -3
- package/src/Component/Translate/README.md +4 -2
- package/src/Component/Translate/Translate.stories.ts +2 -2
- package/src/Component/Translate/Translate.stories.tsx +2 -2
- package/src/Component/Translate/Translate.tsx +1 -1
- package/src/Component/Translate/__snapshots__/Translate.stories.ts.snap +1 -1
- package/src/Component/Translate/__snapshots__/Translate.stories.tsx.snap +1 -1
- package/src/Component/Translate/translate.twig +1 -1
- package/src/Form/form.css +17 -19
- package/src/Introduction.mdx +1 -1
- package/src/Layout/Footer/__snapshots__/Footer.stories.ts.snap +3 -3
- package/src/Layout/Header/__snapshots__/Header.stories.ts.snap +6 -6
- package/src/Layout/Sidebar/sidebar.css +10 -3
- package/src/Utility/Elements/google-translate-widget.ts +1 -1
- package/src/_custom-media.css +2 -0
- package/src/tokens.js +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer popover-polyfill,design-system.defaults,design-system.atoms,design-system.layout,design-system.utilities;@layer design-system.components{.mx-side-nav__parent{border-block-end:var(--line-width,2px) solid var(--line-colour,currentcolor);& a{color:inherit;padding:var(--item-spacing,var(--spacing-xxs));font-weight:var(--font-weight-bold);text-decoration-line:none;display:block;&:hover{text-decoration-line:underline}}}.mx-side-nav{--outline-offset:-1px;& ul li{position:relative;&:has([aria-current=page],.is-active)>a{font-weight:var(--font-weight-bold)}& a{color:inherit;border-block-end:var(--line-width,1px) solid var(--line-colour,var(--colour-border));padding-block:var(--item-spacing,var(--spacing-xxs));padding-inline:var(--indent,var(--spacing-xxs)) var(--item-spacing,var(--spacing-xxs));display:block}}& .mx-nav__level-2>li>a{--indent:var(--spacing-s);@media (width>=720px){--indent:var(--spacing-m)}}& .mx-nav__level-3>li>a{--indent:var(--spacing-m);@media (width>=720px){--indent:var(--spacing-l)}}& :is([aria-current=page],.is-active>a){background-color:var(--nav-active-background,var(--background,var(--colour-background-alt)));color:var(--nav-active-foreground,inherit)}
|
|
1
|
+
@layer popover-polyfill,design-system.defaults,design-system.atoms,design-system.layout,design-system.utilities;@layer design-system.components{.mx-side-nav__parent{border-block-end:var(--line-width,2px) solid var(--line-colour,currentcolor);& a{color:inherit;padding:var(--item-spacing,var(--spacing-xxs));font-weight:var(--font-weight-bold);text-decoration-line:none;display:block;&:hover{text-decoration-line:underline}}}.mx-side-nav{--outline-offset:-1px;& ul li{position:relative;&:has([aria-current=page],.is-active)>a{font-weight:var(--font-weight-bold)}& a{color:inherit;border-block-end:var(--line-width,1px) solid var(--line-colour,var(--colour-border));padding-block:var(--item-spacing,var(--spacing-xxs));padding-inline:var(--indent,var(--spacing-xxs)) var(--item-spacing,var(--spacing-xxs));display:block}}& .mx-nav__level-2>li>a{--indent:var(--spacing-s);@media (width>=720px){--indent:var(--spacing-m)}}& .mx-nav__level-3>li>a{--indent:var(--spacing-m);@media (width>=720px){--indent:var(--spacing-l)}}& :is([aria-current=page],.is-active>a){background-color:var(--nav-active-background,var(--background,var(--colour-background-alt)));color:var(--nav-active-foreground,inherit)}&:not(.mx-nav--collapsible) .mx-nav__toggle{display:none}}}
|
package/dist/build/sidebar.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer popover-polyfill,design-system.defaults,design-system.atoms,design-system.layout,design-system.utilities,design-system.components;@layer design-system.layouts{.mx-grid--sidebar{&:where(:not(:has(>aside))){grid-column:narrow}&:where(:has(>aside)){flex-flow:var(--sidebar-direction,column) wrap;gap:var(--sidebar-gap,var(--gap));justify-content:space-between;display:flex;@media (width>=720px){--sidebar-direction:row}&>aside{flex-grow:1;align-content:start;@media (width>=720px){max-inline-size:var(--sidebar-width,24ch)}}&>section{min-inline-size:var(--content-min,50%);max-inline-size:var(--container-max-width,76ch);flex-grow:999;flex-basis:0;& .mx-grid{--grid-min:18ch}}&.mx-grid--sidebar-rev{@media (width>=720px){--sidebar-direction:row-reverse}}&.mx-grid--sidebar-rev-lg{@media (width>=946px){--sidebar-direction:row-reverse}}}}}
|
|
1
|
+
@layer popover-polyfill,design-system.defaults,design-system.atoms,design-system.layout,design-system.utilities,design-system.components;@layer design-system.layouts{.mx-grid--sidebar{&:where(:not(:has(>aside))){grid-column:narrow}&:where(:has(>aside)){flex-flow:var(--sidebar-direction,column) wrap;gap:var(--sidebar-gap,var(--gap));justify-content:space-between;align-items:start;display:flex;@media (width>=720px){--sidebar-direction:row}&>aside{inline-size:100%;border-block-start:var(--line-width,6px) solid var(--line-colour,var(--colour-primary));flex-grow:1;align-content:start;padding-block-start:var(--line-gap,var(--gap));@media (width>=720px){max-inline-size:var(--sidebar-width,24ch);border-block-start:unset;padding-block-start:unset}}&>section{min-inline-size:var(--content-min,50%);inline-size:100%;max-inline-size:var(--container-max-width,76ch);flex-grow:999;flex-basis:0;& .mx-grid{--grid-min:18ch}}&.mx-grid--sidebar-rev{@media (width>=720px){--sidebar-direction:row-reverse}}&.mx-grid--sidebar-rev-lg{@media (width>=946px){--sidebar-direction:row-reverse}}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./chunks/Sticky-
|
|
1
|
+
import "./chunks/Sticky-C1H8MNqK.js";
|
package/dist/build/tabs.entry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./chunks/Tabs-
|
|
1
|
+
import "./chunks/Tabs-BJD3kABL.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./chunks/Translate-
|
|
1
|
+
import "./chunks/Translate-yAgySwet.js";
|
|
@@ -17,17 +17,16 @@ export default class Navigation extends HTMLElement {
|
|
|
17
17
|
keyboard: Keyboard;
|
|
18
18
|
subNavs?: Map<string, SubNavType>;
|
|
19
19
|
flyout?: boolean;
|
|
20
|
-
|
|
20
|
+
openActive: boolean;
|
|
21
21
|
mq: string;
|
|
22
|
-
iO?: IntersectionObserver;
|
|
23
22
|
constructor();
|
|
24
23
|
connectedCallback(): void;
|
|
25
24
|
disconnectedCallback(): void;
|
|
26
25
|
handleDisclosure: ({ detail }: CustomEvent<DisclosureWidgetEvent>) => void;
|
|
27
26
|
handleCloseAny: () => void;
|
|
27
|
+
handleOpenActive: () => void;
|
|
28
28
|
handleFlyout: (event: MouseEvent) => void;
|
|
29
29
|
handleBreakpoint: ({ matches }: MediaQueryList | MediaQueryListEvent) => void;
|
|
30
|
-
handleEdgeCheck(): void;
|
|
31
30
|
get links(): NodeListOf<HTMLAnchorElement> | null;
|
|
32
31
|
get lists(): NodeListOf<HTMLUListElement> | null;
|
|
33
32
|
get breakpoint(): MediaQueryList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Navigation.d.ts","sourceRoot":"","sources":["../../../../../src/Component/Navigation/Elements/Navigation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,QAAQ,EAER,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,4BAA4B,CAAA;AAEnC,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,UAAU,EAAE,gBAAgB,CAAA;IAC5B,UAAU,EAAE,eAAe,CAAA;IAC3B,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,
|
|
1
|
+
{"version":3,"file":"Navigation.d.ts","sourceRoot":"","sources":["../../../../../src/Component/Navigation/Elements/Navigation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,QAAQ,EAER,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,4BAA4B,CAAA;AAEnC,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAA;CAC9B,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,WAAW;IACjD,UAAU,EAAE,gBAAgB,CAAA;IAC5B,UAAU,EAAE,eAAe,CAAA;IAC3B,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,EAAG,OAAO,CAAA;IACpB,EAAE,EAAG,MAAM,CAAA;IAEX,cAIC;IAED,iBAAiB,IAAI,IAAI,CA6CxB;IAED,oBAAoB,IAAI,IAAI,CAG3B;IAED,gBAAgB,eAAgB,WAAW,CAAC,qBAAqB,CAAC,KAAG,IAAI,CASxE;IAED,cAAc,QAAO,IAAI,CAKxB;IAED,gBAAgB,QAAO,IAAI,CAU1B;IAED,YAAY,UAAW,UAAU,KAAG,IAAI,CAWvC;IAED,gBAAgB,gBAAiB,cAAc,GAAG,mBAAmB,KAAG,IAAI,CAS3E;IAED,IAAI,KAAK,IAAI,UAAU,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAMhD;IAED,IAAI,KAAK,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAE/C;IAED,IAAI,UAAU,IAAI,cAAc,CAE/B;CACF;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,QAAQ,EAAE,UAAU,CAAA;KACrB;CACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { JSX } from "react";
|
|
1
|
+
import { JSX, ComponentPropsWithoutRef } from "react";
|
|
2
2
|
import { MenuTree } from "@pnx-mixtape/ids-shape";
|
|
3
|
-
type SideNavigationTreeProps = {
|
|
3
|
+
type SideNavigationTreeProps = ComponentPropsWithoutRef<"ul"> & {
|
|
4
4
|
items: MenuTree[];
|
|
5
5
|
level?: number;
|
|
6
6
|
};
|
|
7
|
-
declare const SideNavigationTree: ({ items, level }: SideNavigationTreeProps) => JSX.Element;
|
|
7
|
+
declare const SideNavigationTree: ({ items, level, ...props }: SideNavigationTreeProps) => JSX.Element;
|
|
8
8
|
export default SideNavigationTree;
|
|
9
9
|
//# sourceMappingURL=SideNavigationTree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SideNavigationTree.d.ts","sourceRoot":"","sources":["../../../../../src/Component/SideNavigation/Components/SideNavigationTree.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"SideNavigationTree.d.ts","sourceRoot":"","sources":["../../../../../src/Component/SideNavigation/Components/SideNavigationTree.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,wBAAwB,EAAqB,MAAM,OAAO,CAAA;AAExE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAIjD,KAAK,uBAAuB,GAAG,wBAAwB,CAAC,IAAI,CAAC,GAAG;IAC9D,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AA2DD,QAAA,MAAM,kBAAkB,+BAIrB,uBAAuB,KAAG,GAAG,CAAC,OAQhC,CAAA;eACc,kBAAkB"}
|
|
@@ -3,8 +3,10 @@ type SideNavigationProps = PropsWithChildren & {
|
|
|
3
3
|
parent?: ReactNode;
|
|
4
4
|
title?: string;
|
|
5
5
|
id?: string;
|
|
6
|
+
collapsible?: boolean;
|
|
6
7
|
className?: string;
|
|
7
8
|
};
|
|
8
|
-
declare const
|
|
9
|
+
export declare const SideNavigationContext: import("react").Context<boolean>;
|
|
10
|
+
declare const SideNavigation: ({ children, parent, title, id, collapsible, className, }: SideNavigationProps) => JSX.Element;
|
|
9
11
|
export default SideNavigation;
|
|
10
12
|
//# sourceMappingURL=SideNavigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SideNavigation.d.ts","sourceRoot":"","sources":["../../../../src/Component/SideNavigation/SideNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"SideNavigation.d.ts","sourceRoot":"","sources":["../../../../src/Component/SideNavigation/SideNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,iBAAiB,EAAwB,MAAM,OAAO,CAAA;AAG/E,KAAK,mBAAmB,GAAG,iBAAiB,GAAG;IAC7C,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAGD,eAAO,MAAM,qBAAqB,kCAAgC,CAAA;AAElE,QAAA,MAAM,cAAc,6DAOjB,mBAAmB,KAAG,GAAG,CAAC,OAoB5B,CAAA;eAEc,cAAc"}
|
package/dist/types/tokens.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/tokens.js"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM;IACjB,IAAI;QACF,KAAK;QACL,IAAI;QACJ,GAAG;QACH,EAAE;QACF,CAAC;QACD,CAAC;QACD,CAAC;QACD,EAAE;QACF,GAAG;QACH,IAAI;QACJ,KAAK;QACL,EAAE;QACF,GAAG;QACH,IAAI;;IAEN,UAAU;QACR,WAAW;QACX,WAAW;QACX,UAAU;QACV,UAAU;QACV,aAAa;QACb,eAAe;QACf,YAAY;QACZ,WAAW;;IAEb,MAAM;QACJ,OAAO;QACP,MAAM;;CAET,CAAA;;IAGC,UAAU;QACR,GAAG;QACH,EAAE;QACF,CAAC;QACD,CAAC;QACD,CAAC;QACD,EAAE;QACF,SAAS;QACT,WAAW;QACX,aAAa;QACb,QAAQ;;
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/tokens.js"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM;IACjB,IAAI;QACF,KAAK;QACL,IAAI;QACJ,GAAG;QACH,EAAE;QACF,CAAC;QACD,CAAC;QACD,CAAC;QACD,EAAE;QACF,GAAG;QACH,IAAI;QACJ,KAAK;QACL,EAAE;QACF,GAAG;QACH,IAAI;;IAEN,UAAU;QACR,WAAW;QACX,WAAW;QACX,UAAU;QACV,UAAU;QACV,aAAa;QACb,eAAe;QACf,YAAY;QACZ,WAAW;;IAEb,MAAM;QACJ,OAAO;QACP,MAAM;;CAET,CAAA;;IAGC,UAAU;QACR,GAAG;QACH,EAAE;QACF,CAAC;QACD,CAAC;QACD,CAAC;QACD,EAAE;QACF,SAAS;QACT,WAAW;QACX,aAAa;QACb,QAAQ;QACR,OAAO;;IAET,MAAM;QACJ,OAAO;YACL,MAAM;YACN,MAAM;;QAER,MAAM;YACJ,MAAM;YACN,MAAM;;QAER,IAAI;YACF,EAAE;YACF,EAAE;YACF,KAAK;YACL,KAAK;YACL,MAAM;YACN,IAAI;YACJ,MAAM;;QAER,OAAO;YACL,EAAE;YACF,EAAE;YACF,KAAK;YACL,KAAK;YACL,MAAM;YACN,IAAI;YACJ,MAAM;;QAER,IAAI;QACJ,OAAO;QACP,OAAO;QACP,KAAK;;IAEP,IAAI;QACF,MAAM;QACN,UAAU;YACR,IAAI;YACJ,OAAO;YACP,EAAE;;QAEJ,MAAM;YACJ,IAAI;YACJ,IAAI;;QAEN,IAAI;YACF,UAAU;YACV,KAAK;YACL,MAAM;YACN,IAAI;;;IAGR,IAAI;QACF,OAAO;YACL,KAAK;YACL,IAAI;YACJ,GAAG;YACH,EAAE;YACF,CAAC;YACD,CAAC;YACD,CAAC;YACD,EAAE;YACF,GAAG;YACH,IAAI;YACJ,KAAK;YACL,EAAE;YACF,GAAG;YACH,IAAI;;QAEN,GAAG;YACD,CAAC;YACD,CAAC;YACD,CAAC;YACD,EAAE;;QAEJ,SAAS;YACP,IAAI;YACJ,KAAK;YACL,OAAO;YACP,MAAM;YACN,SAAS;YACT,SAAS;;;IAGb,OAAO;QACL,OAAO;YACL,KAAK;YACL,KAAK;YACL,MAAM;;QAER,MAAM;YACJ,CAAC;YACD,CAAC;YACD,KAAK;;QAEP,MAAM;YACJ,MAAM;YACN,IAAI;;QAEN,KAAK"}
|
package/docs/CSSGuidelines.md
CHANGED
|
@@ -278,6 +278,8 @@ Import custom media in every CSS file that uses them:
|
|
|
278
278
|
@media (--global-nav-down) /* < 720px */
|
|
279
279
|
@media (--collapse-card-up) /* >= 400px - Card collapse */
|
|
280
280
|
@media (--collapse-card-down) /* < 400px */
|
|
281
|
+
@media (--sidebar-up) /* >= 720px - Sidebar breakpoint */
|
|
282
|
+
@media (--sidebar-down) /* < 720px */
|
|
281
283
|
|
|
282
284
|
/* Interaction */
|
|
283
285
|
@media (--touch) /* Touch devices (no hover) */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnx-mixtape/mxds",
|
|
3
3
|
"description": "The Mixtape Design System",
|
|
4
|
-
"version": "0.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.6",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@floating-ui/dom": "^1.7.6",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"@testing-library/user-event": "^14.6.1",
|
|
38
38
|
"@types/node": "^26.0.0",
|
|
39
39
|
"@vitejs/plugin-react": "^6.0.2",
|
|
40
|
-
"@vitest/browser-playwright": "4.1.
|
|
41
|
-
"@vitest/coverage-v8": "4.1.
|
|
40
|
+
"@vitest/browser-playwright": "4.1.12",
|
|
41
|
+
"@vitest/coverage-v8": "4.1.12",
|
|
42
42
|
"chromatic": "^18.0.1",
|
|
43
43
|
"concurrently": "^10.0.3",
|
|
44
44
|
"cz-conventional-changelog": "^3.3.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"drupal-twig-extensions": "1.0.0-beta.5",
|
|
47
47
|
"jsdom": "^30.0.0",
|
|
48
48
|
"lightningcss": "^1.32.0",
|
|
49
|
-
"oxfmt": "^0.
|
|
49
|
+
"oxfmt": "^0.74.0",
|
|
50
50
|
"oxlint": "^1.71.0",
|
|
51
51
|
"playwright": "^1.61.0",
|
|
52
52
|
"postcss": "^8.5.15",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"typescript": "^7.0.2",
|
|
64
64
|
"vite": "^8.2.2",
|
|
65
65
|
"vite-plugin-twig-drupal": "^1.7.0",
|
|
66
|
-
"vitest": "4.1.
|
|
66
|
+
"vitest": "4.1.12"
|
|
67
67
|
},
|
|
68
68
|
"config": {
|
|
69
69
|
"commitizen": {
|
package/src/Atom/Link/_links.css
CHANGED
|
@@ -25,18 +25,18 @@ export default class Navigation extends HTMLElement {
|
|
|
25
25
|
keyboard: Keyboard
|
|
26
26
|
subNavs?: Map<string, SubNavType>
|
|
27
27
|
flyout?: boolean
|
|
28
|
-
|
|
28
|
+
openActive!: boolean
|
|
29
29
|
mq!: string
|
|
30
|
-
iO?: IntersectionObserver
|
|
31
30
|
|
|
32
31
|
constructor() {
|
|
33
32
|
super()
|
|
34
33
|
this.internals_ = this.attachInternals()
|
|
35
34
|
this.controller = new AbortController()
|
|
36
|
-
this.flyout = this.hasAttribute("flyout")
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
connectedCallback(): void {
|
|
38
|
+
this.flyout = this.hasAttribute("flyout")
|
|
39
|
+
this.openActive = this.hasAttribute("openActive")
|
|
40
40
|
const { signal }: AbortController = this.controller
|
|
41
41
|
|
|
42
42
|
// Add keyboard navigation events.
|
|
@@ -69,21 +69,21 @@ export default class Navigation extends HTMLElement {
|
|
|
69
69
|
}
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
-
this.
|
|
72
|
+
if (this.openActive && this.subNavs.size > 0) this.handleOpenActive()
|
|
73
73
|
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
if (this.flyout) {
|
|
75
|
+
this.mq = this.getAttribute("mq") || "(min-width: 720px)"
|
|
76
|
+
this.handleBreakpoint(this.breakpoint)
|
|
77
|
+
this.breakpoint.addEventListener("change", this.handleBreakpoint, {
|
|
78
|
+
signal,
|
|
79
|
+
})
|
|
80
|
+
this.addEventListener("disclosure-toggle", this.handleDisclosure)
|
|
81
|
+
}
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
disconnectedCallback(): void {
|
|
84
85
|
this.controller.abort()
|
|
85
86
|
this.subNavs?.forEach((subNav: SubNavType): void => subNav.widget.detach())
|
|
86
|
-
this.iO?.disconnect()
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
handleDisclosure = ({ detail }: CustomEvent<DisclosureWidgetEvent>): void => {
|
|
@@ -104,6 +104,18 @@ export default class Navigation extends HTMLElement {
|
|
|
104
104
|
})
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
handleOpenActive = (): void => {
|
|
108
|
+
this.subNavs?.forEach(({ widget, list, link }: SubNavType): void => {
|
|
109
|
+
if (!widget || widget.isOpen) return
|
|
110
|
+
if (
|
|
111
|
+
!link.hasAttribute("aria-current") &&
|
|
112
|
+
!list.querySelector("[aria-current=page], .is-active")
|
|
113
|
+
)
|
|
114
|
+
return
|
|
115
|
+
widget.handleToggle()
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
107
119
|
handleFlyout = (event: MouseEvent): void => {
|
|
108
120
|
const target = event.target as HTMLElement
|
|
109
121
|
const parent: HTMLLIElement = target.closest("li")
|
|
@@ -122,32 +134,16 @@ export default class Navigation extends HTMLElement {
|
|
|
122
134
|
if (matches) {
|
|
123
135
|
this.addEventListener("mouseover", this.handleFlyout, { signal })
|
|
124
136
|
this.addEventListener("mouseleave", this.handleCloseAny, { signal })
|
|
125
|
-
if (this.edgeCheck) this.handleEdgeCheck()
|
|
126
137
|
} else {
|
|
127
138
|
this.removeEventListener("mouseover", this.handleFlyout)
|
|
128
139
|
this.removeEventListener("mouseleave", this.handleCloseAny)
|
|
129
140
|
}
|
|
130
141
|
}
|
|
131
142
|
|
|
132
|
-
handleEdgeCheck() {
|
|
133
|
-
const windowInnerWidth: number = window.innerWidth
|
|
134
|
-
this.iO = new IntersectionObserver((entries, obs) => {
|
|
135
|
-
entries.forEach(({ boundingClientRect, target }) => {
|
|
136
|
-
if (windowInnerWidth < boundingClientRect.right) target.classList.add("mx-nav--reverse")
|
|
137
|
-
obs.unobserve(target)
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
this.subNavs?.forEach(({ list }: SubNavType): void => {
|
|
141
|
-
this.iO.observe(list)
|
|
142
|
-
const nestedLists: NodeListOf<HTMLUListElement> = list.querySelectorAll("ul")
|
|
143
|
-
nestedLists?.forEach(nestedList => this.iO.observe(nestedList))
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
|
|
147
143
|
get links(): NodeListOf<HTMLAnchorElement> | null {
|
|
148
144
|
const links: NodeListOf<HTMLAnchorElement> | null = this.querySelectorAll("a")
|
|
149
145
|
if (!links.length) {
|
|
150
|
-
throw new Error(`${this.localName} must links`)
|
|
146
|
+
throw new Error(`${this.localName} must contain links`)
|
|
151
147
|
}
|
|
152
148
|
return links
|
|
153
149
|
}
|
|
@@ -170,15 +170,17 @@ Behind the scenes, each top-level item with children is rendered by `DropdownLev
|
|
|
170
170
|
</mx-nav>
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
The `<mx-nav>` Web Component wires up keyboard navigation, hover flyouts (when the `flyout` attribute is set)
|
|
173
|
+
The `<mx-nav>` Web Component wires up keyboard navigation, hover flyouts (when the `flyout` attribute is set) and `inert`/`aria-expanded` toggling on sub-menus.
|
|
174
174
|
|
|
175
175
|
**`<mx-nav>` attributes:**
|
|
176
176
|
|
|
177
|
-
| Attribute
|
|
178
|
-
|
|
|
179
|
-
| `flyout`
|
|
180
|
-
| `
|
|
181
|
-
| `mq`
|
|
177
|
+
| Attribute | Description |
|
|
178
|
+
| ------------ | ------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| `flyout` | Opens sub-menus on hover at or above `mq` |
|
|
180
|
+
| `openActive` | Opens sub-menus whose parent link or descendants are `aria-current="page"` / `.is-active` on load |
|
|
181
|
+
| `mq` | Media query for hover behaviour (default: `"(min-width: 720px)"`) |
|
|
182
|
+
|
|
183
|
+
**Sub-menu positioning:** at `--global-nav-up`, dropdown and mega sub-menus use CSS anchor positioning — no JS. Each `li` with a sub-menu is its own anchor (`anchor-name` + `anchor-scope: --mx-nav-item`), and the sub-menu is `position: fixed` with `position-try-fallbacks: flip-inline`, so it flips to the other side when it would overflow the viewport. Level-2 chevrons always point inline-end, even when the sub-menu has flipped — `@container anchored(fallback: flip-inline)` could fix that, but Lightning CSS can't parse it yet.
|
|
182
184
|
|
|
183
185
|
---
|
|
184
186
|
|
|
@@ -210,7 +212,7 @@ Two templates are provided. `navigation.twig` is a thin wrapper that sets modifi
|
|
|
210
212
|
| ------------- | ----------------------------------- | --------------------- | ------------------------- |
|
|
211
213
|
| `collapsible` | `mx-nav--collapsible` | yes | — |
|
|
212
214
|
| `dropdown` | `mx-nav--dropdown` | yes | `flyout` |
|
|
213
|
-
| `mega` | `mx-nav--dropdown mx-nav--mega-nav` | yes |
|
|
215
|
+
| `mega` | `mx-nav--dropdown mx-nav--mega-nav` | yes | — |
|
|
214
216
|
| `footer` | `mx-nav--footer` | no | sub-lists are not `inert` |
|
|
215
217
|
|
|
216
218
|
**`MenuItem` shape** (consumed by `menu.twig`):
|
|
@@ -234,8 +236,7 @@ Two templates are provided. `navigation.twig` is a thin wrapper that sets modifi
|
|
|
234
236
|
| `mx-nav--dropdown` | React `Dropdown` / Twig `type: 'dropdown'` | Horizontal top level, absolute-positioned level-2 panels |
|
|
235
237
|
| `mx-nav--mega-nav` | Twig `type: 'mega'` | Extends `--dropdown` for a third level positioned to the side of level 2 |
|
|
236
238
|
| `mx-nav--footer` | Twig `type: 'footer'` | Used by Footer layout; sub-lists stay visible (not `inert`) |
|
|
237
|
-
| `mx-nav--
|
|
238
|
-
| `mx-nav--open` | `<mx-nav>` JS | Added to `<li>` while its sub-menu is open |
|
|
239
|
+
| `mx-nav--open` | `<mx-nav flyout>` JS | Added to `<li>` while its sub-menu is open (flyout navs only — chevron rotation keys off `aria-expanded`) |
|
|
239
240
|
| `mx-nav__level-1` / `__level-2` / `__level-3` | Structural | Sub-list nesting level |
|
|
240
241
|
| `mx-nav__has-subnav` | Structural | Applied to any `<li>` that contains a child `<ul>` |
|
|
241
242
|
| `mx-nav__toggle` | Structural | The chevron button that opens a sub-menu |
|
|
@@ -248,7 +249,7 @@ Two templates are provided. `navigation.twig` is a thin wrapper that sets modifi
|
|
|
248
249
|
- The outer `<nav>` receives an `aria-label` from the `title` prop — always provide a meaningful label so screen-reader users can distinguish multiple navs on a page (e.g. "Primary navigation", "Footer links").
|
|
249
250
|
- Sub-menu toggle buttons expose `aria-expanded` (true/false) and `aria-controls` pointing to the `id` of their `<ul>`.
|
|
250
251
|
- Sub-lists that are closed use the `inert` attribute — removing them from the tab order and from assistive tech — so no additional ARIA is needed on the list itself.
|
|
251
|
-
- The `<mx-nav>` Web Component attaches keyboard handling via the shared `Keyboard` utility: arrow keys move between links
|
|
252
|
+
- The `<mx-nav>` Web Component attaches keyboard handling via the shared `Keyboard` utility: arrow keys move between links. `Escape` closes open sub-menus only on `flyout` navs (dropdown) — collapsible and mega navs close via their toggle button.
|
|
252
253
|
- `DropdownLevel` (React) handles these keys on the toggle button itself: `Escape`/`ArrowUp` close; `ArrowDown`/`Enter`/`Space` open.
|
|
253
254
|
- The chevron button uses `mx-icon--only` — its accessible name comes from the text "Sub-navigation" inside the button. Never rely on the chevron rotation alone to convey state.
|
|
254
255
|
- Current-page items should carry `aria-current="page"`; collapsible navigation styles this with a bold weight and an accent background.
|
|
@@ -15,7 +15,7 @@ exports[`Collapsible 1`] = `
|
|
|
15
15
|
<a href="#" id="unique-2">
|
|
16
16
|
What we do
|
|
17
17
|
</a>
|
|
18
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
18
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
19
19
|
<ul class="mx-nav__level-2" inert="" id="unique-0" aria-labelledby="unique-1">
|
|
20
20
|
<li>
|
|
21
21
|
<a href="#">
|
|
@@ -26,7 +26,7 @@ exports[`Collapsible 1`] = `
|
|
|
26
26
|
<a href="#" id="unique-3">
|
|
27
27
|
Who we are
|
|
28
28
|
</a>
|
|
29
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-2">Sub-navigation</button>
|
|
29
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-2">Sub-navigation</button>
|
|
30
30
|
<ul class="mx-nav__level-3" inert="" id="unique-1" aria-labelledby="unique-3">
|
|
31
31
|
<li>
|
|
32
32
|
<a href="#">
|
|
@@ -91,7 +91,7 @@ exports[`Dropdown 1`] = `
|
|
|
91
91
|
<a href="#" id="unique-1">
|
|
92
92
|
What we do
|
|
93
93
|
</a>
|
|
94
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
94
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
95
95
|
<ul class="mx-nav__level-2" id="unique-0" aria-labelledby="unique-1" inert="">
|
|
96
96
|
<li>
|
|
97
97
|
<a href="#">
|
|
@@ -136,7 +136,7 @@ exports[`Dropdown 1`] = `
|
|
|
136
136
|
exports[`Mega 1`] = `
|
|
137
137
|
"
|
|
138
138
|
|
|
139
|
-
<mx-nav
|
|
139
|
+
<mx-nav>
|
|
140
140
|
<nav class="mx-nav mx-nav--dropdown mx-nav--mega-nav" aria-label="Links" id="links-story">
|
|
141
141
|
<ul class="mx-nav__level-1">
|
|
142
142
|
<li>
|
|
@@ -148,13 +148,13 @@ exports[`Mega 1`] = `
|
|
|
148
148
|
<a href="#" id="unique-3">
|
|
149
149
|
About
|
|
150
150
|
</a>
|
|
151
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
151
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
152
152
|
<ul class="mx-nav__level-2" inert="" id="unique-0" aria-labelledby="unique-1">
|
|
153
153
|
<li class="mx-nav__has-subnav">
|
|
154
154
|
<a href="#" aria-current="page" id="unique-4">
|
|
155
155
|
Who
|
|
156
156
|
</a>
|
|
157
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-2">Sub-navigation</button>
|
|
157
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-2">Sub-navigation</button>
|
|
158
158
|
<ul class="mx-nav__level-3" inert="" id="unique-1" aria-labelledby="unique-3">
|
|
159
159
|
<li>
|
|
160
160
|
<a href="#" aria-current="page">
|
|
@@ -191,7 +191,7 @@ exports[`Mega 1`] = `
|
|
|
191
191
|
<a href="#" id="unique-5">
|
|
192
192
|
Contact
|
|
193
193
|
</a>
|
|
194
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-4">Sub-navigation</button>
|
|
194
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-4">Sub-navigation</button>
|
|
195
195
|
<ul class="mx-nav__level-2" inert="" id="unique-2" aria-labelledby="unique-5">
|
|
196
196
|
<li>
|
|
197
197
|
<a href="#" aria-current="page">
|
|
@@ -259,7 +259,7 @@ exports[`Screen Reader Announcements 1`] = `
|
|
|
259
259
|
<a href="#" id="unique-1">
|
|
260
260
|
What we do
|
|
261
261
|
</a>
|
|
262
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
262
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button" aria-expanded="false" aria-controls="unique-0">Sub-navigation</button>
|
|
263
263
|
<ul class="mx-nav__level-2" id="unique-0" aria-labelledby="unique-1" inert="">
|
|
264
264
|
<li>
|
|
265
265
|
<a href="#">
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
&:is(.mx-nav__has-subnav, :has(> ul)) {
|
|
21
21
|
position: relative;
|
|
22
22
|
|
|
23
|
+
/* Each sub-menu anchors to its own parent item. */
|
|
24
|
+
anchor-scope: --mx-nav-item;
|
|
25
|
+
anchor-name: --mx-nav-item;
|
|
26
|
+
|
|
23
27
|
& > a {
|
|
24
28
|
--toggle-gap: var(--spacing-l);
|
|
25
29
|
}
|
|
@@ -90,7 +94,11 @@
|
|
|
90
94
|
margin: 0;
|
|
91
95
|
|
|
92
96
|
@media (--global-nav-up) {
|
|
93
|
-
|
|
97
|
+
/* Fixed so fallbacks flip against the viewport, not the parent item. */
|
|
98
|
+
position: fixed;
|
|
99
|
+
position-anchor: --mx-nav-item;
|
|
100
|
+
position-area: block-end span-inline-end;
|
|
101
|
+
position-try-fallbacks: flip-inline;
|
|
94
102
|
inline-size: var(--dropdown-width, 270px);
|
|
95
103
|
border-radius: var(--border-radius);
|
|
96
104
|
background-color: var(
|
|
@@ -113,16 +121,6 @@
|
|
|
113
121
|
}
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
& .mx-nav--reverse .nav__level-2 {
|
|
117
|
-
@media (--global-nav-up) {
|
|
118
|
-
inset-inline: auto 0;
|
|
119
|
-
|
|
120
|
-
& .mx-nav__toggle::before {
|
|
121
|
-
transform: rotate(90deg);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
124
|
& .mx-nav__separator {
|
|
127
125
|
border-block-start: var(--line-width, 1px) solid var(--line-colour, var(--colour-border));
|
|
128
126
|
}
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
inline-size: 100%;
|
|
18
18
|
|
|
19
19
|
@media (--global-nav-up) {
|
|
20
|
-
position:
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
position: fixed;
|
|
21
|
+
position-anchor: --mx-nav-item;
|
|
22
|
+
position-area: span-block-end inline-end;
|
|
23
|
+
position-try-fallbacks: flip-inline;
|
|
23
24
|
inline-size: var(--dropdown-width, 270px);
|
|
24
|
-
min-block-size:
|
|
25
|
+
min-block-size: anchor-size(block);
|
|
25
26
|
padding-inline-start: 0;
|
|
26
27
|
border-block-start: 0;
|
|
27
28
|
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
|
@@ -37,12 +38,5 @@
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
& .mx-nav--reverse .mx-nav__level-2 ul {
|
|
42
|
-
@media (--global-nav-up) {
|
|
43
|
-
inset-inline-start: calc(var(--dropdown-width, 270px) * -1);
|
|
44
|
-
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
41
|
}
|
|
48
42
|
}
|
|
@@ -45,11 +45,13 @@
|
|
|
45
45
|
inset-block-start: var(--toggle-top, 12px);
|
|
46
46
|
inset-inline-end: 0;
|
|
47
47
|
cursor: pointer;
|
|
48
|
-
}
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
& > .mx-nav__toggle::before {
|
|
49
|
+
&[aria-expanded="true"]::before {
|
|
52
50
|
transform: rotate(180deg);
|
|
53
51
|
}
|
|
54
52
|
}
|
|
53
|
+
|
|
54
|
+
mx-nav:not(:defined) .mx-nav__toggle {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
55
57
|
}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
{{ item.link.title }}
|
|
24
24
|
{% endif %}
|
|
25
25
|
{% if item.items is not empty %}
|
|
26
|
-
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only">Sub-navigation</button>
|
|
26
|
+
<button class="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only" type="button">Sub-navigation</button>
|
|
27
27
|
{{ nav.menutree(item.items, level + 1, setInert, baseClass) }}
|
|
28
28
|
{% endif %}
|
|
29
29
|
</li>
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
{% if type == "mega" %}
|
|
15
15
|
{# Horizontal menu with 3 levels deep, no hover flyout. #}
|
|
16
16
|
{% set needsJs = true %}
|
|
17
|
-
{% set componentAttributes = componentAttributes.addAttribute("edgeCheck") %}
|
|
18
17
|
{% set modifiers = ['dropdown', 'mega-nav'] %}
|
|
19
18
|
{% endif %}
|
|
20
19
|
{% if type == "footer" %}
|
|
@@ -1,37 +1,81 @@
|
|
|
1
|
-
import { JSX } from "react"
|
|
1
|
+
import { JSX, ComponentPropsWithoutRef, useContext, useId } from "react"
|
|
2
|
+
import { useDisclosureState } from "react-stately"
|
|
2
3
|
import { MenuTree } from "@pnx-mixtape/ids-shape"
|
|
3
4
|
import Link from "../../../Atom/Link/Link"
|
|
5
|
+
import { SideNavigationContext } from "../SideNavigation"
|
|
4
6
|
|
|
5
|
-
type SideNavigationTreeProps = {
|
|
7
|
+
type SideNavigationTreeProps = ComponentPropsWithoutRef<"ul"> & {
|
|
6
8
|
items: MenuTree[]
|
|
7
9
|
level?: number
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
type SideNavigationItemProps = {
|
|
13
|
+
item: MenuTree
|
|
14
|
+
level: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// True when this item, or any descendant, is the current page.
|
|
18
|
+
const hasCurrent = ({ link, items }: MenuTree): boolean =>
|
|
19
|
+
Boolean(link.current) || Boolean(items?.some(hasCurrent))
|
|
20
|
+
|
|
21
|
+
const SideNavigationItem = ({ item, level }: SideNavigationItemProps): JSX.Element => {
|
|
22
|
+
const collapsible = useContext(SideNavigationContext)
|
|
23
|
+
const { isExpanded, toggle } = useDisclosureState({ defaultExpanded: hasCurrent(item) })
|
|
24
|
+
const listId = useId()
|
|
25
|
+
const labelId = useId()
|
|
26
|
+
const hasItems = item.items && item.items.length > 0
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<li className={hasItems ? "mx-nav__has-subnav" : undefined}>
|
|
30
|
+
{item.link.href ? (
|
|
31
|
+
<Link
|
|
32
|
+
to={item.link.href}
|
|
33
|
+
id={hasItems && collapsible ? labelId : undefined}
|
|
34
|
+
aria-current={item.link.current ? "page" : undefined}
|
|
35
|
+
>
|
|
36
|
+
{item.link.title}
|
|
37
|
+
</Link>
|
|
38
|
+
) : (
|
|
39
|
+
item.link.title
|
|
40
|
+
)}
|
|
41
|
+
{hasItems && (
|
|
42
|
+
<>
|
|
43
|
+
<button
|
|
44
|
+
className="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only"
|
|
45
|
+
type="button"
|
|
46
|
+
{...(collapsible && {
|
|
47
|
+
"aria-expanded": isExpanded,
|
|
48
|
+
"aria-controls": listId,
|
|
49
|
+
onClick: toggle,
|
|
50
|
+
})}
|
|
51
|
+
>
|
|
52
|
+
Sub-navigation
|
|
53
|
+
</button>
|
|
54
|
+
<SideNavigationTree
|
|
55
|
+
items={item.items}
|
|
56
|
+
level={level + 1}
|
|
57
|
+
{...(collapsible && {
|
|
58
|
+
id: listId,
|
|
59
|
+
"aria-labelledby": item.link.href ? labelId : undefined,
|
|
60
|
+
inert: !isExpanded,
|
|
61
|
+
})}
|
|
62
|
+
/>
|
|
63
|
+
</>
|
|
64
|
+
)}
|
|
65
|
+
</li>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const SideNavigationTree = ({
|
|
70
|
+
items,
|
|
71
|
+
level = 0,
|
|
72
|
+
...props
|
|
73
|
+
}: SideNavigationTreeProps): JSX.Element => (
|
|
74
|
+
<ul className={`mx-nav__level-${level + 1}`} {...props}>
|
|
12
75
|
{items.map((item, i) => (
|
|
13
76
|
// Menu items have no stable id; index is the only available key.
|
|
14
77
|
// oxlint-disable-next-line react/no-array-index-key
|
|
15
|
-
<
|
|
16
|
-
{item.link.href ? (
|
|
17
|
-
<Link to={item.link.href} aria-current={item.link.current ? "page" : undefined}>
|
|
18
|
-
{item.link.title}
|
|
19
|
-
</Link>
|
|
20
|
-
) : (
|
|
21
|
-
item.link.title
|
|
22
|
-
)}
|
|
23
|
-
{item.items && item.items.length > 0 && (
|
|
24
|
-
<>
|
|
25
|
-
<button
|
|
26
|
-
className="mx-nav__toggle mx-icon mx-icon--chevron-down mx-icon--only"
|
|
27
|
-
type="button"
|
|
28
|
-
>
|
|
29
|
-
Sub-navigation
|
|
30
|
-
</button>
|
|
31
|
-
<SideNavigationTree items={item.items} level={level + 1} />
|
|
32
|
-
</>
|
|
33
|
-
)}
|
|
34
|
-
</li>
|
|
78
|
+
<SideNavigationItem key={i} item={item} level={level} />
|
|
35
79
|
))}
|
|
36
80
|
</ul>
|
|
37
81
|
)
|