@primer/components 31.2.0-rc.b718ff50 → 31.2.0-rc.decfca99

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 (420) 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 +13 -1
  5. package/dist/browser.esm.js +620 -618
  6. package/dist/browser.esm.js.map +1 -1
  7. package/dist/browser.umd.js +188 -186
  8. package/dist/browser.umd.js.map +1 -1
  9. package/docs/content/ActionList2.mdx +360 -0
  10. package/docs/content/StateLabel.md +5 -4
  11. package/docs/content/getting-started.md +1 -1
  12. package/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +17 -0
  13. package/lib/ActionList/Divider.jsx +29 -0
  14. package/lib/ActionList/Group.jsx +23 -0
  15. package/lib/ActionList/Header.jsx +66 -0
  16. package/lib/ActionList/Item.jsx +301 -0
  17. package/lib/ActionList/List.jsx +138 -0
  18. package/lib/ActionList/index.js +12 -23
  19. package/lib/ActionList2/Description.d.ts +12 -0
  20. package/lib/ActionList2/Description.js +53 -0
  21. package/lib/ActionList2/Description.jsx +30 -0
  22. package/lib/ActionList2/Divider.d.ts +5 -0
  23. package/lib/ActionList2/Divider.js +35 -0
  24. package/lib/ActionList2/Divider.jsx +22 -0
  25. package/lib/ActionList2/Group.d.ts +11 -0
  26. package/lib/ActionList2/Group.js +57 -0
  27. package/lib/ActionList2/Group.jsx +25 -0
  28. package/lib/ActionList2/Header.d.ts +26 -0
  29. package/lib/ActionList2/Header.js +55 -0
  30. package/lib/ActionList2/Header.jsx +36 -0
  31. package/lib/ActionList2/Item.d.ts +63 -0
  32. package/lib/ActionList2/Item.js +244 -0
  33. package/lib/ActionList2/Item.jsx +174 -0
  34. package/lib/ActionList2/LinkItem.d.ts +17 -0
  35. package/lib/ActionList2/LinkItem.js +57 -0
  36. package/lib/ActionList2/LinkItem.jsx +28 -0
  37. package/lib/ActionList2/List.d.ts +26 -0
  38. package/lib/ActionList2/List.js +59 -0
  39. package/lib/ActionList2/List.jsx +41 -0
  40. package/lib/ActionList2/Selection.d.ts +5 -0
  41. package/lib/ActionList2/Selection.js +70 -0
  42. package/lib/ActionList2/Selection.jsx +36 -0
  43. package/lib/ActionList2/Visuals.d.ts +9 -0
  44. package/lib/ActionList2/Visuals.js +90 -0
  45. package/lib/ActionList2/Visuals.jsx +48 -0
  46. package/lib/ActionList2/index.d.ts +36 -0
  47. package/lib/ActionList2/index.js +29 -0
  48. package/lib/ActionMenu.jsx +73 -0
  49. package/lib/AnchoredOverlay/AnchoredOverlay.jsx +100 -0
  50. package/lib/AnchoredOverlay/index.js +4 -12
  51. package/lib/Autocomplete/Autocomplete.d.ts +28 -28
  52. package/lib/Autocomplete/Autocomplete.jsx +100 -0
  53. package/lib/Autocomplete/AutocompleteContext.jsx +5 -0
  54. package/lib/Autocomplete/AutocompleteInput.d.ts +28 -28
  55. package/lib/Autocomplete/AutocompleteInput.jsx +113 -0
  56. package/lib/Autocomplete/AutocompleteMenu.jsx +190 -0
  57. package/lib/Autocomplete/AutocompleteOverlay.jsx +55 -0
  58. package/lib/Autocomplete/index.js +7 -14
  59. package/lib/Avatar.jsx +34 -0
  60. package/lib/AvatarPair.jsx +29 -0
  61. package/lib/AvatarStack.jsx +151 -0
  62. package/lib/BaseStyles.jsx +65 -0
  63. package/lib/BorderBox.jsx +18 -0
  64. package/lib/Box.jsx +10 -0
  65. package/lib/BranchName.jsx +20 -0
  66. package/lib/Breadcrumbs.jsx +74 -0
  67. package/lib/Button/Button.d.ts +25 -25
  68. package/lib/Button/Button.jsx +60 -0
  69. package/lib/Button/ButtonBase.jsx +36 -0
  70. package/lib/Button/ButtonClose.d.ts +45 -45
  71. package/lib/Button/ButtonClose.jsx +55 -0
  72. package/lib/Button/ButtonDanger.d.ts +25 -25
  73. package/lib/Button/ButtonDanger.jsx +63 -0
  74. package/lib/Button/ButtonGroup.jsx +55 -0
  75. package/lib/Button/ButtonInvisible.d.ts +25 -25
  76. package/lib/Button/ButtonInvisible.jsx +52 -0
  77. package/lib/Button/ButtonOutline.d.ts +25 -25
  78. package/lib/Button/ButtonOutline.jsx +63 -0
  79. package/lib/Button/ButtonPrimary.d.ts +25 -25
  80. package/lib/Button/ButtonPrimary.jsx +62 -0
  81. package/lib/Button/ButtonStyles.jsx +37 -0
  82. package/lib/Button/ButtonTableList.jsx +49 -0
  83. package/lib/Button/index.js +21 -70
  84. package/lib/Caret.jsx +93 -0
  85. package/lib/CircleBadge.jsx +43 -0
  86. package/lib/CircleOcticon.d.ts +42 -42
  87. package/lib/CircleOcticon.jsx +21 -0
  88. package/lib/CounterLabel.jsx +44 -0
  89. package/lib/Details.jsx +21 -0
  90. package/lib/Dialog/ConfirmationDialog.jsx +146 -0
  91. package/lib/Dialog/Dialog.jsx +273 -0
  92. package/lib/Dialog.d.ts +45 -45
  93. package/lib/Dialog.jsx +131 -0
  94. package/lib/Dropdown.d.ts +176 -176
  95. package/lib/Dropdown.jsx +134 -0
  96. package/lib/DropdownMenu/DropdownButton.d.ts +46 -46
  97. package/lib/DropdownMenu/DropdownButton.jsx +14 -0
  98. package/lib/DropdownMenu/DropdownMenu.jsx +70 -0
  99. package/lib/DropdownMenu/index.js +6 -20
  100. package/lib/DropdownStyles.js +18 -26
  101. package/lib/FilterList.d.ts +42 -42
  102. package/lib/FilterList.jsx +63 -0
  103. package/lib/FilteredActionList/FilteredActionList.jsx +100 -0
  104. package/lib/FilteredActionList/index.js +4 -12
  105. package/lib/FilteredSearch.jsx +29 -0
  106. package/lib/Flash.jsx +70 -0
  107. package/lib/Flex.jsx +15 -0
  108. package/lib/FormGroup.jsx +25 -0
  109. package/lib/Grid.jsx +15 -0
  110. package/lib/Header.jsx +90 -0
  111. package/lib/Heading.jsx +21 -0
  112. package/lib/Label.jsx +84 -0
  113. package/lib/LabelGroup.jsx +19 -0
  114. package/lib/Link.jsx +38 -0
  115. package/lib/Overlay.jsx +156 -0
  116. package/lib/Pagehead.jsx +18 -0
  117. package/lib/Pagination/Pagination.jsx +163 -0
  118. package/lib/Pagination/index.js +6 -12
  119. package/lib/Pagination/model.jsx +174 -0
  120. package/lib/PointerBox.jsx +25 -0
  121. package/lib/Popover.jsx +210 -0
  122. package/lib/Portal/Portal.jsx +79 -0
  123. package/lib/Portal/index.js +5 -16
  124. package/lib/Position.d.ts +4 -4
  125. package/lib/Position.jsx +46 -0
  126. package/lib/ProgressBar.jsx +39 -0
  127. package/lib/SelectMenu/SelectMenu.d.ts +246 -246
  128. package/lib/SelectMenu/SelectMenu.jsx +114 -0
  129. package/lib/SelectMenu/SelectMenuContext.jsx +5 -0
  130. package/lib/SelectMenu/SelectMenuDivider.jsx +43 -0
  131. package/lib/SelectMenu/SelectMenuFilter.jsx +59 -0
  132. package/lib/SelectMenu/SelectMenuFooter.jsx +46 -0
  133. package/lib/SelectMenu/SelectMenuHeader.jsx +44 -0
  134. package/lib/SelectMenu/SelectMenuItem.d.ts +1 -1
  135. package/lib/SelectMenu/SelectMenuItem.jsx +143 -0
  136. package/lib/SelectMenu/SelectMenuList.jsx +60 -0
  137. package/lib/SelectMenu/SelectMenuLoadingAnimation.jsx +21 -0
  138. package/lib/SelectMenu/SelectMenuModal.d.ts +1 -1
  139. package/lib/SelectMenu/SelectMenuModal.jsx +119 -0
  140. package/lib/SelectMenu/SelectMenuTab.jsx +93 -0
  141. package/lib/SelectMenu/SelectMenuTabPanel.jsx +43 -0
  142. package/lib/SelectMenu/SelectMenuTabs.jsx +58 -0
  143. package/lib/SelectMenu/hooks/useKeyboardNav.js +80 -96
  144. package/lib/SelectMenu/index.js +7 -14
  145. package/lib/SelectPanel/SelectPanel.jsx +105 -0
  146. package/lib/SelectPanel/index.js +4 -12
  147. package/lib/SideNav.jsx +177 -0
  148. package/lib/Spinner.jsx +35 -0
  149. package/lib/StateLabel.d.ts +1 -1
  150. package/lib/StateLabel.js +6 -1
  151. package/lib/StateLabel.jsx +94 -0
  152. package/lib/StyledOcticon.jsx +20 -0
  153. package/lib/SubNav.jsx +104 -0
  154. package/lib/TabNav.jsx +60 -0
  155. package/lib/Text.jsx +14 -0
  156. package/lib/TextInput.jsx +23 -0
  157. package/lib/TextInputWithTokens.d.ts +28 -28
  158. package/lib/TextInputWithTokens.jsx +218 -0
  159. package/lib/ThemeProvider.jsx +130 -0
  160. package/lib/Timeline.d.ts +43 -43
  161. package/lib/Timeline.jsx +124 -0
  162. package/lib/Token/AvatarToken.d.ts +1 -1
  163. package/lib/Token/AvatarToken.jsx +54 -0
  164. package/lib/Token/IssueLabelToken.d.ts +1 -1
  165. package/lib/Token/IssueLabelToken.jsx +125 -0
  166. package/lib/Token/Token.d.ts +1 -1
  167. package/lib/Token/Token.jsx +103 -0
  168. package/lib/Token/TokenBase.jsx +88 -0
  169. package/lib/Token/_RemoveTokenButton.jsx +108 -0
  170. package/lib/Token/_TokenTextContainer.jsx +49 -0
  171. package/lib/Token/index.js +11 -30
  172. package/lib/Tooltip.jsx +246 -0
  173. package/lib/Truncate.jsx +27 -0
  174. package/lib/UnderlineNav.jsx +90 -0
  175. package/lib/_TextInputWrapper.js +2 -2
  176. package/lib/_TextInputWrapper.jsx +120 -0
  177. package/lib/_UnstyledTextInput.jsx +22 -0
  178. package/lib/__tests__/ActionList.test.jsx +49 -0
  179. package/lib/__tests__/ActionList.types.test.jsx +45 -0
  180. package/lib/__tests__/ActionList2.test.d.ts +1 -0
  181. package/lib/__tests__/ActionList2.test.js +53 -0
  182. package/lib/__tests__/ActionList2.test.jsx +46 -0
  183. package/lib/__tests__/ActionMenu.test.jsx +124 -0
  184. package/lib/__tests__/AnchoredOverlay.test.jsx +121 -0
  185. package/lib/__tests__/Autocomplete.test.jsx +299 -0
  186. package/lib/__tests__/Avatar.test.jsx +42 -0
  187. package/lib/__tests__/AvatarStack.test.jsx +43 -0
  188. package/lib/__tests__/BorderBox.test.jsx +36 -0
  189. package/lib/__tests__/Box.test.jsx +41 -0
  190. package/lib/__tests__/BranchName.test.jsx +27 -0
  191. package/lib/__tests__/Breadcrumbs.test.jsx +28 -0
  192. package/lib/__tests__/BreadcrumbsItem.test.jsx +31 -0
  193. package/lib/__tests__/Button.test.jsx +100 -0
  194. package/lib/__tests__/Caret.test.jsx +37 -0
  195. package/lib/__tests__/CircleBadge.test.jsx +55 -0
  196. package/lib/__tests__/CircleOcticon.test.jsx +45 -0
  197. package/lib/__tests__/ConfirmationDialog.test.jsx +119 -0
  198. package/lib/__tests__/CounterLabel.test.jsx +36 -0
  199. package/lib/__tests__/Details.test.jsx +85 -0
  200. package/lib/__tests__/Dialog.test.jsx +139 -0
  201. package/lib/__tests__/Dropdown.test.jsx +49 -0
  202. package/lib/__tests__/DropdownMenu.test.jsx +119 -0
  203. package/lib/__tests__/FilterList.test.jsx +27 -0
  204. package/lib/__tests__/FilterListItem.test.jsx +31 -0
  205. package/lib/__tests__/FilteredSearch.test.jsx +27 -0
  206. package/lib/__tests__/Flash.test.jsx +36 -0
  207. package/lib/__tests__/Flex.test.jsx +51 -0
  208. package/lib/__tests__/FormGroup.test.jsx +36 -0
  209. package/lib/__tests__/Grid.test.jsx +69 -0
  210. package/lib/__tests__/Header.test.jsx +45 -0
  211. package/lib/__tests__/Heading.test.jsx +71 -0
  212. package/lib/__tests__/KeyPaths.types.test.js +5 -8
  213. package/lib/__tests__/Label.test.jsx +33 -0
  214. package/lib/__tests__/LabelGroup.test.jsx +29 -0
  215. package/lib/__tests__/Link.test.jsx +43 -0
  216. package/lib/__tests__/Merge.types.test.js +13 -19
  217. package/lib/__tests__/Overlay.test.jsx +105 -0
  218. package/lib/__tests__/Pagehead.test.jsx +25 -0
  219. package/lib/__tests__/Pagination/Pagination.test.jsx +32 -0
  220. package/lib/__tests__/Pagination/PaginationModel.test.jsx +118 -0
  221. package/lib/__tests__/PointerBox.test.jsx +33 -0
  222. package/lib/__tests__/Popover.test.jsx +58 -0
  223. package/lib/__tests__/Portal.test.jsx +102 -0
  224. package/lib/__tests__/Position.test.jsx +96 -0
  225. package/lib/__tests__/ProgressBar.test.jsx +38 -0
  226. package/lib/__tests__/SelectMenu.test.jsx +120 -0
  227. package/lib/__tests__/SelectPanel.test.jsx +48 -0
  228. package/lib/__tests__/SideNav.test.jsx +55 -0
  229. package/lib/__tests__/Spinner.test.jsx +41 -0
  230. package/lib/__tests__/StateLabel.test.jsx +46 -0
  231. package/lib/__tests__/StyledOcticon.test.jsx +28 -0
  232. package/lib/__tests__/SubNav.test.jsx +47 -0
  233. package/lib/__tests__/SubNavLink.test.jsx +31 -0
  234. package/lib/__tests__/TabNav.test.jsx +32 -0
  235. package/lib/__tests__/Text.test.jsx +71 -0
  236. package/lib/__tests__/TextInput.test.jsx +45 -0
  237. package/lib/__tests__/TextInputWithTokens.test.jsx +302 -0
  238. package/lib/__tests__/ThemeProvider.test.jsx +314 -0
  239. package/lib/__tests__/Timeline.test.jsx +51 -0
  240. package/lib/__tests__/Token.test.jsx +93 -0
  241. package/lib/__tests__/Tooltip.test.jsx +46 -0
  242. package/lib/__tests__/Truncate.test.jsx +41 -0
  243. package/lib/__tests__/UnderlineNav.test.jsx +53 -0
  244. package/lib/__tests__/UnderlineNavLink.test.jsx +31 -0
  245. package/lib/__tests__/behaviors/anchoredPosition.test.js +229 -376
  246. package/lib/__tests__/behaviors/focusTrap.test.jsx +184 -0
  247. package/lib/__tests__/behaviors/focusZone.test.jsx +406 -0
  248. package/lib/__tests__/behaviors/iterateFocusableElements.test.jsx +58 -0
  249. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.js +145 -216
  250. package/lib/__tests__/filterObject.test.js +48 -27
  251. package/lib/__tests__/hooks/useAnchoredPosition.test.jsx +29 -0
  252. package/lib/__tests__/hooks/useOnEscapePress.test.jsx +19 -0
  253. package/lib/__tests__/hooks/useOnOutsideClick.test.jsx +63 -0
  254. package/lib/__tests__/hooks/useOpenAndCloseFocus.test.jsx +61 -0
  255. package/lib/__tests__/hooks/useProvidedStateOrCreate.test.jsx +56 -0
  256. package/lib/__tests__/theme.test.js +33 -34
  257. package/lib/__tests__/themeGet.test.js +12 -23
  258. package/lib/__tests__/useSafeTimeout.test.jsx +36 -0
  259. package/lib/__tests__/utils/createSlots.test.d.ts +1 -0
  260. package/lib/__tests__/utils/createSlots.test.js +75 -0
  261. package/lib/__tests__/utils/createSlots.test.jsx +57 -0
  262. package/lib/behaviors/anchoredPosition.js +205 -234
  263. package/lib/behaviors/focusTrap.js +121 -157
  264. package/lib/behaviors/focusZone.js +434 -509
  265. package/lib/behaviors/scrollIntoViewingArea.js +18 -35
  266. package/lib/constants.js +39 -43
  267. package/lib/drafts.d.ts +7 -0
  268. package/lib/drafts.js +20 -0
  269. package/lib/hooks/index.js +16 -60
  270. package/lib/hooks/useAnchoredPosition.js +32 -40
  271. package/lib/hooks/useCombinedRefs.js +32 -36
  272. package/lib/hooks/useDetails.jsx +39 -0
  273. package/lib/hooks/useDialog.js +72 -96
  274. package/lib/hooks/useFocusTrap.js +43 -60
  275. package/lib/hooks/useFocusZone.js +54 -50
  276. package/lib/hooks/useOnEscapePress.js +25 -36
  277. package/lib/hooks/useOnOutsideClick.jsx +61 -0
  278. package/lib/hooks/useOpenAndCloseFocus.js +22 -34
  279. package/lib/hooks/useOverlay.jsx +15 -0
  280. package/lib/hooks/useProvidedRefOrCreate.js +10 -14
  281. package/lib/hooks/useProvidedStateOrCreate.js +13 -16
  282. package/lib/hooks/useRenderForcingRef.js +13 -17
  283. package/lib/hooks/useResizeObserver.js +15 -18
  284. package/lib/hooks/useSafeTimeout.js +22 -30
  285. package/lib/hooks/useScrollFlash.js +16 -23
  286. package/lib/index.js +161 -636
  287. package/lib/polyfills/eventListenerSignal.js +37 -45
  288. package/lib/stories/ActionList2.stories.js +908 -0
  289. package/lib/stories/TextInput.stories.js +144 -0
  290. package/lib/sx.d.ts +2 -0
  291. package/lib/sx.js +10 -14
  292. package/lib/theme-preval.js +65 -2945
  293. package/lib/theme.js +3 -12
  294. package/lib/utils/create-slots.d.ts +17 -0
  295. package/lib/utils/create-slots.js +105 -0
  296. package/lib/utils/create-slots.jsx +65 -0
  297. package/lib/utils/deprecate.jsx +59 -0
  298. package/lib/utils/isNumeric.jsx +7 -0
  299. package/lib/utils/iterateFocusableElements.js +63 -85
  300. package/lib/utils/ssr.jsx +6 -0
  301. package/lib/utils/test-deprecations.jsx +20 -0
  302. package/lib/utils/test-helpers.jsx +8 -0
  303. package/lib/utils/test-matchers.jsx +100 -0
  304. package/lib/utils/testing.d.ts +14 -1
  305. package/lib/utils/testing.jsx +206 -0
  306. package/lib/utils/theme.js +33 -47
  307. package/lib/utils/types/AriaRole.js +2 -1
  308. package/lib/utils/types/ComponentProps.js +2 -1
  309. package/lib/utils/types/Flatten.js +2 -1
  310. package/lib/utils/types/KeyPaths.js +2 -1
  311. package/lib/utils/types/MandateProps.js +16 -1
  312. package/lib/utils/types/Merge.js +2 -1
  313. package/lib/utils/types/index.js +16 -69
  314. package/lib/utils/uniqueId.js +5 -8
  315. package/lib/utils/use-force-update.d.ts +1 -0
  316. package/lib/utils/use-force-update.js +13 -0
  317. package/lib/utils/useIsomorphicLayoutEffect.js +8 -11
  318. package/lib/utils/userAgent.js +8 -12
  319. package/lib-esm/ActionList2/Description.d.ts +12 -0
  320. package/lib-esm/ActionList2/Description.js +37 -0
  321. package/lib-esm/ActionList2/Divider.d.ts +5 -0
  322. package/lib-esm/ActionList2/Divider.js +23 -0
  323. package/lib-esm/ActionList2/Group.d.ts +11 -0
  324. package/lib-esm/ActionList2/Group.js +40 -0
  325. package/lib-esm/ActionList2/Header.d.ts +26 -0
  326. package/lib-esm/ActionList2/Header.js +44 -0
  327. package/lib-esm/ActionList2/Item.d.ts +63 -0
  328. package/lib-esm/ActionList2/Item.js +210 -0
  329. package/lib-esm/ActionList2/LinkItem.d.ts +17 -0
  330. package/lib-esm/ActionList2/LinkItem.js +43 -0
  331. package/lib-esm/ActionList2/List.d.ts +26 -0
  332. package/lib-esm/ActionList2/List.js +37 -0
  333. package/lib-esm/ActionList2/Selection.d.ts +5 -0
  334. package/lib-esm/ActionList2/Selection.js +52 -0
  335. package/lib-esm/ActionList2/Visuals.d.ts +9 -0
  336. package/lib-esm/ActionList2/Visuals.js +68 -0
  337. package/lib-esm/ActionList2/index.d.ts +36 -0
  338. package/lib-esm/ActionList2/index.js +33 -0
  339. package/lib-esm/Autocomplete/Autocomplete.d.ts +28 -28
  340. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +28 -28
  341. package/lib-esm/Button/Button.d.ts +25 -25
  342. package/lib-esm/Button/ButtonClose.d.ts +45 -45
  343. package/lib-esm/Button/ButtonDanger.d.ts +25 -25
  344. package/lib-esm/Button/ButtonInvisible.d.ts +25 -25
  345. package/lib-esm/Button/ButtonOutline.d.ts +25 -25
  346. package/lib-esm/Button/ButtonPrimary.d.ts +25 -25
  347. package/lib-esm/CircleOcticon.d.ts +42 -42
  348. package/lib-esm/Dialog.d.ts +45 -45
  349. package/lib-esm/Dropdown.d.ts +176 -176
  350. package/lib-esm/DropdownMenu/DropdownButton.d.ts +46 -46
  351. package/lib-esm/FilterList.d.ts +42 -42
  352. package/lib-esm/Position.d.ts +4 -4
  353. package/lib-esm/SelectMenu/SelectMenu.d.ts +246 -246
  354. package/lib-esm/SelectMenu/SelectMenuItem.d.ts +1 -1
  355. package/lib-esm/SelectMenu/SelectMenuModal.d.ts +1 -1
  356. package/lib-esm/StateLabel.d.ts +1 -1
  357. package/lib-esm/StateLabel.js +7 -2
  358. package/lib-esm/TextInputWithTokens.d.ts +28 -28
  359. package/lib-esm/Timeline.d.ts +43 -43
  360. package/lib-esm/Token/AvatarToken.d.ts +1 -1
  361. package/lib-esm/Token/IssueLabelToken.d.ts +1 -1
  362. package/lib-esm/Token/Token.d.ts +1 -1
  363. package/lib-esm/_TextInputWrapper.js +2 -2
  364. package/lib-esm/__tests__/ActionList2.test.d.ts +1 -0
  365. package/lib-esm/__tests__/ActionList2.test.js +41 -0
  366. package/lib-esm/__tests__/utils/createSlots.test.d.ts +1 -0
  367. package/lib-esm/__tests__/utils/createSlots.test.js +67 -0
  368. package/lib-esm/drafts.d.ts +7 -0
  369. package/lib-esm/drafts.js +8 -0
  370. package/lib-esm/stories/ActionList2.stories.js +796 -0
  371. package/lib-esm/stories/TextInput.stories.js +117 -0
  372. package/lib-esm/sx.d.ts +2 -0
  373. package/lib-esm/sx.js +3 -1
  374. package/lib-esm/theme-preval.js +81 -2
  375. package/lib-esm/utils/create-slots.d.ts +17 -0
  376. package/lib-esm/utils/create-slots.js +84 -0
  377. package/lib-esm/utils/testing.d.ts +14 -1
  378. package/lib-esm/utils/use-force-update.d.ts +1 -0
  379. package/lib-esm/utils/use-force-update.js +6 -0
  380. package/package-lock.json +153 -14
  381. package/package.json +7 -4
  382. package/script/build +1 -1
  383. package/src/ActionList2/Description.tsx +49 -0
  384. package/src/ActionList2/Divider.tsx +24 -0
  385. package/src/ActionList2/Group.tsx +34 -0
  386. package/src/ActionList2/Header.tsx +58 -0
  387. package/src/ActionList2/Item.tsx +245 -0
  388. package/src/ActionList2/LinkItem.tsx +49 -0
  389. package/src/ActionList2/List.tsx +55 -0
  390. package/src/ActionList2/Selection.tsx +40 -0
  391. package/src/ActionList2/Visuals.tsx +76 -0
  392. package/src/ActionList2/index.ts +39 -0
  393. package/src/StateLabel.tsx +14 -2
  394. package/src/_TextInputWrapper.tsx +7 -0
  395. package/src/__tests__/ActionList2.test.tsx +47 -0
  396. package/src/__tests__/__snapshots__/ActionList2.test.tsx.snap +14 -0
  397. package/src/__tests__/__snapshots__/Autocomplete.test.tsx.snap +1 -0
  398. package/src/__tests__/__snapshots__/CircleBadge.test.tsx.snap +1 -0
  399. package/src/__tests__/__snapshots__/CircleOcticon.test.tsx.snap +1 -0
  400. package/src/__tests__/__snapshots__/Dialog.test.tsx.snap +1 -0
  401. package/src/__tests__/__snapshots__/DropdownMenu.test.tsx.snap +1 -0
  402. package/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap +4 -0
  403. package/src/__tests__/__snapshots__/SelectPanel.test.tsx.snap +1 -0
  404. package/src/__tests__/__snapshots__/StateLabel.test.tsx.snap +13 -6
  405. package/src/__tests__/__snapshots__/StyledOcticon.test.tsx.snap +1 -0
  406. package/src/__tests__/__snapshots__/TextInputWithTokens.test.tsx.snap +66 -0
  407. package/src/__tests__/__snapshots__/Token.test.tsx.snap +17 -0
  408. package/src/__tests__/utils/__snapshots__/createSlots.test.tsx.snap +55 -0
  409. package/src/__tests__/utils/createSlots.test.tsx +74 -0
  410. package/src/drafts.ts +9 -0
  411. package/src/stories/ActionList2.stories.tsx +1291 -0
  412. package/src/stories/TextInput.stories.tsx +113 -0
  413. package/src/sx.ts +3 -0
  414. package/src/theme-preval.js +1 -0
  415. package/src/utils/create-slots.tsx +96 -0
  416. package/src/utils/use-force-update.ts +7 -0
  417. package/stats.html +1 -1
  418. package/tsconfig.base.json +20 -0
  419. package/tsconfig.build.json +2 -2
  420. package/tsconfig.json +4 -17
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const testing_1 = require("../utils/testing");
8
+ const react_2 = require("@testing-library/react");
9
+ const jest_axe_1 = require("jest-axe");
10
+ require("babel-polyfill");
11
+ const TokenBase_1 = require("../Token/TokenBase");
12
+ const Token_1 = require("../Token");
13
+ const TextInputWithTokens_1 = __importDefault(require("../TextInputWithTokens"));
14
+ expect.extend(jest_axe_1.toHaveNoViolations);
15
+ const mockTokens = [
16
+ { text: 'zero', id: 0 },
17
+ { text: 'one', id: 1 },
18
+ { text: 'two', id: 2 },
19
+ { text: 'three', id: 3 },
20
+ { text: 'four', id: 4 },
21
+ { text: 'five', id: 5 },
22
+ { text: 'six', id: 6 },
23
+ { text: 'seven', id: 7 }
24
+ ];
25
+ const LabelledTextInputWithTokens = ({ onTokenRemove, tokens, ...rest }) => (<>
26
+ {/* eslint-disable-next-line jsx-a11y/label-has-for */}
27
+ <label htmlFor="tokenInput" id="tokenLabel">
28
+ Tokens
29
+ </label>
30
+ <TextInputWithTokens_1.default tokens={tokens} onTokenRemove={onTokenRemove} id="tokenInput" {...rest}/>
31
+ </>);
32
+ jest.useFakeTimers();
33
+ describe('TextInputWithTokens', () => {
34
+ it('renders without tokens', () => {
35
+ const onRemoveMock = jest.fn();
36
+ expect(testing_1.render(<TextInputWithTokens_1.default tokens={[]} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
37
+ });
38
+ it('renders as block layout', () => {
39
+ const onRemoveMock = jest.fn();
40
+ expect(testing_1.render(<TextInputWithTokens_1.default block tokens={[]} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
41
+ });
42
+ it('renders with tokens', () => {
43
+ const onRemoveMock = jest.fn();
44
+ expect(testing_1.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
45
+ });
46
+ it('renders with tokens using a custom token component', () => {
47
+ const onRemoveMock = jest.fn();
48
+ expect(testing_1.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock} tokenComponent={Token_1.IssueLabelToken}/>)).toMatchSnapshot();
49
+ });
50
+ it('renders at a maximum height when specified', () => {
51
+ const onRemoveMock = jest.fn();
52
+ expect(testing_1.render(<TextInputWithTokens_1.default maxHeight="20px" tokens={mockTokens} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
53
+ });
54
+ it('renders tokens on a single line when specified', () => {
55
+ const onRemoveMock = jest.fn();
56
+ expect(testing_1.render(<TextInputWithTokens_1.default preventTokenWrapping tokens={mockTokens} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
57
+ });
58
+ it('renders tokens at the specified sizes', () => {
59
+ const onRemoveMock = jest.fn();
60
+ const tokenSizeKeys = Object.keys(TokenBase_1.tokenSizes);
61
+ for (const tokenSizeKey of tokenSizeKeys) {
62
+ expect(testing_1.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock} size={tokenSizeKey}/>)).toMatchSnapshot();
63
+ }
64
+ });
65
+ it('renders tokens without a remove button when specified', () => {
66
+ const onRemoveMock = jest.fn();
67
+ expect(testing_1.render(<TextInputWithTokens_1.default hideTokenRemoveButtons tokens={mockTokens} onTokenRemove={onRemoveMock}/>)).toMatchSnapshot();
68
+ });
69
+ it('renders a truncated set of tokens', () => {
70
+ const onRemoveMock = jest.fn();
71
+ expect(testing_1.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2}/>)).toMatchSnapshot();
72
+ });
73
+ it('focuses the previous token when keying ArrowLeft', () => {
74
+ const onRemoveMock = jest.fn();
75
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
76
+ const inputNode = getByLabelText('Tokens');
77
+ const lastTokenIndex = mockTokens.length - 1;
78
+ const lastTokenNode = getByText(mockTokens[lastTokenIndex].text);
79
+ expect(document.activeElement).not.toEqual(lastTokenNode);
80
+ react_2.fireEvent.focus(inputNode);
81
+ react_2.fireEvent.keyDown(inputNode, { key: 'ArrowLeft' });
82
+ expect(document.activeElement?.id).toEqual(lastTokenNode.id);
83
+ react_2.fireEvent.keyDown(lastTokenNode, { key: 'ArrowLeft' });
84
+ expect(document.activeElement?.id).toEqual(getByText(mockTokens[lastTokenIndex - 1].text).id);
85
+ });
86
+ it('focuses the next token when keying ArrowRight', () => {
87
+ const onRemoveMock = jest.fn();
88
+ const { getByText } = react_2.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
89
+ const tokenNode = getByText(mockTokens[4].text);
90
+ expect(onRemoveMock).not.toHaveBeenCalled();
91
+ react_2.fireEvent.focus(tokenNode);
92
+ react_2.fireEvent.keyDown(tokenNode, { key: 'ArrowRight' });
93
+ expect(document.activeElement?.id).toEqual(getByText(mockTokens[5].text).id);
94
+ });
95
+ it('focuses the input when keying ArrowLeft on the first token', () => {
96
+ const onRemoveMock = jest.fn();
97
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
98
+ const inputNode = getByLabelText('Tokens');
99
+ const firstTokenNode = getByText(mockTokens[0].text);
100
+ expect(document.activeElement).not.toEqual(firstTokenNode);
101
+ react_2.fireEvent.focus(firstTokenNode);
102
+ react_2.fireEvent.keyDown(firstTokenNode, { key: 'ArrowLeft' });
103
+ expect(document.activeElement?.id).toEqual(inputNode.id);
104
+ });
105
+ it('focuses the input when keying ArrowRight on the last token', () => {
106
+ const onRemoveMock = jest.fn();
107
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
108
+ const inputNode = getByLabelText('Tokens');
109
+ const lastTokenNode = getByText(mockTokens[mockTokens.length - 1].text);
110
+ expect(document.activeElement).not.toEqual(lastTokenNode);
111
+ react_2.fireEvent.focus(lastTokenNode);
112
+ react_2.fireEvent.keyDown(lastTokenNode, { key: 'ArrowRight' });
113
+ expect(document.activeElement?.id).toEqual(inputNode.id);
114
+ });
115
+ it('focuses the input when keying Escape when focused on a token', () => {
116
+ const onRemoveMock = jest.fn();
117
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
118
+ const inputNode = getByLabelText('Tokens');
119
+ const lastTokenNode = getByText(mockTokens[mockTokens.length - 1].text);
120
+ expect(document.activeElement?.id).not.toEqual(inputNode.id);
121
+ react_2.fireEvent.focus(lastTokenNode);
122
+ expect(document.activeElement?.id).toEqual(lastTokenNode.id);
123
+ react_2.fireEvent.keyUp(lastTokenNode, { key: 'Escape' });
124
+ expect(document.activeElement?.id).not.toEqual(lastTokenNode.id);
125
+ expect(document.activeElement?.id).toEqual(inputNode.id);
126
+ });
127
+ it('does not focus the input when clicking a token', () => {
128
+ const onRemoveMock = jest.fn();
129
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2}/>);
130
+ const inputNode = getByLabelText('Tokens');
131
+ const tokenNode = getByText(mockTokens[0].text);
132
+ expect(document.activeElement).not.toEqual(inputNode.id);
133
+ react_2.fireEvent.click(tokenNode);
134
+ expect(document.activeElement?.id).not.toEqual(inputNode.id);
135
+ });
136
+ it('focuses the input when clicking somewhere in the component besides the tokens', () => {
137
+ const onRemoveMock = jest.fn();
138
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={2}/>);
139
+ const inputNode = getByLabelText('Tokens');
140
+ const truncatedTokenCount = getByText('+6');
141
+ expect(document.activeElement).not.toEqual(inputNode.id);
142
+ react_2.fireEvent.click(truncatedTokenCount);
143
+ expect(document.activeElement?.id).toEqual(inputNode.id);
144
+ });
145
+ it('shows all tokens when the input is focused and hides them when it is blurred (when visibleTokenCount is set)', () => {
146
+ const onRemoveMock = jest.fn();
147
+ const visibleTokenCount = 2;
148
+ const { getByLabelText, getByText } = react_2.render(<>
149
+ <LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={visibleTokenCount}/>
150
+ <button id="focusableOutsideComponent">Focus me</button>
151
+ </>);
152
+ const inputNode = getByLabelText('Tokens');
153
+ const focusableOutsideComponentNode = getByText('Focus me');
154
+ const allTokenLabels = mockTokens.map(token => token.text);
155
+ const truncatedTokenCountNode = getByText('+6');
156
+ react_2.act(() => {
157
+ jest.runAllTimers();
158
+ react_2.fireEvent.focus(inputNode);
159
+ });
160
+ setTimeout(() => {
161
+ for (const tokenLabel of allTokenLabels) {
162
+ const tokenNode = getByText(tokenLabel);
163
+ expect(tokenNode).toBeDefined();
164
+ }
165
+ }, 0);
166
+ react_2.act(() => {
167
+ jest.runAllTimers();
168
+ // onBlur isn't called on input unless we specifically fire the "blur" event
169
+ // eslint-disable-next-line github/no-blur
170
+ react_2.fireEvent.blur(inputNode);
171
+ react_2.fireEvent.focus(focusableOutsideComponentNode);
172
+ });
173
+ setTimeout(() => {
174
+ expect(truncatedTokenCountNode).toBeDefined();
175
+ for (const tokenLabel of allTokenLabels) {
176
+ const tokenNode = getByText(tokenLabel);
177
+ if (allTokenLabels.indexOf(tokenLabel) > visibleTokenCount) {
178
+ // eslint-disable-next-line jest/no-conditional-expect
179
+ expect(tokenNode).toBeDefined();
180
+ }
181
+ else {
182
+ // eslint-disable-next-line jest/no-conditional-expect
183
+ expect(tokenNode).not.toBeDefined();
184
+ }
185
+ }
186
+ }, 0);
187
+ jest.useRealTimers();
188
+ });
189
+ it('does not hide tokens when blurring the input to focus within the component (when visibleTokenCount is set)', () => {
190
+ const onRemoveMock = jest.fn();
191
+ const visibleTokenCount = 2;
192
+ const { getByLabelText, getByText } = react_2.render(<>
193
+ <LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} visibleTokenCount={visibleTokenCount}/>
194
+ <button id="focusableOutsideComponent">Focus me</button>
195
+ </>);
196
+ const inputNode = getByLabelText('Tokens');
197
+ const firstTokenNode = getByText(mockTokens[visibleTokenCount - 1].text);
198
+ const allTokenLabels = mockTokens.map(token => token.text);
199
+ const truncatedTokenCountNode = getByText('+6');
200
+ react_2.act(() => {
201
+ react_2.fireEvent.focus(inputNode);
202
+ react_2.fireEvent.focus(firstTokenNode);
203
+ });
204
+ expect(truncatedTokenCountNode).toBeDefined();
205
+ for (const tokenLabel of allTokenLabels) {
206
+ const tokenNode = getByText(tokenLabel);
207
+ expect(tokenNode).toBeDefined();
208
+ }
209
+ });
210
+ it('focuses the first token when keying ArrowRight in the input', () => {
211
+ const onRemoveMock = jest.fn();
212
+ const { getByLabelText, getByText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
213
+ const inputNode = getByLabelText('Tokens');
214
+ const firstTokenNode = getByText(mockTokens[0].text);
215
+ expect(onRemoveMock).not.toHaveBeenCalled();
216
+ react_2.fireEvent.focus(inputNode);
217
+ react_2.fireEvent.keyDown(inputNode, { key: 'ArrowRight' });
218
+ expect(document.activeElement?.id).not.toEqual(inputNode.id);
219
+ expect(document.activeElement?.id).toEqual(firstTokenNode.id);
220
+ });
221
+ it('calls onTokenRemove on the last token when keying Backspace in an empty input', () => {
222
+ const onRemoveMock = jest.fn();
223
+ const { getByLabelText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
224
+ const inputNode = getByLabelText('Tokens');
225
+ const lastTokenIndex = mockTokens.length - 1;
226
+ expect(onRemoveMock).not.toHaveBeenCalled();
227
+ react_2.fireEvent.focus(inputNode);
228
+ react_2.fireEvent.keyDown(inputNode, { key: 'Backspace' });
229
+ expect(onRemoveMock).toHaveBeenCalledWith(mockTokens[lastTokenIndex].id);
230
+ });
231
+ it("sets the input text to the last token's text when keying Backspace in an empty input", () => {
232
+ const onRemoveMock = jest.fn();
233
+ const { getByDisplayValue, getByLabelText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
234
+ const inputNode = getByLabelText('Tokens');
235
+ const lastTokenIndex = mockTokens.length - 1;
236
+ expect(onRemoveMock).not.toHaveBeenCalled();
237
+ react_2.fireEvent.focus(inputNode);
238
+ react_2.fireEvent.keyDown(inputNode, { key: 'Backspace' });
239
+ expect(getByDisplayValue(mockTokens[lastTokenIndex].text).id).toEqual(inputNode.id);
240
+ });
241
+ it('does not call onTokenRemove on the last token when keying Backspace in an input that has a value', () => {
242
+ const onRemoveMock = jest.fn();
243
+ const { getByLabelText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} defaultValue="test"/>);
244
+ const inputNode = getByLabelText('Tokens');
245
+ react_2.fireEvent.focus(inputNode);
246
+ react_2.fireEvent.keyDown(inputNode, { key: 'Backspace' });
247
+ expect(onRemoveMock).not.toHaveBeenCalled();
248
+ });
249
+ it('calls onTokenRemove on the focused token when keying Backspace and moves focus to the next token', () => {
250
+ const onRemoveMock = jest.fn();
251
+ const { getByText } = react_2.render(<TextInputWithTokens_1.default tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
252
+ const tokenNode = getByText(mockTokens[4].text);
253
+ expect(onRemoveMock).not.toHaveBeenCalled();
254
+ react_2.fireEvent.focus(tokenNode);
255
+ react_2.fireEvent.keyDown(tokenNode, { key: 'Backspace' });
256
+ expect(onRemoveMock).toHaveBeenCalledWith(mockTokens[4].id);
257
+ });
258
+ it('moves focus to the next token when removing the first token', () => {
259
+ jest.useFakeTimers();
260
+ const onRemoveMock = jest.fn();
261
+ const { getByText } = react_2.render(<TextInputWithTokens_1.default tokens={[...mockTokens].slice(0, 2)} onTokenRemove={onRemoveMock}/>);
262
+ const tokenNode = getByText(mockTokens[0].text);
263
+ react_2.fireEvent.focus(tokenNode);
264
+ react_2.fireEvent.keyDown(tokenNode, { key: 'Backspace' });
265
+ jest.runAllTimers();
266
+ setTimeout(() => {
267
+ expect(document.activeElement?.textContent).toBe(mockTokens[1].text);
268
+ }, 0);
269
+ jest.useRealTimers();
270
+ });
271
+ it('moves focus to the input when the last token is removed', () => {
272
+ jest.useFakeTimers();
273
+ const onRemoveMock = jest.fn();
274
+ const { getByText, getByLabelText } = react_2.render(<LabelledTextInputWithTokens tokens={[mockTokens[0]]} onTokenRemove={onRemoveMock}/>);
275
+ const tokenNode = getByText(mockTokens[0].text);
276
+ const inputNode = getByLabelText('Tokens');
277
+ react_2.fireEvent.focus(tokenNode);
278
+ react_2.fireEvent.keyDown(tokenNode, { key: 'Backspace' });
279
+ jest.runAllTimers();
280
+ setTimeout(() => {
281
+ expect(document.activeElement?.id).toBe(inputNode.id);
282
+ }, 0);
283
+ jest.useRealTimers();
284
+ });
285
+ it('calls onKeyDown', () => {
286
+ const onRemoveMock = jest.fn();
287
+ const onKeyDownMock = jest.fn();
288
+ const { getByLabelText } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock} onKeyDown={onKeyDownMock}/>);
289
+ const inputNode = getByLabelText('Tokens');
290
+ expect(onKeyDownMock).not.toHaveBeenCalled();
291
+ react_2.fireEvent.focus(inputNode);
292
+ react_2.fireEvent.keyDown(inputNode, { key: 'a' });
293
+ expect(onKeyDownMock).toHaveBeenCalled();
294
+ });
295
+ it('should have no axe violations', async () => {
296
+ const onRemoveMock = jest.fn();
297
+ const { container } = react_2.render(<LabelledTextInputWithTokens tokens={mockTokens} onTokenRemove={onRemoveMock}/>);
298
+ const results = await jest_axe_1.axe(container);
299
+ expect(results).toHaveNoViolations();
300
+ react_2.cleanup();
301
+ });
302
+ });
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = require("@testing-library/react");
7
+ require("jest-styled-components");
8
+ const react_2 = __importDefault(require("react"));
9
+ const __1 = require("..");
10
+ // window.matchMedia() is not implmented by JSDOM so we have to create a mock:
11
+ // https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
12
+ Object.defineProperty(window, 'matchMedia', {
13
+ writable: true,
14
+ value: jest.fn().mockImplementation(query => ({
15
+ matches: false,
16
+ media: query,
17
+ onchange: null,
18
+ addListener: jest.fn(),
19
+ removeListener: jest.fn(),
20
+ addEventListener: jest.fn(),
21
+ removeEventListener: jest.fn(),
22
+ dispatchEvent: jest.fn()
23
+ }))
24
+ });
25
+ const exampleTheme = {
26
+ colors: {
27
+ text: '#f00'
28
+ },
29
+ colorSchemes: {
30
+ light: {
31
+ colors: {
32
+ text: 'black'
33
+ }
34
+ },
35
+ dark: {
36
+ colors: {
37
+ text: 'white'
38
+ }
39
+ },
40
+ dark_dimmed: {
41
+ colors: {
42
+ text: 'gray'
43
+ }
44
+ }
45
+ }
46
+ };
47
+ it('respects theme prop', () => {
48
+ const theme = {
49
+ colors: {
50
+ text: '#f00'
51
+ },
52
+ space: ['0', '0.25rem']
53
+ };
54
+ react_1.render(<__1.ThemeProvider theme={theme}>
55
+ <__1.Text color="text" mb={1}>
56
+ Hello
57
+ </__1.Text>
58
+ </__1.ThemeProvider>);
59
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', '#f00');
60
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('margin-bottom', '0.25rem');
61
+ });
62
+ it('has default theme', () => {
63
+ react_1.render(<__1.ThemeProvider>
64
+ <__1.Text color="fg.default" mb={1}>
65
+ Hello
66
+ </__1.Text>
67
+ </__1.ThemeProvider>);
68
+ expect(react_1.screen.getByText('Hello')).toMatchSnapshot();
69
+ });
70
+ it('inherits theme from parent', () => {
71
+ react_1.render(<__1.ThemeProvider theme={exampleTheme}>
72
+ <__1.ThemeProvider>
73
+ <__1.Text color="text">Hello</__1.Text>
74
+ </__1.ThemeProvider>
75
+ </__1.ThemeProvider>);
76
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
77
+ });
78
+ it('defaults to light color scheme', () => {
79
+ react_1.render(<__1.ThemeProvider theme={exampleTheme}>
80
+ <__1.Text color="text">Hello</__1.Text>
81
+ </__1.ThemeProvider>);
82
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
83
+ });
84
+ it('defaults to dark color scheme in night mode', () => {
85
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="night">
86
+ <__1.Text color="text">Hello</__1.Text>
87
+ </__1.ThemeProvider>);
88
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
89
+ });
90
+ it('defaults to first color scheme when passed an invalid color scheme name', () => {
91
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} dayScheme="foo">
92
+ <__1.Text color="text">Hello</__1.Text>
93
+ </__1.ThemeProvider>);
94
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
95
+ });
96
+ it('respects nightScheme prop', () => {
97
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="night" nightScheme="dark_dimmed">
98
+ <__1.Text color="text">Hello</__1.Text>
99
+ </__1.ThemeProvider>);
100
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'gray');
101
+ });
102
+ it('respects dayScheme prop', () => {
103
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="day" dayScheme="dark" nightScheme="dark_dimmed">
104
+ <__1.Text color="text">Hello</__1.Text>
105
+ </__1.ThemeProvider>);
106
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
107
+ });
108
+ it('works in auto mode', () => {
109
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="auto">
110
+ <__1.Text color="text">Hello</__1.Text>
111
+ </__1.ThemeProvider>);
112
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
113
+ });
114
+ it('works in auto mode (dark)', () => {
115
+ const matchMediaSpy = jest.spyOn(window, 'matchMedia').mockImplementation(query => ({
116
+ matches: true,
117
+ media: query,
118
+ onchange: null,
119
+ addListener: jest.fn(),
120
+ removeListener: jest.fn(),
121
+ addEventListener: jest.fn(),
122
+ removeEventListener: jest.fn(),
123
+ dispatchEvent: jest.fn()
124
+ }));
125
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="auto">
126
+ <__1.Text color="text">Hello</__1.Text>
127
+ </__1.ThemeProvider>);
128
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
129
+ matchMediaSpy.mockRestore();
130
+ });
131
+ it('updates when colorMode prop changes', async () => {
132
+ function App() {
133
+ const [colorMode, setColorMode] = react_2.default.useState('day');
134
+ return (<__1.ThemeProvider theme={exampleTheme} colorMode={colorMode}>
135
+ <__1.Text color="text">{colorMode}</__1.Text>
136
+ <button onClick={() => setColorMode(colorMode === 'day' ? 'night' : 'day')}>Toggle</button>
137
+ </__1.ThemeProvider>);
138
+ }
139
+ react_1.render(<App />);
140
+ // starts in day mode (light scheme)
141
+ expect(react_1.screen.getByText('day')).toHaveStyleRule('color', 'black');
142
+ react_1.screen.getByRole('button').click();
143
+ await react_1.waitFor(() =>
144
+ // clicking the toggle button enables night mode (dark scheme)
145
+ expect(react_1.screen.getByText('night')).toHaveStyleRule('color', 'white'));
146
+ });
147
+ it('updates when dayScheme prop changes', async () => {
148
+ function App() {
149
+ const [dayScheme, setDayScheme] = react_2.default.useState('light');
150
+ return (<__1.ThemeProvider theme={exampleTheme} dayScheme={dayScheme}>
151
+ <__1.Text color="text">{dayScheme}</__1.Text>
152
+ <button onClick={() => setDayScheme(dayScheme === 'light' ? 'dark_dimmed' : 'light')}>Toggle</button>
153
+ </__1.ThemeProvider>);
154
+ }
155
+ react_1.render(<App />);
156
+ // starts in day mode (light scheme)
157
+ expect(react_1.screen.getByText('light')).toHaveStyleRule('color', 'black');
158
+ react_1.screen.getByRole('button').click();
159
+ await react_1.waitFor(() =>
160
+ // clicking the toggle sets the day scheme to dark_dimmed
161
+ expect(react_1.screen.getByText('dark_dimmed')).toHaveStyleRule('color', 'gray'));
162
+ });
163
+ it('updates when nightScheme prop changes', async () => {
164
+ function App() {
165
+ const [nightScheme, setNightScheme] = react_2.default.useState('dark');
166
+ return (<__1.ThemeProvider theme={exampleTheme} colorMode="night" nightScheme={nightScheme}>
167
+ <__1.Text color="text">{nightScheme}</__1.Text>
168
+ <button onClick={() => setNightScheme(nightScheme === 'dark' ? 'dark_dimmed' : 'dark')}>Toggle</button>
169
+ </__1.ThemeProvider>);
170
+ }
171
+ react_1.render(<App />);
172
+ // starts in night mode (dark scheme)
173
+ expect(react_1.screen.getByText('dark')).toHaveStyleRule('color', 'white');
174
+ react_1.screen.getByRole('button').click();
175
+ await react_1.waitFor(() =>
176
+ // clicking the toggle button sets the night scheme to dark_dimmed
177
+ expect(react_1.screen.getByText('dark_dimmed')).toHaveStyleRule('color', 'gray'));
178
+ });
179
+ it('inherits colorMode from parent', async () => {
180
+ function App() {
181
+ const [colorMode, setcolorMode] = react_2.default.useState('day');
182
+ return (<__1.ThemeProvider theme={exampleTheme} colorMode={colorMode}>
183
+ <button onClick={() => setcolorMode(colorMode === 'day' ? 'night' : 'day')}>Toggle</button>
184
+ <__1.ThemeProvider>
185
+ <__1.Text color="text">{colorMode}</__1.Text>
186
+ </__1.ThemeProvider>
187
+ </__1.ThemeProvider>);
188
+ }
189
+ react_1.render(<App />);
190
+ expect(react_1.screen.getByText('day')).toHaveStyleRule('color', 'black');
191
+ react_1.screen.getByRole('button').click();
192
+ await react_1.waitFor(() => expect(react_1.screen.getByText('night')).toHaveStyleRule('color', 'white'));
193
+ });
194
+ it('inherits dayScheme from parent', async () => {
195
+ function App() {
196
+ const [dayScheme, setDayScheme] = react_2.default.useState('light');
197
+ return (<__1.ThemeProvider theme={exampleTheme} colorMode="night" dayScheme={dayScheme}>
198
+ <button onClick={() => setDayScheme(dayScheme === 'light' ? 'dark_dimmed' : 'light')}>Toggle</button>
199
+ <__1.ThemeProvider colorMode="day">
200
+ <__1.Text color="text">{dayScheme}</__1.Text>
201
+ </__1.ThemeProvider>
202
+ </__1.ThemeProvider>);
203
+ }
204
+ react_1.render(<App />);
205
+ expect(react_1.screen.getByText('light')).toHaveStyleRule('color', 'black');
206
+ react_1.screen.getByRole('button').click();
207
+ await react_1.waitFor(() => expect(react_1.screen.getByText('dark_dimmed')).toHaveStyleRule('color', 'gray'));
208
+ });
209
+ it('inherits nightScheme from parent', async () => {
210
+ function App() {
211
+ const [nightScheme, setNightScheme] = react_2.default.useState('dark');
212
+ return (<__1.ThemeProvider theme={exampleTheme} colorMode="day" nightScheme={nightScheme}>
213
+ <button onClick={() => setNightScheme(nightScheme === 'dark' ? 'dark_dimmed' : 'dark')}>Toggle</button>
214
+ <__1.ThemeProvider colorMode="night">
215
+ <__1.Text color="text">{nightScheme}</__1.Text>
216
+ </__1.ThemeProvider>
217
+ </__1.ThemeProvider>);
218
+ }
219
+ react_1.render(<App />);
220
+ expect(react_1.screen.getByText('dark')).toHaveStyleRule('color', 'white');
221
+ react_1.screen.getByRole('button').click();
222
+ await react_1.waitFor(() => expect(react_1.screen.getByText('dark_dimmed')).toHaveStyleRule('color', 'gray'));
223
+ });
224
+ describe('setColorMode', () => {
225
+ it('changes the color mode', () => {
226
+ function ToggleMode() {
227
+ const { colorMode, setColorMode } = __1.useTheme();
228
+ return <button onClick={() => setColorMode(colorMode === 'day' ? 'night' : 'day')}>Toggle</button>;
229
+ }
230
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="day">
231
+ <__1.Text color="text">Hello</__1.Text>
232
+ <ToggleMode />
233
+ </__1.ThemeProvider>);
234
+ // starts in day mode (light scheme)
235
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
236
+ react_1.screen.getByRole('button').click();
237
+ // clicking the toggle button enables night mode (dark scheme)
238
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
239
+ });
240
+ });
241
+ describe('setDayScheme', () => {
242
+ it('changes the day scheme', () => {
243
+ function ToggleDayScheme() {
244
+ const { dayScheme, setDayScheme } = __1.useTheme();
245
+ return <button onClick={() => setDayScheme(dayScheme === 'light' ? 'dark' : 'light')}>Toggle</button>;
246
+ }
247
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="day">
248
+ <__1.Text color="text">Hello</__1.Text>
249
+ <ToggleDayScheme />
250
+ </__1.ThemeProvider>);
251
+ // starts in day mode (light scheme)
252
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'black');
253
+ react_1.screen.getByRole('button').click();
254
+ // clicking the toggle button sets day scheme to dark
255
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
256
+ });
257
+ });
258
+ describe('setNightScheme', () => {
259
+ it('changes the night scheme', () => {
260
+ function ToggleNightScheme() {
261
+ const { nightScheme, setNightScheme } = __1.useTheme();
262
+ return <button onClick={() => setNightScheme(nightScheme === 'dark' ? 'dark_dimmed' : 'dark')}>Toggle</button>;
263
+ }
264
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} colorMode="night">
265
+ <__1.Text color="text">Hello</__1.Text>
266
+ <ToggleNightScheme />
267
+ </__1.ThemeProvider>);
268
+ // starts in night mode (dark scheme)
269
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'white');
270
+ react_1.screen.getByRole('button').click();
271
+ // clicking the toggle button sets night scheme to dark_dimmed
272
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('color', 'gray');
273
+ });
274
+ });
275
+ describe('useColorSchemeVar', () => {
276
+ it('updates value when scheme changes', () => {
277
+ function ToggleMode() {
278
+ const { colorMode, setColorMode } = __1.useTheme();
279
+ return <button onClick={() => setColorMode(colorMode === 'day' ? 'night' : 'day')}>Toggle</button>;
280
+ }
281
+ function CustomBg() {
282
+ const customBg = __1.useColorSchemeVar({
283
+ light: 'red',
284
+ dark: 'blue',
285
+ dark_dimmed: 'green'
286
+ }, 'inherit');
287
+ return <__1.Text bg={customBg}>Hello</__1.Text>;
288
+ }
289
+ react_1.render(<__1.ThemeProvider theme={exampleTheme} nightScheme="dark_dimmed">
290
+ <CustomBg />
291
+ <ToggleMode />
292
+ </__1.ThemeProvider>);
293
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('background-color', 'red');
294
+ react_1.screen.getByRole('button').click();
295
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('background-color', 'green');
296
+ });
297
+ it('supports fallback value', () => {
298
+ function ToggleMode() {
299
+ const { colorMode, setColorMode } = __1.useTheme();
300
+ return <button onClick={() => setColorMode(colorMode === 'day' ? 'night' : 'day')}>Toggle</button>;
301
+ }
302
+ function CustomBg() {
303
+ const customBg = __1.useColorSchemeVar({ dark: 'blue' }, 'red');
304
+ return <__1.Text bg={customBg}>Hello</__1.Text>;
305
+ }
306
+ react_1.render(<__1.ThemeProvider theme={exampleTheme}>
307
+ <CustomBg />
308
+ <ToggleMode />
309
+ </__1.ThemeProvider>);
310
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('background-color', 'red');
311
+ react_1.screen.getByRole('button').click();
312
+ expect(react_1.screen.getByText('Hello')).toHaveStyleRule('background-color', 'blue');
313
+ });
314
+ });
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ require("babel-polyfill");
7
+ const react_1 = require("@testing-library/react");
8
+ const jest_axe_1 = require("jest-axe");
9
+ const testing_1 = require("../utils/testing");
10
+ const react_2 = __importDefault(require("react"));
11
+ const __1 = require("..");
12
+ expect.extend(jest_axe_1.toHaveNoViolations);
13
+ describe('Timeline', () => {
14
+ testing_1.behavesAsComponent({ Component: __1.Timeline });
15
+ testing_1.checkExports('Timeline', {
16
+ default: __1.Timeline
17
+ });
18
+ it('should have no axe violations', async () => {
19
+ const { container } = react_1.render(<__1.Timeline />);
20
+ const results = await jest_axe_1.axe(container);
21
+ expect(results).toHaveNoViolations();
22
+ react_1.cleanup();
23
+ });
24
+ it('renders with clipSidebar prop', () => {
25
+ expect(testing_1.render(<__1.Timeline clipSidebar/>)).toMatchSnapshot();
26
+ });
27
+ });
28
+ describe('Timeline.Item', () => {
29
+ testing_1.behavesAsComponent({ Component: __1.Timeline.Item });
30
+ it('should have no axe violations', async () => {
31
+ const { container } = react_1.render(<__1.Timeline.Item />);
32
+ const results = await jest_axe_1.axe(container);
33
+ expect(results).toHaveNoViolations();
34
+ react_1.cleanup();
35
+ });
36
+ it('renders with condensed prop', () => {
37
+ expect(testing_1.render(<__1.Timeline.Item condensed/>)).toMatchSnapshot();
38
+ });
39
+ it('adds the Timeline-Item class', () => {
40
+ expect(testing_1.rendersClass(<__1.Timeline.Item />, 'Timeline-Item')).toEqual(true);
41
+ });
42
+ });
43
+ describe('Timeline.Badge', () => {
44
+ testing_1.behavesAsComponent({ Component: __1.Timeline.Badge, options: { skipAs: true } });
45
+ it('should have no axe violations', async () => {
46
+ const { container } = react_1.render(<__1.Timeline.Badge />);
47
+ const results = await jest_axe_1.axe(container);
48
+ expect(results).toHaveNoViolations();
49
+ react_1.cleanup();
50
+ });
51
+ });