@primer/components 31.2.0-rc.fbb10090 → 31.2.1-rc.32ed6e21

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 (503) hide show
  1. package/.github/workflows/ci.yml +5 -2
  2. package/.github/workflows/release.yml +1 -0
  3. package/.github/workflows/release_canary.yml +1 -0
  4. package/CHANGELOG.md +26 -0
  5. package/dist/browser.esm.js +671 -654
  6. package/dist/browser.esm.js.map +1 -1
  7. package/dist/browser.umd.js +223 -206
  8. package/dist/browser.umd.js.map +1 -1
  9. package/docs/content/ActionList2.mdx +359 -0
  10. package/docs/content/{Box.md → Box.mdx} +22 -0
  11. package/docs/content/StateLabel.md +5 -4
  12. package/docs/content/getting-started.md +1 -1
  13. package/docs/src/@primer/gatsby-theme-doctocat/components/hero.js +1 -3
  14. package/docs/src/@primer/gatsby-theme-doctocat/components/live-preview-wrapper.js +1 -1
  15. package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +17 -0
  16. package/docs/src/component-checklist.js +81 -0
  17. package/lib/ActionList/Divider.jsx +29 -0
  18. package/lib/ActionList/Group.jsx +23 -0
  19. package/lib/ActionList/Header.jsx +66 -0
  20. package/lib/ActionList/Item.js +55 -71
  21. package/lib/ActionList/Item.jsx +288 -0
  22. package/lib/ActionList/List.jsx +138 -0
  23. package/lib/ActionList/index.js +12 -23
  24. package/lib/ActionList2/Description.d.ts +12 -0
  25. package/lib/ActionList2/Description.js +57 -0
  26. package/lib/ActionList2/Description.jsx +29 -0
  27. package/lib/ActionList2/Divider.d.ts +5 -0
  28. package/lib/ActionList2/Divider.js +35 -0
  29. package/lib/ActionList2/Divider.jsx +22 -0
  30. package/lib/ActionList2/Group.d.ts +37 -0
  31. package/lib/ActionList2/Group.js +106 -0
  32. package/lib/ActionList2/Group.jsx +54 -0
  33. package/lib/ActionList2/Header.d.ts +26 -0
  34. package/lib/ActionList2/Header.js +55 -0
  35. package/lib/ActionList2/Header.jsx +36 -0
  36. package/lib/ActionList2/Item.d.ts +63 -0
  37. package/lib/ActionList2/Item.js +242 -0
  38. package/lib/ActionList2/Item.jsx +174 -0
  39. package/lib/ActionList2/LinkItem.d.ts +17 -0
  40. package/lib/ActionList2/LinkItem.js +57 -0
  41. package/lib/ActionList2/LinkItem.jsx +28 -0
  42. package/lib/ActionList2/List.d.ts +26 -0
  43. package/lib/ActionList2/List.js +59 -0
  44. package/lib/ActionList2/List.jsx +41 -0
  45. package/lib/ActionList2/Selection.d.ts +5 -0
  46. package/lib/ActionList2/Selection.js +84 -0
  47. package/lib/ActionList2/Selection.jsx +50 -0
  48. package/lib/ActionList2/Visuals.d.ts +9 -0
  49. package/lib/ActionList2/Visuals.js +90 -0
  50. package/lib/ActionList2/Visuals.jsx +48 -0
  51. package/lib/ActionList2/index.d.ts +36 -0
  52. package/lib/ActionList2/index.js +29 -0
  53. package/lib/ActionMenu.jsx +73 -0
  54. package/lib/AnchoredOverlay/AnchoredOverlay.jsx +100 -0
  55. package/lib/AnchoredOverlay/index.js +4 -12
  56. package/lib/Autocomplete/Autocomplete.d.ts +28 -28
  57. package/lib/Autocomplete/Autocomplete.jsx +100 -0
  58. package/lib/Autocomplete/AutocompleteContext.jsx +5 -0
  59. package/lib/Autocomplete/AutocompleteInput.d.ts +28 -28
  60. package/lib/Autocomplete/AutocompleteInput.jsx +113 -0
  61. package/lib/Autocomplete/AutocompleteMenu.jsx +190 -0
  62. package/lib/Autocomplete/AutocompleteOverlay.jsx +55 -0
  63. package/lib/Autocomplete/index.js +7 -14
  64. package/lib/Avatar.jsx +34 -0
  65. package/lib/AvatarPair.jsx +29 -0
  66. package/lib/AvatarStack.jsx +151 -0
  67. package/lib/BaseStyles.jsx +65 -0
  68. package/lib/BorderBox.jsx +18 -0
  69. package/lib/Box.jsx +10 -0
  70. package/lib/BranchName.jsx +20 -0
  71. package/lib/Breadcrumbs.jsx +74 -0
  72. package/lib/Button/Button.d.ts +25 -25
  73. package/lib/Button/Button.jsx +60 -0
  74. package/lib/Button/ButtonBase.jsx +36 -0
  75. package/lib/Button/ButtonClose.d.ts +45 -45
  76. package/lib/Button/ButtonClose.jsx +55 -0
  77. package/lib/Button/ButtonDanger.d.ts +25 -25
  78. package/lib/Button/ButtonDanger.jsx +63 -0
  79. package/lib/Button/ButtonGroup.jsx +55 -0
  80. package/lib/Button/ButtonInvisible.d.ts +25 -25
  81. package/lib/Button/ButtonInvisible.jsx +52 -0
  82. package/lib/Button/ButtonOutline.d.ts +25 -25
  83. package/lib/Button/ButtonOutline.jsx +63 -0
  84. package/lib/Button/ButtonPrimary.d.ts +25 -25
  85. package/lib/Button/ButtonPrimary.jsx +62 -0
  86. package/lib/Button/ButtonStyles.jsx +37 -0
  87. package/lib/Button/ButtonTableList.jsx +49 -0
  88. package/lib/Button/index.js +21 -70
  89. package/lib/Caret.jsx +93 -0
  90. package/lib/CircleBadge.jsx +43 -0
  91. package/lib/CircleOcticon.d.ts +42 -42
  92. package/lib/CircleOcticon.jsx +21 -0
  93. package/lib/CounterLabel.jsx +44 -0
  94. package/lib/Details.jsx +21 -0
  95. package/lib/Dialog/ConfirmationDialog.jsx +146 -0
  96. package/lib/Dialog/Dialog.js +1 -0
  97. package/lib/Dialog/Dialog.jsx +273 -0
  98. package/lib/Dialog.d.ts +45 -45
  99. package/lib/Dialog.jsx +131 -0
  100. package/lib/Dropdown.d.ts +176 -176
  101. package/lib/Dropdown.jsx +134 -0
  102. package/lib/DropdownMenu/DropdownButton.d.ts +46 -46
  103. package/lib/DropdownMenu/DropdownButton.jsx +14 -0
  104. package/lib/DropdownMenu/DropdownMenu.jsx +70 -0
  105. package/lib/DropdownMenu/index.js +6 -20
  106. package/lib/DropdownStyles.js +18 -26
  107. package/lib/FilterList.d.ts +42 -42
  108. package/lib/FilterList.jsx +63 -0
  109. package/lib/FilteredActionList/FilteredActionList.jsx +100 -0
  110. package/lib/FilteredActionList/index.js +4 -12
  111. package/lib/FilteredSearch.jsx +29 -0
  112. package/lib/Flash.jsx +70 -0
  113. package/lib/Flex.jsx +15 -0
  114. package/lib/FormGroup.jsx +25 -0
  115. package/lib/Grid.jsx +15 -0
  116. package/lib/Header.jsx +90 -0
  117. package/lib/Heading.jsx +21 -0
  118. package/lib/Label.jsx +84 -0
  119. package/lib/LabelGroup.jsx +19 -0
  120. package/lib/Link.jsx +38 -0
  121. package/lib/NewButton/button-counter.d.ts +6 -0
  122. package/lib/NewButton/button-counter.js +31 -0
  123. package/lib/NewButton/button-counter.jsx +14 -0
  124. package/lib/NewButton/button.d.ts +13 -0
  125. package/lib/NewButton/button.js +308 -0
  126. package/lib/NewButton/button.jsx +279 -0
  127. package/lib/NewButton/index.d.ts +14 -0
  128. package/lib/NewButton/index.js +8 -0
  129. package/lib/NewButton/types.d.ts +32 -0
  130. package/lib/NewButton/types.js +2 -0
  131. package/lib/Overlay.js +3 -1
  132. package/lib/Overlay.jsx +156 -0
  133. package/lib/Pagehead.jsx +18 -0
  134. package/lib/Pagination/Pagination.jsx +163 -0
  135. package/lib/Pagination/index.js +6 -12
  136. package/lib/Pagination/model.jsx +174 -0
  137. package/lib/PointerBox.jsx +25 -0
  138. package/lib/Popover.jsx +210 -0
  139. package/lib/Portal/Portal.js +3 -2
  140. package/lib/Portal/Portal.jsx +79 -0
  141. package/lib/Portal/index.js +5 -16
  142. package/lib/Position.d.ts +4 -4
  143. package/lib/Position.jsx +46 -0
  144. package/lib/ProgressBar.jsx +39 -0
  145. package/lib/SelectMenu/SelectMenu.d.ts +246 -246
  146. package/lib/SelectMenu/SelectMenu.jsx +114 -0
  147. package/lib/SelectMenu/SelectMenuContext.jsx +5 -0
  148. package/lib/SelectMenu/SelectMenuDivider.jsx +43 -0
  149. package/lib/SelectMenu/SelectMenuFilter.jsx +59 -0
  150. package/lib/SelectMenu/SelectMenuFooter.jsx +46 -0
  151. package/lib/SelectMenu/SelectMenuHeader.jsx +44 -0
  152. package/lib/SelectMenu/SelectMenuItem.d.ts +1 -1
  153. package/lib/SelectMenu/SelectMenuItem.jsx +143 -0
  154. package/lib/SelectMenu/SelectMenuList.jsx +60 -0
  155. package/lib/SelectMenu/SelectMenuLoadingAnimation.jsx +21 -0
  156. package/lib/SelectMenu/SelectMenuModal.d.ts +1 -1
  157. package/lib/SelectMenu/SelectMenuModal.jsx +119 -0
  158. package/lib/SelectMenu/SelectMenuTab.jsx +93 -0
  159. package/lib/SelectMenu/SelectMenuTabPanel.jsx +43 -0
  160. package/lib/SelectMenu/SelectMenuTabs.jsx +58 -0
  161. package/lib/SelectMenu/hooks/useKeyboardNav.js +80 -96
  162. package/lib/SelectMenu/index.js +7 -14
  163. package/lib/SelectPanel/SelectPanel.jsx +105 -0
  164. package/lib/SelectPanel/index.js +4 -12
  165. package/lib/SideNav.jsx +177 -0
  166. package/lib/Spinner.jsx +35 -0
  167. package/lib/StateLabel.d.ts +1 -1
  168. package/lib/StateLabel.js +6 -1
  169. package/lib/StateLabel.jsx +94 -0
  170. package/lib/StyledOcticon.jsx +20 -0
  171. package/lib/SubNav.jsx +104 -0
  172. package/lib/TabNav.jsx +60 -0
  173. package/lib/Text.jsx +14 -0
  174. package/lib/TextInput.jsx +23 -0
  175. package/lib/TextInputWithTokens.d.ts +28 -28
  176. package/lib/TextInputWithTokens.jsx +218 -0
  177. package/lib/ThemeProvider.jsx +130 -0
  178. package/lib/Timeline.d.ts +43 -43
  179. package/lib/Timeline.jsx +124 -0
  180. package/lib/Token/AvatarToken.d.ts +1 -1
  181. package/lib/Token/AvatarToken.jsx +54 -0
  182. package/lib/Token/IssueLabelToken.d.ts +1 -1
  183. package/lib/Token/IssueLabelToken.jsx +125 -0
  184. package/lib/Token/Token.d.ts +1 -1
  185. package/lib/Token/Token.jsx +103 -0
  186. package/lib/Token/TokenBase.jsx +88 -0
  187. package/lib/Token/_RemoveTokenButton.jsx +108 -0
  188. package/lib/Token/_TokenTextContainer.jsx +49 -0
  189. package/lib/Token/index.js +11 -30
  190. package/lib/Tooltip.jsx +246 -0
  191. package/lib/Truncate.jsx +27 -0
  192. package/lib/UnderlineNav.jsx +90 -0
  193. package/lib/_TextInputWrapper.js +2 -2
  194. package/lib/_TextInputWrapper.jsx +120 -0
  195. package/lib/_UnstyledTextInput.jsx +22 -0
  196. package/lib/__tests__/ActionList.test.jsx +49 -0
  197. package/lib/__tests__/ActionList.types.test.jsx +45 -0
  198. package/lib/__tests__/ActionList2.test.d.ts +1 -0
  199. package/lib/__tests__/ActionList2.test.js +53 -0
  200. package/lib/__tests__/ActionList2.test.jsx +46 -0
  201. package/lib/__tests__/ActionMenu.test.jsx +124 -0
  202. package/lib/__tests__/AnchoredOverlay.test.js +4 -2
  203. package/lib/__tests__/AnchoredOverlay.test.jsx +121 -0
  204. package/lib/__tests__/Autocomplete.test.jsx +299 -0
  205. package/lib/__tests__/Avatar.test.jsx +42 -0
  206. package/lib/__tests__/AvatarStack.test.jsx +43 -0
  207. package/lib/__tests__/BorderBox.test.jsx +36 -0
  208. package/lib/__tests__/Box.test.jsx +41 -0
  209. package/lib/__tests__/BranchName.test.jsx +27 -0
  210. package/lib/__tests__/Breadcrumbs.test.jsx +28 -0
  211. package/lib/__tests__/BreadcrumbsItem.test.jsx +31 -0
  212. package/lib/__tests__/Button.test.jsx +100 -0
  213. package/lib/__tests__/Caret.test.jsx +37 -0
  214. package/lib/__tests__/CircleBadge.test.jsx +55 -0
  215. package/lib/__tests__/CircleOcticon.test.jsx +45 -0
  216. package/lib/__tests__/ConfirmationDialog.test.jsx +119 -0
  217. package/lib/__tests__/CounterLabel.test.jsx +36 -0
  218. package/lib/__tests__/Details.test.jsx +85 -0
  219. package/lib/__tests__/Dialog.test.jsx +139 -0
  220. package/lib/__tests__/Dropdown.test.jsx +49 -0
  221. package/lib/__tests__/DropdownMenu.test.jsx +119 -0
  222. package/lib/__tests__/FilterList.test.jsx +27 -0
  223. package/lib/__tests__/FilterListItem.test.jsx +31 -0
  224. package/lib/__tests__/FilteredSearch.test.jsx +27 -0
  225. package/lib/__tests__/Flash.test.jsx +36 -0
  226. package/lib/__tests__/Flex.test.jsx +51 -0
  227. package/lib/__tests__/FormGroup.test.jsx +36 -0
  228. package/lib/__tests__/Grid.test.jsx +69 -0
  229. package/lib/__tests__/Header.test.jsx +45 -0
  230. package/lib/__tests__/Heading.test.jsx +71 -0
  231. package/lib/__tests__/KeyPaths.types.test.d.ts +2 -1
  232. package/lib/__tests__/KeyPaths.types.test.js +5 -8
  233. package/lib/__tests__/Label.test.jsx +33 -0
  234. package/lib/__tests__/LabelGroup.test.jsx +29 -0
  235. package/lib/__tests__/Link.test.jsx +43 -0
  236. package/lib/__tests__/Merge.types.test.js +13 -19
  237. package/lib/__tests__/NewButton.test.d.ts +1 -0
  238. package/lib/__tests__/NewButton.test.js +95 -0
  239. package/lib/__tests__/NewButton.test.jsx +61 -0
  240. package/lib/__tests__/Overlay.test.jsx +105 -0
  241. package/lib/__tests__/Pagehead.test.jsx +25 -0
  242. package/lib/__tests__/Pagination/Pagination.test.jsx +32 -0
  243. package/lib/__tests__/Pagination/PaginationModel.test.jsx +118 -0
  244. package/lib/__tests__/PointerBox.test.jsx +33 -0
  245. package/lib/__tests__/Popover.test.jsx +58 -0
  246. package/lib/__tests__/Portal.test.jsx +102 -0
  247. package/lib/__tests__/Position.test.jsx +96 -0
  248. package/lib/__tests__/ProgressBar.test.jsx +38 -0
  249. package/lib/__tests__/SelectMenu.test.jsx +120 -0
  250. package/lib/__tests__/SelectPanel.test.jsx +48 -0
  251. package/lib/__tests__/SideNav.test.jsx +55 -0
  252. package/lib/__tests__/Spinner.test.jsx +41 -0
  253. package/lib/__tests__/StateLabel.test.jsx +46 -0
  254. package/lib/__tests__/StyledOcticon.test.jsx +28 -0
  255. package/lib/__tests__/SubNav.test.jsx +47 -0
  256. package/lib/__tests__/SubNavLink.test.jsx +31 -0
  257. package/lib/__tests__/TabNav.test.jsx +32 -0
  258. package/lib/__tests__/Text.test.jsx +71 -0
  259. package/lib/__tests__/TextInput.test.jsx +45 -0
  260. package/lib/__tests__/TextInputWithTokens.test.js +1 -10
  261. package/lib/__tests__/TextInputWithTokens.test.jsx +302 -0
  262. package/lib/__tests__/ThemeProvider.test.jsx +314 -0
  263. package/lib/__tests__/Timeline.test.jsx +51 -0
  264. package/lib/__tests__/Token.test.jsx +93 -0
  265. package/lib/__tests__/Tooltip.test.jsx +46 -0
  266. package/lib/__tests__/Truncate.test.jsx +41 -0
  267. package/lib/__tests__/UnderlineNav.test.jsx +53 -0
  268. package/lib/__tests__/UnderlineNavLink.test.jsx +31 -0
  269. package/lib/__tests__/behaviors/anchoredPosition.test.js +229 -376
  270. package/lib/__tests__/behaviors/focusTrap.test.jsx +184 -0
  271. package/lib/__tests__/behaviors/focusZone.test.jsx +406 -0
  272. package/lib/__tests__/behaviors/iterateFocusableElements.test.jsx +58 -0
  273. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.js +145 -216
  274. package/lib/__tests__/filterObject.test.js +48 -27
  275. package/lib/__tests__/hooks/useAnchoredPosition.test.jsx +29 -0
  276. package/lib/__tests__/hooks/useOnEscapePress.test.jsx +19 -0
  277. package/lib/__tests__/hooks/useOnOutsideClick.test.jsx +63 -0
  278. package/lib/__tests__/hooks/useOpenAndCloseFocus.test.jsx +61 -0
  279. package/lib/__tests__/hooks/useProvidedStateOrCreate.test.jsx +56 -0
  280. package/lib/__tests__/theme.test.js +33 -34
  281. package/lib/__tests__/themeGet.test.js +12 -23
  282. package/lib/__tests__/useSafeTimeout.test.jsx +36 -0
  283. package/lib/__tests__/utils/createSlots.test.d.ts +1 -0
  284. package/lib/__tests__/utils/createSlots.test.js +75 -0
  285. package/lib/__tests__/utils/createSlots.test.jsx +57 -0
  286. package/lib/behaviors/anchoredPosition.js +205 -234
  287. package/lib/behaviors/focusTrap.js +121 -157
  288. package/lib/behaviors/focusZone.js +434 -509
  289. package/lib/behaviors/scrollIntoViewingArea.js +18 -35
  290. package/lib/constants.js +39 -43
  291. package/lib/drafts.d.ts +8 -0
  292. package/lib/drafts.js +21 -0
  293. package/lib/hooks/index.js +16 -60
  294. package/lib/hooks/useAnchoredPosition.js +32 -39
  295. package/lib/hooks/useCombinedRefs.d.ts +2 -2
  296. package/lib/hooks/useCombinedRefs.js +32 -38
  297. package/lib/hooks/useDetails.jsx +39 -0
  298. package/lib/hooks/useDialog.js +72 -96
  299. package/lib/hooks/useFocusTrap.js +43 -60
  300. package/lib/hooks/useFocusZone.js +54 -50
  301. package/lib/hooks/useOnEscapePress.js +25 -36
  302. package/lib/hooks/useOnOutsideClick.jsx +61 -0
  303. package/lib/hooks/useOpenAndCloseFocus.js +22 -34
  304. package/lib/hooks/useOverlay.jsx +15 -0
  305. package/lib/hooks/useProvidedRefOrCreate.js +10 -14
  306. package/lib/hooks/useProvidedStateOrCreate.js +13 -16
  307. package/lib/hooks/useRenderForcingRef.js +13 -17
  308. package/lib/hooks/useResizeObserver.js +15 -18
  309. package/lib/hooks/useSafeTimeout.js +22 -30
  310. package/lib/hooks/useScrollFlash.js +16 -23
  311. package/lib/index.d.ts +2 -0
  312. package/lib/index.js +163 -636
  313. package/lib/polyfills/eventListenerSignal.js +37 -45
  314. package/lib/stories/ActionList2.stories.js +909 -0
  315. package/lib/stories/NewButton.stories.js +230 -0
  316. package/lib/stories/TextInput.stories.js +144 -0
  317. package/lib/stories/Token.stories.js +19 -2
  318. package/lib/sx.d.ts +2 -0
  319. package/lib/sx.js +10 -14
  320. package/lib/theme-preval.js +65 -2945
  321. package/lib/theme.js +3 -12
  322. package/lib/utils/create-slots.d.ts +17 -0
  323. package/lib/utils/create-slots.js +105 -0
  324. package/lib/utils/create-slots.jsx +65 -0
  325. package/lib/utils/deprecate.jsx +59 -0
  326. package/lib/utils/isNumeric.jsx +7 -0
  327. package/lib/utils/iterateFocusableElements.js +63 -85
  328. package/lib/utils/ssr.jsx +6 -0
  329. package/lib/utils/test-deprecations.jsx +20 -0
  330. package/lib/utils/test-helpers.jsx +8 -0
  331. package/lib/utils/test-matchers.jsx +100 -0
  332. package/lib/utils/testing.d.ts +20 -61
  333. package/lib/utils/testing.jsx +206 -0
  334. package/lib/utils/theme.js +33 -47
  335. package/lib/utils/types/AriaRole.js +2 -1
  336. package/lib/utils/types/ComponentProps.js +2 -1
  337. package/lib/utils/types/Flatten.js +2 -1
  338. package/lib/utils/types/KeyPaths.d.ts +1 -1
  339. package/lib/utils/types/KeyPaths.js +2 -1
  340. package/lib/utils/types/MandateProps.js +16 -1
  341. package/lib/utils/types/Merge.js +2 -1
  342. package/lib/utils/types/index.js +16 -69
  343. package/lib/utils/uniqueId.js +5 -8
  344. package/lib/utils/use-force-update.d.ts +1 -0
  345. package/lib/utils/use-force-update.js +13 -0
  346. package/lib/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  347. package/lib/utils/useIsomorphicLayoutEffect.js +9 -0
  348. package/lib/utils/userAgent.js +8 -12
  349. package/lib-esm/ActionList/Item.js +56 -72
  350. package/lib-esm/ActionList2/Description.d.ts +12 -0
  351. package/lib-esm/ActionList2/Description.js +41 -0
  352. package/lib-esm/ActionList2/Divider.d.ts +5 -0
  353. package/lib-esm/ActionList2/Divider.js +23 -0
  354. package/lib-esm/ActionList2/Group.d.ts +37 -0
  355. package/lib-esm/ActionList2/Group.js +87 -0
  356. package/lib-esm/ActionList2/Header.d.ts +26 -0
  357. package/lib-esm/ActionList2/Header.js +44 -0
  358. package/lib-esm/ActionList2/Item.d.ts +63 -0
  359. package/lib-esm/ActionList2/Item.js +208 -0
  360. package/lib-esm/ActionList2/LinkItem.d.ts +17 -0
  361. package/lib-esm/ActionList2/LinkItem.js +43 -0
  362. package/lib-esm/ActionList2/List.d.ts +26 -0
  363. package/lib-esm/ActionList2/List.js +37 -0
  364. package/lib-esm/ActionList2/Selection.d.ts +5 -0
  365. package/lib-esm/ActionList2/Selection.js +66 -0
  366. package/lib-esm/ActionList2/Visuals.d.ts +9 -0
  367. package/lib-esm/ActionList2/Visuals.js +68 -0
  368. package/lib-esm/ActionList2/index.d.ts +36 -0
  369. package/lib-esm/ActionList2/index.js +33 -0
  370. package/lib-esm/Autocomplete/Autocomplete.d.ts +28 -28
  371. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +28 -28
  372. package/lib-esm/Button/Button.d.ts +25 -25
  373. package/lib-esm/Button/ButtonClose.d.ts +45 -45
  374. package/lib-esm/Button/ButtonDanger.d.ts +25 -25
  375. package/lib-esm/Button/ButtonInvisible.d.ts +25 -25
  376. package/lib-esm/Button/ButtonOutline.d.ts +25 -25
  377. package/lib-esm/Button/ButtonPrimary.d.ts +25 -25
  378. package/lib-esm/CircleOcticon.d.ts +42 -42
  379. package/lib-esm/Dialog/Dialog.js +1 -0
  380. package/lib-esm/Dialog.d.ts +45 -45
  381. package/lib-esm/Dropdown.d.ts +176 -176
  382. package/lib-esm/DropdownMenu/DropdownButton.d.ts +46 -46
  383. package/lib-esm/FilterList.d.ts +42 -42
  384. package/lib-esm/NewButton/button-counter.d.ts +6 -0
  385. package/lib-esm/NewButton/button-counter.js +18 -0
  386. package/lib-esm/NewButton/button.d.ts +13 -0
  387. package/lib-esm/NewButton/button.js +287 -0
  388. package/lib-esm/NewButton/index.d.ts +14 -0
  389. package/lib-esm/NewButton/index.js +5 -0
  390. package/lib-esm/NewButton/types.d.ts +32 -0
  391. package/lib-esm/NewButton/types.js +1 -0
  392. package/lib-esm/Overlay.js +2 -1
  393. package/lib-esm/Portal/Portal.js +2 -1
  394. package/lib-esm/Position.d.ts +4 -4
  395. package/lib-esm/SelectMenu/SelectMenu.d.ts +246 -246
  396. package/lib-esm/SelectMenu/SelectMenuItem.d.ts +1 -1
  397. package/lib-esm/SelectMenu/SelectMenuModal.d.ts +1 -1
  398. package/lib-esm/StateLabel.d.ts +1 -1
  399. package/lib-esm/StateLabel.js +7 -2
  400. package/lib-esm/TextInputWithTokens.d.ts +28 -28
  401. package/lib-esm/Timeline.d.ts +43 -43
  402. package/lib-esm/Token/AvatarToken.d.ts +1 -1
  403. package/lib-esm/Token/IssueLabelToken.d.ts +1 -1
  404. package/lib-esm/Token/Token.d.ts +1 -1
  405. package/lib-esm/_TextInputWrapper.js +2 -2
  406. package/lib-esm/__tests__/ActionList2.test.d.ts +1 -0
  407. package/lib-esm/__tests__/ActionList2.test.js +41 -0
  408. package/lib-esm/__tests__/AnchoredOverlay.test.js +4 -2
  409. package/lib-esm/__tests__/KeyPaths.types.test.d.ts +2 -1
  410. package/lib-esm/__tests__/NewButton.test.d.ts +1 -0
  411. package/lib-esm/__tests__/NewButton.test.js +84 -0
  412. package/lib-esm/__tests__/TextInputWithTokens.test.js +1 -10
  413. package/lib-esm/__tests__/utils/createSlots.test.d.ts +1 -0
  414. package/lib-esm/__tests__/utils/createSlots.test.js +67 -0
  415. package/lib-esm/drafts.d.ts +8 -0
  416. package/lib-esm/drafts.js +9 -0
  417. package/lib-esm/hooks/useAnchoredPosition.js +2 -1
  418. package/lib-esm/hooks/useCombinedRefs.d.ts +2 -2
  419. package/lib-esm/hooks/useCombinedRefs.js +3 -2
  420. package/lib-esm/hooks/useResizeObserver.js +2 -2
  421. package/lib-esm/index.d.ts +2 -0
  422. package/lib-esm/index.js +1 -0
  423. package/lib-esm/stories/ActionList2.stories.js +797 -0
  424. package/lib-esm/stories/NewButton.stories.js +178 -0
  425. package/lib-esm/stories/TextInput.stories.js +117 -0
  426. package/lib-esm/stories/Token.stories.js +14 -1
  427. package/lib-esm/sx.d.ts +2 -0
  428. package/lib-esm/sx.js +3 -1
  429. package/lib-esm/theme-preval.js +147 -368
  430. package/lib-esm/utils/create-slots.d.ts +17 -0
  431. package/lib-esm/utils/create-slots.js +84 -0
  432. package/lib-esm/utils/testing.d.ts +20 -61
  433. package/lib-esm/utils/types/KeyPaths.d.ts +1 -1
  434. package/lib-esm/utils/use-force-update.d.ts +1 -0
  435. package/lib-esm/utils/use-force-update.js +6 -0
  436. package/lib-esm/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  437. package/lib-esm/utils/useIsomorphicLayoutEffect.js +3 -0
  438. package/migrating.md +1 -1
  439. package/package-lock.json +168 -16
  440. package/package.json +9 -5
  441. package/script/build +3 -1
  442. package/src/ActionList/Item.tsx +49 -65
  443. package/src/ActionList2/Description.tsx +52 -0
  444. package/src/ActionList2/Divider.tsx +24 -0
  445. package/src/ActionList2/Group.tsx +103 -0
  446. package/src/ActionList2/Header.tsx +58 -0
  447. package/src/ActionList2/Item.tsx +246 -0
  448. package/src/ActionList2/LinkItem.tsx +49 -0
  449. package/src/ActionList2/List.tsx +55 -0
  450. package/src/ActionList2/Selection.tsx +60 -0
  451. package/src/ActionList2/Visuals.tsx +76 -0
  452. package/src/ActionList2/index.ts +39 -0
  453. package/src/Dialog/Dialog.tsx +1 -0
  454. package/src/NewButton/button-counter.tsx +15 -0
  455. package/src/NewButton/button.tsx +283 -0
  456. package/src/NewButton/index.ts +10 -0
  457. package/src/NewButton/types.ts +36 -0
  458. package/src/Overlay.tsx +2 -1
  459. package/src/Portal/Portal.tsx +2 -1
  460. package/src/StateLabel.tsx +14 -2
  461. package/src/_TextInputWrapper.tsx +7 -0
  462. package/src/__tests__/ActionList2.test.tsx +47 -0
  463. package/src/__tests__/AnchoredOverlay.test.tsx +2 -2
  464. package/src/__tests__/KeyPaths.types.test.ts +2 -1
  465. package/src/__tests__/NewButton.test.tsx +70 -0
  466. package/src/__tests__/TextInputWithTokens.test.tsx +0 -10
  467. package/src/__tests__/__snapshots__/ActionList.test.tsx.snap +5 -5
  468. package/src/__tests__/__snapshots__/ActionList2.test.tsx.snap +14 -0
  469. package/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap +35 -135
  470. package/src/__tests__/__snapshots__/Autocomplete.test.tsx.snap +747 -280
  471. package/src/__tests__/__snapshots__/CircleBadge.test.tsx.snap +1 -0
  472. package/src/__tests__/__snapshots__/CircleOcticon.test.tsx.snap +1 -0
  473. package/src/__tests__/__snapshots__/Dialog.test.tsx.snap +1 -0
  474. package/src/__tests__/__snapshots__/DropdownMenu.test.tsx.snap +1 -0
  475. package/src/__tests__/__snapshots__/NewButton.test.tsx.snap +305 -0
  476. package/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap +4 -0
  477. package/src/__tests__/__snapshots__/SelectPanel.test.tsx.snap +1 -0
  478. package/src/__tests__/__snapshots__/StateLabel.test.tsx.snap +13 -6
  479. package/src/__tests__/__snapshots__/StyledOcticon.test.tsx.snap +1 -0
  480. package/src/__tests__/__snapshots__/TextInputWithTokens.test.tsx.snap +66 -0
  481. package/src/__tests__/__snapshots__/Token.test.tsx.snap +17 -0
  482. package/src/__tests__/utils/__snapshots__/createSlots.test.tsx.snap +55 -0
  483. package/src/__tests__/utils/createSlots.test.tsx +74 -0
  484. package/src/drafts.ts +10 -0
  485. package/src/hooks/useAnchoredPosition.ts +2 -1
  486. package/src/hooks/useCombinedRefs.ts +3 -3
  487. package/src/hooks/useResizeObserver.ts +2 -2
  488. package/src/index.ts +2 -0
  489. package/src/stories/ActionList2.stories.tsx +1291 -0
  490. package/src/stories/Button.stories.tsx +1 -1
  491. package/src/stories/NewButton.stories.tsx +201 -0
  492. package/src/stories/TextInput.stories.tsx +113 -0
  493. package/src/stories/Token.stories.tsx +12 -1
  494. package/src/sx.ts +3 -0
  495. package/src/theme-preval.js +1 -0
  496. package/src/utils/create-slots.tsx +96 -0
  497. package/src/utils/types/KeyPaths.ts +7 -1
  498. package/src/utils/use-force-update.ts +7 -0
  499. package/src/utils/useIsomorphicLayoutEffect.ts +10 -0
  500. package/stats.html +1 -1
  501. package/tsconfig.base.json +20 -0
  502. package/tsconfig.build.json +2 -2
  503. package/tsconfig.json +4 -17
