@pnx-mixtape/mxds 0.0.22 → 0.0.23

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 (375) hide show
  1. package/dist/build/accordion.entry.js +32 -43
  2. package/dist/build/accordion.entry.js.map +1 -1
  3. package/dist/build/base.css +17 -39
  4. package/dist/build/button.css +9 -10
  5. package/dist/build/chunks/{Accordion-O-huO4At.js → Accordion-D1HQ0FDq.js} +23 -21
  6. package/dist/build/chunks/{Accordion-O-huO4At.js.map → Accordion-D1HQ0FDq.js.map} +1 -1
  7. package/dist/build/chunks/disclosure-widget-CdjCdx7t.js +129 -0
  8. package/dist/build/chunks/disclosure-widget-CdjCdx7t.js.map +1 -0
  9. package/dist/build/chunks/drop-menu.entry-fzV-_VFl.js +70 -0
  10. package/dist/build/chunks/drop-menu.entry-fzV-_VFl.js.map +1 -0
  11. package/dist/build/chunks/{polyfills-C-B7iqDG.js → polyfills-DnrsypYs.js} +35 -26
  12. package/dist/build/chunks/polyfills-DnrsypYs.js.map +1 -0
  13. package/dist/build/chunks/popover.entry-BQvyR0d5.js +38 -0
  14. package/dist/build/chunks/popover.entry-BQvyR0d5.js.map +1 -0
  15. package/dist/build/chunks/{utilities-DXELy_An.js → utilities-Ci7wwNeg.js} +9 -106
  16. package/dist/build/chunks/utilities-Ci7wwNeg.js.map +1 -0
  17. package/dist/build/constants.css +10 -31
  18. package/dist/build/dialog.entry.js +23 -31
  19. package/dist/build/dialog.entry.js.map +1 -1
  20. package/dist/build/drop-menu.entry.js +1 -1
  21. package/dist/build/drupal.css +5 -9
  22. package/dist/build/filters.entry.js +54 -50
  23. package/dist/build/filters.entry.js.map +1 -1
  24. package/dist/build/form.css +12 -26
  25. package/dist/build/global-alert.entry.js +26 -19
  26. package/dist/build/global-alert.entry.js.map +1 -1
  27. package/dist/build/grid.css +3 -9
  28. package/dist/build/header.entry.js +93 -88
  29. package/dist/build/header.entry.js.map +1 -1
  30. package/dist/build/icon.css +3 -3
  31. package/dist/build/in-page-navigation.entry.js +16 -12
  32. package/dist/build/in-page-navigation.entry.js.map +1 -1
  33. package/dist/build/navigation.css +9 -23
  34. package/dist/build/navigation.entry.js +148 -50
  35. package/dist/build/navigation.entry.js.map +1 -1
  36. package/dist/build/page.css +1 -1
  37. package/dist/build/popover.css +119 -0
  38. package/dist/build/popover.entry.js +2 -0
  39. package/dist/build/popover.entry.js.map +1 -0
  40. package/dist/build/section.css +1 -1
  41. package/dist/build/sticky.entry.js +11 -12
  42. package/dist/build/sticky.entry.js.map +1 -1
  43. package/dist/build/tabs.entry.js +108 -91
  44. package/dist/build/tabs.entry.js.map +1 -1
  45. package/dist/build/utility-list.css +43 -0
  46. package/dist/build/utility-list.entry.js +80 -0
  47. package/dist/build/utility-list.entry.js.map +1 -0
  48. package/package.json +9 -10
  49. package/src/Atom/{Base.mdx → Atom.mdx} +1 -1
  50. package/src/Atom/Background/Backgrounds.stories.ts +21 -4
  51. package/src/Atom/Background/__snapshots__/Backgrounds.stories.ts.snap +1 -1
  52. package/src/Atom/Background/_background.css +1 -2
  53. package/src/Atom/Blockquote/_blockquote.css +1 -2
  54. package/src/Atom/Button/Button.stories.ts +128 -19
  55. package/src/Atom/Button/__snapshots__/Button.stories.ts.snap +75 -11
  56. package/src/Atom/Button/__snapshots__/Button.stories.tsx.snap +1 -1
  57. package/src/Atom/Button/_buttons.css +4 -5
  58. package/src/Atom/DefinitionList/DefinitionList.stories.ts +20 -3
  59. package/src/Atom/DefinitionList/DefinitionList.stories.tsx +3 -9
  60. package/src/Atom/DefinitionList/DefinitionList.tsx +3 -4
  61. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.ts.snap +1 -1
  62. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.tsx.snap +1 -1
  63. package/src/Atom/Heading/Heading.stories.ts +49 -7
  64. package/src/Atom/Heading/Heading.tsx +1 -6
  65. package/src/Atom/Heading/__snapshots__/Heading.stories.ts.snap +9 -1
  66. package/src/Atom/Heading/__snapshots__/Heading.stories.tsx.snap +1 -1
  67. package/src/Atom/Heading/_headings.css +1 -2
  68. package/src/Atom/Icon/Icon.mdx +5 -1
  69. package/src/Atom/Icon/Icon.stories.ts +76 -6
  70. package/src/Atom/Icon/Icon.tsx +1 -8
  71. package/src/Atom/Icon/__snapshots__/Icon.stories.ts.snap +18 -4
  72. package/src/Atom/Icon/__snapshots__/Icon.stories.tsx.snap +1 -1
  73. package/src/Atom/Icon/_icon.css +1 -1
  74. package/src/Atom/Image/Image.stories.ts +4 -3
  75. package/src/Atom/Image/__snapshots__/Image.stories.ts.snap +1 -1
  76. package/src/Atom/Link/Link.stories.ts +74 -7
  77. package/src/Atom/Link/__snapshots__/Link.stories.ts.snap +4 -4
  78. package/src/Atom/Link/__snapshots__/Link.stories.tsx.snap +1 -1
  79. package/src/Atom/Media/Media.stories.ts +34 -5
  80. package/src/Atom/Media/Media.tsx +1 -6
  81. package/src/Atom/Media/__snapshots__/Media.stories.ts.snap +2 -2
  82. package/src/Atom/Media/__snapshots__/Media.stories.tsx.snap +1 -1
  83. package/src/Atom/Media/_media.css +2 -10
  84. package/src/Atom/Spacing/Spacing.stories.ts +45 -31
  85. package/src/Atom/Spacing/__snapshots__/Spacing.stories.ts.snap +5 -4
  86. package/src/Atom/Spacing/spacing.twig +5 -2
  87. package/src/Atom/Table/__snapshots__/Table.stories.ts.snap +1 -1
  88. package/src/Atom/Table/__snapshots__/TableResponsive.stories.ts.snap +1 -1
  89. package/src/Atom/Table/_table.css +1 -2
  90. package/src/Atom/Text/Text.stories.ts +62 -0
  91. package/src/Atom/Text/__snapshots__/{TextSizes.stories.ts.snap → Text.stories.ts.snap} +14 -27
  92. package/src/Atom/Text/__snapshots__/Text.stories.tsx.snap +1 -1
  93. package/src/Atom/Text/_text-sizes.css +2 -4
  94. package/src/Atom/Text/text-style.twig +11 -1
  95. package/src/Atom/Text/text-styles-example.twig +2 -16
  96. package/src/Atom/Video/Video.stories.ts +6 -4
  97. package/src/Atom/Video/Video.tsx +1 -5
  98. package/src/Atom/Video/__snapshots__/Video.stories.ts.snap +1 -1
  99. package/src/Atom/_generic.css +2 -4
  100. package/src/Atom/_hr.css +1 -2
  101. package/src/Component/Accordion/Accordion.stories.ts +26 -8
  102. package/src/Component/Accordion/Accordion.stories.tsx +8 -10
  103. package/src/Component/Accordion/Accordion.tsx +2 -13
  104. package/src/Component/Accordion/AccordionItem.stories.ts +90 -0
  105. package/src/Component/Accordion/Components/AccordionContent.tsx +1 -5
  106. package/src/Component/Accordion/Components/AccordionTitle.tsx +1 -4
  107. package/src/Component/Accordion/Elements/Accordion.ts +1 -1
  108. package/src/Component/Accordion/Elements/AccordionDiv.ts +4 -11
  109. package/src/Component/Accordion/Elements/AccordionGroup.ts +10 -24
  110. package/src/Component/Accordion/Elements/AccordionMobile.ts +4 -4
  111. package/src/Component/Accordion/__snapshots__/Accordion.stories.ts.snap +17 -6
  112. package/src/Component/Accordion/__snapshots__/Accordion.stories.tsx.snap +1 -1
  113. package/src/Component/Accordion/__snapshots__/AccordionItem.stories.ts.snap +90 -0
  114. package/src/Component/Accordion/accordion.css +7 -5
  115. package/src/Component/Accordion/twig/accordion-div.twig +13 -11
  116. package/src/Component/Accordion/twig/accordion-mobile.twig +13 -11
  117. package/src/Component/Breadcrumb/Breadcrumb.stories.ts +14 -0
  118. package/src/Component/Breadcrumb/Breadcrumb.tsx +2 -12
  119. package/src/Component/Breadcrumb/__snapshots__/Breadcrumb.stories.ts.snap +1 -1
  120. package/src/Component/Breadcrumb/__snapshots__/Breadcrumb.stories.tsx.snap +1 -1
  121. package/src/Component/Breadcrumb/breadcrumb.css +1 -4
  122. package/src/Component/Callout/Callout.stories.ts +20 -0
  123. package/src/Component/Callout/__snapshots__/Callout.stories.ts.snap +1 -1
  124. package/src/Component/Callout/callout.css +1 -2
  125. package/src/Component/Card/Card.stories.ts +129 -14
  126. package/src/Component/Card/Card.stories.tsx +2 -2
  127. package/src/Component/Card/Components/CardContent.tsx +1 -5
  128. package/src/Component/Card/__snapshots__/Card.stories.ts.snap +16 -16
  129. package/src/Component/Card/__snapshots__/Card.stories.tsx.snap +1 -1
  130. package/src/Component/Card/card.css +2 -6
  131. package/src/Component/Carousel/Carousel.stories.ts +61 -8
  132. package/src/Component/Carousel/Elements/Carousel.ts +10 -19
  133. package/src/Component/Carousel/__snapshots__/Carousel.stories.ts.snap +288 -2
  134. package/src/Component/Carousel/carousel.css +1 -2
  135. package/src/Component/ContentBlock/Components/ContentBlockContent.tsx +1 -5
  136. package/src/Component/ContentBlock/Components/ContentBlockMedia.tsx +1 -4
  137. package/src/Component/ContentBlock/ContentBlock.stories.ts +63 -13
  138. package/src/Component/ContentBlock/ContentBlock.stories.tsx +2 -2
  139. package/src/Component/ContentBlock/ContentBlock.tsx +1 -5
  140. package/src/Component/ContentBlock/__snapshots__/ContentBlock.stories.ts.snap +11 -11
  141. package/src/Component/ContentBlock/__snapshots__/ContentBlock.stories.tsx.snap +1 -1
  142. package/src/Component/Dialog/Dialog.stories.ts +78 -21
  143. package/src/Component/Dialog/Dialog.stories.tsx +2 -3
  144. package/src/Component/Dialog/Elements/Dialog.ts +7 -16
  145. package/src/Component/Dialog/__snapshots__/Dialog.stories.ts.snap +8 -11
  146. package/src/Component/Dialog/__snapshots__/Dialog.stories.tsx.snap +1 -1
  147. package/src/Component/Dialog/dialog.css +1 -2
  148. package/src/Component/Dialog/dialog.twig +1 -1
  149. package/src/Component/DropMenu/Components/DropMenuContext.tsx +4 -12
  150. package/src/Component/DropMenu/DropMenu.stories.ts +60 -1
  151. package/src/Component/DropMenu/DropMenu.tsx +2 -7
  152. package/src/Component/DropMenu/Elements/DropMenu.ts +21 -91
  153. package/src/Component/DropMenu/__snapshots__/DropMenu.stories.ts.snap +53 -11
  154. package/src/Component/DropMenu/__snapshots__/DropMenu.stories.tsx.snap +1 -1
  155. package/src/Component/DropMenu/drop-menu.css +13 -41
  156. package/src/Component/DropMenu/drop-menu.twig +8 -6
  157. package/src/Component/Filters/Elements/Filters.ts +7 -11
  158. package/src/Component/Filters/FilterItem.stories.ts +180 -0
  159. package/src/Component/Filters/Filters.stories.ts +83 -8
  160. package/src/Component/Filters/__snapshots__/FilterItem.stories.ts.snap +135 -0
  161. package/src/Component/Filters/__snapshots__/Filters.stories.ts.snap +43 -41
  162. package/src/Component/Filters/filter-item.twig +1 -1
  163. package/src/Component/Filters/filters.css +33 -17
  164. package/src/Component/GlobalAlert/Elements/ClosableAlert.ts +8 -7
  165. package/src/Component/GlobalAlert/GlobalAlert.stories.ts +60 -12
  166. package/src/Component/GlobalAlert/GlobalAlert.stories.tsx +1 -2
  167. package/src/Component/GlobalAlert/__snapshots__/GlobalAlert.stories.ts.snap +8 -6
  168. package/src/Component/GlobalAlert/__snapshots__/GlobalAlert.stories.tsx.snap +3 -3
  169. package/src/Component/HeroBanner/HeroBanner.stories.ts +84 -7
  170. package/src/Component/HeroBanner/HeroBanner.stories.tsx +4 -4
  171. package/src/Component/HeroBanner/__snapshots__/HeroBanner.stories.ts.snap +91 -99
  172. package/src/Component/HeroBanner/__snapshots__/HeroBanner.stories.tsx.snap +1 -1
  173. package/src/Component/HeroSearch/HeroSearch.stories.ts +23 -4
  174. package/src/Component/HeroSearch/HeroSearch.stories.tsx +4 -4
  175. package/src/Component/HeroSearch/__snapshots__/HeroSearch.stories.ts.snap +10 -10
  176. package/src/Component/HeroSearch/__snapshots__/HeroSearch.stories.tsx.snap +1 -1
  177. package/src/Component/InPageAlert/InPageAlert.stories.ts +76 -8
  178. package/src/Component/InPageAlert/InPageAlert.stories.tsx +1 -2
  179. package/src/Component/InPageAlert/InPageAlert.tsx +1 -4
  180. package/src/Component/InPageAlert/__snapshots__/InPageAlert.stories.ts.snap +80 -2
  181. package/src/Component/InPageAlert/__snapshots__/InPageAlert.stories.tsx.snap +1 -1
  182. package/src/Component/InPageNavigation/Elements/InPageNavigation.ts +7 -9
  183. package/src/Component/InPageNavigation/Hooks/useInPageNavigation.ts +3 -5
  184. package/src/Component/InPageNavigation/InPageNavigation.stories.ts +44 -9
  185. package/src/Component/InPageNavigation/InPageNavigation.stories.tsx +32 -40
  186. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.ts.snap +152 -5
  187. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.tsx.snap +1 -1
  188. package/src/Component/LinkList/LinkList.stories.ts +23 -0
  189. package/src/Component/LinkList/__snapshots__/LinkList.stories.ts.snap +8 -8
  190. package/src/Component/LinkList/__snapshots__/LinkList.stories.tsx.snap +1 -1
  191. package/src/Component/LinkList/link-list.css +1 -2
  192. package/src/Component/ListItem/Components/ListItemContent.tsx +1 -5
  193. package/src/Component/ListItem/Components/ListItemMedia.tsx +1 -4
  194. package/src/Component/ListItem/ListItem.stories.ts +91 -11
  195. package/src/Component/ListItem/ListItem.stories.tsx +6 -7
  196. package/src/Component/ListItem/__snapshots__/ListItem.stories.ts.snap +1 -1
  197. package/src/Component/ListItem/__snapshots__/ListItem.stories.tsx.snap +1 -1
  198. package/src/Component/ListItem/list-item.css +1 -2
  199. package/src/Component/Navigation/Components/DropdownLevel.tsx +5 -13
  200. package/src/Component/Navigation/Elements/Navigation.ts +6 -13
  201. package/src/Component/Navigation/Navigation.stories.ts +48 -0
  202. package/src/Component/Navigation/__snapshots__/Dropdown.stories.tsx.snap +1 -1
  203. package/src/Component/Navigation/__snapshots__/Navigation.stories.ts.snap +1 -1
  204. package/src/Component/Navigation/__snapshots__/Navigation.stories.tsx.snap +1 -1
  205. package/src/Component/Navigation/_navigation-collapsible.css +2 -4
  206. package/src/Component/Navigation/_navigation-dropdown.css +2 -6
  207. package/src/Component/Navigation/_navigation-mega.css +1 -4
  208. package/src/Component/Navigation/_navigation.css +1 -4
  209. package/src/Component/Pagination/Components/PaginationContext.tsx +5 -19
  210. package/src/Component/Pagination/Components/PaginationItem.tsx +1 -5
  211. package/src/Component/Pagination/Pagination.stories.ts +28 -0
  212. package/src/Component/Pagination/Pagination.tsx +3 -11
  213. package/src/Component/Pagination/__snapshots__/Pagination.stories.ts.snap +3 -3
  214. package/src/Component/Pagination/__snapshots__/Pagination.stories.tsx.snap +1 -1
  215. package/src/Component/Pagination/pagination.css +1 -4
  216. package/src/Component/Popover/Elements/Popover.ts +55 -0
  217. package/src/Component/Popover/Popover.stories.ts +259 -0
  218. package/src/Component/Popover/__snapshots__/Popover.stories.ts.snap +508 -0
  219. package/src/Component/{DropMenu → Popover}/polyfills.js +6 -4
  220. package/src/Component/Popover/popover.css +113 -0
  221. package/src/Component/Popover/popover.entry.js +1 -0
  222. package/src/Component/Popover/popover.twig +27 -0
  223. package/src/Component/ResultsBar/Components/ResultsBarInfo.tsx +2 -7
  224. package/src/Component/ResultsBar/Components/ResultsBarSort.tsx +1 -6
  225. package/src/Component/ResultsBar/ResultsBar.stories.ts +34 -4
  226. package/src/Component/ResultsBar/__snapshots__/ResultsBar.stories.ts.snap +3 -3
  227. package/src/Component/ResultsBar/__snapshots__/ResultsBar.stories.tsx.snap +1 -1
  228. package/src/Component/SideNavigation/SideNavigation.stories.ts +40 -0
  229. package/src/Component/SideNavigation/__snapshots__/SideNavigation.stories.ts.snap +1 -1
  230. package/src/Component/SideNavigation/side-navigation.css +3 -6
  231. package/src/Component/SocialLinks/SocialLinks.stories.ts +20 -0
  232. package/src/Component/SocialLinks/__snapshots__/SocialLinks.stories.ts.snap +5 -5
  233. package/src/Component/SocialShare/SocialShare.stories.ts +37 -0
  234. package/src/Component/SocialShare/SocialShare.tsx +2 -4
  235. package/src/Component/SocialShare/__snapshots__/SocialShare.stories.ts.snap +40 -0
  236. package/src/Component/SocialShare/__snapshots__/SocialShare.stories.tsx.snap +1 -1
  237. package/src/Component/SocialShare/social-share.twig +34 -0
  238. package/src/Component/Steps/StepItem.stories.ts +48 -0
  239. package/src/Component/Steps/Steps.stories.ts +82 -13
  240. package/src/Component/Steps/__snapshots__/StepItem.stories.ts.snap +31 -0
  241. package/src/Component/Steps/__snapshots__/Steps.stories.ts.snap +97 -16
  242. package/src/Component/Steps/steps.css +4 -11
  243. package/src/Component/Sticky/Elements/Sticky.ts +3 -8
  244. package/src/Component/Sticky/Sticky.stories.ts +35 -3
  245. package/src/Component/Sticky/__snapshots__/Sticky.stories.ts.snap +1 -1
  246. package/src/Component/Sticky/__snapshots__/Sticky.stories.tsx.snap +1 -1
  247. package/src/Component/Sticky/sticky.twig +1 -1
  248. package/src/Component/Tabs/Components/Tab.tsx +2 -8
  249. package/src/Component/Tabs/Components/TabPanel.tsx +1 -5
  250. package/src/Component/Tabs/Elements/Tabs.ts +21 -31
  251. package/src/Component/Tabs/TabItem.stories.ts +52 -0
  252. package/src/Component/Tabs/Tabs.stories.ts +51 -8
  253. package/src/Component/Tabs/Tabs.tsx +6 -22
  254. package/src/Component/Tabs/__snapshots__/TabItem.stories.ts.snap +12 -0
  255. package/src/Component/Tabs/__snapshots__/Tabs.stories.ts.snap +127 -11
  256. package/src/Component/Tabs/__snapshots__/Tabs.stories.tsx.snap +1 -1
  257. package/src/Component/Tabs/tab-item.twig +1 -2
  258. package/src/Component/Tabs/tabs.css +56 -59
  259. package/src/Component/Tag/Tag.stories.ts +30 -0
  260. package/src/Component/Tag/Tag.tsx +1 -5
  261. package/src/Component/Tag/__snapshots__/Tag.stories.ts.snap +1 -1
  262. package/src/Component/Tag/__snapshots__/Tag.stories.tsx.snap +1 -1
  263. package/src/Component/Tag/tag.css +1 -4
  264. package/src/Component/UtilityList/Elements/UtilityList.ts +110 -0
  265. package/src/Component/UtilityList/UtilityList.stories.ts +72 -0
  266. package/src/Component/UtilityList/__snapshots__/UtilityList.stories.ts.snap +274 -0
  267. package/src/Component/UtilityList/utility-list.css +40 -0
  268. package/src/Component/UtilityList/utility-list.entry.js +1 -0
  269. package/src/Component/UtilityList/utility-list.twig +66 -0
  270. package/src/Form/Checkbox/FormCheckbox.stories.tsx +1 -3
  271. package/src/Form/Checkbox/FormCheckbox.tsx +4 -25
  272. package/src/Form/Checkbox/__snapshots__/Checkbox.stories.ts.snap +3 -3
  273. package/src/Form/Description/Description.stories.ts +1 -2
  274. package/src/Form/Description/FormStatus.stories.ts +1 -4
  275. package/src/Form/Description/__snapshots__/Description.stories.ts.snap +1 -1
  276. package/src/Form/Description/__snapshots__/FormDescription.stories.tsx.snap +1 -1
  277. package/src/Form/Description/__snapshots__/FormStatus.stories.ts.snap +3 -3
  278. package/src/Form/Form/Form.tsx +1 -3
  279. package/src/Form/Form/__snapshots__/Form.stories.tsx.snap +1 -1
  280. package/src/Form/Form/__snapshots__/FormTitle.stories.tsx.snap +1 -1
  281. package/src/Form/FormItem/FormItem.stories.ts +3 -9
  282. package/src/Form/FormItem/__snapshots__/FormItem.stories.ts.snap +18 -18
  283. package/src/Form/FormItem/__snapshots__/FormItem.stories.tsx.snap +1 -1
  284. package/src/Form/Label/FormLabel.tsx +1 -5
  285. package/src/Form/Label/__snapshots__/FormLabel.stories.tsx.snap +1 -1
  286. package/src/Form/Label/__snapshots__/Label.stories.ts.snap +3 -3
  287. package/src/Form/Radio/FormRadio.stories.tsx +1 -3
  288. package/src/Form/Radio/FormRadio.tsx +4 -25
  289. package/src/Form/Radio/__snapshots__/Radio.stories.ts.snap +9 -9
  290. package/src/Form/Search/__snapshots__/Search.stories.ts.snap +1 -1
  291. package/src/Form/Select/FormSelect.tsx +3 -9
  292. package/src/Form/Select/__snapshots__/FormSelect.stories.tsx.snap +1 -1
  293. package/src/Form/Select/__snapshots__/Select.stories.ts.snap +2 -2
  294. package/src/Form/TextInput/FormText.tsx +3 -9
  295. package/src/Form/TextInput/TextInput.stories.ts +1 -4
  296. package/src/Form/TextInput/__snapshots__/FormText.stories.tsx.snap +1 -1
  297. package/src/Form/TextInput/__snapshots__/InputDivider.stories.ts.snap +1 -1
  298. package/src/Form/TextInput/__snapshots__/TextInput.stories.ts.snap +3 -3
  299. package/src/Form/Textarea/FormTextarea.tsx +3 -9
  300. package/src/Form/Textarea/__snapshots__/FormTextarea.stories.tsx.snap +1 -1
  301. package/src/Form/Textarea/__snapshots__/Textarea.stories.ts.snap +2 -2
  302. package/src/Form/form.css +6 -14
  303. package/src/Introduction.mdx +1 -2
  304. package/src/Layout/Footer/Footer.stories.ts +1 -5
  305. package/src/Layout/Footer/Footer.stories.tsx +2 -3
  306. package/src/Layout/Footer/Footer.tsx +3 -12
  307. package/src/Layout/Footer/__snapshots__/Footer.stories.ts.snap +4 -4
  308. package/src/Layout/Footer/__snapshots__/Footer.stories.tsx.snap +1 -1
  309. package/src/Layout/Grid/Grid.stories.ts +40 -8
  310. package/src/Layout/Grid/Grid.tsx +1 -2
  311. package/src/Layout/Grid/GridItem.stories.ts +63 -0
  312. package/src/Layout/Grid/__snapshots__/Grid.stories.ts.snap +29 -4
  313. package/src/Layout/Grid/__snapshots__/Grid.stories.tsx.snap +1 -1
  314. package/src/Layout/Grid/__snapshots__/GridItem.stories.ts.snap +19 -0
  315. package/src/Layout/Grid/grid-item.twig +3 -9
  316. package/src/Layout/Grid/grid.css +1 -4
  317. package/src/Layout/Header/Elements/GlobalToggle.ts +9 -29
  318. package/src/Layout/Header/__snapshots__/Header.stories.ts.snap +5 -5
  319. package/src/Layout/Header/__snapshots__/Header.stories.tsx.snap +3 -3
  320. package/src/Layout/Masthead/Masthead.stories.ts +1 -4
  321. package/src/Layout/Masthead/__snapshots__/Masthead.stories.ts.snap +3 -3
  322. package/src/Layout/Page/Page.stories.tsx +2 -2
  323. package/src/Layout/Page/__snapshots__/Page.stories.tsx.snap +3 -3
  324. package/src/Layout/Page/page.css +2 -10
  325. package/src/Layout/Section/Background.stories.ts +14 -39
  326. package/src/Layout/Section/Breakouts.stories.ts +3 -0
  327. package/src/Layout/Section/Flow.stories.ts +3 -0
  328. package/src/Layout/Section/Section.stories.ts +93 -11
  329. package/src/Layout/Section/Section.tsx +3 -13
  330. package/src/Layout/Section/SectionGrid.tsx +2 -9
  331. package/src/Layout/Section/__snapshots__/Background.stories.ts.snap +4 -4
  332. package/src/Layout/Section/__snapshots__/Breakouts.stories.ts.snap +1 -1
  333. package/src/Layout/Section/__snapshots__/Flow.stories.ts.snap +1 -1
  334. package/src/Layout/Section/__snapshots__/Section.stories.ts.snap +93 -3
  335. package/src/Layout/Section/__snapshots__/Section.stories.tsx.snap +1 -1
  336. package/src/Layout/Section/__snapshots__/SectionGrid.stories.tsx.snap +1 -1
  337. package/src/Layout/Section/section.css +2 -5
  338. package/src/Layout/Section/section.twig +1 -3
  339. package/src/Layout/Sidebar/Sidebar.stories.ts +46 -4
  340. package/src/Layout/Sidebar/Sidebar.tsx +1 -3
  341. package/src/Layout/Sidebar/__snapshots__/Sidebar.stories.ts.snap +4 -4
  342. package/src/Layout/Sidebar/__snapshots__/Sidebar.stories.tsx.snap +1 -1
  343. package/src/Utility/Context/ImageComponent.tsx +4 -8
  344. package/src/Utility/Context/LinkComponent.tsx +1 -5
  345. package/src/Utility/Drupal/drupal.css +2 -4
  346. package/src/Utility/Elements/breakpoint-loader.ts +4 -10
  347. package/src/Utility/Elements/cookie-compliance.ts +2 -8
  348. package/src/Utility/Elements/disclosure-widget.ts +11 -18
  349. package/src/Utility/Elements/io-loader.ts +4 -6
  350. package/src/Utility/Elements/keyboard.ts +4 -14
  351. package/src/Utility/Hooks/useLocalStorage.ts +5 -18
  352. package/src/Utility/Hooks/useMediaQuery.ts +1 -4
  353. package/src/Utility/Hooks/useToggle.ts +1 -3
  354. package/src/Utility/global.d.ts +1 -5
  355. package/src/Utility/utilities.ts +20 -45
  356. package/src/constants.css +7 -28
  357. package/src/enums.ts +3 -1
  358. package/src/react.ts +5 -21
  359. package/src/tokens.js +2 -2
  360. package/dist/build/chunks/disclosure-widget-DVpnRsTI.js +0 -126
  361. package/dist/build/chunks/disclosure-widget-DVpnRsTI.js.map +0 -1
  362. package/dist/build/chunks/drop-menu.entry-B4TtnC50.js +0 -132
  363. package/dist/build/chunks/drop-menu.entry-B4TtnC50.js.map +0 -1
  364. package/dist/build/chunks/keyboard-rvZ4dfGF.js +0 -104
  365. package/dist/build/chunks/keyboard-rvZ4dfGF.js.map +0 -1
  366. package/dist/build/chunks/polyfills-C-B7iqDG.js.map +0 -1
  367. package/dist/build/chunks/utilities-DXELy_An.js.map +0 -1
  368. package/src/Atom/Text/TextSizes.stories.ts +0 -25
  369. package/src/Atom/Text/text-alignment.twig +0 -5
  370. package/src/Component/Accordion/twig/accordion-example.twig +0 -36
  371. package/src/Component/Tile/README.md +0 -3
  372. package/src/Component/Tile/Tile.stories.ts +0 -49
  373. package/src/Component/Tile/Tile.stories.tsx +0 -35
  374. package/src/Component/Tile/__snapshots__/Tile.stories.ts.snap +0 -57
  375. package/src/Component/Tile/__snapshots__/Tile.stories.tsx.snap +0 -23
