@primer/components 31.2.0-rc.c7f73427 → 31.2.1-rc.0e01900c

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 (456) 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 +18 -0
  5. package/dist/browser.esm.js +656 -645
  6. package/dist/browser.esm.js.map +1 -1
  7. package/dist/browser.umd.js +211 -200
  8. package/dist/browser.umd.js.map +1 -1
  9. package/docs/content/ActionList2.mdx +358 -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.js +28 -19
  17. package/lib/ActionList/Item.jsx +311 -0
  18. package/lib/ActionList/List.jsx +138 -0
  19. package/lib/ActionList/index.js +12 -23
  20. package/lib/ActionList2/Description.d.ts +12 -0
  21. package/lib/ActionList2/Description.js +57 -0
  22. package/lib/ActionList2/Description.jsx +29 -0
  23. package/lib/ActionList2/Divider.d.ts +5 -0
  24. package/lib/ActionList2/Divider.js +35 -0
  25. package/lib/ActionList2/Divider.jsx +22 -0
  26. package/lib/ActionList2/Group.d.ts +11 -0
  27. package/lib/ActionList2/Group.js +57 -0
  28. package/lib/ActionList2/Group.jsx +25 -0
  29. package/lib/ActionList2/Header.d.ts +26 -0
  30. package/lib/ActionList2/Header.js +55 -0
  31. package/lib/ActionList2/Header.jsx +36 -0
  32. package/lib/ActionList2/Item.d.ts +63 -0
  33. package/lib/ActionList2/Item.js +242 -0
  34. package/lib/ActionList2/Item.jsx +174 -0
  35. package/lib/ActionList2/LinkItem.d.ts +17 -0
  36. package/lib/ActionList2/LinkItem.js +57 -0
  37. package/lib/ActionList2/LinkItem.jsx +28 -0
  38. package/lib/ActionList2/List.d.ts +26 -0
  39. package/lib/ActionList2/List.js +59 -0
  40. package/lib/ActionList2/List.jsx +41 -0
  41. package/lib/ActionList2/Selection.d.ts +5 -0
  42. package/lib/ActionList2/Selection.js +84 -0
  43. package/lib/ActionList2/Selection.jsx +50 -0
  44. package/lib/ActionList2/Visuals.d.ts +9 -0
  45. package/lib/ActionList2/Visuals.js +90 -0
  46. package/lib/ActionList2/Visuals.jsx +48 -0
  47. package/lib/ActionList2/index.d.ts +36 -0
  48. package/lib/ActionList2/index.js +29 -0
  49. package/lib/ActionMenu.jsx +73 -0
  50. package/lib/AnchoredOverlay/AnchoredOverlay.jsx +100 -0
  51. package/lib/AnchoredOverlay/index.js +4 -12
  52. package/lib/Autocomplete/Autocomplete.d.ts +28 -28
  53. package/lib/Autocomplete/Autocomplete.jsx +100 -0
  54. package/lib/Autocomplete/AutocompleteContext.jsx +5 -0
  55. package/lib/Autocomplete/AutocompleteInput.d.ts +28 -28
  56. package/lib/Autocomplete/AutocompleteInput.jsx +113 -0
  57. package/lib/Autocomplete/AutocompleteMenu.jsx +190 -0
  58. package/lib/Autocomplete/AutocompleteOverlay.jsx +55 -0
  59. package/lib/Autocomplete/index.js +7 -14
  60. package/lib/Avatar.jsx +34 -0
  61. package/lib/AvatarPair.jsx +29 -0
  62. package/lib/AvatarStack.jsx +151 -0
  63. package/lib/BaseStyles.jsx +65 -0
  64. package/lib/BorderBox.jsx +18 -0
  65. package/lib/Box.jsx +10 -0
  66. package/lib/BranchName.jsx +20 -0
  67. package/lib/Breadcrumbs.jsx +74 -0
  68. package/lib/Button/Button.d.ts +25 -25
  69. package/lib/Button/Button.jsx +60 -0
  70. package/lib/Button/ButtonBase.jsx +36 -0
  71. package/lib/Button/ButtonClose.d.ts +45 -45
  72. package/lib/Button/ButtonClose.jsx +55 -0
  73. package/lib/Button/ButtonDanger.d.ts +25 -25
  74. package/lib/Button/ButtonDanger.jsx +63 -0
  75. package/lib/Button/ButtonGroup.jsx +55 -0
  76. package/lib/Button/ButtonInvisible.d.ts +25 -25
  77. package/lib/Button/ButtonInvisible.jsx +52 -0
  78. package/lib/Button/ButtonOutline.d.ts +25 -25
  79. package/lib/Button/ButtonOutline.jsx +63 -0
  80. package/lib/Button/ButtonPrimary.d.ts +25 -25
  81. package/lib/Button/ButtonPrimary.jsx +62 -0
  82. package/lib/Button/ButtonStyles.jsx +37 -0
  83. package/lib/Button/ButtonTableList.jsx +49 -0
  84. package/lib/Button/index.js +21 -70
  85. package/lib/Caret.jsx +93 -0
  86. package/lib/CircleBadge.jsx +43 -0
  87. package/lib/CircleOcticon.d.ts +42 -42
  88. package/lib/CircleOcticon.jsx +21 -0
  89. package/lib/CounterLabel.jsx +44 -0
  90. package/lib/Details.jsx +21 -0
  91. package/lib/Dialog/ConfirmationDialog.jsx +146 -0
  92. package/lib/Dialog/Dialog.js +1 -0
  93. package/lib/Dialog/Dialog.jsx +273 -0
  94. package/lib/Dialog.d.ts +45 -45
  95. package/lib/Dialog.jsx +131 -0
  96. package/lib/Dropdown.d.ts +176 -176
  97. package/lib/Dropdown.jsx +134 -0
  98. package/lib/DropdownMenu/DropdownButton.d.ts +46 -46
  99. package/lib/DropdownMenu/DropdownButton.jsx +14 -0
  100. package/lib/DropdownMenu/DropdownMenu.jsx +70 -0
  101. package/lib/DropdownMenu/index.js +6 -20
  102. package/lib/DropdownStyles.js +18 -26
  103. package/lib/FilterList.d.ts +42 -42
  104. package/lib/FilterList.jsx +63 -0
  105. package/lib/FilteredActionList/FilteredActionList.jsx +100 -0
  106. package/lib/FilteredActionList/index.js +4 -12
  107. package/lib/FilteredSearch.jsx +29 -0
  108. package/lib/Flash.jsx +70 -0
  109. package/lib/Flex.jsx +15 -0
  110. package/lib/FormGroup.jsx +25 -0
  111. package/lib/Grid.jsx +15 -0
  112. package/lib/Header.jsx +90 -0
  113. package/lib/Heading.jsx +21 -0
  114. package/lib/Label.jsx +84 -0
  115. package/lib/LabelGroup.jsx +19 -0
  116. package/lib/Link.jsx +38 -0
  117. package/lib/NewButton/button-counter.d.ts +6 -0
  118. package/lib/NewButton/button-counter.js +31 -0
  119. package/lib/NewButton/button-counter.jsx +14 -0
  120. package/lib/NewButton/button.d.ts +13 -0
  121. package/lib/NewButton/button.js +316 -0
  122. package/lib/NewButton/button.jsx +278 -0
  123. package/lib/NewButton/index.d.ts +14 -0
  124. package/lib/NewButton/index.js +8 -0
  125. package/lib/NewButton/types.d.ts +32 -0
  126. package/lib/NewButton/types.js +2 -0
  127. package/lib/Overlay.jsx +156 -0
  128. package/lib/Pagehead.jsx +18 -0
  129. package/lib/Pagination/Pagination.jsx +163 -0
  130. package/lib/Pagination/index.js +6 -12
  131. package/lib/Pagination/model.jsx +174 -0
  132. package/lib/PointerBox.jsx +25 -0
  133. package/lib/Popover.jsx +210 -0
  134. package/lib/Portal/Portal.jsx +79 -0
  135. package/lib/Portal/index.js +5 -16
  136. package/lib/Position.d.ts +4 -4
  137. package/lib/Position.jsx +46 -0
  138. package/lib/ProgressBar.jsx +39 -0
  139. package/lib/SelectMenu/SelectMenu.d.ts +246 -246
  140. package/lib/SelectMenu/SelectMenu.jsx +114 -0
  141. package/lib/SelectMenu/SelectMenuContext.jsx +5 -0
  142. package/lib/SelectMenu/SelectMenuDivider.jsx +43 -0
  143. package/lib/SelectMenu/SelectMenuFilter.jsx +59 -0
  144. package/lib/SelectMenu/SelectMenuFooter.jsx +46 -0
  145. package/lib/SelectMenu/SelectMenuHeader.jsx +44 -0
  146. package/lib/SelectMenu/SelectMenuItem.d.ts +1 -1
  147. package/lib/SelectMenu/SelectMenuItem.jsx +143 -0
  148. package/lib/SelectMenu/SelectMenuList.jsx +60 -0
  149. package/lib/SelectMenu/SelectMenuLoadingAnimation.jsx +21 -0
  150. package/lib/SelectMenu/SelectMenuModal.d.ts +1 -1
  151. package/lib/SelectMenu/SelectMenuModal.jsx +119 -0
  152. package/lib/SelectMenu/SelectMenuTab.jsx +93 -0
  153. package/lib/SelectMenu/SelectMenuTabPanel.jsx +43 -0
  154. package/lib/SelectMenu/SelectMenuTabs.jsx +58 -0
  155. package/lib/SelectMenu/hooks/useKeyboardNav.js +80 -96
  156. package/lib/SelectMenu/index.js +7 -14
  157. package/lib/SelectPanel/SelectPanel.jsx +105 -0
  158. package/lib/SelectPanel/index.js +4 -12
  159. package/lib/SideNav.jsx +177 -0
  160. package/lib/Spinner.jsx +35 -0
  161. package/lib/StateLabel.d.ts +1 -1
  162. package/lib/StateLabel.js +6 -1
  163. package/lib/StateLabel.jsx +94 -0
  164. package/lib/StyledOcticon.jsx +20 -0
  165. package/lib/SubNav.jsx +104 -0
  166. package/lib/TabNav.jsx +60 -0
  167. package/lib/Text.jsx +14 -0
  168. package/lib/TextInput.jsx +23 -0
  169. package/lib/TextInputWithTokens.d.ts +28 -28
  170. package/lib/TextInputWithTokens.jsx +218 -0
  171. package/lib/ThemeProvider.jsx +130 -0
  172. package/lib/Timeline.d.ts +43 -43
  173. package/lib/Timeline.jsx +124 -0
  174. package/lib/Token/AvatarToken.d.ts +1 -1
  175. package/lib/Token/AvatarToken.jsx +54 -0
  176. package/lib/Token/IssueLabelToken.d.ts +1 -1
  177. package/lib/Token/IssueLabelToken.jsx +125 -0
  178. package/lib/Token/Token.d.ts +1 -1
  179. package/lib/Token/Token.jsx +103 -0
  180. package/lib/Token/TokenBase.jsx +88 -0
  181. package/lib/Token/_RemoveTokenButton.jsx +108 -0
  182. package/lib/Token/_TokenTextContainer.jsx +49 -0
  183. package/lib/Token/index.js +11 -30
  184. package/lib/Tooltip.jsx +246 -0
  185. package/lib/Truncate.jsx +27 -0
  186. package/lib/UnderlineNav.jsx +90 -0
  187. package/lib/_TextInputWrapper.jsx +120 -0
  188. package/lib/_UnstyledTextInput.jsx +22 -0
  189. package/lib/__tests__/ActionList.test.jsx +49 -0
  190. package/lib/__tests__/ActionList.types.test.jsx +45 -0
  191. package/lib/__tests__/ActionList2.test.d.ts +1 -0
  192. package/lib/__tests__/ActionList2.test.js +53 -0
  193. package/lib/__tests__/ActionList2.test.jsx +46 -0
  194. package/lib/__tests__/ActionMenu.test.jsx +124 -0
  195. package/lib/__tests__/AnchoredOverlay.test.jsx +121 -0
  196. package/lib/__tests__/Autocomplete.test.jsx +299 -0
  197. package/lib/__tests__/Avatar.test.jsx +42 -0
  198. package/lib/__tests__/AvatarStack.test.jsx +43 -0
  199. package/lib/__tests__/BorderBox.test.jsx +36 -0
  200. package/lib/__tests__/Box.test.jsx +41 -0
  201. package/lib/__tests__/BranchName.test.jsx +27 -0
  202. package/lib/__tests__/Breadcrumbs.test.jsx +28 -0
  203. package/lib/__tests__/BreadcrumbsItem.test.jsx +31 -0
  204. package/lib/__tests__/Button.test.jsx +100 -0
  205. package/lib/__tests__/Caret.test.jsx +37 -0
  206. package/lib/__tests__/CircleBadge.test.jsx +55 -0
  207. package/lib/__tests__/CircleOcticon.test.jsx +45 -0
  208. package/lib/__tests__/ConfirmationDialog.test.jsx +119 -0
  209. package/lib/__tests__/CounterLabel.test.jsx +36 -0
  210. package/lib/__tests__/Details.test.jsx +85 -0
  211. package/lib/__tests__/Dialog.test.jsx +139 -0
  212. package/lib/__tests__/Dropdown.test.jsx +49 -0
  213. package/lib/__tests__/DropdownMenu.test.jsx +119 -0
  214. package/lib/__tests__/FilterList.test.jsx +27 -0
  215. package/lib/__tests__/FilterListItem.test.jsx +31 -0
  216. package/lib/__tests__/FilteredSearch.test.jsx +27 -0
  217. package/lib/__tests__/Flash.test.jsx +36 -0
  218. package/lib/__tests__/Flex.test.jsx +51 -0
  219. package/lib/__tests__/FormGroup.test.jsx +36 -0
  220. package/lib/__tests__/Grid.test.jsx +69 -0
  221. package/lib/__tests__/Header.test.jsx +45 -0
  222. package/lib/__tests__/Heading.test.jsx +71 -0
  223. package/lib/__tests__/KeyPaths.types.test.js +5 -8
  224. package/lib/__tests__/Label.test.jsx +33 -0
  225. package/lib/__tests__/LabelGroup.test.jsx +29 -0
  226. package/lib/__tests__/Link.test.jsx +43 -0
  227. package/lib/__tests__/Merge.types.test.js +13 -19
  228. package/lib/__tests__/NewButton.test.d.ts +1 -0
  229. package/lib/__tests__/NewButton.test.js +95 -0
  230. package/lib/__tests__/NewButton.test.jsx +61 -0
  231. package/lib/__tests__/Overlay.test.jsx +105 -0
  232. package/lib/__tests__/Pagehead.test.jsx +25 -0
  233. package/lib/__tests__/Pagination/Pagination.test.jsx +32 -0
  234. package/lib/__tests__/Pagination/PaginationModel.test.jsx +118 -0
  235. package/lib/__tests__/PointerBox.test.jsx +33 -0
  236. package/lib/__tests__/Popover.test.jsx +58 -0
  237. package/lib/__tests__/Portal.test.jsx +102 -0
  238. package/lib/__tests__/Position.test.jsx +96 -0
  239. package/lib/__tests__/ProgressBar.test.jsx +38 -0
  240. package/lib/__tests__/SelectMenu.test.jsx +120 -0
  241. package/lib/__tests__/SelectPanel.test.jsx +48 -0
  242. package/lib/__tests__/SideNav.test.jsx +55 -0
  243. package/lib/__tests__/Spinner.test.jsx +41 -0
  244. package/lib/__tests__/StateLabel.test.jsx +46 -0
  245. package/lib/__tests__/StyledOcticon.test.jsx +28 -0
  246. package/lib/__tests__/SubNav.test.jsx +47 -0
  247. package/lib/__tests__/SubNavLink.test.jsx +31 -0
  248. package/lib/__tests__/TabNav.test.jsx +32 -0
  249. package/lib/__tests__/Text.test.jsx +71 -0
  250. package/lib/__tests__/TextInput.test.jsx +45 -0
  251. package/lib/__tests__/TextInputWithTokens.test.jsx +302 -0
  252. package/lib/__tests__/ThemeProvider.test.jsx +314 -0
  253. package/lib/__tests__/Timeline.test.jsx +51 -0
  254. package/lib/__tests__/Token.test.jsx +93 -0
  255. package/lib/__tests__/Tooltip.test.jsx +46 -0
  256. package/lib/__tests__/Truncate.test.jsx +41 -0
  257. package/lib/__tests__/UnderlineNav.test.jsx +53 -0
  258. package/lib/__tests__/UnderlineNavLink.test.jsx +31 -0
  259. package/lib/__tests__/behaviors/anchoredPosition.test.js +229 -376
  260. package/lib/__tests__/behaviors/focusTrap.test.jsx +184 -0
  261. package/lib/__tests__/behaviors/focusZone.test.jsx +406 -0
  262. package/lib/__tests__/behaviors/iterateFocusableElements.test.jsx +58 -0
  263. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.js +145 -216
  264. package/lib/__tests__/filterObject.test.js +48 -27
  265. package/lib/__tests__/hooks/useAnchoredPosition.test.jsx +29 -0
  266. package/lib/__tests__/hooks/useOnEscapePress.test.jsx +19 -0
  267. package/lib/__tests__/hooks/useOnOutsideClick.test.jsx +63 -0
  268. package/lib/__tests__/hooks/useOpenAndCloseFocus.test.jsx +61 -0
  269. package/lib/__tests__/hooks/useProvidedStateOrCreate.test.jsx +56 -0
  270. package/lib/__tests__/theme.test.js +33 -34
  271. package/lib/__tests__/themeGet.test.js +12 -23
  272. package/lib/__tests__/useSafeTimeout.test.jsx +36 -0
  273. package/lib/__tests__/utils/createSlots.test.d.ts +1 -0
  274. package/lib/__tests__/utils/createSlots.test.js +75 -0
  275. package/lib/__tests__/utils/createSlots.test.jsx +57 -0
  276. package/lib/behaviors/anchoredPosition.js +205 -234
  277. package/lib/behaviors/focusTrap.js +121 -157
  278. package/lib/behaviors/focusZone.js +434 -509
  279. package/lib/behaviors/scrollIntoViewingArea.js +18 -35
  280. package/lib/constants.js +39 -43
  281. package/lib/drafts.d.ts +8 -0
  282. package/lib/drafts.js +21 -0
  283. package/lib/hooks/index.js +16 -60
  284. package/lib/hooks/useAnchoredPosition.js +32 -40
  285. package/lib/hooks/useCombinedRefs.js +32 -36
  286. package/lib/hooks/useDetails.jsx +39 -0
  287. package/lib/hooks/useDialog.js +72 -96
  288. package/lib/hooks/useFocusTrap.js +43 -60
  289. package/lib/hooks/useFocusZone.js +54 -50
  290. package/lib/hooks/useOnEscapePress.js +25 -36
  291. package/lib/hooks/useOnOutsideClick.jsx +61 -0
  292. package/lib/hooks/useOpenAndCloseFocus.js +22 -34
  293. package/lib/hooks/useOverlay.jsx +15 -0
  294. package/lib/hooks/useProvidedRefOrCreate.js +10 -14
  295. package/lib/hooks/useProvidedStateOrCreate.js +13 -16
  296. package/lib/hooks/useRenderForcingRef.js +13 -17
  297. package/lib/hooks/useResizeObserver.js +15 -18
  298. package/lib/hooks/useSafeTimeout.js +22 -30
  299. package/lib/hooks/useScrollFlash.js +16 -23
  300. package/lib/index.d.ts +2 -0
  301. package/lib/index.js +163 -636
  302. package/lib/polyfills/eventListenerSignal.js +37 -45
  303. package/lib/stories/ActionList2.stories.js +908 -0
  304. package/lib/stories/NewButton.stories.js +230 -0
  305. package/lib/sx.d.ts +2 -0
  306. package/lib/sx.js +10 -14
  307. package/lib/theme-preval.js +65 -2945
  308. package/lib/theme.js +3 -12
  309. package/lib/utils/create-slots.d.ts +17 -0
  310. package/lib/utils/create-slots.js +105 -0
  311. package/lib/utils/create-slots.jsx +65 -0
  312. package/lib/utils/deprecate.jsx +59 -0
  313. package/lib/utils/isNumeric.jsx +7 -0
  314. package/lib/utils/iterateFocusableElements.js +63 -85
  315. package/lib/utils/ssr.jsx +6 -0
  316. package/lib/utils/test-deprecations.jsx +20 -0
  317. package/lib/utils/test-helpers.jsx +8 -0
  318. package/lib/utils/test-matchers.jsx +100 -0
  319. package/lib/utils/testing.d.ts +14 -1
  320. package/lib/utils/testing.jsx +206 -0
  321. package/lib/utils/theme.js +33 -47
  322. package/lib/utils/types/AriaRole.js +2 -1
  323. package/lib/utils/types/ComponentProps.js +2 -1
  324. package/lib/utils/types/Flatten.js +2 -1
  325. package/lib/utils/types/KeyPaths.js +2 -1
  326. package/lib/utils/types/MandateProps.js +16 -1
  327. package/lib/utils/types/Merge.js +2 -1
  328. package/lib/utils/types/index.js +16 -69
  329. package/lib/utils/uniqueId.js +5 -8
  330. package/lib/utils/use-force-update.d.ts +1 -0
  331. package/lib/utils/use-force-update.js +13 -0
  332. package/lib/utils/useIsomorphicLayoutEffect.js +8 -11
  333. package/lib/utils/userAgent.js +8 -12
  334. package/lib-esm/ActionList/Item.js +28 -19
  335. package/lib-esm/ActionList2/Description.d.ts +12 -0
  336. package/lib-esm/ActionList2/Description.js +41 -0
  337. package/lib-esm/ActionList2/Divider.d.ts +5 -0
  338. package/lib-esm/ActionList2/Divider.js +23 -0
  339. package/lib-esm/ActionList2/Group.d.ts +11 -0
  340. package/lib-esm/ActionList2/Group.js +40 -0
  341. package/lib-esm/ActionList2/Header.d.ts +26 -0
  342. package/lib-esm/ActionList2/Header.js +44 -0
  343. package/lib-esm/ActionList2/Item.d.ts +63 -0
  344. package/lib-esm/ActionList2/Item.js +208 -0
  345. package/lib-esm/ActionList2/LinkItem.d.ts +17 -0
  346. package/lib-esm/ActionList2/LinkItem.js +43 -0
  347. package/lib-esm/ActionList2/List.d.ts +26 -0
  348. package/lib-esm/ActionList2/List.js +37 -0
  349. package/lib-esm/ActionList2/Selection.d.ts +5 -0
  350. package/lib-esm/ActionList2/Selection.js +66 -0
  351. package/lib-esm/ActionList2/Visuals.d.ts +9 -0
  352. package/lib-esm/ActionList2/Visuals.js +68 -0
  353. package/lib-esm/ActionList2/index.d.ts +36 -0
  354. package/lib-esm/ActionList2/index.js +33 -0
  355. package/lib-esm/Autocomplete/Autocomplete.d.ts +28 -28
  356. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +28 -28
  357. package/lib-esm/Button/Button.d.ts +25 -25
  358. package/lib-esm/Button/ButtonClose.d.ts +45 -45
  359. package/lib-esm/Button/ButtonDanger.d.ts +25 -25
  360. package/lib-esm/Button/ButtonInvisible.d.ts +25 -25
  361. package/lib-esm/Button/ButtonOutline.d.ts +25 -25
  362. package/lib-esm/Button/ButtonPrimary.d.ts +25 -25
  363. package/lib-esm/CircleOcticon.d.ts +42 -42
  364. package/lib-esm/Dialog/Dialog.js +1 -0
  365. package/lib-esm/Dialog.d.ts +45 -45
  366. package/lib-esm/Dropdown.d.ts +176 -176
  367. package/lib-esm/DropdownMenu/DropdownButton.d.ts +46 -46
  368. package/lib-esm/FilterList.d.ts +42 -42
  369. package/lib-esm/NewButton/button-counter.d.ts +6 -0
  370. package/lib-esm/NewButton/button-counter.js +18 -0
  371. package/lib-esm/NewButton/button.d.ts +13 -0
  372. package/lib-esm/NewButton/button.js +298 -0
  373. package/lib-esm/NewButton/index.d.ts +14 -0
  374. package/lib-esm/NewButton/index.js +5 -0
  375. package/lib-esm/NewButton/types.d.ts +32 -0
  376. package/lib-esm/NewButton/types.js +1 -0
  377. package/lib-esm/Position.d.ts +4 -4
  378. package/lib-esm/SelectMenu/SelectMenu.d.ts +246 -246
  379. package/lib-esm/SelectMenu/SelectMenuItem.d.ts +1 -1
  380. package/lib-esm/SelectMenu/SelectMenuModal.d.ts +1 -1
  381. package/lib-esm/StateLabel.d.ts +1 -1
  382. package/lib-esm/StateLabel.js +7 -2
  383. package/lib-esm/TextInputWithTokens.d.ts +28 -28
  384. package/lib-esm/Timeline.d.ts +43 -43
  385. package/lib-esm/Token/AvatarToken.d.ts +1 -1
  386. package/lib-esm/Token/IssueLabelToken.d.ts +1 -1
  387. package/lib-esm/Token/Token.d.ts +1 -1
  388. package/lib-esm/__tests__/ActionList2.test.d.ts +1 -0
  389. package/lib-esm/__tests__/ActionList2.test.js +41 -0
  390. package/lib-esm/__tests__/NewButton.test.d.ts +1 -0
  391. package/lib-esm/__tests__/NewButton.test.js +84 -0
  392. package/lib-esm/__tests__/utils/createSlots.test.d.ts +1 -0
  393. package/lib-esm/__tests__/utils/createSlots.test.js +67 -0
  394. package/lib-esm/drafts.d.ts +8 -0
  395. package/lib-esm/drafts.js +9 -0
  396. package/lib-esm/index.d.ts +2 -0
  397. package/lib-esm/index.js +1 -0
  398. package/lib-esm/stories/ActionList2.stories.js +796 -0
  399. package/lib-esm/stories/NewButton.stories.js +178 -0
  400. package/lib-esm/sx.d.ts +2 -0
  401. package/lib-esm/sx.js +3 -1
  402. package/lib-esm/theme-preval.js +81 -2
  403. package/lib-esm/utils/create-slots.d.ts +17 -0
  404. package/lib-esm/utils/create-slots.js +84 -0
  405. package/lib-esm/utils/testing.d.ts +14 -1
  406. package/lib-esm/utils/use-force-update.d.ts +1 -0
  407. package/lib-esm/utils/use-force-update.js +6 -0
  408. package/package-lock.json +153 -14
  409. package/package.json +7 -4
  410. package/script/build +1 -1
  411. package/src/ActionList/Item.tsx +32 -19
  412. package/src/ActionList2/Description.tsx +52 -0
  413. package/src/ActionList2/Divider.tsx +24 -0
  414. package/src/ActionList2/Group.tsx +34 -0
  415. package/src/ActionList2/Header.tsx +58 -0
  416. package/src/ActionList2/Item.tsx +246 -0
  417. package/src/ActionList2/LinkItem.tsx +49 -0
  418. package/src/ActionList2/List.tsx +55 -0
  419. package/src/ActionList2/Selection.tsx +60 -0
  420. package/src/ActionList2/Visuals.tsx +76 -0
  421. package/src/ActionList2/index.ts +39 -0
  422. package/src/Dialog/Dialog.tsx +1 -0
  423. package/src/NewButton/button-counter.tsx +15 -0
  424. package/src/NewButton/button.tsx +279 -0
  425. package/src/NewButton/index.ts +10 -0
  426. package/src/NewButton/types.ts +36 -0
  427. package/src/StateLabel.tsx +14 -2
  428. package/src/__tests__/ActionList2.test.tsx +47 -0
  429. package/src/__tests__/NewButton.test.tsx +70 -0
  430. package/src/__tests__/__snapshots__/ActionList2.test.tsx.snap +14 -0
  431. package/src/__tests__/__snapshots__/Autocomplete.test.tsx.snap +722 -255
  432. package/src/__tests__/__snapshots__/CircleBadge.test.tsx.snap +1 -0
  433. package/src/__tests__/__snapshots__/CircleOcticon.test.tsx.snap +1 -0
  434. package/src/__tests__/__snapshots__/Dialog.test.tsx.snap +1 -0
  435. package/src/__tests__/__snapshots__/DropdownMenu.test.tsx.snap +1 -0
  436. package/src/__tests__/__snapshots__/NewButton.test.tsx.snap +300 -0
  437. package/src/__tests__/__snapshots__/SelectMenu.test.tsx.snap +4 -0
  438. package/src/__tests__/__snapshots__/SelectPanel.test.tsx.snap +1 -0
  439. package/src/__tests__/__snapshots__/StateLabel.test.tsx.snap +13 -6
  440. package/src/__tests__/__snapshots__/StyledOcticon.test.tsx.snap +1 -0
  441. package/src/__tests__/__snapshots__/TextInputWithTokens.test.tsx.snap +66 -0
  442. package/src/__tests__/__snapshots__/Token.test.tsx.snap +17 -0
  443. package/src/__tests__/utils/__snapshots__/createSlots.test.tsx.snap +55 -0
  444. package/src/__tests__/utils/createSlots.test.tsx +74 -0
  445. package/src/drafts.ts +10 -0
  446. package/src/index.ts +2 -0
  447. package/src/stories/ActionList2.stories.tsx +1291 -0
  448. package/src/stories/NewButton.stories.tsx +201 -0
  449. package/src/sx.ts +3 -0
  450. package/src/theme-preval.js +1 -0
  451. package/src/utils/create-slots.tsx +96 -0
  452. package/src/utils/use-force-update.ts +7 -0
  453. package/stats.html +1 -1
  454. package/tsconfig.base.json +20 -0
  455. package/tsconfig.build.json +2 -2
  456. package/tsconfig.json +4 -17