@@ -7,7 +7,7 @@ import {ItemInput} from './List'
7
7
  import styled from 'styled-components'
8
8
  import {StyledHeader} from './Header'
9
9
  import {StyledDivider} from './Divider'
10
- import {useColorSchemeVar, useTheme} from '../ThemeProvider'
10
+ import {useTheme} from '../ThemeProvider'
11
11
  import {
12
12
  activeDescendantActivatedDirectly,
13
13
  activeDescendantActivatedIndirectly,
@@ -17,36 +17,6 @@ import {useSSRSafeId} from '@react-aria/ssr'
17
17
  import {ForwardRefComponent as PolymorphicForwardRefComponent} from '@radix-ui/react-polymorphic'
18
18
  import {AriaRole} from '../utils/types'
19
19
 
20
- /**
21
- * These colors are not yet in our default theme. Need to remove this once they are added.
22
- */
23
- const customItemThemes = {
24
- default: {
25
- hover: {
26
- light: 'rgba(46, 77, 108, 0.06)',
27
- dark: 'rgba(201, 206, 212, 0.12)',
28
- dark_dimmed: 'rgba(201, 206, 212, 0.12)'
29
- },
30
- focus: {
31
- light: 'rgba(54, 77, 100, 0.16)',
32
- dark: 'rgba(201, 206, 212, 0.24)',
33
- dark_dimmed: 'rgba(201, 206, 212, 0.24)'
34
- }
35
- },
36
- danger: {
37
- hover: {
38
- light: 'rgba(234, 74, 90, 0.08)',
39
- dark: 'rgba(248, 81, 73, 0.16)',
40
- dark_dimmed: 'rgba(248, 81, 73, 0.16)'
41
- },
42
- focus: {
43
- light: 'rgba(234, 74, 90, 0.14)',
44
- dark: 'rgba(248, 81, 73, 0.24)',
45
- dark_dimmed: 'rgba(248, 81, 73, 0.24)'
46
- }
47
- }
48
- } as const
49
-
50
20
  /**
51
21
  * Contract for props passed to the `Item` component.
52
22
  */
@@ -166,14 +136,19 @@ const getItemVariant = (variant = 'default', disabled?: boolean) => {
166
136
  color: get('colors.danger.fg'),
167
137
  iconColor: get('colors.danger.fg'),
168
138
  annotationColor: get('colors.fg.muted'),
169
- hoverCursor: 'pointer'
139
+ hoverCursor: 'pointer',
140
+ hoverBg: get('colors.actionListItem.danger.hoverBg'),
141
+ focusBg: get('colors.actionListItem.danger.activeBg'),
142
+ hoverText: get('colors.actionListItem.danger.hoverText')
170
143
  }
171
144
  default:
172
145
  return {
173
146
  color: get('colors.fg.default'),
174
147
  iconColor: get('colors.fg.muted'),
175
148
  annotationColor: get('colors.fg.muted'),
176
- hoverCursor: 'pointer'
149
+ hoverCursor: 'pointer',
150
+ hoverBg: get('colors.actionListItem.default.hoverBg'),
151
+ focusBg: get('colors.actionListItem.default.activeBg')
177
152
  }
178
153
  }
