@pnx-mixtape/mxds 0.1.0-rc.4 → 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.
Files changed (236) hide show
  1. package/.claude/skills/create-mxds-component/SKILL.md +77 -0
  2. package/DESIGN.md +595 -0
  3. package/README.md +2 -3
  4. package/dist/build/accordion.entry.js +2 -1
  5. package/dist/build/autocomplete.entry.js +1 -1
  6. package/dist/build/back-to-top.css +1 -0
  7. package/dist/build/back-to-top.entry.js +1 -0
  8. package/dist/build/base.css +1 -1
  9. package/dist/build/button.css +1 -1
  10. package/dist/build/card.css +1 -1
  11. package/dist/build/chunks/Accordion-Bqe8vTNR.js +44 -0
  12. package/dist/build/chunks/AccordionGroup-BYtoAFxg.js +47 -0
  13. package/dist/build/chunks/AccordionMobile-D517oXYZ.js +26 -0
  14. package/dist/build/chunks/Autocomplete-kRo8RNbC.js +135 -0
  15. package/dist/build/chunks/BackToTop-4M-Wl7z3.js +64 -0
  16. package/dist/build/chunks/ClosableAlert-CZ114JsL.js +55 -0
  17. package/dist/build/chunks/CookieConsent-wd8gQ2Oe.js +18 -0
  18. package/dist/build/chunks/Dialog-DoYcGqhW.js +48 -0
  19. package/dist/build/chunks/DropMenu-CSTZq0Zt.js +68 -0
  20. package/dist/build/chunks/FeedbackForm-BsL7fv8s.js +64 -0
  21. package/dist/build/chunks/Gallery-DqJPujX5.js +165 -0
  22. package/dist/build/chunks/GlobalToggle-7H3F1Wvc.js +82 -0
  23. package/dist/build/chunks/InPageNavigation-D7m3IN89.js +86 -0
  24. package/dist/build/chunks/Navigation-CRModT40.js +142 -0
  25. package/dist/build/chunks/Popover-CiTAftNU.js +30 -0
  26. package/dist/build/chunks/Sticky-C1H8MNqK.js +51 -0
  27. package/dist/build/chunks/Tabs-BJD3kABL.js +160 -0
  28. package/dist/build/chunks/Translate-yAgySwet.js +46 -0
  29. package/dist/build/chunks/cookie-compliance-CG6x-TcV.js +119 -0
  30. package/dist/build/chunks/enums-BrHxPZZ_.js +36 -0
  31. package/dist/build/chunks/polyfills-D-qh1a_2.js +33 -0
  32. package/dist/build/chunks/utilities-B9mNRs7V.js +255 -0
  33. package/dist/build/content-block.css +1 -1
  34. package/dist/build/cookie-consent.entry.js +1 -1
  35. package/dist/build/dialog.entry.js +1 -1
  36. package/dist/build/drop-menu.entry.js +1 -1
  37. package/dist/build/elements.js +147 -1
  38. package/dist/build/feedback-form.css +1 -0
  39. package/dist/build/feedback-form.entry.js +1 -0
  40. package/dist/build/filters.entry.js +145 -1
  41. package/dist/build/form.css +1 -1
  42. package/dist/build/gallery.entry.js +1 -1
  43. package/dist/build/global-alert.entry.js +1 -1
  44. package/dist/build/header.css +1 -1
  45. package/dist/build/header.entry.js +1 -1
  46. package/dist/build/icon.css +1 -1
  47. package/dist/build/in-page-navigation.entry.js +1 -1
  48. package/dist/build/navigation.css +1 -1
  49. package/dist/build/navigation.entry.js +1 -1
  50. package/dist/build/pagination.css +1 -1
  51. package/dist/build/popover.entry.js +1 -1
  52. package/dist/build/react.js +2291 -1
  53. package/dist/build/side-navigation.css +1 -1
  54. package/dist/build/sidebar.css +1 -1
  55. package/dist/build/sticky.entry.js +1 -1
  56. package/dist/build/tabs.entry.js +1 -1
  57. package/dist/build/translate.css +1 -0
  58. package/dist/build/translate.entry.js +1 -0
  59. package/dist/build/utility-list.entry.js +53 -1
  60. package/dist/types/Component/BackToTop/BackToTop.d.ts +20 -0
  61. package/dist/types/Component/BackToTop/BackToTop.d.ts.map +1 -0
  62. package/dist/types/Component/BackToTop/Elements/BackToTop.d.ts +27 -0
  63. package/dist/types/Component/BackToTop/Elements/BackToTop.d.ts.map +1 -0
  64. package/dist/types/Component/BackToTop/back-to-top.entry.d.ts +2 -0
  65. package/dist/types/Component/BackToTop/back-to-top.entry.d.ts.map +1 -0
  66. package/dist/types/Component/DropMenu/DropMenu.d.ts +2 -1
  67. package/dist/types/Component/DropMenu/DropMenu.d.ts.map +1 -1
  68. package/dist/types/Component/Navigation/Elements/Navigation.d.ts +2 -3
  69. package/dist/types/Component/Navigation/Elements/Navigation.d.ts.map +1 -1
  70. package/dist/types/Component/SideNavigation/Components/SideNavigationTree.d.ts +3 -3
  71. package/dist/types/Component/SideNavigation/Components/SideNavigationTree.d.ts.map +1 -1
  72. package/dist/types/Component/SideNavigation/SideNavigation.d.ts +3 -1
  73. package/dist/types/Component/SideNavigation/SideNavigation.d.ts.map +1 -1
  74. package/dist/types/Component/Tabs/Components/TabDropMenu.d.ts.map +1 -1
  75. package/dist/types/Component/Tabs/Elements/Tabs.d.ts.map +1 -1
  76. package/dist/types/Component/Translate/Elements/Translate.d.ts +23 -0
  77. package/dist/types/Component/Translate/Elements/Translate.d.ts.map +1 -0
  78. package/dist/types/Component/Translate/Translate.d.ts +37 -0
  79. package/dist/types/Component/Translate/Translate.d.ts.map +1 -0
  80. package/dist/types/Component/Translate/languages.d.ts +11 -0
  81. package/dist/types/Component/Translate/languages.d.ts.map +1 -0
  82. package/dist/types/Component/Translate/translate.entry.d.ts +2 -0
  83. package/dist/types/Component/Translate/translate.entry.d.ts.map +1 -0
  84. package/dist/types/Form/FeedbackForm/Elements/FeedbackForm.d.ts +37 -0
  85. package/dist/types/Form/FeedbackForm/Elements/FeedbackForm.d.ts.map +1 -0
  86. package/dist/types/Form/FeedbackForm/FeedbackForm.d.ts +36 -0
  87. package/dist/types/Form/FeedbackForm/FeedbackForm.d.ts.map +1 -0
  88. package/dist/types/Form/FeedbackForm/feedback-form.entry.d.ts +2 -0
  89. package/dist/types/Form/FeedbackForm/feedback-form.entry.d.ts.map +1 -0
  90. package/dist/types/Utility/Elements/google-translate-widget.d.ts +91 -0
  91. package/dist/types/Utility/Elements/google-translate-widget.d.ts.map +1 -0
  92. package/dist/types/Utility/utilities.d.ts +2 -0
  93. package/dist/types/Utility/utilities.d.ts.map +1 -1
  94. package/dist/types/elements.d.ts +3 -0
  95. package/dist/types/elements.d.ts.map +1 -1
  96. package/dist/types/enums.d.ts +3 -1
  97. package/dist/types/enums.d.ts.map +1 -1
  98. package/dist/types/react.d.ts +3 -0
  99. package/dist/types/react.d.ts.map +1 -1
  100. package/dist/types/tokens.d.ts +1 -0
  101. package/dist/types/tokens.d.ts.map +1 -1
  102. package/docs/API.md +1215 -0
  103. package/docs/CSSGuidelines.md +893 -0
  104. package/docs/CodeQuality.md +940 -0
  105. package/docs/ComponentArchitecture.md +714 -0
  106. package/docs/Contributing.md +626 -0
  107. package/docs/MemoryManagement.md +598 -0
  108. package/docs/Migrations.md +6 -0
  109. package/docs/README.md +100 -0
  110. package/docs/Security.md +444 -0
  111. package/docs/Testing.md +739 -0
  112. package/docs/Troubleshooting.md +674 -0
  113. package/package.json +9 -6
  114. package/src/Atom/Button/Button.tsx +1 -1
  115. package/src/Atom/Button/__snapshots__/Button.stories.tsx.snap +2 -2
  116. package/src/Atom/Button/_buttons.css +1 -0
  117. package/src/Atom/Icon/README.md +1 -1
  118. package/src/Atom/Icon/_icon.css +1 -0
  119. package/src/Atom/Icon/images/thumb.svg +1 -0
  120. package/src/Atom/Link/_links.css +1 -0
  121. package/src/Atom/Media/__snapshots__/Media.stories.ts.snap +4 -9
  122. package/src/Atom/Media/media.twig +4 -5
  123. package/src/Component/BackToTop/BackToTop.stories.ts +127 -0
  124. package/src/Component/BackToTop/BackToTop.stories.tsx +53 -0
  125. package/src/Component/BackToTop/BackToTop.tsx +120 -0
  126. package/src/Component/BackToTop/Elements/BackToTop.ts +119 -0
  127. package/src/Component/BackToTop/README.md +164 -0
  128. package/src/Component/BackToTop/__snapshots__/BackToTop.stories.ts.snap +24 -0
  129. package/src/Component/BackToTop/__snapshots__/BackToTop.stories.tsx.snap +3 -0
  130. package/src/Component/BackToTop/back-to-top.css +70 -0
  131. package/src/Component/BackToTop/back-to-top.entry.js +1 -0
  132. package/src/Component/BackToTop/back-to-top.twig +26 -0
  133. package/src/Component/Card/Components/CardContent.tsx +1 -1
  134. package/src/Component/Card/Components/CardMedia.tsx +1 -1
  135. package/src/Component/Card/__snapshots__/Card.stories.tsx.snap +3 -3
  136. package/src/Component/Card/card.css +1 -1
  137. package/src/Component/Carousel/Carousel.stories.ts +66 -36
  138. package/src/Component/Carousel/__snapshots__/Carousel.stories.tsx.snap +5 -5
  139. package/src/Component/ContentBlock/Components/ContentBlockMedia.tsx +1 -1
  140. package/src/Component/ContentBlock/content-block.css +1 -1
  141. package/src/Component/DropMenu/DropMenu.stories.ts +21 -2
  142. package/src/Component/DropMenu/DropMenu.tsx +14 -4
  143. package/src/Component/DropMenu/__snapshots__/DropMenu.stories.ts.snap +3 -3
  144. package/src/Component/DropMenu/__snapshots__/DropMenu.stories.tsx.snap +2 -2
  145. package/src/Component/DropMenu/drop-menu.twig +7 -1
  146. package/src/Component/HeroBanner/__snapshots__/HeroBanner.stories.tsx.snap +1 -1
  147. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.ts.snap +48 -13
  148. package/src/Component/InPageNavigation/in-page-navigation.twig +4 -6
  149. package/src/Component/ListItem/Components/ListItemMedia.tsx +1 -1
  150. package/src/Component/Navigation/Elements/Navigation.ts +25 -29
  151. package/src/Component/Navigation/README.md +11 -10
  152. package/src/Component/Navigation/__snapshots__/Navigation.stories.ts.snap +8 -8
  153. package/src/Component/Navigation/_navigation-dropdown.css +9 -11
  154. package/src/Component/Navigation/_navigation-mega.css +5 -11
  155. package/src/Component/Navigation/_navigation.css +5 -3
  156. package/src/Component/Navigation/menu.twig +1 -1
  157. package/src/Component/Navigation/navigation.twig +0 -1
  158. package/src/Component/Pagination/Pagination.stories.ts +57 -27
  159. package/src/Component/Pagination/pagination.css +16 -7
  160. package/src/Component/Popover/__snapshots__/Popover.stories.tsx.snap +3 -3
  161. package/src/Component/SideNavigation/Components/SideNavigationTree.tsx +68 -24
  162. package/src/Component/SideNavigation/README.md +78 -32
  163. package/src/Component/SideNavigation/SideNavigation.stories.ts +41 -2
  164. package/src/Component/SideNavigation/SideNavigation.stories.tsx +31 -0
  165. package/src/Component/SideNavigation/SideNavigation.tsx +13 -3
  166. package/src/Component/SideNavigation/__snapshots__/SideNavigation.stories.ts.snap +87 -3
  167. package/src/Component/SideNavigation/__snapshots__/SideNavigation.stories.tsx.snap +2 -0
  168. package/src/Component/SideNavigation/side-navigation.css +3 -3
  169. package/src/Component/SideNavigation/side-navigation.twig +10 -3
  170. package/src/Component/Tabs/Components/TabDropMenu.tsx +7 -1
  171. package/src/Component/Tabs/Elements/Tabs.ts +13 -3
  172. package/src/Component/Tabs/Tabs.stories.ts +33 -12
  173. package/src/Component/Tabs/Tabs.stories.tsx +28 -14
  174. package/src/Component/Tabs/__snapshots__/Tabs.stories.ts.snap +3 -3
  175. package/src/Component/Tabs/__snapshots__/Tabs.stories.tsx.snap +2 -2
  176. package/src/Component/Translate/Elements/Translate.ts +76 -0
  177. package/src/Component/Translate/README.md +285 -0
  178. package/src/Component/Translate/Translate.stories.ts +87 -0
  179. package/src/Component/Translate/Translate.stories.tsx +77 -0
  180. package/src/Component/Translate/Translate.tsx +213 -0
  181. package/src/Component/Translate/__snapshots__/Translate.stories.ts.snap +18 -0
  182. package/src/Component/Translate/__snapshots__/Translate.stories.tsx.snap +3 -0
  183. package/src/Component/Translate/languages.ts +39 -0
  184. package/src/Component/Translate/translate.css +62 -0
  185. package/src/Component/Translate/translate.entry.js +1 -0
  186. package/src/Component/Translate/translate.twig +44 -0
  187. package/src/Form/Autocomplete/Autocomplete.stories.tsx +2 -1
  188. package/src/Form/FeedbackForm/Elements/FeedbackForm.ts +122 -0
  189. package/src/Form/FeedbackForm/FeedbackForm.stories.ts +99 -0
  190. package/src/Form/FeedbackForm/FeedbackForm.stories.tsx +73 -0
  191. package/src/Form/FeedbackForm/FeedbackForm.tsx +196 -0
  192. package/src/Form/FeedbackForm/README.md +233 -0
  193. package/src/Form/FeedbackForm/__snapshots__/FeedbackForm.stories.ts.snap +125 -0
  194. package/src/Form/FeedbackForm/__snapshots__/FeedbackForm.stories.tsx.snap +5 -0
  195. package/src/Form/FeedbackForm/feedback-form.css +74 -0
  196. package/src/Form/FeedbackForm/feedback-form.entry.js +1 -0
  197. package/src/Form/FeedbackForm/feedback-form.twig +80 -0
  198. package/src/Form/form.css +17 -19
  199. package/src/Introduction.mdx +1 -1
  200. package/src/Layout/Footer/__snapshots__/Footer.stories.ts.snap +3 -3
  201. package/src/Layout/Header/Components/GlobalToggle.tsx +1 -1
  202. package/src/Layout/Header/Header.stories.ts +53 -48
  203. package/src/Layout/Header/Header.stories.tsx +35 -22
  204. package/src/Layout/Header/Header.tsx +2 -2
  205. package/src/Layout/Header/__snapshots__/Header.stories.ts.snap +18 -14
  206. package/src/Layout/Header/__snapshots__/Header.stories.tsx.snap +2 -2
  207. package/src/Layout/Header/_toggles.css +7 -7
  208. package/src/Layout/Page/__snapshots__/Page.stories.tsx.snap +1 -1
  209. package/src/Layout/Sidebar/sidebar.css +10 -3
  210. package/src/Utility/Elements/google-translate-widget.ts +293 -0
  211. package/src/Utility/global.d.ts +4 -0
  212. package/src/Utility/utilities.ts +2 -0
  213. package/src/_custom-media.css +2 -0
  214. package/src/elements.ts +3 -0
  215. package/src/enums.ts +2 -0
  216. package/src/react.ts +3 -0
  217. package/src/tokens.js +1 -0
  218. package/dist/build/chunks/Accordion-GN0sME4W.js +0 -1
  219. package/dist/build/chunks/AccordionGroup-Bzqp5__q.js +0 -1
  220. package/dist/build/chunks/AccordionMobile-DG5jSe8Q.js +0 -1
  221. package/dist/build/chunks/Autocomplete-B4RtkAyh.js +0 -1
  222. package/dist/build/chunks/ClosableAlert-DEhj8Nxm.js +0 -1
  223. package/dist/build/chunks/CookieConsent-BkCMRVST.js +0 -1
  224. package/dist/build/chunks/Dialog-Haahn-Yn.js +0 -1
  225. package/dist/build/chunks/DropMenu-1baQc8Yc.js +0 -1
  226. package/dist/build/chunks/Gallery-D8NGXy2Q.js +0 -1
  227. package/dist/build/chunks/GlobalToggle-B52fdBQu.js +0 -1
  228. package/dist/build/chunks/InPageNavigation-Dyn2TR-N.js +0 -1
  229. package/dist/build/chunks/Navigation-hOrfLq7h.js +0 -1
  230. package/dist/build/chunks/Popover-Cxg-s5Jn.js +0 -1
  231. package/dist/build/chunks/Sticky-BGCuuEJK.js +0 -1
  232. package/dist/build/chunks/Tabs-DYy1YTdU.js +0 -15
  233. package/dist/build/chunks/cookie-compliance-Bbm-0vpj.js +0 -1
  234. package/dist/build/chunks/enums-DLV_1NAf.js +0 -1
  235. package/dist/build/chunks/polyfills-C7pRt54M.js +0 -1
  236. package/dist/build/chunks/utilities-_Bq3TxAQ.js +0 -1