@@ -0,0 +1,32 @@
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 __1 = require("..");
8
+ const testing_1 = require("../utils/testing");
9
+ const react_2 = require("@testing-library/react");
10
+ const jest_axe_1 = require("jest-axe");
11
+ require("babel-polyfill");
12
+ expect.extend(jest_axe_1.toHaveNoViolations);
13
+ describe('TabNav', () => {
14
+ testing_1.behavesAsComponent({ Component: __1.TabNav });
15
+ testing_1.checkExports('TabNav', {
16
+ default: __1.TabNav
17
+ });
18
+ describe('TabNav.Link', () => {
19
+ testing_1.behavesAsComponent({ Component: __1.TabNav.Link });
20
+ });
21
+ it('should have no axe violations', async () => {
22
+ const { container } = react_2.render(<__1.TabNav aria-label="main"/>);
23
+ const results = await jest_axe_1.axe(container);
24
+ expect(results).toHaveNoViolations();
25
+ react_2.cleanup();
26
+ });
27
+ it('sets aria-label appropriately', () => {
28
+ const { getByLabelText } = react_2.render(<__1.TabNav aria-label="stuff"/>);
29
+ expect(getByLabelText('stuff')).toBeTruthy();
30
+ expect(getByLabelText('stuff').tagName).toEqual('NAV');
31
+ });
32
+ });
@@ -0,0 +1,71 @@
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 __1 = require("..");
8
+ const theme_1 = __importDefault(require("../theme"));
9
+ const testing_1 = require("../utils/testing");
10
+ const react_2 = require("@testing-library/react");
11
+ const jest_axe_1 = require("jest-axe");
12
+ require("babel-polyfill");
13
+ expect.extend(jest_axe_1.toHaveNoViolations);
14
+ describe('Text', () => {
15
+ testing_1.behavesAsComponent({ Component: __1.Text });
16
+ testing_1.checkExports('Text', {
17
+ default: __1.Text
18
+ });
19
+ it('renders a <span> by default', () => {
20
+ expect(testing_1.render(<__1.Text />).type).toEqual('span');
21
+ });
22
+ it('should have no axe violations', async () => {
23
+ const { container } = react_2.render(<__1.Text>hello</__1.Text>);
24
+ const results = await jest_axe_1.axe(container);
25
+ expect(results).toHaveNoViolations();
26
+ react_2.cleanup();
27
+ });
28
+ it('renders fontSize', () => {
29
+ for (const fontSize of theme_1.default.fontSizes) {
30
+ expect(testing_1.render(<__1.Text fontSize={fontSize}/>)).toHaveStyleRule('font-size', testing_1.px(fontSize));
31
+ }
32
+ });
33
+ it('renders responsive fontSize', () => {
34
+ expect(testing_1.renderStyles(<__1.Text fontSize={[1, 2]}/>)).toEqual({
35
+ 'font-size': testing_1.px(theme_1.default.fontSizes[1]),
36
+ [`@media screen and (min-width:${testing_1.px(theme_1.default.breakpoints[0])})`]: {
37
+ 'font-size': testing_1.px(theme_1.default.fontSizes[2])
38
+ }
39
+ });
40
+ });
41
+ it('renders responsive lineHeight', () => {
42
+ expect(testing_1.renderStyles(<__1.Text lineHeight={['condensed', 'default']}/>)).toEqual({
43
+ 'line-height': String(theme_1.default.lineHeights.condensed),
44
+ [`@media screen and (min-width:${testing_1.px(theme_1.default.breakpoints[0])})`]: {
45
+ 'line-height': String(theme_1.default.lineHeights.default)
46
+ }
47
+ });
48
+ });
49
+ it('respects fontWeight', () => {
50
+ expect(testing_1.render(<__1.Text fontWeight="bold"/>)).toHaveStyleRule('font-weight', '600');
51
+ expect(testing_1.render(<__1.Text fontWeight="normal"/>)).toHaveStyleRule('font-weight', '400');
52
+ });
53
+ it('respects the "fontStyle" prop', () => {
54
+ expect(testing_1.render(<__1.Text fontStyle="italic"/>)).toHaveStyleRule('font-style', 'italic');
55
+ expect(testing_1.render(<__1.Text as="i" fontStyle="normal"/>)).toHaveStyleRule('font-style', 'normal');
56
+ });
57
+ it('respects lineHeight', () => {
58
+ for (const [name, value] of Object.entries(theme_1.default.lineHeights)) {
59
+ expect(testing_1.render(<__1.Text lineHeight={name}/>)).toHaveStyleRule('line-height', String(value));
60
+ }
61
+ });
62
+ it('respects fontFamily="mono"', () => {
63
+ // styled-components removes the whitespace between font-family values
64
+ const mono = theme_1.default.fonts.mono.replace(/, /g, ',');
65
+ expect(testing_1.render(<__1.Text fontFamily="mono"/>)).toHaveStyleRule('font-family', mono);
66
+ });
67
+ it('respects other values for fontSize', () => {
68
+ expect(testing_1.render(<__1.Text fontSize="2em"/>)).toHaveStyleRule('font-size', '2em');
69
+ expect(testing_1.render(<__1.Text fontSize={100}/>)).toHaveStyleRule('font-size', '100px');
70
+ });
71
+ });
@@ -0,0 +1,45 @@
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 __1 = require("..");
8
+ const testing_1 = require("../utils/testing");
9
+ const react_2 = require("@testing-library/react");
10
+ const jest_axe_1 = require("jest-axe");
11
+ require("babel-polyfill");
12
+ expect.extend(jest_axe_1.toHaveNoViolations);
13
+ describe('TextInput', () => {
14
+ testing_1.behavesAsComponent({ Component: __1.TextInput, options: { skipAs: true } });
15
+ testing_1.checkExports('TextInput', {
16
+ default: __1.TextInput
17
+ });
18
+ it('should have no axe violations', async () => {
19
+ const { container } = react_2.render(<__1.TextInput aria-label="zipcode" name="zipcode" variant="small"/>);
20
+ const results = await jest_axe_1.axe(container);
21
+ expect(results).toHaveNoViolations();
22
+ react_2.cleanup();
23
+ });
24
+ it('renders', () => {
25
+ expect(testing_1.render(<__1.TextInput name="zipcode"/>)).toMatchSnapshot();
26
+ });
27
+ it('renders small', () => {
28
+ expect(testing_1.render(<__1.TextInput name="zipcode" variant="small"/>)).toMatchSnapshot();
29
+ });
30
+ it('renders large', () => {
31
+ expect(testing_1.render(<__1.TextInput name="zipcode" variant="large"/>)).toMatchSnapshot();
32
+ });
33
+ it('renders block', () => {
34
+ expect(testing_1.render(<__1.TextInput name="zipcode" block/>)).toMatchSnapshot();
35
+ });
36
+ it('should call onChange prop with input value', () => {
37
+ const onChangeMock = jest.fn();
38
+ const component = testing_1.mount(<__1.TextInput onChange={onChangeMock} value="test"/>);
39
+ component.find('input').simulate('change');
40
+ expect(onChangeMock).toHaveBeenCalled();
41
+ });
42
+ it('should render a password input', () => {
43
+ expect(testing_1.render(<__1.TextInput name="password" type="password"/>)).toMatchSnapshot();
44
+ });
45
+ });
@@ -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
+ });