179
154
  }
@@ -200,8 +175,6 @@ const StyledItem = styled.div<
200
175
  variant: ItemProps['variant']
201
176
  showDivider: ItemProps['showDivider']
202
177
  item?: ItemInput
203
- hoverBackground: string
204
- focusBackground: string
205
178
  } & SxProp
206
179
  >`
207
180
  /* 6px vertical padding + 20px line height = 32px total height
@@ -220,7 +193,11 @@ const StyledItem = styled.div<
220
193
  @media (hover: hover) and (pointer: fine) {
221
194
  :hover {
222
195
  // allow override in case another item in the list is active/focused
223
- background: var(--item-hover-bg-override, ${({hoverBackground}) => hoverBackground});
196
+ background: var(
197
+ --item-hover-bg-override,
198
+ ${({variant, item}) => getItemVariant(variant, item?.disabled).hoverBg}
199
+ );
200
+ color: ${({variant, item}) => getItemVariant(variant, item?.disabled).hoverText};
224
201
  cursor: ${({variant, item}) => getItemVariant(variant, item?.disabled).hoverCursor};
225
202
  }
226
203
  }
@@ -266,19 +243,19 @@ const StyledItem = styled.div<
266
243
 
267
244
  // Active Descendant
268
245
  &[${isActiveDescendantAttribute}='${activeDescendantActivatedDirectly}'] {
269
- background: ${({focusBackground}) => focusBackground};
246
+ background: ${({variant, item}) => getItemVariant(variant, item?.disabled).focusBg};
270
247
  }
271
248
  &[${isActiveDescendantAttribute}='${activeDescendantActivatedIndirectly}'] {
272
- background: ${({hoverBackground}) => hoverBackground};
249
+ background: ${({variant, item}) => getItemVariant(variant, item?.disabled).hoverBg};
273
250
  }
274
251
 
275
252
  &:focus {
276
- background: ${({focusBackground}) => focusBackground};
253
+ background: ${({variant, item}) => getItemVariant(variant, item?.disabled).focusBg};
277
254
  outline: none;
278
255
  }
279
256
 
280
257
  &:active {
281
- background: ${({focusBackground}) => focusBackground};
258
+ background: ${({variant, item}) => getItemVariant(variant, item?.disabled).focusBg};
282
259
  }
283
260
 
284
261
  ${sx}
@@ -295,6 +272,9 @@ const BaseVisualContainer = styled.div<{variant?: ItemProps['variant']; disabled
295
272
  height: 20px;
296
273
  width: ${get('space.3')};
297
274
  margin-right: ${get('space.2')};
275
+ display: flex;
276
+ justify-content: center;
277
+ align-items: center;
298
278
  `