@@ -21,6 +21,8 @@ type DropMenuType = {
21
21
  id?: string
22
22
  role?: "menu" | "tablist"
23
23
  placement?: PopoverPlacementModifier
24
+ description?: string
25
+ ariaLabel?: string
24
26
  }
25
27
 
26
28
  /**
@@ -38,6 +40,7 @@ const meta: Meta<DropMenuType> = {
38
40
  { label: "Stories", href: "#stories" },
39
41
  ],
40
42
  placement: PopoverPlacementModifier.BOTTOM_START,
43
+ description: "Results will update when you make a selection. Press escape to close.",
41
44
  },
42
45
  argTypes: {
43
46
  placement: {
@@ -75,6 +78,22 @@ const meta: Meta<DropMenuType> = {
75
78
  options: ["menu", "tablist"],
76
79
  type: "string",
77
80
  },
81
+ description: {
82
+ description:
83
+ "Screen-reader-only text describing the popover, announced via `aria-describedby` when it opens.",
84
+ control: "text",
85
+ table: {
86
+ type: { summary: "string" },
87
+ },
88
+ },
89
+ ariaLabel: {
90
+ description:
91
+ "Overrides the popover's accessible name. Defaults to the trigger button's `label` via `aria-labelledby`.",
92
+ control: "text",
93
+ table: {
94
+ type: { summary: "string" },
95
+ },
96
+ },
78
97
  },
79
98
  }
80
99
 
@@ -168,11 +187,11 @@ export const ScreenReaderAnnouncements: Story = {
168
187
  await expect(log).toEqual([
169
188
  "document",
170
189
  "button, Categories",
171
- "menu, Categories, orientated vertically",
190
+ "menu, Categories, Results will update when you make a selection. Press escape to close., orientated vertically",
172
191
  "menuitemradio, News, not checked, position 1, set size 3",
173
192
  "menuitemradio, Events, not checked, position 2, set size 3",
174
193
  "menuitemradio, Stories, not checked, position 3, set size 3",
175
- "end of menu, Categories, orientated vertically",
194
+ "end of menu, Categories, Results will update when you make a selection. Press escape to close., orientated vertically",
176
195
  "end of document",
177
196
  ])
178
197
 
@@ -19,6 +19,7 @@ type DropMenuProps = PropsWithChildren & {
19
19
  popoverClassName?: string
20
20
  role?: "menu" | "tablist"
21
21
  ariaLabel?: string
22
+ triggerDescription?: string
22
23
  description?: string
23
24
  }
24
25
 
@@ -37,6 +38,7 @@ const DropMenu = ({
37
38
  popoverClassName,
38
39
  role = "menu",
39
40
  ariaLabel,
41
+ triggerDescription,
40
42
  description = "Results will update when you make a selection. Press escape to close.",
41
43
  }: DropMenuProps): JSX.Element => {
42
44
  const { dropMenuId, triggerId, descriptionId, popoverRef } = useDropMenuContext()
@@ -55,9 +57,20 @@ const DropMenu = ({
55
57
  className={classNames([...triggerClassNames, "mx-popover__trigger"])}
56
58
  popoverTarget={dropMenuId}
57
59
  style={triggerStyle}
60
+ aria-describedby={triggerDescription ? `${triggerId}-desc` : null}
58
61
  >
59
62
  {label}
60
63
  </button>
64
+ {triggerDescription && (
65
+ <span id={`${triggerId}-desc`} className="sr-only" aria-hidden="true">
66
+ {triggerDescription}
67
+ </span>
68
+ )}
69
+ {description && (
70
+ <span id={descriptionId} className="sr-only" aria-hidden="true">
71
+ {description}
72
+ </span>
73
+ )}
61
74
  <div
62
75
  id={dropMenuId}
63
76
  className={classNames("mx-popover mx-drop-menu", popoverClassName)}
@@ -66,12 +79,9 @@ const DropMenu = ({
66
79
  ref={popoverRef}
67
80
  aria-labelledby={ariaLabel ? null : triggerId}
68
81
  aria-label={ariaLabel}
69
- aria-describedby={descriptionId}
82
+ aria-describedby={descriptionId ? descriptionId : null}
70
83
  role={role}
71
84
  >
72
- <div id={descriptionId} className="sr-only" aria-hidden="true">
73
- {description}
74
- </div>
75
85
  <FocusScope>{children}</FocusScope>
76
86
  </div>
77
87
  </Container>
@@ -5,7 +5,7 @@ exports[`Buttons 1`] = `
5
5
  <button id="unique-0" class="mx-popover__trigger mx-button mx-icon mx-icon--chevron-down mx-icon--end" popovertarget="dropdown-menu" style="anchor-name: --dropdown-menu">
6
6
  Categories
7
7
  </button>
8
- <div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="" role="menu">
8
+ <span id="unique-1" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</span><div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-labelledby="unique-0" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="" role="menu">
9
9
  <button type="button" data-id="news" role="menuitemradio" aria-checked="false">News</button>
10
10
  <button type="button" data-id="events" role="menuitemradio" aria-checked="true">Events</button>
11
11
  <button type="button" data-id="stories" role="menuitemradio" aria-checked="false">Stories</button>
@@ -19,7 +19,7 @@ exports[`Drop Menu 1`] = `
19
19
  <button id="unique-0" class="mx-popover__trigger mx-button mx-icon mx-icon--chevron-down mx-icon--end" popovertarget="dropdown-menu" style="anchor-name: --dropdown-menu">
20
20
  Categories
21
21
  </button>
22
- <div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="">
22
+ <span id="unique-1" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</span><div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-labelledby="unique-0" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="">
23
23
  <a href="#news">News</a>
24
24
  <a href="#events">Events</a>
25
25
  <a href="#stories">Stories</a>
@@ -33,7 +33,7 @@ exports[`Screen Reader Announcements 1`] = `
33
33
  <button id="unique-0" class="mx-popover__trigger mx-button mx-icon mx-icon--chevron-down mx-icon--end" popovertarget="dropdown-menu" style="anchor-name: --dropdown-menu">
34
34
  Categories
35
35
  </button>
36
- <div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="" role="menu">
36
+ <span id="unique-1" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</span><div class="mx-popover mx-drop-menu" id="dropdown-menu" aria-labelledby="unique-0" aria-describedby="unique-0" style="position-anchor: --dropdown-menu" data-placement="bottom-start" popover="" role="menu">
37
37
  <button type="button" data-id="news" role="menuitemradio" aria-checked="false">News</button>
38
38
  <button type="button" data-id="events" role="menuitemradio" aria-checked="false">Events</button>
39
39
  <button type="button" data-id="stories" role="menuitemradio" aria-checked="false">Stories</button>
@@ -1,5 +1,5 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`Drop Menu 1`] = `"<button id="drop-menu-storybook-target" type="button" class="mx-button mx-icon mx-icon--chevron-down mx-icon--end mx-popover__trigger" popovertarget="drop-menu-storybook" style="anchor-name: --drop-menu-drop-menu-storybook;">Categories</button><div id="drop-menu-storybook" class="mx-popover mx-drop-menu" popover="" aria-labelledby="drop-menu-storybook-target" aria-describedby="drop-menu-storybook-description" role="menu" style="position-anchor: --drop-menu-drop-menu-storybook;"><div id="drop-menu-storybook-description" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</div><span data-focus-scope-start="true" hidden=""></span><button type="button" data-id="news" aria-checked="false" role="menuitemradio">News</button><button type="button" data-id="events" aria-checked="false" role="menuitemradio">Events</button><button type="button" data-id="stories" aria-checked="false" role="menuitemradio">Stories</button><span data-focus-scope-end="true" hidden=""></span></div>"`;
3
+ exports[`Drop Menu 1`] = `"<button id="drop-menu-storybook-target" type="button" class="mx-button mx-icon mx-icon--chevron-down mx-icon--end mx-popover__trigger" popovertarget="drop-menu-storybook" style="anchor-name: --drop-menu-drop-menu-storybook;">Categories</button><span id="drop-menu-storybook-description" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</span><div id="drop-menu-storybook" class="mx-popover mx-drop-menu" popover="" aria-labelledby="drop-menu-storybook-target" aria-describedby="drop-menu-storybook-description" role="menu" style="position-anchor: --drop-menu-drop-menu-storybook;"><span data-focus-scope-start="true" hidden=""></span><button type="button" data-id="news" aria-checked="false" role="menuitemradio">News</button><button type="button" data-id="events" aria-checked="false" role="menuitemradio">Events</button><button type="button" data-id="stories" aria-checked="false" role="menuitemradio">Stories</button><span data-focus-scope-end="true" hidden=""></span></div>"`;
4
4
 
5
- exports[`Screen Reader Announcements 1`] = `"<button id="drop-menu-storybook-target" type="button" class="mx-button mx-icon mx-icon--chevron-down mx-icon--end mx-popover__trigger" popovertarget="drop-menu-storybook" style="anchor-name: --drop-menu-drop-menu-storybook;">Categories</button><div id="drop-menu-storybook" class="mx-popover mx-drop-menu" popover="" aria-labelledby="drop-menu-storybook-target" aria-describedby="drop-menu-storybook-description" role="menu" style="position-anchor: --drop-menu-drop-menu-storybook;"><div id="drop-menu-storybook-description" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</div><span data-focus-scope-start="true" hidden=""></span><button type="button" data-id="news" aria-checked="false" role="menuitemradio">News</button><button type="button" data-id="events" aria-checked="false" role="menuitemradio">Events</button><button type="button" data-id="stories" aria-checked="false" role="menuitemradio">Stories</button><span data-focus-scope-end="true" hidden=""></span></div>"`;
5
+ exports[`Screen Reader Announcements 1`] = `"<button id="drop-menu-storybook-target" type="button" class="mx-button mx-icon mx-icon--chevron-down mx-icon--end mx-popover__trigger" popovertarget="drop-menu-storybook" style="anchor-name: --drop-menu-drop-menu-storybook;">Categories</button><span id="drop-menu-storybook-description" class="sr-only" aria-hidden="true">Results will update when you make a selection. Press escape to close.</span><div id="drop-menu-storybook" class="mx-popover mx-drop-menu" popover="" aria-labelledby="drop-menu-storybook-target" aria-describedby="drop-menu-storybook-description" role="menu" style="position-anchor: --drop-menu-drop-menu-storybook;"><span data-focus-scope-start="true" hidden=""></span><button type="button" data-id="news" aria-checked="false" role="menuitemradio">News</button><button type="button" data-id="events" aria-checked="false" role="menuitemradio">Events</button><button type="button" data-id="stories" aria-checked="false" role="menuitemradio">Stories</button><span data-focus-scope-end="true" hidden=""></span></div>"`;
@@ -1,18 +1,24 @@
1
1
  <mx-dropmenu closeonclick>
2
2
  {% set id = id|default('dropdown-menu') %}
3
3
  {% set name = id ~ '-target' %}
4
+ {% set triggerDescriptionId = name ~ '-descr' %}
5
+ {% set descriptionId = name ~ '-description' %}
4
6
  <button
5
7
  id="{{ name }}"
6
8
  class="mx-popover__trigger mx-button mx-icon mx-icon--chevron-down mx-icon--end"
7
9
  popovertarget="{{ id }}"
8
10
  style="anchor-name: --{{ id }}"
11
+ {% if triggerDescription %}aria-describedby="{{ triggerDescriptionId }}"{% endif %}
9
12
  >
10
13
  {{ label }}
11
14
  </button>
15
+ {% if triggerDescription %}<span id="{{ triggerDescriptionId }}" class="sr-only" aria-hidden="true">{{ triggerDescription }}</span>{% endif %}
16
+ {% if description %}<span id="{{ descriptionId }}" class="sr-only" aria-hidden="true">{{ description }}</span>{% endif %}
12
17
  <div
13
18
  class="mx-popover mx-drop-menu"
14
19
  id="{{ id }}"
15
- aria-describedby="{{ name }}"
20
+ {% if ariaLabel %}aria-label="{{ ariaLabel }}"{% else %}aria-labelledby="{{ name }}"{% endif %}
21
+ {% if description %}aria-describedby="{{ descriptionId }}"{% endif %}
16
22
  style="position-anchor: --{{ id }}"
17
23
  data-placement="{{ placement|default('bottom-start') }}"
18
24
  popover
@@ -2,6 +2,6 @@
2
2
 
3
3
  exports[`Hero Banner 1`] = `"<div class="mx-page mx-hero-banner"><div class="mx-hero-banner__inner"><div class="mx-hero-banner__content mx-vertical-flow-flex mx-section--xl"><h1 class="" id="always-put-your-best">Always put your best foot forward.</h1><p class="mx-text--lede">Make the most of the opportunity by encouraging an action and keeping your copy clear and concise.</p></div></div></div>"`;
4
4
 
5
- exports[`Highlight 1`] = `"<div class="mx-page mx-hero-banner mx-background--primary mx-hero-banner--hero"><div class="mx-hero-banner__inner"><div class="mx-hero-banner__content mx-vertical-flow-flex mx-section--xl"><h1 class="mx-headline" id="always-put-your-best">Always put your best foot forward.</h1><p class="mx-text--lede">Make the most of the opportunity by encouraging an action and keeping your copy clear and concise.</p><button class="mx-button mx-button--dark" type="button">Button</button></div><div class="mx-hero-banner__aside mx-section--xl"><img alt="Blurry bubbles" src="https://picsum.photos/id/56/558/418?grayscale"></div></div></div>"`;
5
+ exports[`Highlight 1`] = `"<div class="mx-page mx-hero-banner mx-background--primary mx-hero-banner--hero"><div class="mx-hero-banner__inner"><div class="mx-hero-banner__content mx-vertical-flow-flex mx-section--xl"><h1 class="mx-headline" id="always-put-your-best">Always put your best foot forward.</h1><p class="mx-text--lede">Make the most of the opportunity by encouraging an action and keeping your copy clear and concise.</p><button class="mx-button mx-button--dark" type="button"><span>Button</span></button></div><div class="mx-hero-banner__aside mx-section--xl"><img alt="Blurry bubbles" src="https://picsum.photos/id/56/558/418?grayscale"></div></div></div>"`;
6
6
 
7
7
  exports[`With Link List 1`] = `"<div class="mx-page mx-hero-banner"><div class="mx-hero-banner__inner"><div class="mx-hero-banner__content mx-vertical-flow-flex mx-section--xl"><h1 class="" id="always-put-your-best">Always put your best foot forward.</h1><p class="mx-text--lede">Make the most of the opportunity by encouraging an action and keeping your copy clear and concise.</p></div><div class="mx-hero-banner__aside mx-section--xl"><h2 class="mx-heading--m" id="popular-links">Popular links</h2><ul class="mx-link-list"><li><a href="#1" class="mx-link">Page link #1<span class="mx-icon mx-icon--chevron-right"></span></a></li><li><a href="#2" class="mx-link">Page link #2<span class="mx-icon mx-icon--chevron-right"></span></a></li><li><a href="#3" class="mx-link">Page link #3<span class="mx-icon mx-icon--chevron-right"></span></a></li></ul></div></div></div>"`;
@@ -2,7 +2,8 @@
2
2
 
3
3
  exports[`Generated Items 1`] = `
4
4
  "<mx-in-page-navigation data-content=".js-content" data-levels="" data-title="On this page">
5
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav></mx-in-page-navigation>
5
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav>
6
+ </mx-in-page-navigation>
6
7
  <div class="js-content mx-rich-text mx-vertical-flow">
7
8
  <h2 id="section-1">Section 1</h2>
8
9
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -18,7 +19,8 @@ exports[`Generated Items 1`] = `
18
19
 
19
20
  exports[`Identical Headings 1`] = `
20
21
  "<mx-in-page-navigation data-content=".js-content" data-levels="h2,h3" data-title="On this page">
21
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#test-level-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Test level 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#identical-heading"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-subheading"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical subheading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-heading-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-subheading-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical subheading</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#identical-heading-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li></ul></nav></mx-in-page-navigation>
22
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#test-level-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Test level 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#identical-heading"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-subheading"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical subheading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-heading-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#identical-subheading-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical subheading</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#identical-heading-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Identical heading</span></a></li></ul></nav>
23
+ </mx-in-page-navigation>
22
24
  <div class="js-content mx-rich-text mx-vertical-flow">
23
25
  <h2 id="section-1">Section 1</h2>
24
26
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -44,16 +46,31 @@ exports[`Identical Headings 1`] = `
44
46
 
45
47
  exports[`In Page Navigation 1`] = `
46
48
  "<mx-in-page-navigation data-content=".js-content" data-levels="" data-title="On this page">
47
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span>
49
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow">
50
+ <h2 class="is-excluded mx-heading--m">On this page</h2>
51
+ <ul>
52
+ <li><a href="#section-1">
53
+
54
+ <span class="mx-icon mx-icon--chevron-right"></span>
48
55
 
49
56
  Section 1
50
- </a></li><li><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span>
57
+ </a>
58
+ </li>
59
+ <li><a href="#section-2">
60
+
61
+ <span class="mx-icon mx-icon--chevron-right"></span>
51
62
 
52
63
  Section 2
53
- </a></li><li><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span>
64
+ </a>
65
+ </li>
66
+ <li><a href="#section-3">
67
+
68
+ <span class="mx-icon mx-icon--chevron-right"></span>
54
69
 
55
70
  Section 3
56
- </a></li></ul></nav></mx-in-page-navigation>
71
+ </a>
72
+ </li></ul></nav>
73
+ </mx-in-page-navigation>
57
74
  <div class="js-content mx-rich-text mx-vertical-flow">
58
75
  <h2 id="section-1">Section 1</h2>
59
76
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -69,7 +86,8 @@ exports[`In Page Navigation 1`] = `
69
86
 
70
87
  exports[`Nested 1`] = `
71
88
  "<mx-in-page-navigation data-content=".js-content" data-levels="h2,h3" data-title="On this page">
72
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#test-level-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Test level 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav></mx-in-page-navigation>
89
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h3"><a href="#test-level-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Test level 3</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav>
90
+ </mx-in-page-navigation>
73
91
  <div class="js-content mx-rich-text mx-vertical-flow">
74
92
  <h2 id="section-1">Section 1</h2>
75
93
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -85,7 +103,8 @@ exports[`Nested 1`] = `
85
103
 
86
104
  exports[`No Headings 1`] = `
87
105
  "<mx-in-page-navigation data-content=".js-content" data-levels="h4" data-title="On this page">
88
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"></nav></mx-in-page-navigation>
106
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"></nav>
107
+ </mx-in-page-navigation>
89
108
  <div class="js-content mx-rich-text mx-vertical-flow">
90
109
  <h2 id="section-1">Section 1</h2>
91
110
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -102,7 +121,8 @@ exports[`No Headings 1`] = `
102
121
  exports[`Other Container 1`] = `
103
122
  "<div class="mx-background--box mx-section--m mx-margin--bottom-m">
104
123
  <mx-in-page-navigation data-content=".js-content" data-levels="" data-title="On this page">
105
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav></mx-in-page-navigation>
124
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li class="mx-in-page-navigation__level--h2"><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 1</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 2</span></a></li><li class="mx-in-page-navigation__level--h2"><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span><span>Section 3</span></a></li></ul></nav>
125
+ </mx-in-page-navigation>
106
126
  </div>
107
127
  <div class="js-content mx-rich-text mx-vertical-flow">
108
128
  <h2 id="section-1">Section 1</h2>
@@ -119,16 +139,31 @@ exports[`Other Container 1`] = `
119
139
 
120
140
  exports[`Screen Reader Announcements 1`] = `
121
141
  "<mx-in-page-navigation data-content=".js-content" data-levels="" data-title="On this page">
122
- <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow"><h2 class="is-excluded mx-heading--m">On this page</h2><ul><li><a href="#section-1"><span class="mx-icon mx-icon--chevron-right"></span>
142
+ <nav class="mx-nav mx-nav--list mx-in-page-navigation mx-vertical-flow">
143
+ <h2 class="is-excluded mx-heading--m">On this page</h2>
144
+ <ul>
145
+ <li><a href="#section-1">
146
+
147
+ <span class="mx-icon mx-icon--chevron-right"></span>
123
148
 
124
149
  Section 1
125
- </a></li><li><a href="#section-2"><span class="mx-icon mx-icon--chevron-right"></span>
150
+ </a>
151
+ </li>
152
+ <li><a href="#section-2">
153
+
154
+ <span class="mx-icon mx-icon--chevron-right"></span>
126
155
 
127
156
  Section 2
128
- </a></li><li><a href="#section-3"><span class="mx-icon mx-icon--chevron-right"></span>
157
+ </a>
158
+ </li>
159
+ <li><a href="#section-3">
160
+
161
+ <span class="mx-icon mx-icon--chevron-right"></span>
129
162
 
130
163
  Section 3
131
- </a></li></ul></nav></mx-in-page-navigation>
164
+ </a>
165
+ </li></ul></nav>
166
+ </mx-in-page-navigation>
132
167
  <div class="js-content mx-rich-text mx-vertical-flow">
133
168
  <h2 id="section-1">Section 1</h2>
134
169
  <p>In publishing and graphic design, lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document without relying on meaningful content. Replacing the actual content with placeholder text allows designers to design the form of the content before the content itself has been produced.</p>
@@ -6,14 +6,12 @@
6
6
  ] %}
7
7
  {% set attributes = (attributes ?? create_attribute()).addClass(classes) %}
8
8
  <mx-in-page-navigation data-content="{{ contentSelector|default('.js-content') }}" data-levels="{{ levels|join(",") }}" data-title="{{ title|striptags|trim }}">
9
- {% apply spaceless %}
10
9
  <nav{{ attributes }}>
11
- {% if items %}
12
- {{ title }}
10
+ {%- if items -%}
11
+ {{- title -}}
13
12
  <ul>
14
- {{ items }}
13
+ {{- items -}}
15
14
  </ul>
16
- {% endif %}
15
+ {%- endif -%}
17
16
  </nav>
18
- {% endapply %}
19
17
  </mx-in-page-navigation>
@@ -8,7 +8,7 @@ type CardProps = PropsWithChildren & {
8
8
  const ListItemMedia = ({ children, skeleton = false }: CardProps): JSX.Element => {
9
9
  return (
10
10
  <figure className={classNames("mx-list-item__media", "stack")}>
11
- {skeleton && <div className="mx-skeleton mx-skeleton--bg"></div>}
11
+ {skeleton && <div className="skeleton skeleton--bg"></div>}
12
12
  {children}
13
13
  </figure>
14
14
  )
@@ -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
- edgeCheck!: boolean
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.addEventListener("disclosure-toggle", this.handleDisclosure)
72
+ if (this.openActive && this.subNavs.size > 0) this.handleOpenActive()
73
73
 
74
- if (!this.flyout) return
75
- this.edgeCheck = this.hasAttribute("edgeCheck")
76
- this.mq = this.getAttribute("mq") || "(min-width: 720px)"
77
- this.handleBreakpoint(this.breakpoint)
78
- this.breakpoint.addEventListener("change", this.handleBreakpoint, {
79
- signal,
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), edge detection (when `edgeCheck` is set), and `inert`/`aria-expanded` toggling on sub-menus.
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 | Description |
178
- | ----------- | -------------------------------------------------------------------- |
179
- | `flyout` | Opens sub-menus on hover at or above `mq` |
180
- | `edgeCheck` | Adds `mx-nav--reverse` to sub-menus that would overflow the viewport |
181
- | `mq` | Media query for hover behaviour (default: `"(min-width: 720px)"`) |
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 | `edgeCheck` |
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--reverse` | `<mx-nav edgeCheck>` JS | Flips sub-menu alignment when it would overflow the viewport |
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, `Escape` closes open sub-menus.
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 edgecheck="">
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="#">