@@ -1,23 +1,28 @@
1
1
  import { Meta, StoryObj } from "@storybook/html-vite"
2
+ import DrupalAttribute from "drupal-attribute"
2
3
  import Component from "./dialog.twig"
3
4
  import "./dialog.css"
4
5
  import "./Elements/Dialog"
5
- import {
6
- ButtonModifiers,
7
- Dialog as DialogType,
8
- HeadingTypes,
9
- } from "@pnx-mixtape/ids-shape"
6
+ import { ButtonModifiers, Dialog as DialogType, HeadingTypes } from "@pnx-mixtape/ids-shape"
10
7
 
11
8
  // Deps.
12
9
  import Heading from "../../Atom/Heading/heading.twig"
13
10
  import Button from "../../Atom/Button/button.twig"
14
11
  import Link from "../../Atom/Link/link.twig"
15
- import DrupalAttribute from "drupal-attribute"
16
12
 
17
13
  type MxDialogType = DialogType & {
18
14
  fullscreen?: boolean
19
15
  }
20
16
 
17
+ /**
18
+ * The Dialog component creates a native HTML dialog.
19
+ * It requires the `Dialog` custom element javascript.
20
+ *
21
+ * There should be an associated trigger [Button](/?path=/docs/atom-button--docs) or [Link](/?path=/docs/atom-link--docs)
22
+ * with a valid reference to the dialogs ID: `href="#example-dialog"` or `aria-controls="example-dialog"`.
23
+ *
24
+ * Adding the `[data-close]` attribute to a button inside the dialog will also close the dialog when clicked.
25
+ */
21
26
  const meta: Meta<MxDialogType> = {
22
27
  tags: ["autodocs", "ids-mvp"],
23
28
  component: Component,
@@ -32,14 +37,66 @@ const meta: Meta<MxDialogType> = {
32
37
  link: Button({
33
38
  title: "Let's go",
34
39
  modifiers: [ButtonModifiers.DARK],
35
-
36
40
  attributes: new DrupalAttribute()?.setAttribute("data-close", ""),
37
41
  }),
38
42
  },
39
43
  argTypes: {
40
- open: { control: "boolean" },
41
- modal: { control: "boolean" },
42
- fullscreen: { control: "boolean" },
44
+ id: {
45
+ description: "The dialog id, used to connect the dialog to the relevant trigger.",
46
+ type: {
47
+ name: "string",
48
+ required: true,
49
+ },
50
+ },
51
+ open: {
52
+ description: "Option to set the dialog as open by default.",
53
+ type: "boolean",
54
+ table: {
55
+ defaultValue: { summary: "false" },
56
+ },
57
+ },
58
+ modal: {
59
+ description: "Option to create a Modal dialog.",
60
+ type: "boolean",
61
+ table: {
62
+ defaultValue: { summary: "false" },
63
+ },
64
+ },
65
+ fullscreen: {
66
+ description: "Option to make the dialog display full screen.",
67
+ type: "boolean",
68
+ table: {
69
+ defaultValue: { summary: "false" },
70
+ },
71
+ },
72
+ title: {
73
+ description: "A [Heading](/?path=/docs/atom-heading--docs) component.",
74
+ control: "text",
75
+ table: {
76
+ type: { summary: "Heading" },
77
+ subcategory: "Dialog content",
78
+ },
79
+ },
80
+ content: {
81
+ description: "Content.",
82
+ control: "text",
83
+ type: {
84
+ name: "string",
85
+ required: true,
86
+ },
87
+ table: {
88
+ type: { summary: "WysiwygText" },
89
+ subcategory: "Dialog content",
90
+ },
91
+ },
92
+ link: {
93
+ description: "Optional content [Link](/?path=/docs/atom-link--docs).",
94
+ control: "text",
95
+ table: {
96
+ type: { summary: "Link" },
97
+ subcategory: "Dialog content",
98
+ },
99
+ },
43
100
  },
44
101
  render: args => `
45
102
  ${Link({
@@ -54,8 +111,14 @@ const meta: Meta<MxDialogType> = {
54
111
  export default meta
55
112
  type Story = StoryObj<MxDialogType>
56
113
 
114
+ /**
115
+ * Non-modal dialog, that allows interaction outside of it. See [show()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/show)
116
+ */
57
117
  export const Dialog: Story = {}
58
118
 
119
+ /**
120
+ * Modals display in the top layer and cover all other content (with backdrop). See [showModal()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal)
121
+ */
59
122
  export const Modal: Story = {
60
123
  args: {
61
124
  id: "example-modal",
@@ -65,31 +128,25 @@ export const Modal: Story = {
65
128
  ${Button({
66
129
  title: "Open modal",
67
130
  modifiers: [ButtonModifiers.DARK],
68
-
69
- attributes: new DrupalAttribute()?.setAttribute(
70
- "aria-controls",
71
- "example-modal",
72
- ),
131
+ attributes: new DrupalAttribute()?.setAttribute("aria-controls", "example-modal"),
73
132
  })}
74
133
  ${Component(args)}
75
134
  `,
76
135
  }