299
279
 
300
280
  const ColoredVisualContainer = styled(BaseVisualContainer)`
@@ -333,8 +313,16 @@ const DescriptionContainer = styled.span`
333
313
  flex-basis: var(--description-container-flex-basis);
334
314
  `
335
315
 
336
- const MultiSelectInput = styled.input`
337
- pointer-events: none;
316
+ const MultiSelectIcon = styled.svg<{selected?: boolean}>`
317
+ rect {
318
+ fill: ${({selected}) => (selected ? get('colors.accent.fg') : get('colors.canvas.default'))};
319
+ stroke: ${({selected}) => (selected ? get('colors.accent.fg') : get('colors.border.default'))};
320
+ }
321
+ path {
322
+ fill: ${get('colors.fg.onEmphasis')};
323
+ boxshadow: ${get('shadow.small')};
324
+ opacity: ${({selected}) => (selected ? 1 : 0)};
325
+ }
338
326
  `
339
327
 
340
328
  /**
@@ -372,11 +360,6 @@ export const Item = React.forwardRef((itemProps, ref) => {
372
360
  return
373
361
  }
374
362
  onKeyPress?.(event)
375
- const isCheckbox = event.target instanceof HTMLInputElement && event.target.type === 'checkbox'
376
- if (isCheckbox && event.key === ' ') {
377
- // space key on a checkbox will also trigger a click event. Ignore the space key so we don't get double events
378
- return
379
- }
380
363
 
381
364
  if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
382
365
  onAction?.(itemProps, event)
@@ -398,10 +381,6 @@ export const Item = React.forwardRef((itemProps, ref) => {
398
381
  [onAction, disabled, itemProps, onClick]
399
382
  )
400
383
 
401
- const customItemTheme = customItemThemes[variant]
402
- const hoverBackground = useColorSchemeVar(customItemTheme.hover, 'inherit')
403
- const focusBackground = useColorSchemeVar(customItemTheme.focus, 'inherit')
404
-
405
384
  const {theme} = useTheme()
406
385
 
407
386
  return (
@@ -418,26 +397,31 @@ export const Item = React.forwardRef((itemProps, ref) => {
418
397
  data-id={id}
419
398
  onKeyPress={keyPressHandler}
420
399
  onClick={clickHandler}
421
- hoverBackground={disabled ? 'inherit' : hoverBackground}
422
- focusBackground={disabled ? 'inherit' : focusBackground}
423
400
  >
424
401
  {!!selected === selected && (
425
402
  <BaseVisualContainer>
426
403
  {selectionVariant === 'multiple' ? (
427
404
  <>
428
- {/*
429
- * readOnly is required because we are doing a one-way bind to `checked`.
430
- * aria-readonly="false" tells screen that they can still interact with the checkbox
405
+ {/**
406
+ * we use a svg instead of an input because there should not
407
+ * be an interactive element inside an option
408
+ * svg copied from primer/css
431
409
  */}
