@primer/components 29.1.1 → 30.0.0-rc.9be85598

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 (740) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +10 -0
  3. package/.devcontainer/devcontainer.json +8 -0
  4. package/.eslintrc.json +136 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  6. package/.github/ISSUE_TEMPLATE/new_component_proposal_template.md +41 -0
  7. package/.github/dependabot.yml +18 -0
  8. package/.github/pull_request_template.md +18 -0
  9. package/.github/workflows/ci.yml +31 -0
  10. package/.github/workflows/deploy_preview.yml +47 -0
  11. package/.github/workflows/deploy_production.yml +70 -0
  12. package/.github/workflows/release.yml +35 -0
  13. package/.github/workflows/release_canary.yml +70 -0
  14. package/.github/workflows/release_candidate.yml +60 -0
  15. package/.github/workflows/size.yml +13 -0
  16. package/.github/workflows/stale.yml +26 -0
  17. package/.gitignore +10 -0
  18. package/.npmrc +4 -0
  19. package/.nvmrc +1 -0
  20. package/.storybook/main.js +11 -0
  21. package/.storybook/preview.js +69 -0
  22. package/.vscode/launch.json +21 -0
  23. package/.vscode/settings.json +13 -0
  24. package/@types/@styled-system/index.d.ts +0 -0
  25. package/@types/@styled-system/prop-types/index.d.ts +1 -0
  26. package/@types/@styled-system/props/index.d.ts +1 -0
  27. package/@types/jest-styled-components/index.d.ts +1 -0
  28. package/CHANGELOG.md +13 -1
  29. package/CODEOWNERS +2 -0
  30. package/babel-defines.js +13 -0
  31. package/babel.config.js +39 -0
  32. package/contributor-docs/CODE_OF_CONDUCT.md +76 -0
  33. package/contributor-docs/CONTRIBUTING.md +274 -0
  34. package/contributor-docs/adrs/adr-001-typescript.md +23 -0
  35. package/contributor-docs/adrs/adr-002-behavior-isolation.md +106 -0
  36. package/contributor-docs/behaviors.md +132 -0
  37. package/contributor-docs/component-contents-api-patterns.md +316 -0
  38. package/contributor-docs/principles.md +39 -0
  39. package/dist/browser.esm.js +131 -131
  40. package/dist/browser.esm.js.map +1 -1
  41. package/dist/browser.umd.js +114 -114
  42. package/dist/browser.umd.js.map +1 -1
  43. package/docs/.eslintrc +0 -0
  44. package/docs/.gitignore +91 -0
  45. package/docs/components/PropsList.js +5 -0
  46. package/docs/components/State.js +9 -0
  47. package/docs/components/constants.js +34 -0
  48. package/docs/components/index.js +2 -0
  49. package/docs/content/ActionList.mdx +72 -0
  50. package/docs/content/ActionMenu.mdx +80 -0
  51. package/docs/content/AnchoredOverlay.mdx +37 -0
  52. package/docs/content/Avatar.mdx +33 -0
  53. package/docs/content/AvatarStack.mdx +43 -0
  54. package/docs/content/BorderBox.md +46 -0
  55. package/docs/content/Box.md +74 -0
  56. package/docs/content/BranchName.md +18 -0
  57. package/docs/content/Breadcrumbs.md +52 -0
  58. package/docs/content/Buttons.md +56 -0
  59. package/docs/content/CircleBadge.md +45 -0
  60. package/docs/content/CircleOcticon.md +18 -0
  61. package/docs/content/CounterLabel.md +32 -0
  62. package/docs/content/Details.md +105 -0
  63. package/docs/content/Dialog.md +108 -0
  64. package/docs/content/Dialog2.mdx +179 -0
  65. package/docs/content/Dropdown.md +72 -0
  66. package/docs/content/DropdownMenu.mdx +49 -0
  67. package/docs/content/FilterList.md +44 -0
  68. package/docs/content/FilteredSearch.md +39 -0
  69. package/docs/content/Flash.md +44 -0
  70. package/docs/content/Flex.md +58 -0
  71. package/docs/content/FormGroup.md +46 -0
  72. package/docs/content/Grid.md +59 -0
  73. package/docs/content/Header.md +79 -0
  74. package/docs/content/Heading.md +22 -0
  75. package/docs/content/Label.md +42 -0
  76. package/docs/content/LabelGroup.md +31 -0
  77. package/docs/content/Link.md +37 -0
  78. package/docs/content/Overlay.mdx +94 -0
  79. package/docs/content/Pagehead.md +27 -0
  80. package/docs/content/Pagination.md +187 -0
  81. package/docs/content/PointerBox.md +81 -0
  82. package/docs/content/Popover.md +137 -0
  83. package/docs/content/Portal.mdx +78 -0
  84. package/docs/content/Position.md +100 -0
  85. package/docs/content/ProgressBar.mdx +29 -0
  86. package/docs/content/SelectMenu.md +435 -0
  87. package/docs/content/SelectPanel.mdx +67 -0
  88. package/docs/content/SideNav.md +179 -0
  89. package/docs/content/Spinner.mdx +32 -0
  90. package/docs/content/StateLabel.md +35 -0
  91. package/docs/content/StyledOcticon.md +36 -0
  92. package/docs/content/SubNav.md +102 -0
  93. package/docs/content/TabNav.md +50 -0
  94. package/docs/content/Text.md +31 -0
  95. package/docs/content/TextInput.md +34 -0
  96. package/docs/content/Timeline.md +138 -0
  97. package/docs/content/Tooltip.md +41 -0
  98. package/docs/content/Truncate.md +64 -0
  99. package/docs/content/UnderlineNav.md +53 -0
  100. package/docs/content/anchoredPosition.mdx +163 -0
  101. package/docs/content/core-concepts.md +70 -0
  102. package/docs/content/focusTrap.mdx +103 -0
  103. package/docs/content/focusZone.mdx +145 -0
  104. package/docs/content/getting-started.md +138 -0
  105. package/docs/content/index.md +33 -0
  106. package/docs/content/linting.md +35 -0
  107. package/docs/content/overriding-styles.mdx +81 -0
  108. package/docs/content/philosophy.md +23 -0
  109. package/docs/content/primer-theme.md +89 -0
  110. package/docs/content/ssr.mdx +43 -0
  111. package/docs/content/system-props.mdx +37 -0
  112. package/docs/content/theme-reference.md +16 -0
  113. package/docs/content/theming.md +249 -0
  114. package/docs/content/useOnEscapePress.mdx +56 -0
  115. package/docs/content/useOnOutsideClick.mdx +57 -0
  116. package/docs/content/useOpenAndCloseFocus.mdx +49 -0
  117. package/docs/content/useOverlay.mdx +62 -0
  118. package/docs/content/useSafeTimeout.mdx +32 -0
  119. package/docs/gatsby-config.js +30 -0
  120. package/docs/gatsby-node.js +101 -0
  121. package/docs/package-lock.json +20979 -0
  122. package/docs/package.json +36 -0
  123. package/docs/src/@primer/gatsby-theme-doctocat/components/hero.js +21 -0
  124. package/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js +84 -0
  125. package/docs/src/@primer/gatsby-theme-doctocat/components/live-preview-wrapper.js +39 -0
  126. package/docs/src/@primer/gatsby-theme-doctocat/components/nav-dropdown.js +48 -0
  127. package/docs/src/@primer/gatsby-theme-doctocat/components/wrap-page-element.js +25 -0
  128. package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +54 -0
  129. package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +127 -0
  130. package/docs/src/@primer/gatsby-theme-doctocat/primer-components-hero.svg +1411 -0
  131. package/docs/src/props.js +77 -0
  132. package/jest.config.js +13 -0
  133. package/lib/ActionList/Item.js +1 -1
  134. package/lib/Breadcrumbs.d.ts +40 -0
  135. package/lib/{Breadcrumb.js → Breadcrumbs.js} +31 -21
  136. package/lib/__tests__/ActionList.d.ts +1 -0
  137. package/lib/__tests__/ActionList.js +64 -0
  138. package/lib/__tests__/ActionMenu.d.ts +1 -0
  139. package/lib/__tests__/ActionMenu.js +151 -0
  140. package/lib/__tests__/AnchoredOverlay.d.ts +1 -0
  141. package/lib/__tests__/AnchoredOverlay.js +160 -0
  142. package/lib/__tests__/Avatar.d.ts +1 -0
  143. package/lib/__tests__/Avatar.js +67 -0
  144. package/lib/__tests__/AvatarStack.d.ts +1 -0
  145. package/lib/__tests__/AvatarStack.js +68 -0
  146. package/lib/__tests__/BorderBox.d.ts +1 -0
  147. package/lib/__tests__/BorderBox.js +58 -0
  148. package/lib/__tests__/Box.d.ts +1 -0
  149. package/lib/__tests__/Box.js +78 -0
  150. package/lib/__tests__/BranchName.d.ts +1 -0
  151. package/lib/__tests__/BranchName.js +36 -0
  152. package/lib/__tests__/Breadcrumbs.d.ts +1 -0
  153. package/lib/__tests__/Breadcrumbs.js +37 -0
  154. package/lib/__tests__/BreadcrumbsItem.d.ts +1 -0
  155. package/lib/__tests__/BreadcrumbsItem.js +49 -0
  156. package/lib/__tests__/Button.d.ts +1 -0
  157. package/lib/__tests__/Button.js +143 -0
  158. package/lib/__tests__/Caret.d.ts +1 -0
  159. package/lib/__tests__/Caret.js +52 -0
  160. package/lib/__tests__/CircleBadge.d.ts +1 -0
  161. package/lib/__tests__/CircleBadge.js +83 -0
  162. package/lib/__tests__/CircleOcticon.d.ts +1 -0
  163. package/lib/__tests__/CircleOcticon.js +71 -0
  164. package/lib/__tests__/CounterLabel.d.ts +1 -0
  165. package/lib/__tests__/CounterLabel.js +58 -0
  166. package/lib/__tests__/Details.d.ts +1 -0
  167. package/lib/__tests__/Details.js +117 -0
  168. package/lib/__tests__/Dialog.d.ts +1 -0
  169. package/lib/__tests__/Dialog.js +184 -0
  170. package/lib/__tests__/Dropdown.d.ts +1 -0
  171. package/lib/__tests__/Dropdown.js +63 -0
  172. package/lib/__tests__/DropdownMenu.d.ts +1 -0
  173. package/lib/__tests__/DropdownMenu.js +150 -0
  174. package/lib/__tests__/FilterList.d.ts +1 -0
  175. package/lib/__tests__/FilterList.js +36 -0
  176. package/lib/__tests__/FilterListItem.d.ts +1 -0
  177. package/lib/__tests__/FilterListItem.js +46 -0
  178. package/lib/__tests__/FilteredSearch.d.ts +1 -0
  179. package/lib/__tests__/FilteredSearch.js +36 -0
  180. package/lib/__tests__/Flash.d.ts +1 -0
  181. package/lib/__tests__/Flash.js +62 -0
  182. package/lib/__tests__/Flex.d.ts +1 -0
  183. package/lib/__tests__/Flex.js +74 -0
  184. package/lib/__tests__/FormGroup.d.ts +1 -0
  185. package/lib/__tests__/FormGroup.js +54 -0
  186. package/lib/__tests__/Grid.d.ts +1 -0
  187. package/lib/__tests__/Grid.js +104 -0
  188. package/lib/__tests__/Header.d.ts +1 -0
  189. package/lib/__tests__/Header.js +58 -0
  190. package/lib/__tests__/Heading.d.ts +1 -0
  191. package/lib/__tests__/Heading.js +109 -0
  192. package/lib/__tests__/Label.d.ts +1 -0
  193. package/lib/__tests__/Label.js +46 -0
  194. package/lib/__tests__/LabelGroup.d.ts +1 -0
  195. package/lib/__tests__/LabelGroup.js +38 -0
  196. package/lib/__tests__/Link.d.ts +1 -0
  197. package/lib/__tests__/Link.js +70 -0
  198. package/lib/__tests__/Overlay.d.ts +1 -0
  199. package/lib/__tests__/Overlay.js +145 -0
  200. package/lib/__tests__/Pagehead.d.ts +1 -0
  201. package/lib/__tests__/Pagehead.js +37 -0
  202. package/lib/__tests__/Pagination/Pagination.d.ts +1 -0
  203. package/lib/__tests__/Pagination/Pagination.js +47 -0
  204. package/lib/__tests__/Pagination/PaginationModel.d.ts +1 -0
  205. package/lib/__tests__/Pagination/PaginationModel.js +186 -0
  206. package/lib/__tests__/PointerBox.d.ts +1 -0
  207. package/lib/__tests__/PointerBox.js +46 -0
  208. package/lib/__tests__/Popover.d.ts +1 -0
  209. package/lib/__tests__/Popover.js +66 -0
  210. package/lib/__tests__/Portal.d.ts +1 -0
  211. package/lib/__tests__/Portal.js +124 -0
  212. package/lib/__tests__/Position.d.ts +1 -0
  213. package/lib/__tests__/Position.js +143 -0
  214. package/lib/__tests__/ProgressBar.d.ts +1 -0
  215. package/lib/__tests__/ProgressBar.js +68 -0
  216. package/lib/__tests__/SelectMenu.d.ts +1 -0
  217. package/lib/__tests__/SelectMenu.js +155 -0
  218. package/lib/__tests__/SelectPanel.d.ts +1 -0
  219. package/lib/__tests__/SelectPanel.js +80 -0
  220. package/lib/__tests__/SideNav.d.ts +1 -0
  221. package/lib/__tests__/SideNav.js +71 -0
  222. package/lib/__tests__/Spinner.d.ts +1 -0
  223. package/lib/__tests__/Spinner.js +53 -0
  224. package/lib/__tests__/StateLabel.d.ts +1 -0
  225. package/lib/__tests__/StateLabel.js +71 -0
  226. package/lib/__tests__/StyledOcticon.d.ts +1 -0
  227. package/lib/__tests__/StyledOcticon.js +40 -0
  228. package/lib/__tests__/SubNav.d.ts +1 -0
  229. package/lib/__tests__/SubNav.js +62 -0
  230. package/lib/__tests__/SubNavLink.d.ts +1 -0
  231. package/lib/__tests__/SubNavLink.js +49 -0
  232. package/lib/__tests__/TabNav.d.ts +1 -0
  233. package/lib/__tests__/TabNav.js +49 -0
  234. package/lib/__tests__/Text.d.ts +1 -0
  235. package/lib/__tests__/Text.js +105 -0
  236. package/lib/__tests__/TextInput.d.ts +1 -0
  237. package/lib/__tests__/TextInput.js +78 -0
  238. package/lib/__tests__/ThemeProvider.d.ts +1 -0
  239. package/lib/__tests__/ThemeProvider.js +444 -0
  240. package/lib/__tests__/Timeline.d.ts +1 -0
  241. package/lib/__tests__/Timeline.js +75 -0
  242. package/lib/__tests__/Tooltip.d.ts +1 -0
  243. package/lib/__tests__/Tooltip.js +69 -0
  244. package/lib/__tests__/Truncate.d.ts +1 -0
  245. package/lib/__tests__/Truncate.js +63 -0
  246. package/lib/__tests__/UnderlineNav.d.ts +1 -0
  247. package/lib/__tests__/UnderlineNav.js +72 -0
  248. package/lib/__tests__/UnderlineNavLink.d.ts +1 -0
  249. package/lib/__tests__/UnderlineNavLink.js +51 -0
  250. package/lib/__tests__/behaviors/anchoredPosition.d.ts +1 -0
  251. package/lib/__tests__/behaviors/anchoredPosition.js +390 -0
  252. package/lib/__tests__/behaviors/focusTrap.d.ts +1 -0
  253. package/lib/__tests__/behaviors/focusTrap.js +234 -0
  254. package/lib/__tests__/behaviors/focusZone.d.ts +1 -0
  255. package/lib/__tests__/behaviors/focusZone.js +570 -0
  256. package/lib/__tests__/behaviors/iterateFocusableElements.d.ts +1 -0
  257. package/lib/__tests__/behaviors/iterateFocusableElements.js +55 -0
  258. package/lib/__tests__/filterObject.d.ts +1 -0
  259. package/lib/__tests__/filterObject.js +30 -0
  260. package/lib/__tests__/hooks/useAnchoredPosition.d.ts +1 -0
  261. package/lib/__tests__/hooks/useAnchoredPosition.js +54 -0
  262. package/lib/__tests__/hooks/useOnEscapePress.d.ts +1 -0
  263. package/lib/__tests__/hooks/useOnEscapePress.js +32 -0
  264. package/lib/__tests__/hooks/useOnOutsideClick.d.ts +1 -0
  265. package/lib/__tests__/hooks/useOnOutsideClick.js +87 -0
  266. package/lib/__tests__/hooks/useOpenAndCloseFocus.d.ts +1 -0
  267. package/lib/__tests__/hooks/useOpenAndCloseFocus.js +60 -0
  268. package/lib/__tests__/hooks/useProvidedStateOrCreate.d.ts +1 -0
  269. package/lib/__tests__/hooks/useProvidedStateOrCreate.js +45 -0
  270. package/lib/__tests__/theme.d.ts +1 -0
  271. package/lib/__tests__/theme.js +36 -0
  272. package/lib/__tests__/themeGet.d.ts +1 -0
  273. package/lib/__tests__/themeGet.js +25 -0
  274. package/lib/__tests__/useSafeTimeout.d.ts +1 -0
  275. package/lib/__tests__/useSafeTimeout.js +45 -0
  276. package/lib/index.d.ts +2 -2
  277. package/lib/index.js +8 -2
  278. package/lib/stories/ActionList.stories.js +382 -0
  279. package/lib/stories/ActionMenu.stories.js +338 -0
  280. package/lib/stories/AnchoredOverlay.stories.js +127 -0
  281. package/lib/stories/AvatarStack.stories.js +49 -0
  282. package/lib/stories/Button.stories.js +114 -0
  283. package/lib/stories/ConfirmationDialog.stories.js +111 -0
  284. package/lib/stories/Dialog.stories.js +265 -0
  285. package/lib/stories/DropdownMenu.stories.js +122 -0
  286. package/lib/stories/Overlay.stories.js +185 -0
  287. package/lib/stories/Portal.stories.js +104 -0
  288. package/lib/stories/SelectPanel.stories.js +342 -0
  289. package/lib/stories/ThemeProvider.stories.js +102 -0
  290. package/lib/stories/useAnchoredPosition.stories.js +351 -0
  291. package/lib/stories/useFocusTrap.stories.js +356 -0
  292. package/lib/stories/useFocusZone.stories.js +599 -0
  293. package/lib/utils/testing.d.ts +0 -1
  294. package/lib-esm/ActionList/Item.js +1 -1
  295. package/lib-esm/Breadcrumbs.d.ts +40 -0
  296. package/lib-esm/{Breadcrumb.js → Breadcrumbs.js} +28 -19
  297. package/lib-esm/__tests__/ActionList.d.ts +1 -0
  298. package/lib-esm/__tests__/ActionList.js +52 -0
  299. package/lib-esm/__tests__/ActionMenu.d.ts +1 -0
  300. package/lib-esm/__tests__/ActionMenu.js +139 -0
  301. package/lib-esm/__tests__/AnchoredOverlay.d.ts +1 -0
  302. package/lib-esm/__tests__/AnchoredOverlay.js +134 -0
  303. package/lib-esm/__tests__/Avatar.d.ts +1 -0
  304. package/lib-esm/__tests__/Avatar.js +56 -0
  305. package/lib-esm/__tests__/AvatarStack.d.ts +1 -0
  306. package/lib-esm/__tests__/AvatarStack.js +55 -0
  307. package/lib-esm/__tests__/BorderBox.d.ts +1 -0
  308. package/lib-esm/__tests__/BorderBox.js +47 -0
  309. package/lib-esm/__tests__/Box.d.ts +1 -0
  310. package/lib-esm/__tests__/Box.js +67 -0
  311. package/lib-esm/__tests__/BranchName.d.ts +1 -0
  312. package/lib-esm/__tests__/BranchName.js +26 -0
  313. package/lib-esm/__tests__/Breadcrumbs.d.ts +1 -0
  314. package/lib-esm/__tests__/Breadcrumbs.js +27 -0
  315. package/lib-esm/__tests__/BreadcrumbsItem.d.ts +1 -0
  316. package/lib-esm/__tests__/BreadcrumbsItem.js +39 -0
  317. package/lib-esm/__tests__/Button.d.ts +1 -0
  318. package/lib-esm/__tests__/Button.js +133 -0
  319. package/lib-esm/__tests__/Caret.d.ts +1 -0
  320. package/lib-esm/__tests__/Caret.js +42 -0
  321. package/lib-esm/__tests__/CircleBadge.d.ts +1 -0
  322. package/lib-esm/__tests__/CircleBadge.js +70 -0
  323. package/lib-esm/__tests__/CircleOcticon.d.ts +1 -0
  324. package/lib-esm/__tests__/CircleOcticon.js +59 -0
  325. package/lib-esm/__tests__/CounterLabel.d.ts +1 -0
  326. package/lib-esm/__tests__/CounterLabel.js +47 -0
  327. package/lib-esm/__tests__/Details.d.ts +1 -0
  328. package/lib-esm/__tests__/Details.js +107 -0
  329. package/lib-esm/__tests__/Dialog.d.ts +1 -0
  330. package/lib-esm/__tests__/Dialog.js +171 -0
  331. package/lib-esm/__tests__/Dropdown.d.ts +1 -0
  332. package/lib-esm/__tests__/Dropdown.js +53 -0
  333. package/lib-esm/__tests__/DropdownMenu.d.ts +1 -0
  334. package/lib-esm/__tests__/DropdownMenu.js +137 -0
  335. package/lib-esm/__tests__/FilterList.d.ts +1 -0
  336. package/lib-esm/__tests__/FilterList.js +26 -0
  337. package/lib-esm/__tests__/FilterListItem.d.ts +1 -0
  338. package/lib-esm/__tests__/FilterListItem.js +36 -0
  339. package/lib-esm/__tests__/FilteredSearch.d.ts +1 -0
  340. package/lib-esm/__tests__/FilteredSearch.js +26 -0
  341. package/lib-esm/__tests__/Flash.d.ts +1 -0
  342. package/lib-esm/__tests__/Flash.js +51 -0
  343. package/lib-esm/__tests__/Flex.d.ts +1 -0
  344. package/lib-esm/__tests__/Flex.js +64 -0
  345. package/lib-esm/__tests__/FormGroup.d.ts +1 -0
  346. package/lib-esm/__tests__/FormGroup.js +44 -0
  347. package/lib-esm/__tests__/Grid.d.ts +1 -0
  348. package/lib-esm/__tests__/Grid.js +94 -0
  349. package/lib-esm/__tests__/Header.d.ts +1 -0
  350. package/lib-esm/__tests__/Header.js +48 -0
  351. package/lib-esm/__tests__/Heading.d.ts +1 -0
  352. package/lib-esm/__tests__/Heading.js +99 -0
  353. package/lib-esm/__tests__/Label.d.ts +1 -0
  354. package/lib-esm/__tests__/Label.js +36 -0
  355. package/lib-esm/__tests__/LabelGroup.d.ts +1 -0
  356. package/lib-esm/__tests__/LabelGroup.js +26 -0
  357. package/lib-esm/__tests__/Link.d.ts +1 -0
  358. package/lib-esm/__tests__/Link.js +60 -0
  359. package/lib-esm/__tests__/Overlay.d.ts +1 -0
  360. package/lib-esm/__tests__/Overlay.js +123 -0
  361. package/lib-esm/__tests__/Pagehead.d.ts +1 -0
  362. package/lib-esm/__tests__/Pagehead.js +26 -0
  363. package/lib-esm/__tests__/Pagination/Pagination.d.ts +1 -0
  364. package/lib-esm/__tests__/Pagination/Pagination.js +35 -0
  365. package/lib-esm/__tests__/Pagination/PaginationModel.d.ts +1 -0
  366. package/lib-esm/__tests__/Pagination/PaginationModel.js +182 -0
  367. package/lib-esm/__tests__/PointerBox.d.ts +1 -0
  368. package/lib-esm/__tests__/PointerBox.js +36 -0
  369. package/lib-esm/__tests__/Popover.d.ts +1 -0
  370. package/lib-esm/__tests__/Popover.js +53 -0
  371. package/lib-esm/__tests__/Portal.d.ts +1 -0
  372. package/lib-esm/__tests__/Portal.js +104 -0
  373. package/lib-esm/__tests__/Position.d.ts +1 -0
  374. package/lib-esm/__tests__/Position.js +133 -0
  375. package/lib-esm/__tests__/ProgressBar.d.ts +1 -0
  376. package/lib-esm/__tests__/ProgressBar.js +58 -0
  377. package/lib-esm/__tests__/SelectMenu.d.ts +1 -0
  378. package/lib-esm/__tests__/SelectMenu.js +145 -0
  379. package/lib-esm/__tests__/SelectPanel.d.ts +1 -0
  380. package/lib-esm/__tests__/SelectPanel.js +65 -0
  381. package/lib-esm/__tests__/SideNav.d.ts +1 -0
  382. package/lib-esm/__tests__/SideNav.js +60 -0
  383. package/lib-esm/__tests__/Spinner.d.ts +1 -0
  384. package/lib-esm/__tests__/Spinner.js +43 -0
  385. package/lib-esm/__tests__/StateLabel.d.ts +1 -0
  386. package/lib-esm/__tests__/StateLabel.js +61 -0
  387. package/lib-esm/__tests__/StyledOcticon.d.ts +1 -0
  388. package/lib-esm/__tests__/StyledOcticon.js +29 -0
  389. package/lib-esm/__tests__/SubNav.d.ts +1 -0
  390. package/lib-esm/__tests__/SubNav.js +50 -0
  391. package/lib-esm/__tests__/SubNavLink.d.ts +1 -0
  392. package/lib-esm/__tests__/SubNavLink.js +39 -0
  393. package/lib-esm/__tests__/TabNav.d.ts +1 -0
  394. package/lib-esm/__tests__/TabNav.js +39 -0
  395. package/lib-esm/__tests__/Text.d.ts +1 -0
  396. package/lib-esm/__tests__/Text.js +93 -0
  397. package/lib-esm/__tests__/TextInput.d.ts +1 -0
  398. package/lib-esm/__tests__/TextInput.js +68 -0
  399. package/lib-esm/__tests__/ThemeProvider.d.ts +1 -0
  400. package/lib-esm/__tests__/ThemeProvider.js +408 -0
  401. package/lib-esm/__tests__/Timeline.d.ts +1 -0
  402. package/lib-esm/__tests__/Timeline.js +65 -0
  403. package/lib-esm/__tests__/Tooltip.d.ts +1 -0
  404. package/lib-esm/__tests__/Tooltip.js +59 -0
  405. package/lib-esm/__tests__/Truncate.d.ts +1 -0
  406. package/lib-esm/__tests__/Truncate.js +53 -0
  407. package/lib-esm/__tests__/UnderlineNav.d.ts +1 -0
  408. package/lib-esm/__tests__/UnderlineNav.js +60 -0
  409. package/lib-esm/__tests__/UnderlineNavLink.d.ts +1 -0
  410. package/lib-esm/__tests__/UnderlineNavLink.js +41 -0
  411. package/lib-esm/__tests__/behaviors/anchoredPosition.d.ts +1 -0
  412. package/lib-esm/__tests__/behaviors/anchoredPosition.js +388 -0
  413. package/lib-esm/__tests__/behaviors/focusTrap.d.ts +1 -0
  414. package/lib-esm/__tests__/behaviors/focusTrap.js +227 -0
  415. package/lib-esm/__tests__/behaviors/focusZone.d.ts +1 -0
  416. package/lib-esm/__tests__/behaviors/focusZone.js +487 -0
  417. package/lib-esm/__tests__/behaviors/iterateFocusableElements.d.ts +1 -0
  418. package/lib-esm/__tests__/behaviors/iterateFocusableElements.js +48 -0
  419. package/lib-esm/__tests__/filterObject.d.ts +1 -0
  420. package/lib-esm/__tests__/filterObject.js +27 -0
  421. package/lib-esm/__tests__/hooks/useAnchoredPosition.d.ts +1 -0
  422. package/lib-esm/__tests__/hooks/useAnchoredPosition.js +46 -0
  423. package/lib-esm/__tests__/hooks/useOnEscapePress.d.ts +1 -0
  424. package/lib-esm/__tests__/hooks/useOnEscapePress.js +23 -0
  425. package/lib-esm/__tests__/hooks/useOnOutsideClick.d.ts +1 -0
  426. package/lib-esm/__tests__/hooks/useOnOutsideClick.js +68 -0
  427. package/lib-esm/__tests__/hooks/useOpenAndCloseFocus.d.ts +1 -0
  428. package/lib-esm/__tests__/hooks/useOpenAndCloseFocus.js +52 -0
  429. package/lib-esm/__tests__/hooks/useProvidedStateOrCreate.d.ts +1 -0
  430. package/lib-esm/__tests__/hooks/useProvidedStateOrCreate.js +36 -0
  431. package/lib-esm/__tests__/theme.d.ts +1 -0
  432. package/lib-esm/__tests__/theme.js +33 -0
  433. package/lib-esm/__tests__/themeGet.d.ts +1 -0
  434. package/lib-esm/__tests__/themeGet.js +22 -0
  435. package/lib-esm/__tests__/useSafeTimeout.d.ts +1 -0
  436. package/lib-esm/__tests__/useSafeTimeout.js +39 -0
  437. package/lib-esm/index.d.ts +2 -2
  438. package/lib-esm/index.js +1 -1
  439. package/lib-esm/stories/ActionList.stories.js +334 -0
  440. package/lib-esm/stories/ActionMenu.stories.js +293 -0
  441. package/lib-esm/stories/AnchoredOverlay.stories.js +101 -0
  442. package/lib-esm/stories/AvatarStack.stories.js +32 -0
  443. package/lib-esm/stories/Button.stories.js +78 -0
  444. package/lib-esm/stories/ConfirmationDialog.stories.js +86 -0
  445. package/lib-esm/stories/Dialog.stories.js +240 -0
  446. package/lib-esm/stories/DropdownMenu.stories.js +94 -0
  447. package/lib-esm/stories/Overlay.stories.js +154 -0
  448. package/lib-esm/stories/Portal.stories.js +68 -0
  449. package/lib-esm/stories/SelectPanel.stories.js +284 -0
  450. package/lib-esm/stories/ThemeProvider.stories.js +83 -0
  451. package/lib-esm/stories/useAnchoredPosition.stories.js +313 -0
  452. package/lib-esm/stories/useFocusTrap.stories.js +309 -0
  453. package/lib-esm/stories/useFocusZone.stories.js +554 -0
  454. package/lib-esm/utils/testing.d.ts +0 -1
  455. package/migrating.md +250 -0
  456. package/now.json +17 -0
  457. package/package-lock.json +29072 -0
  458. package/package.json +10 -9
  459. package/rollup.config.js +36 -0
  460. package/script/build +19 -0
  461. package/script/build-storybook +10 -0
  462. package/script/setup +12 -0
  463. package/src/ActionList/Divider.tsx +25 -0
  464. package/src/ActionList/Group.tsx +45 -0
  465. package/src/ActionList/Header.tsx +74 -0
  466. package/src/ActionList/Item.tsx +460 -0
  467. package/src/ActionList/List.tsx +253 -0
  468. package/src/ActionList/index.ts +21 -0
  469. package/src/ActionMenu.tsx +106 -0
  470. package/src/AnchoredOverlay/AnchoredOverlay.tsx +180 -0
  471. package/src/AnchoredOverlay/index.ts +2 -0
  472. package/src/Avatar.tsx +46 -0
  473. package/src/AvatarPair.tsx +35 -0
  474. package/src/AvatarStack.tsx +161 -0
  475. package/src/BaseStyles.tsx +53 -0
  476. package/src/BorderBox.tsx +18 -0
  477. package/src/Box.tsx +54 -0
  478. package/src/BranchName.tsx +19 -0
  479. package/src/Breadcrumbs.tsx +101 -0
  480. package/src/Button/Button.tsx +40 -0
  481. package/src/Button/ButtonBase.tsx +43 -0
  482. package/src/Button/ButtonClose.tsx +40 -0
  483. package/src/Button/ButtonDanger.tsx +43 -0
  484. package/src/Button/ButtonGroup.tsx +55 -0
  485. package/src/Button/ButtonInvisible.tsx +27 -0
  486. package/src/Button/ButtonOutline.tsx +43 -0
  487. package/src/Button/ButtonPrimary.tsx +41 -0
  488. package/src/Button/ButtonStyles.tsx +36 -0
  489. package/src/Button/ButtonTableList.tsx +58 -0
  490. package/src/Button/index.ts +16 -0
  491. package/src/Caret.tsx +133 -0
  492. package/src/CircleBadge.tsx +55 -0
  493. package/src/CircleOcticon.tsx +37 -0
  494. package/src/CounterLabel.tsx +52 -0
  495. package/src/Details.tsx +23 -0
  496. package/src/Dialog/ConfirmationDialog.tsx +184 -0
  497. package/src/Dialog/Dialog.tsx +419 -0
  498. package/src/Dialog.tsx +149 -0
  499. package/src/Dropdown.tsx +158 -0
  500. package/src/DropdownMenu/DropdownButton.tsx +15 -0
  501. package/src/DropdownMenu/DropdownMenu.tsx +115 -0
  502. package/src/DropdownMenu/index.ts +4 -0
  503. package/src/DropdownStyles.ts +128 -0
  504. package/src/FilterList.tsx +81 -0
  505. package/src/FilteredActionList/FilteredActionList.tsx +152 -0
  506. package/src/FilteredActionList/index.ts +2 -0
  507. package/src/FilteredSearch.tsx +28 -0
  508. package/src/Flash.tsx +77 -0
  509. package/src/Flex.tsx +15 -0
  510. package/src/FormGroup.tsx +27 -0
  511. package/src/Grid.tsx +15 -0
  512. package/src/Header.tsx +84 -0
  513. package/src/Heading.tsx +21 -0
  514. package/src/Label.tsx +75 -0
  515. package/src/LabelGroup.tsx +18 -0
  516. package/src/Link.tsx +46 -0
  517. package/src/Overlay.tsx +194 -0
  518. package/src/Pagehead.tsx +17 -0
  519. package/src/Pagination/Pagination.tsx +214 -0
  520. package/src/Pagination/index.ts +4 -0
  521. package/src/Pagination/model.tsx +187 -0
  522. package/src/PointerBox.tsx +31 -0
  523. package/src/Popover.tsx +236 -0
  524. package/src/Portal/Portal.tsx +96 -0
  525. package/src/Portal/index.ts +5 -0
  526. package/src/Position.tsx +63 -0
  527. package/src/ProgressBar.tsx +52 -0
  528. package/src/SelectMenu/SelectMenu.tsx +125 -0
  529. package/src/SelectMenu/SelectMenuContext.tsx +9 -0
  530. package/src/SelectMenu/SelectMenuDivider.tsx +25 -0
  531. package/src/SelectMenu/SelectMenuFilter.tsx +51 -0
  532. package/src/SelectMenu/SelectMenuFooter.tsx +28 -0
  533. package/src/SelectMenu/SelectMenuHeader.tsx +50 -0
  534. package/src/SelectMenu/SelectMenuItem.tsx +137 -0
  535. package/src/SelectMenu/SelectMenuList.tsx +42 -0
  536. package/src/SelectMenu/SelectMenuLoadingAnimation.tsx +24 -0
  537. package/src/SelectMenu/SelectMenuModal.tsx +121 -0
  538. package/src/SelectMenu/SelectMenuTab.tsx +88 -0
  539. package/src/SelectMenu/SelectMenuTabPanel.tsx +30 -0
  540. package/src/SelectMenu/SelectMenuTabs.tsx +44 -0
  541. package/src/SelectMenu/hooks/useKeyboardNav.js +90 -0
  542. package/src/SelectMenu/index.ts +15 -0
  543. package/src/SelectPanel/SelectPanel.tsx +172 -0
  544. package/src/SelectPanel/index.ts +2 -0
  545. package/src/SideNav.tsx +193 -0
  546. package/src/Spinner.tsx +59 -0
  547. package/src/StateLabel.tsx +110 -0
  548. package/src/StyledOcticon.tsx +24 -0
  549. package/src/SubNav.tsx +129 -0
  550. package/src/TabNav.tsx +77 -0
  551. package/src/Text.tsx +13 -0
  552. package/src/TextInput.tsx +183 -0
  553. package/src/ThemeProvider.tsx +176 -0
  554. package/src/Timeline.tsx +141 -0
  555. package/src/Tooltip.tsx +263 -0
  556. package/src/Truncate.tsx +36 -0
  557. package/src/UnderlineNav.tsx +110 -0
  558. package/src/__tests__/.eslintrc.json +11 -0
  559. package/src/__tests__/ActionList.tsx +47 -0
  560. package/src/__tests__/ActionMenu.tsx +136 -0
  561. package/src/__tests__/AnchoredOverlay.tsx +150 -0
  562. package/src/__tests__/Avatar.tsx +44 -0
  563. package/src/__tests__/AvatarStack.tsx +44 -0
  564. package/src/__tests__/BorderBox.tsx +43 -0
  565. package/src/__tests__/Box.tsx +42 -0
  566. package/src/__tests__/BranchName.tsx +26 -0
  567. package/src/__tests__/Breadcrumbs.tsx +27 -0
  568. package/src/__tests__/BreadcrumbsItem.tsx +31 -0
  569. package/src/__tests__/Button.tsx +128 -0
  570. package/src/__tests__/Caret.tsx +36 -0
  571. package/src/__tests__/CircleBadge.tsx +66 -0
  572. package/src/__tests__/CircleOcticon.tsx +50 -0
  573. package/src/__tests__/CounterLabel.tsx +50 -0
  574. package/src/__tests__/Details.tsx +115 -0
  575. package/src/__tests__/Dialog.tsx +155 -0
  576. package/src/__tests__/Dropdown.tsx +53 -0
  577. package/src/__tests__/DropdownMenu.tsx +136 -0
  578. package/src/__tests__/FilterList.tsx +26 -0
  579. package/src/__tests__/FilterListItem.tsx +31 -0
  580. package/src/__tests__/FilteredSearch.tsx +26 -0
  581. package/src/__tests__/Flash.tsx +45 -0
  582. package/src/__tests__/Flex.tsx +58 -0
  583. package/src/__tests__/FormGroup.tsx +38 -0
  584. package/src/__tests__/Grid.tsx +82 -0
  585. package/src/__tests__/Header.tsx +49 -0
  586. package/src/__tests__/Heading.tsx +91 -0
  587. package/src/__tests__/Label.tsx +34 -0
  588. package/src/__tests__/LabelGroup.tsx +30 -0
  589. package/src/__tests__/Link.tsx +47 -0
  590. package/src/__tests__/Overlay.tsx +103 -0
  591. package/src/__tests__/Pagehead.tsx +23 -0
  592. package/src/__tests__/Pagination/Pagination.tsx +30 -0
  593. package/src/__tests__/Pagination/PaginationModel.tsx +133 -0
  594. package/src/__tests__/Pagination/__snapshots__/Pagination.tsx.snap +184 -0
  595. package/src/__tests__/PointerBox.tsx +34 -0
  596. package/src/__tests__/Popover.tsx +68 -0
  597. package/src/__tests__/Portal.tsx +103 -0
  598. package/src/__tests__/Position.tsx +117 -0
  599. package/src/__tests__/ProgressBar.tsx +40 -0
  600. package/src/__tests__/SelectMenu.tsx +142 -0
  601. package/src/__tests__/SelectPanel.tsx +63 -0
  602. package/src/__tests__/SideNav.tsx +62 -0
  603. package/src/__tests__/Spinner.tsx +42 -0
  604. package/src/__tests__/StateLabel.tsx +48 -0
  605. package/src/__tests__/StyledOcticon.tsx +26 -0
  606. package/src/__tests__/SubNav.tsx +50 -0
  607. package/src/__tests__/SubNavLink.tsx +31 -0
  608. package/src/__tests__/TabNav.tsx +32 -0
  609. package/src/__tests__/Text.tsx +78 -0
  610. package/src/__tests__/TextInput.tsx +49 -0
  611. package/src/__tests__/ThemeProvider.tsx +441 -0
  612. package/src/__tests__/Timeline.tsx +58 -0
  613. package/src/__tests__/Tooltip.tsx +52 -0
  614. package/src/__tests__/Truncate.tsx +43 -0
  615. package/src/__tests__/UnderlineNav.tsx +58 -0
  616. package/src/__tests__/UnderlineNavLink.tsx +31 -0
  617. package/src/__tests__/__snapshots__/ActionList.tsx.snap +27 -0
  618. package/src/__tests__/__snapshots__/ActionMenu.tsx.snap +80 -0
  619. package/src/__tests__/__snapshots__/AnchoredOverlay.tsx.snap +332 -0
  620. package/src/__tests__/__snapshots__/Avatar.tsx.snap +19 -0
  621. package/src/__tests__/__snapshots__/AvatarStack.tsx.snap +377 -0
  622. package/src/__tests__/__snapshots__/BorderBox.tsx.snap +14 -0
  623. package/src/__tests__/__snapshots__/Box.tsx.snap +201 -0
  624. package/src/__tests__/__snapshots__/BranchName.tsx.snap +17 -0
  625. package/src/__tests__/__snapshots__/Breadcrumbs.tsx.snap +29 -0
  626. package/src/__tests__/__snapshots__/BreadcrumbsItem.tsx.snap +79 -0
  627. package/src/__tests__/__snapshots__/Button.tsx.snap +832 -0
  628. package/src/__tests__/__snapshots__/Caret.tsx.snap +373 -0
  629. package/src/__tests__/__snapshots__/CircleBadge.tsx.snap +141 -0
  630. package/src/__tests__/__snapshots__/CircleOcticon.tsx.snap +64 -0
  631. package/src/__tests__/__snapshots__/CounterLabel.tsx.snap +22 -0
  632. package/src/__tests__/__snapshots__/Details.tsx.snap +15 -0
  633. package/src/__tests__/__snapshots__/Dialog.tsx.snap +200 -0
  634. package/src/__tests__/__snapshots__/Dropdown.tsx.snap +249 -0
  635. package/src/__tests__/__snapshots__/DropdownMenu.tsx.snap +106 -0
  636. package/src/__tests__/__snapshots__/FilterList.tsx.snap +13 -0
  637. package/src/__tests__/__snapshots__/FilterListItem.tsx.snap +80 -0
  638. package/src/__tests__/__snapshots__/FilteredSearch.tsx.snap +32 -0
  639. package/src/__tests__/__snapshots__/Flash.tsx.snap +32 -0
  640. package/src/__tests__/__snapshots__/Flex.tsx.snap +130 -0
  641. package/src/__tests__/__snapshots__/FormGroup.tsx.snap +25 -0
  642. package/src/__tests__/__snapshots__/Grid.tsx.snap +178 -0
  643. package/src/__tests__/__snapshots__/Header.tsx.snap +79 -0
  644. package/src/__tests__/__snapshots__/Heading.tsx.snap +13 -0
  645. package/src/__tests__/__snapshots__/Label.tsx.snap +74 -0
  646. package/src/__tests__/__snapshots__/LabelGroup.tsx.snap +15 -0
  647. package/src/__tests__/__snapshots__/Link.tsx.snap +213 -0
  648. package/src/__tests__/__snapshots__/Pagehead.tsx.snap +15 -0
  649. package/src/__tests__/__snapshots__/PointerBox.tsx.snap +174 -0
  650. package/src/__tests__/__snapshots__/Popover.tsx.snap +4687 -0
  651. package/src/__tests__/__snapshots__/Position.tsx.snap +44 -0
  652. package/src/__tests__/__snapshots__/ProgressBar.tsx.snap +53 -0
  653. package/src/__tests__/__snapshots__/SelectMenu.tsx.snap +469 -0
  654. package/src/__tests__/__snapshots__/SelectPanel.tsx.snap +123 -0
  655. package/src/__tests__/__snapshots__/SideNav.tsx.snap +143 -0
  656. package/src/__tests__/__snapshots__/Spinner.tsx.snap +33 -0
  657. package/src/__tests__/__snapshots__/StateLabel.tsx.snap +409 -0
  658. package/src/__tests__/__snapshots__/StyledOcticon.tsx.snap +25 -0
  659. package/src/__tests__/__snapshots__/SubNav.tsx.snap +44 -0
  660. package/src/__tests__/__snapshots__/SubNavLink.tsx.snap +199 -0
  661. package/src/__tests__/__snapshots__/TabNav.tsx.snap +58 -0
  662. package/src/__tests__/__snapshots__/Text.tsx.snap +7 -0
  663. package/src/__tests__/__snapshots__/TextInput.tsx.snap +440 -0
  664. package/src/__tests__/__snapshots__/ThemeProvider.tsx.snap +15 -0
  665. package/src/__tests__/__snapshots__/Timeline.tsx.snap +159 -0
  666. package/src/__tests__/__snapshots__/Tooltip.tsx.snap +227 -0
  667. package/src/__tests__/__snapshots__/Truncate.tsx.snap +17 -0
  668. package/src/__tests__/__snapshots__/UnderlineNav.tsx.snap +59 -0
  669. package/src/__tests__/__snapshots__/UnderlineNavLink.tsx.snap +130 -0
  670. package/src/__tests__/behaviors/anchoredPosition.ts +295 -0
  671. package/src/__tests__/behaviors/focusTrap.tsx +236 -0
  672. package/src/__tests__/behaviors/focusZone.tsx +549 -0
  673. package/src/__tests__/behaviors/iterateFocusableElements.tsx +61 -0
  674. package/src/__tests__/filterObject.ts +54 -0
  675. package/src/__tests__/hooks/useAnchoredPosition.tsx +31 -0
  676. package/src/__tests__/hooks/useOnEscapePress.tsx +16 -0
  677. package/src/__tests__/hooks/useOnOutsideClick.tsx +48 -0
  678. package/src/__tests__/hooks/useOpenAndCloseFocus.tsx +48 -0
  679. package/src/__tests__/hooks/useProvidedStateOrCreate.tsx +39 -0
  680. package/src/__tests__/theme.ts +41 -0
  681. package/src/__tests__/themeGet.ts +15 -0
  682. package/src/__tests__/useSafeTimeout.tsx +36 -0
  683. package/src/behaviors/anchoredPosition.ts +442 -0
  684. package/src/behaviors/focusTrap.ts +184 -0
  685. package/src/behaviors/focusZone.ts +713 -0
  686. package/src/constants.ts +62 -0
  687. package/src/hooks/index.ts +11 -0
  688. package/src/hooks/useAnchoredPosition.ts +53 -0
  689. package/src/hooks/useCombinedRefs.ts +40 -0
  690. package/src/hooks/useDetails.tsx +54 -0
  691. package/src/hooks/useDialog.ts +121 -0
  692. package/src/hooks/useFocusTrap.ts +80 -0
  693. package/src/hooks/useFocusZone.ts +64 -0
  694. package/src/hooks/useOnEscapePress.ts +63 -0
  695. package/src/hooks/useOnOutsideClick.tsx +82 -0
  696. package/src/hooks/useOpenAndCloseFocus.ts +27 -0
  697. package/src/hooks/useOverlay.tsx +32 -0
  698. package/src/hooks/useProvidedRefOrCreate.ts +14 -0
  699. package/src/hooks/useProvidedStateOrCreate.ts +27 -0
  700. package/src/hooks/useRenderForcingRef.ts +22 -0
  701. package/src/hooks/useResizeObserver.ts +11 -0
  702. package/src/hooks/useSafeTimeout.ts +38 -0
  703. package/src/hooks/useScrollFlash.ts +21 -0
  704. package/src/index.ts +165 -0
  705. package/src/polyfills/eventListenerSignal.ts +66 -0
  706. package/src/stories/ActionList.stories.tsx +364 -0
  707. package/src/stories/ActionMenu.stories.tsx +322 -0
  708. package/src/stories/AnchoredOverlay.stories.tsx +117 -0
  709. package/src/stories/AvatarStack.stories.tsx +37 -0
  710. package/src/stories/Button.stories.tsx +88 -0
  711. package/src/stories/ConfirmationDialog.stories.tsx +105 -0
  712. package/src/stories/Dialog.stories.tsx +240 -0
  713. package/src/stories/DropdownMenu.stories.tsx +84 -0
  714. package/src/stories/Overlay.stories.tsx +186 -0
  715. package/src/stories/Portal.stories.tsx +109 -0
  716. package/src/stories/SelectPanel.stories.tsx +300 -0
  717. package/src/stories/ThemeProvider.stories.tsx +104 -0
  718. package/src/stories/useAnchoredPosition.stories.tsx +320 -0
  719. package/src/stories/useFocusTrap.stories.tsx +400 -0
  720. package/src/stories/useFocusZone.stories.tsx +663 -0
  721. package/src/sx.ts +9 -0
  722. package/src/theme-preval.js +136 -0
  723. package/src/theme.ts +3 -0
  724. package/src/utils/deprecate.tsx +73 -0
  725. package/src/utils/isNumeric.tsx +4 -0
  726. package/src/utils/iterateFocusableElements.ts +121 -0
  727. package/src/utils/ssr.tsx +1 -0
  728. package/src/utils/test-deprecations.tsx +19 -0
  729. package/src/utils/test-helpers.tsx +7 -0
  730. package/src/utils/test-matchers.tsx +109 -0
  731. package/src/utils/testing.tsx +242 -0
  732. package/src/utils/theme.js +64 -0
  733. package/src/utils/types.ts +90 -0
  734. package/src/utils/uniqueId.ts +6 -0
  735. package/src/utils/userAgent.ts +7 -0
  736. package/stats.html +3279 -0
  737. package/tsconfig.build.json +7 -0
  738. package/tsconfig.json +20 -0
  739. package/lib/Breadcrumb.d.ts +0 -23
  740. package/lib-esm/Breadcrumb.d.ts +0 -23