77
136
 
137
+ /**
138
+ * Full screen dialogs always trigger the Modal behaviour.
139
+ */
78
140
  export const Fullscreen: Story = {
79
141
  args: {
80
142
  id: "example-fullscreen",
81
143
  fullscreen: true,
82
- modal: true,
83
144
  },
84
145
  render: args => `
85
146
  ${Button({
86
147
  title: "Open fullscreen modal",
87
148
  modifiers: [ButtonModifiers.DARK],
88
-
89
- attributes: new DrupalAttribute()?.setAttribute(
90
- "aria-controls",
91
- "example-fullscreen",
92
- ),
149
+ attributes: new DrupalAttribute()?.setAttribute("aria-controls", "example-fullscreen"),
93
150
  })}
94
151
  ${Component(args)}
95
152
  `,
@@ -17,9 +17,8 @@ const meta: Meta<typeof Component> = {
17
17
  <DialogContent>
18
18
  <Heading as={HeadingTypes.THREE}>Thanks, you're almost done!</Heading>
19
19
  <Text>
20
- To finish the process, you will need to upload a few more documents.
21
- Please have your confirmation email ready before starting. Are you
22
- ready?
20
+ To finish the process, you will need to upload a few more documents. Please have your
21
+ confirmation email ready before starting. Are you ready?
23
22
  </Text>
24
23
  <form method="dialog">
25
24
  <div className="mx-form-actions">
@@ -3,6 +3,7 @@
3
3
  * @file Support opening/closing, and adding a scroll lock to the body.
4
4
  */
5
5
 
6
+ // Needed until Safari supports https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dialog#closedby
6
7
  import { handleOutsideClick, handleEscape } from "../../../Utility/utilities"
7
8
 
8
9
  export default class Dialog extends HTMLElement {
@@ -22,14 +23,10 @@ export default class Dialog extends HTMLElement {
22
23
  const { signal }: AbortController = this.controller
23
24
 
24
25
  // Open on toggle click.
25
- this.openBtns?.forEach(btn =>
26
- btn.addEventListener("click", this.handleOpen, { signal }),
27
- )
26
+ this.openBtns?.forEach(btn => btn.addEventListener("click", this.handleOpen, { signal }))
28
27
 
29
28
  // Close on close button click.
30
- this.closeBtns?.forEach(btn =>
31
- btn.addEventListener("click", this.handleClose, { signal }),
32
- )
29
+ this.closeBtns?.forEach(btn => btn.addEventListener("click", this.handleClose, { signal }))
33
30
 
34
31
  // Close on outside click.
35
32
  document.addEventListener(
@@ -61,9 +58,7 @@ export default class Dialog extends HTMLElement {
61
58
  disconnectedCallback(): void {
62
59
  if (!this.dialog) return
63
60
  if (typeof this.dialog.close === "function") this.dialog.close()
64
- this.openBtns?.forEach((btn: Element) =>
65
- btn.setAttribute("aria-expanded", "false"),
66
- )
61
+ this.openBtns?.forEach((btn: Element) => btn.setAttribute("aria-expanded", "false"))
67
62
  if (this.isModal) document.body.classList.remove(this.scrollLockClass)
68
63
  this.controller.abort()
69
64
  }
@@ -74,18 +69,14 @@ export default class Dialog extends HTMLElement {
74
69
  if (typeof this.dialog.show === "function") {
75
70
  this.isModal ? this.dialog.showModal() : this.dialog.show()
76
71
  }
77
- this.openBtns?.forEach((btn: Element) =>
78
- btn.setAttribute("aria-expanded", "true"),
79
- )
72
+ this.openBtns?.forEach((btn: Element) => btn.setAttribute("aria-expanded", "true"))
80
73
  if (this.isModal) document.body.classList.add(this.scrollLockClass)
81
74
  }
82
75
 
83
76
  handleClose = (): void => {
84
77
  if (!this.dialog) return
85
78
  if (typeof this.dialog.close === "function") this.dialog.close()
86
- this.openBtns?.forEach((btn: Element) =>
87
- btn.setAttribute("aria-expanded", "false"),
88
- )
79
+ this.openBtns?.forEach((btn: Element) => btn.setAttribute("aria-expanded", "false"))
89
80
  if (this.isModal) document.body.classList.remove(this.scrollLockClass)
90
81
  }
91
82
 
@@ -116,7 +107,7 @@ export default class Dialog extends HTMLElement {
116
107
  }
117
108
  }
118
109
 
119
- customElements.define("mx-dialog", Dialog)
110
+ if (!customElements.get("mx-dialog")) customElements.define("mx-dialog", Dialog)
120
111
 
121
112
  declare global {
122
113
  interface HTMLElementTagNameMap {
@@ -1,4 +1,4 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
3
  exports[`Component/Dialog Dialog smoke-test 1`] = `
4
4
  <div class="mx-page default">
@@ -10,7 +10,7 @@ exports[`Component/Dialog Dialog smoke-test 1`] = `
10
10
  </span>
11
11
  </a>
12
12
  <mx-dialog id="unique-0">
13
- <dialog class="mx-dialog ">
13
+ <dialog class="mx-dialog">
14
14
  <button autofocus
15
15
  class="mx-button mx-button--icon-only mx-icon mx-icon--close"
16
16
  data-close
@@ -24,8 +24,7 @@ exports[`Component/Dialog Dialog smoke-test 1`] = `
24
24
  <p>
25
25
  I'm baby air plant hashtag letterpress blue bottle. Cloud bread dreamcatcher everyday carry lumbersexual, iceland cardigan swag chicharrones lo-fi fanny pack affogato freegan XOXO shaman. Shoreditch cloud bread waistcoat tbh XOXO. Chillwave pour-over umami pug glossier health goth.
26
26
  </p>
27
- <button data-close
28
- class="mx-button mx-button--dark"
27
+ <button class="mx-button mx-button--dark"
29
28
  type="button"
30
29
  >
31
30
  <span>
@@ -41,7 +40,7 @@ exports[`Component/Dialog Dialog smoke-test 1`] = `
41
40
  exports[`Component/Dialog Fullscreen smoke-test 1`] = `
42
41
  <div class="mx-page default">
43
42
  <button aria-controls="unique-0"
44
- class="mx-button mx-button--dark"
43
+ class="mx-button mx-button--dark"
45
44
  type="button"
46
45
  >
47
46
  <span>
@@ -65,8 +64,7 @@ exports[`Component/Dialog Fullscreen smoke-test 1`] = `
65
64
  <p>
66
65
  I'm baby air plant hashtag letterpress blue bottle. Cloud bread dreamcatcher everyday carry lumbersexual, iceland cardigan swag chicharrones lo-fi fanny pack affogato freegan XOXO shaman. Shoreditch cloud bread waistcoat tbh XOXO. Chillwave pour-over umami pug glossier health goth.
67
66
  </p>
68
- <button data-close
69
- class="mx-button mx-button--dark"
67
+ <button class="mx-button mx-button--dark"
70
68
  type="button"
71
69
  >
72
70
  <span>
@@ -82,7 +80,7 @@ exports[`Component/Dialog Fullscreen smoke-test 1`] = `
82
80
  exports[`Component/Dialog Modal smoke-test 1`] = `
83
81
  <div class="mx-page default">
84
82
  <button aria-controls="unique-0"
85
- class="mx-button mx-button--dark"
83
+ class="mx-button mx-button--dark"
86
84
  type="button"
87
85
  >
88
86
  <span>
@@ -92,7 +90,7 @@ exports[`Component/Dialog Modal smoke-test 1`] = `
92
90
  <mx-dialog id="unique-0"
93
91
  data-modal
94
92
  >
95
- <dialog class="mx-dialog ">
93
+ <dialog class="mx-dialog">
96
94
  <button autofocus
97
95
  class="mx-button mx-button--icon-only mx-icon mx-icon--close"
98
96
  data-close
@@ -106,8 +104,7 @@ exports[`Component/Dialog Modal smoke-test 1`] = `
106
104
  <p>
107
105
  I'm baby air plant hashtag letterpress blue bottle. Cloud bread dreamcatcher everyday carry lumbersexual, iceland cardigan swag chicharrones lo-fi fanny pack affogato freegan XOXO shaman. Shoreditch cloud bread waistcoat tbh XOXO. Chillwave pour-over umami pug glossier health goth.
108
106
  </p>
109
- <button data-close
110
- class="mx-button mx-button--dark"
107
+ <button class="mx-button mx-button--dark"
111
108
  type="button"
112
109
  >
113
110
  <span>
@@ -1,4 +1,4 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
3
  exports[`Component/Dialog Dialog smoke-test 1`] = `
4
4
  <dialog class="mx-dialog"
@@ -15,8 +15,7 @@
15
15
  overflow: auto hidden;
16
16
  overscroll-behavior: contain;
17
17
  background-color: var(--dialog-background, var(--colour-background));
18
- border: var(--line-width, 1px) solid
19
- var(--line-colour, var(--colour-border));
18
+ border: var(--line-width, 1px) solid var(--line-colour, var(--colour-border));
20
19
  padding: 0;
21
20
  place-self: center;
22
21
  opacity: 0;
@@ -5,7 +5,7 @@
5
5
  ] %}
6
6
  {% set attributes = (attributes ?? create_attribute()).addClass(classes) %}
7
7
 
8
- <mx-dialog id="{{ id }}"{% if modal %} data-modal{% endif %}>
8
+ <mx-dialog id="{{ id }}"{% if modal or fullscreen %} data-modal{% endif %}>
9
9
  <dialog{{ attributes }}{% if open %} open{% endif %}>
10
10
  <button autofocus class="mx-button mx-button--icon-only mx-icon mx-icon--close" data-close>Close dialog</button>
11
11
  <div class="mx-dialog__content mx-vertical-flow">
@@ -36,11 +36,7 @@ type DropMenuContextValues = {
36
36
  type DropMenuProviderProps = PropsWithChildren & {
37
37
  id: string
38
38
  multiple?: boolean
39
- onClick?: (
40
- event: MouseEvent | KeyboardEvent,
41
- key: string,
42
- updated?: string[],
43
- ) => void
39
+ onClick?: (event: MouseEvent | KeyboardEvent, key: string, updated?: string[]) => void
44
40
  closeOnClick?: boolean
45
41
  selectedItem?: string[]
46
42
  focusRef?: RefObject<HTMLElement>
@@ -77,7 +73,7 @@ const DropMenuProvider = ({
77
73
  if (!popoverRef.current || polyfilled.current) return
78
74
  const polyfill = async () => {
79
75
  if (!("anchorName" in document.documentElement.style)) {
80
- const { default: Polyfills } = await import("../polyfills")
76
+ const { default: Polyfills } = await import("../../Popover/polyfills")
81
77
  new Polyfills(popoverRef.current)
82
78
  polyfilled.current = true
83
79
  }
@@ -119,8 +115,7 @@ const DropMenuProvider = ({
119
115
  popoverRef.current.querySelectorAll(":scope > button")
120
116
  if (!items) return
121
117
 
122
- const attachKeyboardMenu = () =>
123
- keyboard.attachMenu(popoverRef.current, items)
118
+ const attachKeyboardMenu = () => keyboard.attachMenu(popoverRef.current, items)
124
119
  popoverRef.current.addEventListener("focusin", attachKeyboardMenu, {
125
120
  signal,
126
121
  })
@@ -137,10 +132,7 @@ const DropMenuProvider = ({
137
132
  }, [on, popoverRef])
138
133
 
139
134
  // Handle item click events.
140
- const handleClick = (
141
- event: MouseEvent | KeyboardEvent,
142
- key: string,
143
- ): void => {
135
+ const handleClick = (event: MouseEvent | KeyboardEvent, key: string): void => {
144
136
  event.preventDefault()
145
137
  let updated: string[] = []
146
138
  if (selected.includes(key)) {
@@ -3,6 +3,10 @@ import Component from "./drop-menu.twig"
3
3
  import "./drop-menu.css"
4
4
  import "./Elements/DropMenu"
5
5
 
6
+ // Deps.
7
+ import "../Popover/popover.css"
8
+ import { PopoverPlacementModifier } from "@pnx-mixtape/ids-shape"
9
+
6
10
  type DropMenuItemType = {
7
11
  label: string
8
12
  href?: string
@@ -13,8 +17,14 @@ type DropMenuType = {
13
17
  items: DropMenuItemType[]
14
18
  label: string
15
19
  id?: string
20
+ role?: "menu" | "tablist"
21
+ placement?: PopoverPlacementModifier
16
22
  }
17
23
 
24
+ /**
25
+ * The DropMenu extends [Popoover](/?path=/docs/component-popover--docs) to support a menu selection.
26
+ * It requires the `DropMenu` custom element javascript.
27
+ */
18
28
  const meta: Meta<DropMenuType> = {
19
29
  tags: ["autodocs", "ids-mvp"],
20
30
  component: Component,
@@ -23,8 +33,46 @@ const meta: Meta<DropMenuType> = {
23
33
  items: [
24
34
  { label: "News", href: "#news" },
25
35
  { label: "Events", href: "#events" },
26
- { label: "Stories", id: "stories" },
36
+ { label: "Stories", href: "#stories" },
27
37
  ],
38
+ placement: PopoverPlacementModifier.BOTTOM_START,
39
+ },
40
+ argTypes: {
41
+ placement: {
42
+ description: "Places the DropMenu relative to the trigger element.",
43
+ control: "select",
44
+ options: Object.values(PopoverPlacementModifier),
45
+ table: {
46
+ defaultValue: { summary: `${PopoverPlacementModifier.BOTTOM_START}` },
47
+ type: { summary: "enum" },
48
+ },
49
+ },
50
+ label: {
51
+ description: "The text to display inside the trigger button",
52
+ type: {
53
+ name: "string",
54
+ required: true,
55
+ },
56
+ },
57
+ items: {
58
+ description:
59
+ "A list of `DropMenuItem<{ label: string, href?: string }>` objects for links or `DropMenuItem<{ label: string, id?: string }>` for buttons.",
60
+ type: {
61
+ name: "other",
62
+ required: true,
63
+ value: "array",
64
+ },
65
+ table: {
66
+ type: { summary: "DropMenuItem[]" },
67
+ },
68
+ },
69
+ role: {
70
+ description:
71
+ "An optional ARIA role attribute for the popover, for use when DropMenuItem is a list of buttons.",
72
+ control: "select",
73
+ options: ["menu", "tablist"],
74
+ type: "string",
75
+ },
28
76
  },
29
77
  }
30
78
 
@@ -34,3 +82,14 @@ type Story = StoryObj<DropMenuType>
34
82
  export const DropMenu: Story = {
35
83
  args: {},
36
84
  }
85
+
86
+ export const Buttons: Story = {
87
+ args: {
88
+ role: "menu",
89
+ items: [
90
+ { label: "News", id: "news" },
91
+ { label: "Events", id: "events" },
92
+ { label: "Stories", id: "stories" },
93
+ ],
94
+ },
95
+ }
@@ -7,11 +7,7 @@ type ContainerProps = ComponentPropsWithoutRef<"div"> &
7
7
  condition: boolean
8
8
  }
9
9
 
10
- const Container = ({
11
- condition,
12
- children,
13
- ...props
14
- }: ContainerProps): JSX.Element =>
10
+ const Container = ({ condition, children, ...props }: ContainerProps): JSX.Element =>
15
11
  condition ? <div {...props}>{children}</div> : <>{children}</>
16
12
 
17
13
  type DropMenuProps = PropsWithChildren & {
@@ -42,8 +38,7 @@ const DropMenu = ({
42
38
  ariaLabel,
43
39
  description = "Results will update when you make a selection. Press escape to close.",
44
40
  }: DropMenuProps): JSX.Element => {
45
- const { dropMenuId, triggerId, descriptionId, popoverRef } =
46
- useDropMenuContext()
41
+ const { dropMenuId, triggerId, descriptionId, popoverRef } = useDropMenuContext()
47
42
 
48
43
  return (
49
44
  <Container className={classNames(className)} condition={!!className}>
@@ -1,51 +1,43 @@
1
1
  /**
2
2
  * DropMenu
3
- * @file Create a DropMenu using the Popover and Anchor APIs
3
+ * @file Create a DropMenu using the Popover and Anchor APIs.
4
+ * Handle's menu item select.
5
+ *
6
+ * Once polyfills are no longer needed, this can just extent HTMLElement
7
+ * instead of Popover.
4
8
  */
5
9
 
6
- import { Keyboard, makeAnchor } from "../../../Utility/utilities"
10
+ import Popover from "../../Popover/Elements/Popover"
7
11
 
8
12
  export type DropMenuEvent = CustomEvent<{
9
13
  event: MouseEvent | KeyboardEvent
10
14
  target: HTMLButtonElement | HTMLAnchorElement
11
15
  }>
12
16
 
13
- export default class DropMenu extends HTMLElement {
14
- internals_: ElementInternals
17
+ export default class DropMenu extends Popover {
15
18
  controller: AbortController
16
- keyboard: Keyboard = new Keyboard()
17
19
  closeOnClick: boolean
18
20
 
19
21
  constructor() {
20
22
  super()
21
- this.internals_ = this.attachInternals()
22
23
  this.controller = new AbortController()
23
24
  }
24
25
 
25
26
  async connectedCallback() {
26
- if (!this.menu || !this.trigger) return
27
+ await super.connectedCallback()
28
+ if (!this.container || !this.trigger) return
27
29
 
28
- // Polyfill anchor (everywhere so far).
29
- if (!("anchorName" in document.documentElement.style)) {
30
- const { default: Polyfills } = await import("../polyfills.js")
31
- new Polyfills(this.menu)
32
- }
33
- // Polyfill popover (FF only)
34
- if (!Object.hasOwn(HTMLElement, "popover")) {
35
- await import("@oddbird/popover-polyfill")
36
- }
37
30
  this.closeOnClick = this.hasAttribute("closeonclick")
38
31
 
39
32
  const { signal }: AbortController = this.controller
40
33
  document.addEventListener(
41
34
  "click",
42
35
  (event: MouseEvent): void => {
43
- const { target } = event
36
+ const targetElement = event.target as HTMLElement
37
+ const selectable = targetElement.closest("a, button")
44
38
  if (
45
- (target as HTMLElement) !== this.menu &&
46
- ![...this.items].includes(
47
- target as HTMLButtonElement | HTMLAnchorElement,
48
- )
39
+ (targetElement as HTMLElement) !== this.container &&
40
+ ![...this.items].includes(selectable as HTMLButtonElement | HTMLAnchorElement)
49
41
  )
50
42
  return
51
43
  this.handleSelect(event)
@@ -61,10 +53,8 @@ export default class DropMenu extends HTMLElement {
61
53
  (event: KeyboardEvent): void => {
62
54
  const { target, key } = event
63
55
  if (
64
- (target as HTMLElement) !== this.menu &&
65
- ![...this.items].includes(
66
- target as HTMLButtonElement | HTMLAnchorElement,
67
- )
56
+ (target as HTMLElement) !== this.container &&
57
+ ![...this.items].includes(target as HTMLButtonElement | HTMLAnchorElement)
68
58
  )
69
59
  return
70
60
  if (key === "Enter") this.handleSelect(event)
@@ -74,27 +64,15 @@ export default class DropMenu extends HTMLElement {
74
64
  signal,
75
65
  },
76
66
  )
77
-
78
- this.keyboard.attachEventListeners(signal)
79
- this.menu.addEventListener("focusin", this.attachKeyboardMenu, {
80
- signal,
81
- })
82
- this.menu.addEventListener("focusout", this.detachKeyboardMenu, {
83
- signal,
84
- })
85
- this.menu.addEventListener("toggle", this.handleToggle, {
86
- signal,
87
- })
88
67
  }
89
68
 
90
69
  disconnectedCallback(): void {
91
70
  this.controller.abort()
92
- this.keyboard.detachMenu()
93
71
  }
94
72
 
95
73
  handleSelect = (event: MouseEvent | KeyboardEvent): void => {
96
74
  const target = event.target as HTMLButtonElement | HTMLAnchorElement
97
- this.items.forEach(item => {
75
+ this.items?.forEach(item => {
98
76
  if (!(item instanceof HTMLButtonElement)) return
99
77
  item.setAttribute("aria-checked", String(item === target))
100
78
  })
@@ -106,64 +84,16 @@ export default class DropMenu extends HTMLElement {
106
84
  target,
107
85
  },
108
86
  })
109
- this.menu.dispatchEvent(newEvent)
110
- if (this.closeOnClick) this.menu.togglePopover()
111
- }
112
-
113
- handleToggle = ({ newState }: ToggleEvent): void => {
114
- const handleClose = () => this.menu.togglePopover()
115
- if (newState === "open") {
116
- this.keyboard.attachPopup(this.menu.id, handleClose)
117
- } else {
118
- this.keyboard.detachPopup(this.menu.id)
119
- }
120
- }
121
-
122
- attachKeyboardMenu = (): void => {
123
- this.keyboard.attachMenu(this.menu, this.items)
124
- }
125
-
126
- detachKeyboardMenu = (): void => {
127
- this.keyboard.detachMenu()
128
- }
129
-
130
- get menu(): HTMLDivElement | null {
131
- const menu: HTMLDivElement | null = this.querySelector("[popover]")
132
- if (!menu) {
133
- throw new Error(`${this.localName} must contain a <div popover> element.`)
134
- }
135
- menu.id = menu.id || this.generatedId()
136
- return menu
137
- }
138
-
139
- get items(): NodeListOf<HTMLButtonElement | HTMLAnchorElement> {
140
- const items: NodeListOf<HTMLButtonElement | HTMLAnchorElement> =
141
- this.menu.querySelectorAll(":scope > *")
142
- if (!items) {
143
- throw new Error(`${this.localName} must contain some menu items.`)
144
- }
145
- return items
146
- }
147
-
148
- get trigger(): HTMLButtonElement | null {
149
- const trigger: HTMLButtonElement | null = this.querySelector(
150
- `[popovertarget=${this.menu?.id}]`,
151
- )
152
- if (!trigger) {
153
- throw new Error(
154
- `${this.localName} must contain a <button popovertarget="${this.menu.id}">`,
155
- )
156
- }
157
- return trigger
87
+ this.container.dispatchEvent(newEvent)
88
+ if (this.closeOnClick) this.container.togglePopover()
158
89
  }
159
90
 
160
- generatedId = (): string => {
161
- const string: string | undefined = this.trigger?.textContent?.trim()
162
- return !string ? "" : makeAnchor(string)
91
+ get items(): NodeListOf<HTMLButtonElement | HTMLAnchorElement> | null {
92
+ return this.container.querySelectorAll("a, button")
163
93
  }
164
94
  }
165
95
 
166
- customElements.define("mx-dropmenu", DropMenu)
96
+ if (!customElements.get("mx-dropmenu")) customElements.define("mx-dropmenu", DropMenu)
167
97
 
168
98
  declare global {
169
99
  interface HTMLElementTagNameMap {