432
- <MultiSelectInput
433
- disabled={disabled}
434
- tabIndex={-1}
435
- type="checkbox"
436
- checked={selected}
437
- aria-label={text}
438
- readOnly
439
- aria-readonly="false"
440
- />
410
+ <MultiSelectIcon
411
+ selected={selected}
412
+ width="16"
413
+ height="16"
414
+ viewBox="0 0 16 16"
415
+ xmlns="http://www.w3.org/2000/svg"
416
+ aria-hidden="true"
417
+ >
418
+ <rect x="2" y="2" width="12" height="12" rx="4"></rect>
419
+ <path
420
+ fillRule="evenodd"
421
+ strokeWidth="0"
422
+ d="M4.03231 8.69862C3.84775 8.20646 4.49385 7.77554 4.95539 7.77554C5.41693 7.77554 6.80154 9.85246 6.80154 9.85246C6.80154 9.85246 10.2631 4.314 10.4938 4.08323C10.7246 3.85246 11.8785 4.08323 11.4169 5.00631C11.0081 5.82388 7.26308 11.4678 7.26308 11.4678C7.26308 11.4678 6.80154 12.1602 6.34 11.4678C5.87846 10.7755 4.21687 9.19077 4.03231 8.69862Z"
423
+ />
424
+ </MultiSelectIcon>
441
425
  </>