@@ -0,0 +1,460 @@
1
+ import {CheckIcon, IconProps} from '@primer/octicons-react'
2
+ import React, {useCallback} from 'react'
3
+ import {get} from '../constants'
4
+ import sx, {SxProp} from '../sx'
5
+ import Truncate from '../Truncate'
6
+ import {ItemInput} from './List'
7
+ import styled from 'styled-components'
8
+ import {StyledHeader} from './Header'
9
+ import {StyledDivider} from './Divider'
10
+ import {useColorSchemeVar, useTheme} from '../ThemeProvider'
11
+ import {
12
+ activeDescendantActivatedDirectly,
13
+ activeDescendantActivatedIndirectly,
14
+ isActiveDescendantAttribute
15
+ } from '../behaviors/focusZone'
16
+ import {useSSRSafeId} from '@react-aria/ssr'
17
+
18
+ /**
19
+ * These colors are not yet in our default theme. Need to remove this once they are added.
20
+ */
21
+ const customItemThemes = {
22
+ default: {
23
+ hover: {
24
+ light: 'rgba(46, 77, 108, 0.06)',
25
+ dark: 'rgba(201, 206, 212, 0.12)',
26
+ dark_dimmed: 'rgba(201, 206, 212, 0.12)'
27
+ },
28
+ focus: {
29
+ light: 'rgba(54, 77, 100, 0.16)',
30
+ dark: 'rgba(201, 206, 212, 0.24)',
31
+ dark_dimmed: 'rgba(201, 206, 212, 0.24)'
32
+ }
33
+ },
34
+ danger: {
35
+ hover: {
36
+ light: 'rgba(234, 74, 90, 0.08)',
37
+ dark: 'rgba(248, 81, 73, 0.16)',
38
+ dark_dimmed: 'rgba(248, 81, 73, 0.16)'
39
+ },
40
+ focus: {
41
+ light: 'rgba(234, 74, 90, 0.14)',
42
+ dark: 'rgba(248, 81, 73, 0.24)',
43
+ dark_dimmed: 'rgba(248, 81, 73, 0.24)'
44
+ }
45
+ }
46
+ } as const
47
+
48
+ /**
49
+ * Contract for props passed to the `Item` component.
50
+ */
51
+ export interface ItemProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'id'>, SxProp {
52
+ /**
53
+ * Primary text which names an `Item`.
54
+ */
55
+ text?: string
56
+
57
+ /**
58
+ * Secondary text which provides additional information about an `Item`.
59
+ */
60
+ description?: string
61
+
62
+ /**
63
+ * Secondary text style variations. Usage is discretionary.
64
+ *
65
+ * - `"inline"` - Secondary text is positioned beside primary text.
66
+ * - `"block"` - Secondary text is positioned below primary text.
67
+ */
68
+ descriptionVariant?: 'inline' | 'block'
69
+
70
+ /**
71
+ * Icon (or similar) positioned before `Item` text.
72
+ */
73
+ leadingVisual?: React.FunctionComponent<IconProps>
74
+
75
+ /**
76
+ * Icon (or similar) positioned after `Item` text.
77
+ */
78
+ trailingIcon?: React.FunctionComponent<IconProps>
79
+
80
+ /**
81
+ * Text positioned after `Item` text and optional trailing icon.
82
+ */
83
+ trailingText?: string
84
+
85
+ /**
86
+ * Style variations associated with various `Item` types.
87
+ *
88
+ * - `"default"` - An action `Item`.
89
+ * - `"danger"` - A destructive action `Item`.
90
+ */
91
+ variant?: 'default' | 'danger'
92
+
93
+ /**
94
+ * Whether to display a divider above the `Item` when it does not follow a `Header` or `Divider`.
95
+ */
96
+ showDivider?: boolean
97
+
98
+ /**
99
+ * For `Item`s which can be selected, whether the `Item` is currently selected.
100
+ */
101
+ selected?: boolean
102
+
103
+ /**
104
+ * For `Item`s which can be selected, whether `multiple` `Item`s or a `single` `Item` can be selected
105
+ */
106
+ selectionVariant?: 'single' | 'multiple'
107
+
108
+ /**
109
+ * Designates the group that an item belongs to.
110
+ */
111
+ groupId?: string
112
+
113
+ /**
114
+ * Items that are disabled can not be clicked, selected, or navigated through.
115
+ */
116
+ disabled?: boolean
117
+
118
+ /**
119
+ * Callback that will trigger both on click selection and keyboard selection.
120
+ */
121
+ onAction?: (item: ItemProps, event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void
122
+
123
+ /**
124
+ * An id associated with this item. Should be unique between items
125
+ */
126
+ id?: number | string
127
+ }
128
+
129
+ const getItemVariant = (variant = 'default', disabled?: boolean) => {
130
+ if (disabled) {
131
+ return {
132
+ color: get('colors.fg.muted'),
133
+ iconColor: get('colors.fg.muted'),
134
+ annotationColor: get('colors.fg.muted'),
135
+ hoverCursor: 'default'
136
+ }
137
+ }
138
+
139
+ switch (variant) {
140
+ case 'danger':
141
+ return {
142
+ color: get('colors.danger.fg'),
143
+ iconColor: get('colors.danger.fg'),
144
+ annotationColor: get('colors.fg.muted'),
145
+ hoverCursor: 'pointer'
146
+ }
147
+ default:
148
+ return {
149
+ color: get('colors.fg.default'),
150
+ iconColor: get('colors.fg.muted'),
151
+ annotationColor: get('colors.fg.muted'),
152
+ hoverCursor: 'pointer'
153
+ }
154
+ }
155
+ }
156
+
157
+ const DividedContent = styled.div`
158
+ display: flex;
159
+ min-width: 0;
160
+
161
+ /* Required for dividers */
162
+ position: relative;
163
+ flex-grow: 1;
164
+ `
165
+
166
+ const MainContent = styled.div`
167
+ align-items: baseline;
168
+ display: flex;
169
+ min-width: 0;
170
+ flex-direction: var(--main-content-flex-direction);
171
+ flex-grow: 1;
172
+ `
173
+
174
+ const StyledItem = styled.div<
175
+ {
176
+ variant: ItemProps['variant']
177
+ showDivider: ItemProps['showDivider']
178
+ item?: ItemInput
179
+ hoverBackground: string
180
+ focusBackground: string
181
+ } & SxProp
182
+ >`
183
+ /* 6px vertical padding + 20px line height = 32px total height
184
+ *
185
+ * TODO: When rem-based spacing on a 4px scale lands, replace
186
+ * hardcoded '6px' with 'calc((${get('space.s32')} - ${get('space.20')}) / 2)'.
187
+ */
188
+ padding: 6px ${get('space.2')};
189
+ display: flex;
190
+ border-radius: ${get('radii.2')};
191
+ color: ${({variant, item}) => getItemVariant(variant, item?.disabled).color};
192
+ // 2 frames on a 60hz monitor
193
+ transition: background 33.333ms linear;
194
+
195
+ @media (hover: hover) and (pointer: fine) {
196
+ :hover {
197
+ // allow override in case another item in the list is active/focused
198
+ background: var(--item-hover-bg-override, ${({hoverBackground}) => hoverBackground});
199
+ cursor: ${({variant, item}) => getItemVariant(variant, item?.disabled).hoverCursor};
200
+ }
201
+ }
202
+
203
+ // Item dividers
204
+ :not(:first-of-type):not(${StyledDivider} + &):not(${StyledHeader} + &) {
205
+ margin-top: ${({showDivider}) => (showDivider ? `1px` : '0')};
206
+
207
+ ${DividedContent}::before {
208
+ content: ' ';
209
+ display: block;
210
+ position: absolute;
211
+ width: 100%;
212
+ top: -7px;
213
+ // NB: This 'get' won’t execute if it’s moved into the arrow function below.
214
+ border: 0 solid ${get('colors.border.muted')};
215
+ border-top-width: ${({showDivider}) => (showDivider ? `1px` : '0')};
216
+ }
217
+ }
218
+
219
+ // Item dividers should not be visible:
220
+ // - above Hovered
221
+ &:hover ${DividedContent}::before,
222
+ // - below Hovered
223
+ // '*' instead of '&' because '&' maps to separate class names depending on 'variant'
224
+ :hover + * ${DividedContent}::before {
225
+ // allow override in case another item in the list is active/focused
226
+ border-color: var(--item-hover-divider-border-color-override, transparent) !important;
227
+ }
228
+
229
+ // - above Focused
230
+ &:focus ${DividedContent}::before,
231
+ // - below Focused
232
+ // '*' instead of '&' because '&' maps to separate class names depending on 'variant'
233
+ :focus + * ${DividedContent}::before,
234
+ // - above Active Descendent
235
+ &[${isActiveDescendantAttribute}] ${DividedContent}::before,
236
+ // - below Active Descendent
237
+ [${isActiveDescendantAttribute}] + & ${DividedContent}::before {
238
+ // '!important' because all the ':not's above give higher specificity
239
+ border-color: transparent !important;
240
+ }
241
+
242
+ // Active Descendant
243
+ &[${isActiveDescendantAttribute}='${activeDescendantActivatedDirectly}'] {
244
+ background: ${({focusBackground}) => focusBackground};
245
+ }
246
+ &[${isActiveDescendantAttribute}='${activeDescendantActivatedIndirectly}'] {
247
+ background: ${({hoverBackground}) => hoverBackground};
248
+ }
249
+
250
+ &:focus {
251
+ background: ${({focusBackground}) => focusBackground};
252
+ outline: none;
253
+ }
254
+
255
+ &:active {
256
+ background: ${({focusBackground}) => focusBackground};
257
+ }
258
+
259
+ ${sx}
260
+ `
261
+
262
+ export const TextContainer = styled.span<{
263
+ dangerouslySetInnerHtml?: React.DOMAttributes<HTMLDivElement>['dangerouslySetInnerHTML']
264
+ }>``
265
+
266
+ const BaseVisualContainer = styled.div<{variant?: ItemProps['variant']; disabled?: boolean}>`
267
+ // Match visual height to adjacent text line height.
268
+ // TODO: When rem-based spacing on a 4px scale lands, replace
269
+ // hardcoded '20px' with '${get('space.s20')}'.
270
+ height: 20px;
271
+ width: ${get('space.3')};
272
+ margin-right: ${get('space.2')};
273
+ `
274
+
275
+ const ColoredVisualContainer = styled(BaseVisualContainer)`
276
+ svg {
277
+ fill: ${({variant, disabled}) => getItemVariant(variant, disabled).iconColor};
278
+ font-size: ${get('fontSizes.0')};
279
+ }
280
+ `
281
+
282
+ const LeadingVisualContainer = styled(ColoredVisualContainer)`
283
+ flex-shrink: 0;
284
+ display: flex;
285
+ flex-direction: column;
286
+ justify-content: center;
287
+ `
288
+
289
+ const TrailingContent = styled(ColoredVisualContainer)`
290
+ color: ${({variant, disabled}) => getItemVariant(variant, disabled).annotationColor}};
291
+ margin-left: ${get('space.2')};
292
+ margin-right: 0;
293
+ width: auto;
294
+ div:nth-child(2) {
295
+ margin-left: ${get('space.2')};
296
+ }
297
+ `
298
+
299
+ const DescriptionContainer = styled.span`
300
+ color: ${get('colors.fg.muted')};
301
+ font-size: ${get('fontSizes.0')};
302
+ // TODO: When rem-based spacing on a 4px scale lands, replace
303
+ // hardcoded '16px' with '${get('lh-12')}'.
304
+ line-height: 16px;
305
+ margin-left: var(--description-container-margin-left);
306
+ min-width: 0;
307
+ flex-grow: 1;
308
+ flex-basis: var(--description-container-flex-basis);
309
+ `
310
+
311
+ const MultiSelectInput = styled.input`
312
+ pointer-events: none;
313
+ `
314
+
315
+ /**
316
+ * An actionable or selectable `Item` with an optional icon and description.
317
+ */
318
+ export function Item(itemProps: Partial<ItemProps> & {item?: ItemInput}): JSX.Element {
319
+ const {
320
+ text,
321
+ description,
322
+ descriptionVariant = 'inline',
323
+ selected,
324
+ selectionVariant,
325
+ leadingVisual: LeadingVisual,
326
+ trailingIcon: TrailingIcon,
327
+ trailingText,
328
+ variant = 'default',
329
+ showDivider,
330
+ disabled,
331
+ onAction,
332
+ onKeyPress,
333
+ children,
334
+ onClick,
335
+ id,
336
+ ...props
337
+ } = itemProps
338
+
339
+ const labelId = useSSRSafeId()
340
+ const descriptionId = useSSRSafeId()
341
+
342
+ const keyPressHandler = useCallback(
343
+ event => {
344
+ if (disabled) {
345
+ return
346
+ }
347
+ onKeyPress?.(event)
348
+ const isCheckbox = event.target instanceof HTMLInputElement && event.target.type === 'checkbox'
349
+ if (isCheckbox && event.key === ' ') {
350
+ // space key on a checkbox will also trigger a click event. Ignore the space key so we don't get double events
351
+ return
352
+ }
353
+
354
+ if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
355
+ onAction?.(itemProps as ItemProps, event)
356
+ }
357
+ },
358
+ [onAction, disabled, itemProps, onKeyPress]
359
+ )
360
+
361
+ const clickHandler = useCallback(
362
+ event => {
363
+ if (disabled) {
364
+ return
365
+ }
366
+ onClick?.(event)
367
+ if (!event.defaultPrevented) {
368
+ onAction?.(itemProps as ItemProps, event)
369
+ }
370
+ },
371
+ [onAction, disabled, itemProps, onClick]
372
+ )
373
+
374
+ const customItemTheme = customItemThemes[variant]
375
+ const hoverBackground = useColorSchemeVar(customItemTheme.hover, 'inherit')
376
+ const focusBackground = useColorSchemeVar(customItemTheme.focus, 'inherit')
377
+
378
+ const {theme} = useTheme()
379
+
380
+ return (
381
+ <StyledItem
382
+ tabIndex={disabled ? undefined : -1}
383
+ variant={variant}
384
+ showDivider={showDivider}
385
+ aria-selected={selected}
386
+ aria-labelledby={text ? labelId : undefined}
387
+ aria-describedby={description ? descriptionId : undefined}
388
+ {...props}
389
+ data-id={id}
390
+ onKeyPress={keyPressHandler}
391
+ onClick={clickHandler}
392
+ hoverBackground={disabled ? 'inherit' : hoverBackground}
393
+ focusBackground={disabled ? 'inherit' : focusBackground}
394
+ >
395
+ {!!selected === selected && (
396
+ <BaseVisualContainer>
397
+ {selectionVariant === 'multiple' ? (
398
+ <>
399
+ {/*
400
+ * readOnly is required because we are doing a one-way bind to `checked`.
401
+ * aria-readonly="false" tells screen that they can still interact with the checkbox
402
+ */}
403
+ <MultiSelectInput
404
+ disabled={disabled}
405
+ tabIndex={-1}
406
+ type="checkbox"
407
+ checked={selected}
408
+ aria-label={text}
409
+ readOnly
410
+ aria-readonly="false"
411
+ />
412
+ </>
413
+ ) : (
414
+ selected && <CheckIcon fill={theme?.colors.text.primary} />
415
+ )}
416
+ </BaseVisualContainer>
417
+ )}
418
+ {LeadingVisual && (
419
+ <LeadingVisualContainer variant={variant} disabled={disabled}>
420
+ <LeadingVisual />
421
+ </LeadingVisualContainer>
422
+ )}
423
+ <DividedContent>
424
+ <MainContent
425
+ style={
426
+ {'--main-content-flex-direction': descriptionVariant === 'inline' ? 'row' : 'column'} as React.CSSProperties
427
+ }
428
+ >
429
+ {children}
430
+ {text ? <TextContainer id={labelId}>{text}</TextContainer> : null}
431
+ {description ? (
432
+ <DescriptionContainer
433
+ id={descriptionId}
434
+ style={
435
+ {
436
+ '--description-container-margin-left': descriptionVariant === 'inline' ? get('space.2')(theme) : 0,
437
+ '--description-container-flex-basis': descriptionVariant === 'inline' ? 0 : 'auto'
438
+ } as React.CSSProperties
439
+ }
440
+ >
441
+ {descriptionVariant === 'block' ? (
442
+ description
443
+ ) : (
444
+ <Truncate title={description} inline={true} maxWidth="100%">
445
+ {description}
446
+ </Truncate>
447
+ )}
448
+ </DescriptionContainer>
449
+ ) : null}
450
+ </MainContent>
451
+ {TrailingIcon || trailingText ? (
452
+ <TrailingContent variant={variant} disabled={disabled}>
453
+ {trailingText}
454
+ {TrailingIcon && <TrailingIcon />}
455
+ </TrailingContent>
456
+ ) : null}
457
+ </DividedContent>
458
+ </StyledItem>
459
+ )
460
+ }
@@ -0,0 +1,253 @@
1
+ import React from 'react'
2
+ import type {AriaRole} from '../utils/types'
3
+ import {Group, GroupProps} from './Group'
4
+ import {Item, ItemProps} from './Item'
5
+ import {Divider} from './Divider'
6
+ import styled from 'styled-components'
7
+ import {get} from '../constants'
8
+ import {SystemCssProperties} from '@styled-system/css'
9
+ import {hasActiveDescendantAttribute} from '../behaviors/focusZone'
10
+
11
+ export type ItemInput = ItemProps | (Partial<ItemProps> & {renderItem: typeof Item})
12
+
13
+ /**
14
+ * Contract for props passed to the `List` component.
15
+ */
16
+ export interface ListPropsBase {
17
+ /**
18
+ * A collection of `Item` props and `Item`-level custom `Item` renderers.
19
+ */
20
+ items: ItemInput[]
21
+
22
+ /**
23
+ * The ARIA role describing the function of `List` component. `listbox` is a common value.
24
+ */
25
+ role?: AriaRole
26
+
27
+ /**
28
+ * id to attach to the base DOM node of the list
29
+ */
30
+ id?: string
31
+
32
+ /**
33
+ * A `List`-level custom `Item` renderer. Every `Item` within this `List`
34
+ * without a `Group`-level or `Item`-level custom `Item` renderer will be
35
+ * rendered using this function component.
36
+ */
37
+ renderItem?: typeof Item
38
+
39
+ /**
40
+ * A `List`-level custom `Group` renderer. Every `Group` within this `List`
41
+ * without a `Group`-level custom `Item` renderer will be rendered using
42
+ * this function component.
43
+ */
44
+ renderGroup?: typeof Group
45
+
46
+ /**
47
+ * Style variations. Usage is discretionary.
48
+ *
49
+ * - `"inset"` - `List` children are offset (vertically and horizontally) from `List`’s edges
50
+ * - `"full"` - `List` children are flush (vertically and horizontally) with `List` edges
51
+ */
52
+ variant?: 'inset' | 'full'
53
+
54
+ /**
55
+ * For `Item`s which can be selected, whether `multiple` `Item`s or a `single` `Item` can be selected
56
+ */
57
+ selectionVariant?: 'single' | 'multiple'
58
+
59
+ /**
60
+ * Whether to display a divider above each `Item` in this `List` when it does not follow a `Header` or `Divider`.
61
+ */
62
+ showItemDividers?: boolean
63
+ }
64
+
65
+ /**
66
+ * Contract for props passed to the `List` component, when its `Item`s are collected in `Group`s.
67
+ */
68
+ export interface GroupedListProps extends ListPropsBase {
69
+ /**
70
+ * A collection of `Group` props (except `items`), plus a unique group identifier
71
+ * and `Group`-level custom `Item` or `Group` renderers.
72
+ */
73
+ groupMetadata: ((
74
+ | Omit<GroupProps, 'items'>
75
+ | Omit<Partial<GroupProps> & {renderItem?: typeof Item; renderGroup?: typeof Group}, 'items'>
76
+ ) & {groupId: string})[]
77
+
78
+ /**
79
+ * A collection of `Item` props, plus associated group identifiers
80
+ * and `Item`-level custom `Item` renderers.
81
+ */
82
+ items: ((ItemProps | (Partial<ItemProps> & {renderItem: typeof Item})) & {groupId: string})[]
83
+ }
84
+
85
+ /**
86
+ * Asserts that the given value fulfills the `GroupedListProps` contract.
87
+ * @param props A value which fulfills either the `ListPropsBase` or the `GroupedListProps` contract.
88
+ */
89
+ function isGroupedListProps(props: ListProps): props is GroupedListProps {
90
+ return 'groupMetadata' in props
91
+ }
92
+
93
+ /**
94
+ * Contract for props passed to the `List` component.
95
+ */
96
+ export type ListProps = ListPropsBase | GroupedListProps
97
+
98
+ const StyledList = styled.div`
99
+ font-size: ${get('fontSizes.1')};
100
+ /* 14px font-size * 1.428571429 = 20px line height
101
+ *
102
+ * TODO: When rem-based spacing on a 4px scale lands, replace
103
+ * hardcoded '20px'
104
+ */
105
+ line-height: 20px;
106
+
107
+ &[${hasActiveDescendantAttribute}], &:focus-within {
108
+ --item-hover-bg-override: none;
109
+ --item-hover-divider-border-color-override: ${get('colors.border.muted')};
110
+ }
111
+ `
112
+
113
+ /**
114
+ * Returns `sx` prop values for `List` children matching the given `List` style variation.
115
+ * @param variant `List` style variation.
116
+ */
117
+ function useListVariant(variant: ListProps['variant'] = 'inset'): {
118
+ firstGroupStyle?: SystemCssProperties
119
+ lastGroupStyle?: SystemCssProperties
120
+ headerStyle?: SystemCssProperties
121
+ itemStyle?: SystemCssProperties
122
+ } {
123
+ switch (variant) {
124
+ case 'full':
125
+ return {
126
+ headerStyle: {paddingX: get('space.2')},
127
+ itemStyle: {borderRadius: 0}
128
+ }
129
+ default:
130
+ return {
131
+ firstGroupStyle: {marginTop: get('space.2')},
132
+ lastGroupStyle: {marginBottom: get('space.2')},
133
+ itemStyle: {marginX: get('space.2')}
134
+ }
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Lists `Item`s, either grouped or ungrouped, with a `Divider` between each `Group`.
140
+ */
141
+ export const List = React.forwardRef<HTMLDivElement, ListProps>((props, forwardedRef): JSX.Element => {
142
+ // Get `sx` prop values for `List` children matching the given `List` style variation.
143
+ const {firstGroupStyle, lastGroupStyle, headerStyle, itemStyle} = useListVariant(props.variant)
144
+
145
+ /**
146
+ * Render a `Group` using the first of the following renderers that is defined:
147
+ * A `Group`-level or `List`-level custom `Group` renderer, or
148
+ * the default `Group` renderer.
149
+ */
150
+ const renderGroup = (
151
+ groupProps: GroupProps | (Partial<GroupProps> & {renderItem?: typeof Item; renderGroup?: typeof Group})
152
+ ) => {
153
+ const GroupComponent = (('renderGroup' in groupProps && groupProps.renderGroup) ?? props.renderGroup) || Group
154
+ return <GroupComponent {...groupProps} key={groupProps.groupId} />
155
+ }
156
+
157
+ /**
158
+ * Render an `Item` using the first of the following renderers that is defined:
159
+ * An `Item`-level, `Group`-level, or `List`-level custom `Item` renderer,
160
+ * or the default `Item` renderer.
161
+ */
162
+ const renderItem = (itemProps: ItemInput, item: ItemInput, itemIndex: number) => {
163
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
164
+ const ItemComponent = ('renderItem' in itemProps && itemProps.renderItem) || props.renderItem || Item
165
+ const key = itemProps.key ?? itemProps.id?.toString() ?? itemIndex.toString()
166
+ return (
167
+ <ItemComponent
168
+ showDivider={props.showItemDividers}
169
+ selectionVariant={props.selectionVariant}
170
+ {...itemProps}
171
+ key={key}
172
+ sx={{...itemStyle, ...itemProps.sx}}
173
+ item={item}
174
+ />
175
+ )
176
+ }
177
+
178
+ /**
179
+ * An array of `Group`s, each with an associated `Header` and with an array of `Item`s belonging to that `Group`.
180
+ */
181
+ let groups: (GroupProps | (Partial<GroupProps> & {renderItem?: typeof Item; renderGroup?: typeof Group}))[] = []
182
+
183
+ // Collect rendered `Item`s into `Group`s, avoiding excess iteration over the lists of `items` and `groupMetadata`:
184
+ if (!isGroupedListProps(props)) {
185
+ // When no `groupMetadata`s is provided, collect rendered `Item`s into a single anonymous `Group`.
186
+ groups = [{items: props.items.map((item, index) => renderItem(item, item, index)), groupId: '0'}]
187
+ } else {
188
+ // When `groupMetadata` is provided, collect rendered `Item`s into their associated `Group`s.
189
+
190
+ /**
191
+ * A map of group identifiers to `Group`s, each with an associated array of `Item`s belonging to that `Group`.
192
+ */
193
+ const groupMap = props.groupMetadata.reduce(
194
+ (groupAccumulator, groupMetadata) => groupAccumulator.set(groupMetadata.groupId, groupMetadata),
195
+ new Map<string, GroupProps | (Partial<GroupProps> & {renderItem?: typeof Item; renderGroup?: typeof Group})>()
196
+ )
197
+
198
+ for (const itemProps of props.items) {
199
+ // Look up the group associated with the current item.
200
+ const group = groupMap.get(itemProps.groupId)
201
+ const itemIndex = group?.items?.length ?? 0
202
+
203
+ // Upsert the group to include the current item (rendered).
204
+ groupMap.set(itemProps.groupId, {
205
+ ...group,
206
+ items: [
207
+ ...(group?.items ?? []),
208
+ renderItem(
209
+ {
210
+ showDivider: group?.showItemDividers,
211
+ ...(group && 'renderItem' in group && {renderItem: group.renderItem}),
212
+ ...itemProps
213
+ },
214
+ itemProps,
215
+ itemIndex
216
+ )
217
+ ]
218
+ })
219
+ }
220
+
221
+ groups = [...groupMap.values()]
222
+ }
223
+
224
+ return (
225
+ <StyledList {...props} ref={forwardedRef}>
226
+ {groups.map(({header, ...groupProps}, index) => {
227
+ const hasFilledHeader = header?.variant === 'filled'
228
+ const shouldShowDivider = index > 0 && !hasFilledHeader
229
+ return (
230
+ <React.Fragment key={groupProps.groupId}>
231
+ {shouldShowDivider ? <Divider key={`${groupProps.groupId}-divider`} /> : null}
232
+ {renderGroup({
233
+ sx: {
234
+ ...(index === 0 && firstGroupStyle),
235
+ ...(index === groups.length - 1 && lastGroupStyle),
236
+ ...(index > 0 && !shouldShowDivider && {mt: 2})
237
+ },
238
+ ...(header && {
239
+ header: {
240
+ ...header,
241
+ sx: {...headerStyle, ...header.sx}
242
+ }
243
+ }),
244
+ ...groupProps
245
+ })}
246
+ </React.Fragment>
247
+ )
248
+ })}
249
+ </StyledList>
250
+ )
251
+ })
252
+
253
+ List.displayName = 'ActionList'