442
426
  ) : (
443
427
  selected && <CheckIcon fill={theme?.colors.fg.default} />
@@ -0,0 +1,52 @@
1
+ import React from 'react'
2
+ import Box from '../Box'
3
+ import {SxProp, merge} from '../sx'
4
+ import Truncate from '../Truncate'
5
+ import {Slot, ItemContext} from './Item'
6
+
7
+ export type DescriptionProps = {
8
+ /**
9
+ * Secondary text style variations.
10
+ *
11
+ * - `"inline"` - Secondary text is positioned beside primary text.
12
+ * - `"block"` - Secondary text is positioned below primary text.
13
+ */
14
+ variant?: 'inline' | 'block'
15
+ } & SxProp
16
+
17
+ export const Description: React.FC<DescriptionProps> = ({variant = 'inline', sx = {}, ...props}) => {
18
+ const styles = {
19
+ fontSize: 0,
20
+ lineHeight: '16px',
21
+ flexGrow: 1,
22
+ flexBasis: 0,
23
+ minWidth: 0,
24
+ marginLeft: variant === 'block' ? 0 : 2
25
+ }
26
+
27
+ return (
28
+ <Slot name={variant === 'block' ? 'BlockDescription' : 'InlineDescription'}>
29
+ {({blockDescriptionId, inlineDescriptionId, disabled}: ItemContext) =>
30
+ variant === 'block' ? (
31
+ <Box
32
+ as="span"
33
+ sx={merge({...styles, color: disabled ? 'fg.disabled' : 'fg.muted'}, sx as SxProp)}
34
+ id={blockDescriptionId}
35
+ >
36
+ {props.children}
37
+ </Box>
38
+ ) : (
39
+ <Truncate
40
+ id={inlineDescriptionId}
41
+ sx={merge({...styles, color: disabled ? 'fg.disabled' : 'fg.muted'}, sx as SxProp)}
42
+ title={props.children as string}
43
+ inline={true}
44
+ maxWidth="100%"
45
+ >
46
+ {props.children}
47
+ </Truncate>
48
+ )
49
+ }
50
+ </Slot>
51
+ )
52
+ }
@@ -0,0 +1,24 @@
1
+ import React from 'react'
2
+ import Box from '../Box'
3
+ import {get} from '../constants'
4
+ import {Theme} from '../ThemeProvider'
5
+
6
+ /**
7
+ * Visually separates `Item`s or `Group`s in an `ActionList`.
8
+ */
9
+ export function Divider(): JSX.Element {
10
+ return (
11
+ <Box
12
+ as="li"
13
+ role="separator"
14
+ sx={{
15
+ height: 1,
16
+ backgroundColor: 'actionListItem.inlineDivider',
17
+ marginTop: (theme: Theme) => `calc(${get('space.2')(theme)} - 1px)`,
18
+ marginBottom: 2,
19
+ listStyle: 'none' // hide the ::marker inserted by browser's stylesheet
20
+ }}
21
+ data-component="ActionList.Divider"
22
+ />
23
+ )
24
+ }
@@ -0,0 +1,103 @@
1
+ import React from 'react'
2
+ import {useSSRSafeId} from '@react-aria/ssr'
3
+ import Box from '../Box'
4
+ import {SxProp} from '../sx'
5
+ import {ListContext, ListProps} from './List'
6
+ import {AriaRole} from '../utils/types'
7
+
8
+ export type GroupProps = {
9
+ /**
10
+ * Style variations. Usage is discretionary.
11
+ *
12
+ * - `"filled"` - Superimposed on a background, offset from nearby content
13
+ * - `"subtle"` - Relatively less offset from nearby content
14
+ */
15
+ variant?: 'subtle' | 'filled'
16
+ /**
17
+ * Primary text which names a `Group`.
18
+ */
19
+ title?: string
20
+ /**
21
+ * Secondary text which provides additional information about a `Group`.
22
+ */
23
+ auxiliaryText?: string
24
+ /**
25
+ * The ARIA role describing the function of the list inside `Group` component. `listbox` or `menu` are a common values.
26
+ */
27
+ role?: AriaRole
28
+ } & SxProp & {
29
+ /**
30
+ * Whether multiple Items or a single Item can be selected in the Group. Overrides value on ActionList root.
31
+ */
32
+ selectionVariant?: ListProps['selectionVariant'] | false
33
+ }
34
+
35
+ type ContextProps = Pick<GroupProps, 'selectionVariant'>
36
+ export const GroupContext = React.createContext<ContextProps>({})
37
+
38
+ export const Group: React.FC<GroupProps> = ({
39
+ title,
40
+ variant = 'subtle',
41
+ auxiliaryText,
42
+ selectionVariant,
43
+ role,
44
+ sx = {},
45
+ ...props
46
+ }) => {
47
+ const labelId = useSSRSafeId()
48
+
49
+ return (
50
+ <Box
51
+ as="li"
52
+ sx={{
53
+ '&:not(:first-child)': {marginTop: 2},
54
+ listStyle: 'none', // hide the ::marker inserted by browser's stylesheet
55
+ ...sx
56
+ }}
57
+ {...props}
58
+ >
59
+ {title && <Header title={title} variant={variant} auxiliaryText={auxiliaryText} labelId={labelId} />}
60
+ <GroupContext.Provider value={{selectionVariant}}>
61
+ <Box as="ul" sx={{paddingInlineStart: 0}} aria-labelledby={title ? labelId : undefined} role={role}>
62
+ {props.children}
63
+ </Box>
64
+ </GroupContext.Provider>
65
+ </Box>
66
+ )
67
+ }
68
+
69
+ export type HeaderProps = Pick<GroupProps, 'variant' | 'title' | 'auxiliaryText'> & {
70
+ labelId: string
71
+ }
72
+
73
+ /**
74
+ * Displays the name and description of a `Group`.
75
+ *
76
+ * For visual presentation only. It's hidden from screen readers.
77
+ */
78
+ const Header: React.FC<HeaderProps> = ({variant, title, auxiliaryText, labelId, ...props}) => {
79
+ const {variant: listVariant} = React.useContext(ListContext)
80
+
81
+ const styles = {
82
+ paddingY: '6px',
83
+ paddingX: listVariant === 'full' ? 2 : 3,
84
+ fontSize: 0,
85
+ fontWeight: 'bold',
86
+ color: 'fg.muted',
87
+ ...(variant === 'filled' && {
88
+ backgroundColor: 'canvas.subtle',
89
+ marginX: 0,
90
+ marginBottom: 2,
91
+ borderTop: '1px solid',
92
+ borderBottom: '1px solid',
93
+ borderColor: 'neutral.muted'
94
+ })
95
+ }
96
+
97
+ return (
98
+ <Box sx={styles} role="presentation" aria-hidden="true" {...props}>
99
+ <span id={labelId}>{title}</span>
100
+ {auxiliaryText && <span>{auxiliaryText}</span>}
101
+ </Box>
102
+ )
103
+ }
@@ -0,0 +1,58 @@
1
+ import React from 'react'
2
+ import Box from '../Box'
3
+ import {SxProp} from '../sx'
4
+ import {ListContext} from './List'
5
+
6
+ /**
7
+ * Contract for props passed to the `Header` component.
8
+ */
9
+ export type HeaderProps = {
10
+ /**
11
+ * Style variations. Usage is discretionary.
12
+ *
13
+ * - `"filled"` - Superimposed on a background, offset from nearby content
14
+ * - `"subtle"` - Relatively less offset from nearby content
15
+ */
16
+ variant?: 'subtle' | 'filled'
17
+
18
+ /**
19
+ * Primary text which names a `Group`.
20
+ */
21
+ title?: string
22
+
23
+ /**
24
+ * Secondary text which provides additional information about a `Group`.
25
+ */
26
+ auxiliaryText?: string
27
+ } & SxProp
28
+
29
+ /**
30
+ * Displays the name and description of a `Group`.
31
+ */
32
+ export const Header = ({variant = 'subtle', title, auxiliaryText, sx = {}, ...props}: HeaderProps): JSX.Element => {
33
+ const {variant: listVariant} = React.useContext(ListContext)
34
+
35
+ const styles = {
36
+ paddingY: '6px',
37
+ paddingX: listVariant === 'full' ? 2 : 3,
38
+ fontSize: 0,
39
+ fontWeight: 'bold',
40
+ color: 'fg.muted',
41
+ ...(variant === 'filled' && {
42
+ backgroundColor: 'canvas.subtle',
43
+ marginX: 0,
44
+ marginBottom: 2,
45
+ borderTop: '1px solid',
46
+ borderBottom: '1px solid',
47
+ borderColor: 'neutral.muted'
48
+ }),
49
+ ...sx
50
+ }
51
+
52
+ return (
53
+ <Box sx={styles} role="heading" {...props}>
54
+ {title}
55
+ {auxiliaryText && <span>{auxiliaryText}</span>}
56
+ </Box>
57
+ )
58
+ }
@@ -0,0 +1,246 @@
1
+ import React from 'react'
2
+ import {ForwardRefComponent as PolymorphicForwardRefComponent} from '@radix-ui/react-polymorphic'
3
+ import {useSSRSafeId} from '@react-aria/ssr'
4
+ import styled from 'styled-components'
5
+ import {useTheme} from '../ThemeProvider'
6
+ import Box, {BoxProps} from '../Box'
7
+ import sx, {SxProp, merge} from '../sx'
8
+ import createSlots from '../utils/create-slots'
9
+ import {AriaRole} from '../utils/types'
10
+ import {ListContext} from './List'
11
+ import {Selection} from './Selection'
12
+
13
+ export const getVariantStyles = (variant: ItemProps['variant'], disabled: ItemProps['disabled']) => {
14
+ if (disabled) {
15
+ return {
16
+ color: 'primer.fg.disabled',
17
+ iconColor: 'primer.fg.disabled',
18
+ annotationColor: 'primer.fg.disabled'
19
+ }
20
+ }
21
+
22
+ switch (variant) {
23
+ case 'danger':
24
+ return {
25
+ color: 'danger.fg',
26
+ iconColor: 'danger.fg',
27
+ annotationColor: 'fg.muted',
28
+ hoverColor: 'actionListItem.danger.hoverText'
29
+ }
30
+ default:
31
+ return {
32
+ color: 'fg.default',
33
+ iconColor: 'fg.muted',
34
+ annotationColor: 'fg.muted',
35
+ hoverColor: 'fg.default'
36
+ }
37
+ }
38
+ }
39
+
40
+ export type ItemProps = {
41
+ /**
42
+ * Primary content for an Item
43
+ */
44
+ children?: React.ReactNode
45
+ /**
46
+ * Callback that will trigger both on click selection and keyboard selection.
47
+ */
48
+ onSelect?: (event: React.MouseEvent<HTMLLIElement> | React.KeyboardEvent<HTMLLIElement>) => void
49
+ /**
50
+ * Is the `Item` is currently selected?
51
+ */
52
+ selected?: boolean
53
+ /**
54
+ * Style variations associated with various `Item` types.
55
+ *
56
+ * - `"default"` - An action `Item`.
57
+ * - `"danger"` - A destructive action `Item`.
58
+ */
59
+ variant?: 'default' | 'danger'
60
+ /**
61
+ * Items that are disabled can not be clicked, selected, or navigated through.
62
+ */
63
+ disabled?: boolean
64
+ /**
65
+ * The ARIA role describing the function of `Item` component. `option` is a common value.
66
+ */
67
+ role?: AriaRole
68
+ /**
69
+ * id to attach to the root element of the Item
70
+ */
71
+ id?: string
72
+ /**
73
+ * Private API for use internally only. Used by LinkItem to wrap contents in an anchor
74
+ */
75
+ _PrivateItemWrapper?: React.FC
76
+ } & SxProp
77
+
78
+ const {Slots, Slot} = createSlots(['LeadingVisual', 'InlineDescription', 'BlockDescription', 'TrailingVisual'])
79
+ export {Slot}
80
+ export type ItemContext = Pick<ItemProps, 'variant' | 'disabled'> & {
81
+ inlineDescriptionId: string
82
+ blockDescriptionId: string
83
+ }
84
+
85
+ const LiBox = styled.li<SxProp>(sx)
86
+ export const TEXT_ROW_HEIGHT = '20px' // custom value off the scale
87
+
88
+ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
89
+ (
90
+ {
91
+ variant = 'default',
92
+ disabled = false,
93
+ selected = undefined,
94
+ onSelect = () => null,
95
+ sx: sxProp = {},
96
+ id,
97
+ _PrivateItemWrapper,
98
+ ...props
99
+ },
100
+ forwardedRef
101
+ ): JSX.Element => {
102
+ const {variant: listVariant, showDividers} = React.useContext(ListContext)
103
+
104
+ const {theme} = useTheme()
105
+
106
+ const styles = {
107
+ display: 'flex',
108
+ paddingX: 2,
109
+ fontSize: 1,
110
+ paddingY: '6px', // custom value off the scale
111
+ lineHeight: TEXT_ROW_HEIGHT,
112
+ minHeight: 5,
113
+ marginX: listVariant === 'inset' ? 2 : 0,
114
+ borderRadius: listVariant === 'inset' ? 2 : 0,
115
+ transition: 'background 33.333ms linear',
116
+ color: getVariantStyles(variant, disabled).color,
117
+ cursor: 'pointer',
118
+ '&[aria-disabled]': {cursor: 'not-allowed'},
119
+
120
+ '@media (hover: hover) and (pointer: fine)': {
121
+ ':hover:not([aria-disabled])': {
122
+ backgroundColor: `actionListItem.${variant}.hoverBg`,
123
+ color: getVariantStyles(variant, disabled).hoverColor
124
+ },
125
+ ':focus:not([data-focus-visible-added])': {
126
+ backgroundColor: `actionListItem.${variant}.selectedBg`,
127
+ color: getVariantStyles(variant, disabled).hoverColor,
128
+ outline: 'none'
129
+ },
130
+ '&[data-focus-visible-added]': {
131
+ // we don't use :focus-visible because not all browsers (safari) have it yet
132
+ outline: 'none',
133
+ border: `2 solid`,
134
+ boxShadow: `0 0 0 2px ${theme?.colors.accent.emphasis}`
135
+ },
136
+ ':active:not([aria-disabled])': {
137
+ backgroundColor: `actionListItem.${variant}.activeBg`,
138
+ color: getVariantStyles(variant, disabled).hoverColor
139
+ }
140
+ },
141
+
142
+ /** Divider styles */
143
+ '[data-component="ActionList.Item--DividerContainer"]': {
144
+ position: 'relative'
145
+ },
146
+ '[data-component="ActionList.Item--DividerContainer"]::before': {
147
+ content: '" "',
148
+ display: 'block',
149
+ position: 'absolute',
150
+ width: '100%',
151
+ top: '-7px',
152
+ border: '0 solid',
153
+ borderTopWidth: showDividers ? `1px` : '0',
154
+ borderColor: 'var(--divider-color, transparent)'
155
+ },
156
+ // show between 2 items
157
+ ':not(:first-of-type)': {'--divider-color': theme?.colors.actionListItem.inlineDivider},
158
+ // hide divider after dividers & group header, with higher importance!
159
+ '[data-component="ActionList.Divider"] + &': {'--divider-color': 'transparent !important'},
160
+ // hide border on current and previous item
161
+ '&:hover:not([aria-disabled]), &:focus:not([aria-disabled]), &[data-focus-visible-added]:not([aria-disabled])': {
162
+ '--divider-color': 'transparent'
163
+ },
164
+ '&:hover:not([aria-disabled]) + &, &:focus:not([aria-disabled]) + &, &[data-focus-visible-added] + li': {
165
+ '--divider-color': 'transparent'
166
+ }
167
+ }
168
+
169
+ const clickHandler = React.useCallback(
170
+ event => {
171
+ if (disabled) return
172
+ if (!event.defaultPrevented) onSelect(event)
173
+ },
174
+ [onSelect, disabled]
175
+ )
176
+
177
+ const keyPressHandler = React.useCallback(
178
+ event => {
179
+ if (disabled) return
180
+
181
+ if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
182
+ onSelect(event)
183
+ }
184
+ },
185
+ [onSelect, disabled]
186
+ )
187
+
188
+ // use props.id if provided, otherwise generate one.
189
+ const labelId = useSSRSafeId(id)
190
+ const inlineDescriptionId = useSSRSafeId(id && `${id}--inline-description`)
191
+ const blockDescriptionId = useSSRSafeId(id && `${id}--block-description`)
192
+
193
+ const ItemWrapper = _PrivateItemWrapper || React.Fragment
194
+
195
+ return (
196
+ <Slots context={{variant, disabled, inlineDescriptionId, blockDescriptionId}}>
197
+ {slots => (
198
+ <LiBox
199
+ ref={forwardedRef}
200
+ sx={merge(styles, sxProp as SxProp)}
201
+ onClick={clickHandler}
202
+ onKeyPress={keyPressHandler}
203
+ aria-selected={selected}
204
+ aria-disabled={disabled ? true : undefined}
205
+ tabIndex={disabled || _PrivateItemWrapper ? undefined : 0}
206
+ aria-labelledby={`${labelId} ${slots.InlineDescription ? inlineDescriptionId : ''}`}
207
+ aria-describedby={slots.BlockDescription ? blockDescriptionId : undefined}
208
+ {...props}
209
+ >
210
+ <ItemWrapper>
211
+ <Selection selected={selected} />
212
+ {slots.LeadingVisual}
213
+ <Box
214
+ data-component="ActionList.Item--DividerContainer"
215
+ sx={{display: 'flex', flexDirection: 'column', flexGrow: 1, minWidth: 0}}
216
+ >
217
+ <ConditionalBox if={Boolean(slots.TrailingVisual)} sx={{display: 'flex', flexGrow: 1}}>
218
+ <ConditionalBox
219
+ if={Boolean(slots.InlineDescription)}
220
+ sx={{display: 'flex', flexGrow: 1, alignItems: 'baseline', minWidth: 0}}
221
+ >
222
+ <Box as="span" id={labelId} sx={{flexGrow: slots.InlineDescription ? 0 : 1}}>
223
+ {props.children}
224
+ </Box>
225
+ {slots.InlineDescription}
226
+ </ConditionalBox>
227
+ {slots.TrailingVisual}
228
+ </ConditionalBox>
229
+ {slots.BlockDescription}
230
+ </Box>
231
+ </ItemWrapper>
232
+ </LiBox>
233
+ )}
234
+ </Slots>
235
+ )
236
+ }
237
+ ) as PolymorphicForwardRefComponent<'li', ItemProps>
238
+
239
+ Item.displayName = 'ActionList.Item'
240
+
241
+ const ConditionalBox: React.FC<{if: boolean} & BoxProps> = props => {
242
+ const {if: condition, ...rest} = props
243
+
244
+ if (condition) return <Box {...rest}>{props.children}</Box>
245
+ else return <>{props.children}</>
246
+ }