@telus-uds/components-base 0.0.2-prerelease.1 → 0.0.2-prerelease.10

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 (475) hide show
  1. package/.ultra.cache.json +1 -0
  2. package/CHANGELOG.md +120 -0
  3. package/README.md +4 -2
  4. package/__fixtures__/Accessible.js +33 -0
  5. package/__fixtures__/Accessible.native.js +32 -0
  6. package/__fixtures__/test-utils.js +25 -0
  7. package/__fixtures__/testTheme.js +1146 -145
  8. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  9. package/__tests__/Box/Box.test.jsx +81 -58
  10. package/__tests__/Button/ButtonBase.test.jsx +3 -32
  11. package/__tests__/Button/ButtonGroup.test.jsx +6 -7
  12. package/__tests__/Card/Card.test.jsx +63 -0
  13. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  14. package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
  15. package/__tests__/Divider/Divider.test.jsx +26 -5
  16. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  17. package/__tests__/Feedback/Feedback.test.jsx +42 -0
  18. package/__tests__/FlexGrid/Col.test.jsx +5 -0
  19. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  20. package/__tests__/Icon/Icon.test.jsx +3 -3
  21. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  22. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  23. package/__tests__/Link/LinkBase.test.jsx +0 -14
  24. package/__tests__/List/List.test.jsx +60 -0
  25. package/__tests__/Modal/Modal.test.jsx +47 -0
  26. package/__tests__/Notification/Notification.test.jsx +20 -0
  27. package/__tests__/Pagination/Pagination.test.jsx +160 -0
  28. package/__tests__/Progress/Progress.test.jsx +79 -0
  29. package/__tests__/Radio/Radio.test.jsx +87 -0
  30. package/__tests__/Radio/RadioGroup.test.jsx +220 -0
  31. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  32. package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
  33. package/__tests__/Search/Search.test.jsx +73 -0
  34. package/__tests__/Select/Select.test.jsx +94 -0
  35. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  36. package/__tests__/Spacer/Spacer.test.jsx +63 -0
  37. package/__tests__/StackView/StackView.test.jsx +216 -0
  38. package/__tests__/StackView/StackWrap.test.jsx +47 -0
  39. package/__tests__/StackView/getStackedContent.test.jsx +295 -0
  40. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  41. package/__tests__/Tabs/Tabs.test.jsx +40 -0
  42. package/__tests__/Tags/Tags.test.jsx +327 -0
  43. package/__tests__/TextInput/TextArea.test.jsx +35 -0
  44. package/__tests__/TextInput/TextInputBase.test.jsx +125 -0
  45. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  46. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +14 -8
  47. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  48. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  49. package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
  50. package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
  51. package/__tests__/utils/children.test.jsx +128 -0
  52. package/__tests__/utils/input.test.js +59 -1
  53. package/__tests__/utils/useCopy.test.js +42 -0
  54. package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
  55. package/__tests__/utils/useSpacingScale.test.jsx +273 -0
  56. package/__tests__/utils/useUniqueId.test.js +31 -0
  57. package/babel.config.js +18 -1
  58. package/jest.config.js +19 -9
  59. package/lib/A11yInfoProvider/index.js +54 -26
  60. package/lib/A11yText/index.js +36 -15
  61. package/lib/ActivityIndicator/Spinner.js +78 -0
  62. package/lib/ActivityIndicator/Spinner.native.js +121 -87
  63. package/lib/ActivityIndicator/index.js +28 -12
  64. package/lib/ActivityIndicator/shared.js +27 -12
  65. package/lib/BaseProvider/index.js +34 -11
  66. package/lib/Box/Box.js +214 -87
  67. package/lib/Box/index.js +13 -2
  68. package/lib/Button/Button.js +37 -11
  69. package/lib/Button/ButtonBase.js +119 -110
  70. package/lib/Button/ButtonGroup.js +98 -101
  71. package/lib/Button/ButtonLink.js +40 -14
  72. package/lib/Button/index.js +31 -4
  73. package/lib/Button/propTypes.js +32 -9
  74. package/lib/Card/Card.js +98 -0
  75. package/lib/Card/CardBase.js +78 -0
  76. package/lib/Card/PressableCardBase.js +137 -0
  77. package/lib/Card/index.js +40 -0
  78. package/lib/Checkbox/Checkbox.js +344 -0
  79. package/lib/Checkbox/CheckboxGroup.js +231 -0
  80. package/lib/Checkbox/CheckboxInput.js +74 -0
  81. package/lib/Checkbox/CheckboxInput.native.js +14 -0
  82. package/lib/Checkbox/index.js +21 -0
  83. package/lib/Divider/Divider.js +80 -18
  84. package/lib/Divider/index.js +13 -2
  85. package/lib/ExpandCollapse/Accordion.js +19 -8
  86. package/lib/ExpandCollapse/Control.js +50 -29
  87. package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
  88. package/lib/ExpandCollapse/Panel.js +77 -41
  89. package/lib/ExpandCollapse/index.js +25 -7
  90. package/lib/Feedback/Feedback.js +161 -0
  91. package/lib/Feedback/index.js +13 -0
  92. package/lib/Fieldset/Fieldset.js +160 -0
  93. package/lib/Fieldset/FieldsetContainer.js +41 -0
  94. package/lib/Fieldset/FieldsetContainer.native.js +33 -0
  95. package/lib/Fieldset/Legend.js +33 -0
  96. package/lib/Fieldset/Legend.native.js +43 -0
  97. package/lib/Fieldset/cssReset.js +21 -0
  98. package/lib/Fieldset/index.js +13 -0
  99. package/lib/FlexGrid/Col/Col.js +66 -39
  100. package/lib/FlexGrid/Col/index.js +13 -2
  101. package/lib/FlexGrid/FlexGrid.js +70 -47
  102. package/lib/FlexGrid/Row/Row.js +47 -28
  103. package/lib/FlexGrid/Row/index.js +13 -2
  104. package/lib/FlexGrid/helpers/index.js +9 -1
  105. package/lib/FlexGrid/index.js +13 -2
  106. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  107. package/lib/HorizontalScroll/HorizontalScroll.js +199 -0
  108. package/lib/HorizontalScroll/HorizontalScrollButton.js +121 -0
  109. package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
  110. package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
  111. package/lib/HorizontalScroll/dictionary.js +18 -0
  112. package/lib/HorizontalScroll/index.js +35 -0
  113. package/lib/HorizontalScroll/itemPositions.js +128 -0
  114. package/lib/Icon/Icon.js +52 -47
  115. package/lib/Icon/IconText.js +100 -0
  116. package/lib/Icon/index.js +31 -3
  117. package/lib/IconButton/IconButton.js +135 -0
  118. package/lib/IconButton/index.js +13 -0
  119. package/lib/InputLabel/InputLabel.js +145 -0
  120. package/lib/InputLabel/LabelContent.js +39 -0
  121. package/lib/InputLabel/LabelContent.native.js +16 -0
  122. package/lib/InputLabel/index.js +13 -0
  123. package/lib/InputSupports/InputSupports.js +104 -0
  124. package/lib/InputSupports/index.js +13 -0
  125. package/lib/InputSupports/propTypes.js +66 -0
  126. package/lib/InputSupports/useInputSupports.js +41 -0
  127. package/lib/Link/ChevronLink.js +56 -16
  128. package/lib/Link/InlinePressable.js +50 -0
  129. package/lib/Link/InlinePressable.native.js +101 -0
  130. package/lib/Link/Link.js +29 -14
  131. package/lib/Link/LinkBase.js +120 -147
  132. package/lib/Link/TextButton.js +46 -18
  133. package/lib/Link/index.js +39 -4
  134. package/lib/List/List.js +80 -0
  135. package/lib/List/ListItem.js +239 -0
  136. package/lib/List/index.js +13 -0
  137. package/lib/Modal/Modal.js +226 -0
  138. package/lib/Modal/dictionary.js +16 -0
  139. package/lib/Modal/index.js +13 -0
  140. package/lib/Notification/Notification.js +215 -0
  141. package/lib/Notification/dictionary.js +15 -0
  142. package/lib/Notification/index.js +13 -0
  143. package/lib/Pagination/PageButton.js +89 -0
  144. package/lib/Pagination/Pagination.js +148 -0
  145. package/lib/Pagination/SideButton.js +124 -0
  146. package/lib/Pagination/dictionary.js +25 -0
  147. package/lib/Pagination/index.js +13 -0
  148. package/lib/Pagination/usePagination.js +80 -0
  149. package/lib/Progress/Progress.js +99 -0
  150. package/lib/Progress/ProgressBar.js +146 -0
  151. package/lib/Progress/ProgressBarBackground.js +57 -0
  152. package/lib/Progress/index.js +16 -0
  153. package/lib/Radio/Radio.js +292 -0
  154. package/lib/Radio/RadioButton.js +141 -0
  155. package/lib/Radio/RadioGroup.js +234 -0
  156. package/lib/Radio/RadioInput.js +76 -0
  157. package/lib/Radio/RadioInput.native.js +14 -0
  158. package/lib/Radio/index.js +21 -0
  159. package/lib/RadioCard/RadioCard.js +243 -0
  160. package/lib/RadioCard/RadioCardGroup.js +251 -0
  161. package/lib/RadioCard/index.js +21 -0
  162. package/lib/Search/Search.js +250 -0
  163. package/lib/Search/dictionary.js +19 -0
  164. package/lib/Search/index.js +13 -0
  165. package/lib/Select/Group.js +33 -0
  166. package/lib/Select/Group.native.js +25 -0
  167. package/lib/Select/Item.js +29 -0
  168. package/lib/Select/Item.native.js +19 -0
  169. package/lib/Select/Picker.js +79 -0
  170. package/lib/Select/Picker.native.js +127 -0
  171. package/lib/Select/Select.js +341 -0
  172. package/lib/Select/index.js +19 -0
  173. package/lib/SideNav/Item.js +54 -35
  174. package/lib/SideNav/ItemContent.js +41 -15
  175. package/lib/SideNav/ItemsGroup.js +53 -34
  176. package/lib/SideNav/SideNav.js +94 -70
  177. package/lib/SideNav/index.js +15 -1
  178. package/lib/Skeleton/Skeleton.js +137 -0
  179. package/lib/Skeleton/index.js +13 -0
  180. package/lib/Skeleton/skeleton.constant.js +12 -0
  181. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  182. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  183. package/lib/Spacer/Spacer.js +117 -0
  184. package/lib/Spacer/index.js +13 -0
  185. package/lib/StackView/StackView.js +130 -0
  186. package/lib/StackView/StackWrap.js +55 -0
  187. package/lib/StackView/StackWrap.native.js +14 -0
  188. package/lib/StackView/StackWrapBox.js +120 -0
  189. package/lib/StackView/StackWrapGap.js +71 -0
  190. package/lib/StackView/common.js +47 -0
  191. package/lib/StackView/getStackedContent.js +141 -0
  192. package/lib/StackView/index.js +29 -0
  193. package/lib/StepTracker/Step.js +245 -0
  194. package/lib/StepTracker/StepTracker.js +197 -0
  195. package/lib/StepTracker/dictionary.js +17 -0
  196. package/lib/StepTracker/index.js +13 -0
  197. package/lib/Tabs/Tabs.js +118 -0
  198. package/lib/Tabs/TabsItem.js +237 -0
  199. package/lib/Tabs/index.js +13 -0
  200. package/lib/Tags/Tags.js +250 -0
  201. package/lib/Tags/index.js +13 -0
  202. package/lib/TextInput/TextArea.js +109 -0
  203. package/lib/TextInput/TextInput.js +75 -0
  204. package/lib/TextInput/TextInputBase.js +255 -0
  205. package/lib/TextInput/index.js +23 -0
  206. package/lib/TextInput/propTypes.js +42 -0
  207. package/lib/ThemeProvider/ThemeProvider.js +46 -18
  208. package/lib/ThemeProvider/index.js +61 -6
  209. package/lib/ThemeProvider/useSetTheme.js +19 -5
  210. package/lib/ThemeProvider/useTheme.js +13 -4
  211. package/lib/ThemeProvider/useThemeTokens.js +111 -16
  212. package/lib/ThemeProvider/utils/index.js +31 -2
  213. package/lib/ThemeProvider/utils/styles.js +52 -16
  214. package/lib/ThemeProvider/utils/theme-tokens.js +154 -19
  215. package/lib/ToggleSwitch/ToggleSwitch.js +87 -93
  216. package/lib/ToggleSwitch/index.js +13 -2
  217. package/lib/Tooltip/Backdrop.js +56 -0
  218. package/lib/Tooltip/Backdrop.native.js +59 -0
  219. package/lib/Tooltip/Tooltip.js +357 -0
  220. package/lib/Tooltip/dictionary.js +15 -0
  221. package/lib/Tooltip/getTooltipPosition.js +172 -0
  222. package/lib/Tooltip/index.js +13 -0
  223. package/lib/TooltipButton/TooltipButton.js +83 -0
  224. package/lib/TooltipButton/index.js +13 -0
  225. package/lib/Typography/Typography.js +58 -49
  226. package/lib/Typography/index.js +13 -2
  227. package/lib/ViewportProvider/ViewportProvider.js +46 -0
  228. package/lib/ViewportProvider/index.js +22 -38
  229. package/lib/ViewportProvider/useViewport.js +15 -0
  230. package/lib/ViewportProvider/useViewportListener.js +57 -0
  231. package/lib/index.js +539 -17
  232. package/lib/utils/a11y/index.js +18 -0
  233. package/lib/utils/a11y/textSize.js +49 -0
  234. package/lib/utils/animation/index.js +15 -2
  235. package/lib/utils/animation/useVerticalExpandAnimation.js +28 -11
  236. package/lib/utils/children.js +134 -0
  237. package/lib/utils/index.js +163 -3
  238. package/lib/utils/info/index.js +19 -0
  239. package/lib/utils/info/platform/index.js +23 -0
  240. package/lib/utils/info/platform/platform.android.js +8 -0
  241. package/lib/utils/info/platform/platform.ios.js +8 -0
  242. package/lib/utils/info/platform/platform.js +8 -0
  243. package/lib/utils/info/platform/platform.native.js +11 -0
  244. package/lib/utils/info/versions.js +16 -0
  245. package/lib/utils/input.js +62 -38
  246. package/lib/utils/pressability.js +120 -0
  247. package/lib/utils/propTypes.js +360 -109
  248. package/lib/utils/useCopy.js +51 -0
  249. package/lib/utils/useHash.js +52 -0
  250. package/lib/utils/useHash.native.js +15 -0
  251. package/lib/utils/useResponsiveProp.js +59 -0
  252. package/lib/utils/useSpacingScale.js +135 -0
  253. package/lib/utils/useUniqueId.js +21 -0
  254. package/package.json +15 -14
  255. package/release-context.json +4 -4
  256. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
  257. package/src/Box/Box.jsx +180 -78
  258. package/src/Button/Button.jsx +9 -5
  259. package/src/Button/ButtonBase.jsx +74 -87
  260. package/src/Button/ButtonGroup.jsx +26 -43
  261. package/src/Button/ButtonLink.jsx +14 -4
  262. package/src/Button/propTypes.js +12 -2
  263. package/src/Card/Card.jsx +75 -0
  264. package/src/Card/CardBase.jsx +57 -0
  265. package/src/Card/PressableCardBase.jsx +112 -0
  266. package/src/Card/index.js +6 -0
  267. package/src/Checkbox/Checkbox.jsx +274 -0
  268. package/src/Checkbox/CheckboxGroup.jsx +196 -0
  269. package/src/Checkbox/CheckboxInput.jsx +55 -0
  270. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  271. package/src/Checkbox/index.js +5 -0
  272. package/src/Divider/Divider.jsx +38 -3
  273. package/src/ExpandCollapse/Control.jsx +3 -4
  274. package/src/ExpandCollapse/Panel.jsx +3 -3
  275. package/src/Feedback/Feedback.jsx +108 -0
  276. package/src/Feedback/index.js +3 -0
  277. package/src/Fieldset/Fieldset.jsx +129 -0
  278. package/src/Fieldset/FieldsetContainer.jsx +22 -0
  279. package/src/Fieldset/FieldsetContainer.native.jsx +16 -0
  280. package/src/Fieldset/Legend.jsx +16 -0
  281. package/src/Fieldset/Legend.native.jsx +22 -0
  282. package/src/Fieldset/cssReset.js +14 -0
  283. package/src/Fieldset/index.js +3 -0
  284. package/src/FlexGrid/Col/Col.jsx +4 -2
  285. package/src/HorizontalScroll/HorizontalScroll.jsx +165 -0
  286. package/src/HorizontalScroll/HorizontalScrollButton.jsx +108 -0
  287. package/src/HorizontalScroll/ScrollViewEnd.jsx +53 -0
  288. package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
  289. package/src/HorizontalScroll/dictionary.js +11 -0
  290. package/src/HorizontalScroll/index.js +17 -0
  291. package/src/HorizontalScroll/itemPositions.js +101 -0
  292. package/src/Icon/Icon.jsx +23 -27
  293. package/src/Icon/IconText.jsx +63 -0
  294. package/src/Icon/index.js +3 -2
  295. package/src/IconButton/IconButton.jsx +107 -0
  296. package/src/IconButton/index.js +3 -0
  297. package/src/InputLabel/InputLabel.jsx +124 -0
  298. package/src/InputLabel/LabelContent.jsx +23 -0
  299. package/src/InputLabel/LabelContent.native.jsx +6 -0
  300. package/src/InputLabel/index.js +3 -0
  301. package/src/InputSupports/InputSupports.jsx +75 -0
  302. package/src/InputSupports/index.js +3 -0
  303. package/src/InputSupports/propTypes.js +44 -0
  304. package/src/InputSupports/useInputSupports.js +30 -0
  305. package/src/Link/ChevronLink.jsx +28 -7
  306. package/src/Link/InlinePressable.jsx +37 -0
  307. package/src/Link/InlinePressable.native.jsx +73 -0
  308. package/src/Link/Link.jsx +17 -13
  309. package/src/Link/LinkBase.jsx +71 -146
  310. package/src/Link/TextButton.jsx +25 -11
  311. package/src/Link/index.js +2 -1
  312. package/src/List/List.jsx +47 -0
  313. package/src/List/ListItem.jsx +184 -0
  314. package/src/List/index.js +3 -0
  315. package/src/Modal/Modal.jsx +185 -0
  316. package/src/Modal/dictionary.js +9 -0
  317. package/src/Modal/index.js +3 -0
  318. package/src/Notification/Notification.jsx +161 -0
  319. package/src/Notification/dictionary.js +8 -0
  320. package/src/Notification/index.js +3 -0
  321. package/src/Pagination/PageButton.jsx +70 -0
  322. package/src/Pagination/Pagination.jsx +135 -0
  323. package/src/Pagination/SideButton.jsx +82 -0
  324. package/src/Pagination/dictionary.js +18 -0
  325. package/src/Pagination/index.js +3 -0
  326. package/src/Pagination/usePagination.js +69 -0
  327. package/src/Progress/Progress.jsx +77 -0
  328. package/src/Progress/ProgressBar.jsx +110 -0
  329. package/src/Progress/ProgressBarBackground.jsx +34 -0
  330. package/src/Progress/index.js +6 -0
  331. package/src/Radio/Radio.jsx +233 -0
  332. package/src/Radio/RadioButton.jsx +131 -0
  333. package/src/Radio/RadioGroup.jsx +199 -0
  334. package/src/Radio/RadioInput.jsx +57 -0
  335. package/src/Radio/RadioInput.native.jsx +6 -0
  336. package/src/Radio/index.js +5 -0
  337. package/src/RadioCard/RadioCard.jsx +191 -0
  338. package/src/RadioCard/RadioCardGroup.jsx +211 -0
  339. package/src/RadioCard/index.js +5 -0
  340. package/src/Search/Search.jsx +215 -0
  341. package/src/Search/dictionary.js +12 -0
  342. package/src/Search/index.js +3 -0
  343. package/src/Select/Group.jsx +15 -0
  344. package/src/Select/Group.native.jsx +14 -0
  345. package/src/Select/Item.jsx +11 -0
  346. package/src/Select/Item.native.jsx +10 -0
  347. package/src/Select/Picker.jsx +67 -0
  348. package/src/Select/Picker.native.jsx +108 -0
  349. package/src/Select/Select.jsx +286 -0
  350. package/src/Select/index.js +8 -0
  351. package/src/SideNav/Item.jsx +5 -5
  352. package/src/SideNav/ItemsGroup.jsx +11 -13
  353. package/src/SideNav/SideNav.jsx +2 -1
  354. package/src/Skeleton/Skeleton.jsx +98 -0
  355. package/src/Skeleton/index.js +3 -0
  356. package/src/Skeleton/skeleton.constant.js +3 -0
  357. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  358. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  359. package/src/Spacer/Spacer.jsx +91 -0
  360. package/src/Spacer/index.js +3 -0
  361. package/src/StackView/StackView.jsx +113 -0
  362. package/src/StackView/StackWrap.jsx +41 -0
  363. package/src/StackView/StackWrap.native.jsx +4 -0
  364. package/src/StackView/StackWrapBox.jsx +102 -0
  365. package/src/StackView/StackWrapGap.jsx +49 -0
  366. package/src/StackView/common.jsx +29 -0
  367. package/src/StackView/getStackedContent.jsx +112 -0
  368. package/src/StackView/index.js +6 -0
  369. package/src/StepTracker/Step.jsx +202 -0
  370. package/src/StepTracker/StepTracker.jsx +163 -0
  371. package/src/StepTracker/dictionary.js +10 -0
  372. package/src/StepTracker/index.js +3 -0
  373. package/src/Tabs/Tabs.jsx +92 -0
  374. package/src/Tabs/TabsItem.jsx +205 -0
  375. package/src/Tabs/index.js +3 -0
  376. package/src/Tags/Tags.jsx +207 -0
  377. package/src/Tags/index.js +3 -0
  378. package/src/TextInput/TextArea.jsx +78 -0
  379. package/src/TextInput/TextInput.jsx +52 -0
  380. package/src/TextInput/TextInputBase.jsx +211 -0
  381. package/src/TextInput/index.js +4 -0
  382. package/src/TextInput/propTypes.js +29 -0
  383. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  384. package/src/ThemeProvider/useSetTheme.js +4 -0
  385. package/src/ThemeProvider/useThemeTokens.js +85 -7
  386. package/src/ThemeProvider/utils/styles.js +18 -5
  387. package/src/ThemeProvider/utils/theme-tokens.js +106 -8
  388. package/src/ToggleSwitch/ToggleSwitch.jsx +25 -46
  389. package/src/Tooltip/Backdrop.jsx +60 -0
  390. package/src/Tooltip/Backdrop.native.jsx +33 -0
  391. package/src/Tooltip/Tooltip.jsx +294 -0
  392. package/src/Tooltip/dictionary.js +8 -0
  393. package/src/Tooltip/getTooltipPosition.js +161 -0
  394. package/src/Tooltip/index.js +3 -0
  395. package/src/TooltipButton/TooltipButton.jsx +49 -0
  396. package/src/TooltipButton/index.js +3 -0
  397. package/src/Typography/Typography.jsx +10 -24
  398. package/src/ViewportProvider/ViewportProvider.jsx +21 -0
  399. package/src/ViewportProvider/index.jsx +2 -41
  400. package/src/ViewportProvider/useViewport.js +5 -0
  401. package/src/ViewportProvider/useViewportListener.js +43 -0
  402. package/src/index.js +38 -1
  403. package/src/utils/a11y/index.js +1 -0
  404. package/src/utils/a11y/textSize.js +30 -0
  405. package/src/utils/children.jsx +119 -0
  406. package/src/utils/index.js +11 -0
  407. package/src/utils/info/index.js +8 -0
  408. package/src/utils/info/platform/index.js +11 -0
  409. package/src/utils/info/platform/platform.android.js +1 -0
  410. package/src/utils/info/platform/platform.ios.js +1 -0
  411. package/src/utils/info/platform/platform.js +1 -0
  412. package/src/utils/info/platform/platform.native.js +4 -0
  413. package/src/utils/info/versions.js +6 -0
  414. package/src/utils/input.js +38 -26
  415. package/src/utils/pressability.js +96 -0
  416. package/src/utils/propTypes.js +298 -66
  417. package/src/utils/useCopy.js +39 -0
  418. package/src/utils/useHash.js +39 -0
  419. package/src/utils/useHash.native.js +6 -0
  420. package/src/utils/useResponsiveProp.js +50 -0
  421. package/src/utils/useSpacingScale.js +108 -0
  422. package/src/utils/useUniqueId.js +14 -0
  423. package/stories/A11yText/A11yText.stories.jsx +15 -13
  424. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +11 -2
  425. package/stories/Box/Box.stories.jsx +46 -17
  426. package/stories/Button/Button.stories.jsx +21 -20
  427. package/stories/Button/ButtonGroup.stories.jsx +2 -1
  428. package/stories/Button/ButtonLink.stories.jsx +6 -4
  429. package/stories/Card/Card.stories.jsx +62 -0
  430. package/stories/Checkbox/Checkbox.stories.jsx +94 -0
  431. package/stories/Divider/Divider.stories.jsx +26 -2
  432. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +74 -79
  433. package/stories/Feedback/Feedback.stories.jsx +96 -0
  434. package/stories/FlexGrid/01 FlexGrid.stories.jsx +20 -7
  435. package/stories/Icon/Icon.stories.jsx +35 -7
  436. package/stories/IconButton/IconButton.stories.jsx +50 -0
  437. package/stories/InputLabel/InputLabel.stories.jsx +42 -0
  438. package/stories/Link/ChevronLink.stories.jsx +20 -4
  439. package/stories/Link/Link.stories.jsx +51 -20
  440. package/stories/Link/TextButton.stories.jsx +24 -3
  441. package/stories/List/List.stories.jsx +117 -0
  442. package/stories/Modal/Modal.stories.jsx +29 -0
  443. package/stories/Notification/Notification.stories.jsx +82 -0
  444. package/stories/Pagination/Pagination.stories.jsx +64 -0
  445. package/stories/Progress/Progress.stories.jsx +93 -0
  446. package/stories/Radio/Radio.stories.jsx +100 -0
  447. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  448. package/stories/Search/Search.stories.jsx +16 -0
  449. package/stories/Select/Select.stories.jsx +55 -0
  450. package/stories/SideNav/SideNav.stories.jsx +17 -2
  451. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  452. package/stories/Spacer/Spacer.stories.jsx +38 -0
  453. package/stories/StackView/StackView.stories.jsx +75 -0
  454. package/stories/StackView/StackWrap.stories.jsx +64 -0
  455. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  456. package/stories/Tabs/Tabs.stories.jsx +97 -0
  457. package/stories/Tags/Tags.stories.jsx +69 -0
  458. package/stories/TextInput/TextArea.stories.jsx +100 -0
  459. package/stories/TextInput/TextInput.stories.jsx +103 -0
  460. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +16 -3
  461. package/stories/Tooltip/Tooltip.stories.jsx +81 -0
  462. package/stories/TooltipButton/TooltipButton.stories.jsx +11 -0
  463. package/stories/Typography/Typography.stories.jsx +12 -3
  464. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  465. package/stories/supports.jsx +148 -14
  466. package/__fixtures__/accessible.icon.svg +0 -6
  467. package/docs/Contributing.stories.mdx +0 -9
  468. package/docs/Fonts.stories.mdx +0 -104
  469. package/docs/Icons.stories.mdx +0 -144
  470. package/docs/Introduction.stories.mdx +0 -9
  471. package/lib/ActivityIndicator/Spinner.web.js +0 -57
  472. package/lib/config/svgr-icons-web.js +0 -9
  473. package/lib/config/svgr-icons.js +0 -52
  474. package/src/config/svgr-icons-web.js +0 -11
  475. package/src/config/svgr-icons.js +0 -46
@@ -4,7 +4,7 @@ import Theme from '../../__fixtures__/Theme'
4
4
  import ActivityIndicator from '../../src/ActivityIndicator'
5
5
 
6
6
  // Used to remove the "Animated: `useNativeDriver` is not supported because the native animated module is missing." warnings
7
- jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper')
7
+ jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
8
8
 
9
9
  const render = (jsx) => baseRender(jsx, { wrapper: Theme })
10
10
 
@@ -1,30 +1,20 @@
1
1
  import React from 'react'
2
2
  import { Text } from 'react-native'
3
3
  import { render, fireEvent } from '@testing-library/react-native'
4
- import { viewports } from '@telus-uds/system-constants'
5
4
  import { Box } from '../../src'
6
5
  import Theme from '../../__fixtures__/Theme'
7
- import Viewport from '../../__fixtures__/Viewport'
8
- import testTheme from '../../__fixtures__/testTheme'
9
6
 
10
7
  const textContent = 'Some text content'
11
8
 
12
- function getSpacing(level, viewport) {
13
- const spacing = testTheme.components.Box.levels[viewport][level]
14
- if (typeof spacing !== 'number') {
15
- throw new Error(
16
- `Invalid spacing ${spacing} (${typeof spacing}) for level ${level}, viewport ${viewport}`
17
- )
18
- }
19
- return spacing
20
- }
9
+ // Based on testTheme
10
+ const expectedScale = [0, 4, 8, 16, 24, 32, 36]
21
11
 
22
12
  describe('Box', () => {
23
13
  it('is scrollable if scroll props provided', async () => {
24
14
  const onScroll = jest.fn()
25
15
  const { getByText } = render(
26
16
  <Theme>
27
- <Box scroll scrollProps={{ onScroll }}>
17
+ <Box scroll={{ onScroll }}>
28
18
  <Text>{textContent}</Text>
29
19
  </Box>
30
20
  </Theme>
@@ -36,53 +26,86 @@ describe('Box', () => {
36
26
  expect(onScroll).toHaveBeenCalledTimes(1)
37
27
  })
38
28
 
39
- // Test the style resolution in every viewport
40
- viewports.keys.forEach((viewport) => {
41
- it(`maps regular props to RN styles at viewport ${viewport}`, () => {
42
- const props = {
43
- top: 1,
44
- below: 2,
45
- bottom: 3,
46
- left: 4,
47
- right: 5
48
- }
49
- const { getByText } = render(
50
- <Theme>
51
- <Viewport viewport={viewport}>
52
- <Box {...props}>
53
- <Text>{textContent}</Text>
54
- </Box>
55
- </Viewport>
56
- </Theme>
57
- )
58
- expect(getByText(textContent).parent).toHaveStyle({
59
- paddingTop: getSpacing(1, viewport),
60
- marginBottom: getSpacing(2, viewport),
61
- paddingBottom: getSpacing(3, viewport),
62
- paddingLeft: getSpacing(4, viewport),
63
- paddingRight: getSpacing(5, viewport)
64
- })
29
+ it('maps regular props to RN styles', () => {
30
+ const props = {
31
+ top: 1,
32
+ bottom: 2,
33
+ left: 3,
34
+ right: 4
35
+ }
36
+ const { getByText } = render(
37
+ <Theme>
38
+ <Box {...props}>
39
+ <Text>{textContent}</Text>
40
+ </Box>
41
+ </Theme>
42
+ )
43
+ expect(getByText(textContent).parent).toHaveStyle({
44
+ paddingTop: expectedScale[1],
45
+ paddingBottom: expectedScale[2],
46
+ paddingLeft: expectedScale[3],
47
+ paddingRight: expectedScale[4]
48
+ })
49
+ })
50
+
51
+ it(`maps horizontal and vertical props to RN styles`, () => {
52
+ const props = {
53
+ horizontal: 1,
54
+ vertical: 2
55
+ }
56
+ const { getByText } = render(
57
+ <Theme>
58
+ <Box {...props}>
59
+ <Text>{textContent}</Text>
60
+ </Box>
61
+ </Theme>
62
+ )
63
+ expect(getByText(textContent).parent).toHaveStyle({
64
+ paddingLeft: expectedScale[1],
65
+ paddingRight: expectedScale[1],
66
+ paddingTop: expectedScale[2],
67
+ paddingBottom: expectedScale[2]
68
+ })
69
+ })
70
+
71
+ it(`maps all-sides space prop to RN styles`, () => {
72
+ const props = {
73
+ space: 3
74
+ }
75
+ const { getByText } = render(
76
+ <Theme>
77
+ <Box {...props}>
78
+ <Text>{textContent}</Text>
79
+ </Box>
80
+ </Theme>
81
+ )
82
+ expect(getByText(textContent).parent).toHaveStyle({
83
+ paddingLeft: expectedScale[3],
84
+ paddingRight: expectedScale[3],
85
+ paddingTop: expectedScale[3],
86
+ paddingBottom: expectedScale[3]
65
87
  })
88
+ })
66
89
 
67
- it(`maps shorthand props to RN styles at viewport ${viewport}`, () => {
68
- const props = {
69
- horizontal: 6,
70
- vertical: 7
71
- }
72
- const { getByText } = render(
73
- <Theme>
74
- <Viewport viewport={viewport}>
75
- <Box {...props}>
76
- <Text>{textContent}</Text>
77
- </Box>
78
- </Viewport>
79
- </Theme>
80
- )
81
- expect(getByText(textContent).parent).toHaveStyle({
82
- // Can't test for paddingTop etc - .toHaveStyle isn't that smart
83
- paddingHorizontal: getSpacing(6, viewport),
84
- paddingVertical: getSpacing(7, viewport)
85
- })
90
+ it(`applies side overrides in increasing specificity`, () => {
91
+ const props = {
92
+ space: 1,
93
+ horizontal: 2,
94
+ top: 3,
95
+ right: 4
96
+ }
97
+ const { getByText } = render(
98
+ <Theme>
99
+ <Box {...props}>
100
+ <Text>{textContent}</Text>
101
+ </Box>
102
+ </Theme>
103
+ )
104
+ expect(getByText(textContent).parent).toHaveStyle({
105
+ paddingLeft: expectedScale[2],
106
+ paddingRight: expectedScale[4],
107
+ paddingTop: expectedScale[3],
108
+ paddingBottom: expectedScale[1]
86
109
  })
87
110
  })
88
111
  })
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-console */
2
1
  import React from 'react'
3
2
  import { render } from '@testing-library/react-native'
4
3
  import { Platform, Text } from 'react-native'
@@ -9,41 +8,13 @@ import ButtonBase from '../../src/Button/ButtonBase'
9
8
 
10
9
  beforeEach(() => jest.clearAllMocks())
11
10
 
12
- describe('ButtonBase', () => {
13
- it('throws if both href and onPress are provided', async () => {
14
- jest.spyOn(console, 'error').mockImplementation()
15
- expect(() =>
16
- render(
17
- <Theme>
18
- <ButtonBase href="example.com" onPress={jest.fn()}>
19
- click me
20
- </ButtonBase>
21
- </Theme>
22
- )
23
- ).toThrow()
24
- expect(console.error).toHaveBeenCalledTimes(1)
25
- })
26
-
27
- it('throws if neither href nor onPress are provided', async () => {
28
- jest.spyOn(console, 'error').mockImplementation()
29
- expect(() =>
30
- render(
31
- <Theme>
32
- <ButtonBase>click me</ButtonBase>
33
- </Theme>
34
- )
35
- ).toThrow()
36
- expect(console.error).toHaveBeenCalledTimes(1)
37
- })
38
- })
39
-
40
11
  describe('ButtonBase with render function child', () => {
41
- it('recieves text styles in render function from button theme', () => {
12
+ it('receives tokens in render function child', () => {
42
13
  const { tokens } = testTheme.components.Button
43
- const arbitraryWeight = '123'
14
+ const arbitraryWeight = '300'
44
15
  const { getByText } = render(
45
16
  <Theme>
46
- <ButtonBase onPress={() => {}} tokens={{ fontWeight: arbitraryWeight }}>
17
+ <ButtonBase onPress={() => {}} tokens={{ ...tokens, fontWeight: arbitraryWeight }}>
47
18
  {({ textStyles }) => <Text style={textStyles}>Function child</Text>}
48
19
  </ButtonBase>
49
20
  </Theme>
@@ -106,7 +106,7 @@ describe('ButtonGroup (uncontrolled)', () => {
106
106
  </Theme>
107
107
  )
108
108
  expect(queryAllByA11yRole('checkbox')).toHaveLength(0)
109
- expect(queryAllByA11yRole('radioGroup')).toHaveLength(1)
109
+ expect(queryAllByA11yRole('radiogroup')).toHaveLength(1)
110
110
  const radios = queryAllByA11yRole('radio')
111
111
  expect(radios).toHaveLength(4)
112
112
 
@@ -158,7 +158,7 @@ describe('ButtonGroup (uncontrolled)', () => {
158
158
  </Theme>
159
159
  )
160
160
 
161
- expect(queryAllByA11yRole('radioGroup')).toHaveLength(0)
161
+ expect(queryAllByA11yRole('radiogroup')).toHaveLength(0)
162
162
  expect(queryAllByA11yRole('radio')).toHaveLength(0)
163
163
 
164
164
  const checks = queryAllByA11yRole('checkbox')
@@ -253,15 +253,14 @@ describe('ButtonGroup (controlled)', () => {
253
253
  expect(handleChange).toHaveBeenCalledTimes(0)
254
254
 
255
255
  const one = getByText('One')
256
- await fireEvent.press(one)
256
+ await fireEvent(one, 'press', { nativeEvent: 'example' })
257
257
  expect(handleChange).toHaveBeenCalledTimes(1)
258
-
259
- expect(handleChange.mock.calls[0][0]).toEqual(['one'])
258
+ expect(handleChange).toHaveBeenLastCalledWith(['one'], { nativeEvent: 'example' })
260
259
 
261
260
  const two = getByText('Two')
262
- await fireEvent.press(two)
261
+ await fireEvent(two, 'press', { nativeEvent: 'example2' })
263
262
  expect(handleChange).toHaveBeenCalledTimes(2)
264
- expect(handleChange.mock.calls[1][0]).toEqual(['two'])
263
+ expect(handleChange).toHaveBeenLastCalledWith(['two'], { nativeEvent: 'example2' })
265
264
  })
266
265
 
267
266
  it("Doesn't change its own selection if `values` is passed", async () => {
@@ -0,0 +1,63 @@
1
+ import React from 'react'
2
+ import { render } from '@testing-library/react-native'
3
+ import { Text } from 'react-native'
4
+
5
+ import { Card } from '../../src'
6
+ import Theme from '../../__fixtures__/Theme'
7
+ import testTheme from '../../__fixtures__/testTheme'
8
+
9
+ const contentText = 'This is a card'
10
+
11
+ const setup = ({ tokens } = {}) =>
12
+ render(
13
+ <Theme>
14
+ <Card tokens={tokens}>
15
+ <Text>{contentText}</Text>
16
+ </Card>
17
+ </Theme>
18
+ )
19
+
20
+ describe('Card', () => {
21
+ it('renders the card content', () => {
22
+ const { getByText } = setup()
23
+ const cardContent = getByText(contentText)
24
+ expect(cardContent).toBeTruthy()
25
+ })
26
+
27
+ it('renders the default style properly', () => {
28
+ const defaultStyle = testTheme.components.Card.tokens
29
+ const { getByText } = setup()
30
+ const card = getByText(contentText).parent
31
+ expect(card).toHaveStyle(defaultStyle)
32
+ })
33
+
34
+ it('renders a card with a custom background color', () => {
35
+ const backgroundColor = '#0F0F0F'
36
+ const { getByText } = setup({ tokens: { backgroundColor } })
37
+ const card = getByText(contentText).parent
38
+ expect(card).toHaveStyle({ backgroundColor })
39
+ })
40
+
41
+ it('renders a card with a custom border', () => {
42
+ const border = {
43
+ borderColor: '#123456',
44
+ borderWidth: 7,
45
+ borderRadius: 8
46
+ }
47
+ const { getByText } = setup({ tokens: { ...border } })
48
+ const card = getByText(contentText).parent
49
+ expect(card).toHaveStyle({ ...border })
50
+ })
51
+
52
+ it('renders a card with a custom padding', () => {
53
+ const padding = {
54
+ paddingBottom: 1,
55
+ paddingLeft: 2,
56
+ paddingRight: 3,
57
+ paddingTop: 4
58
+ }
59
+ const { getByText } = setup({ tokens: { ...padding } })
60
+ const card = getByText(contentText).parent
61
+ expect(card).toHaveStyle({ ...padding })
62
+ })
63
+ })
@@ -0,0 +1,94 @@
1
+ import React from 'react'
2
+ import { fireEvent, render } from '@testing-library/react-native'
3
+
4
+ import { Checkbox } from '../../src'
5
+ import Theme from '../../__fixtures__/Theme'
6
+
7
+ const checkedId = 'Checkbox-Icon'
8
+ const inputId = 'Checkbox-Input'
9
+ const setup = (props) =>
10
+ render(
11
+ <Theme>
12
+ <Checkbox {...props} />
13
+ </Theme>
14
+ )
15
+
16
+ describe('Checkbox', () => {
17
+ it('renders with defaults', () => {
18
+ const { getByRole } = setup()
19
+
20
+ expect(getByRole('checkbox')).toBeTruthy()
21
+ })
22
+
23
+ it('renders the label', () => {
24
+ const label = 'Test label message'
25
+ const { queryByText } = setup({ label })
26
+
27
+ expect(queryByText(label)).toBeTruthy()
28
+ })
29
+
30
+ it('renders the feedback', () => {
31
+ const feedback = 'Test feedback message'
32
+ const { queryByText } = setup({ feedback })
33
+
34
+ expect(queryByText(feedback)).toBeTruthy()
35
+ })
36
+
37
+ it('renders error styling on validation failure', () => {
38
+ const errorBorderColor = '#e12339' // from __fixtures__/testTheme.js
39
+ const { getByTestId } = setup({ error: true })
40
+
41
+ const checkboxInput = getByTestId(inputId)
42
+ expect(checkboxInput).toHaveStyle({ borderColor: errorBorderColor })
43
+ })
44
+
45
+ it('triggers the callback', () => {
46
+ const onChange = jest.fn()
47
+
48
+ const { getByRole } = setup({ onChange })
49
+
50
+ const checkbox = getByRole('checkbox')
51
+ expect(onChange).not.toHaveBeenCalled()
52
+ fireEvent(checkbox, 'press')
53
+ expect(onChange).toHaveBeenCalledTimes(1)
54
+ })
55
+
56
+ it('cannot be changed if inactive', () => {
57
+ const { getByRole, queryByTestId } = setup({ inactive: true })
58
+
59
+ const checkbox = getByRole('checkbox')
60
+ expect(queryByTestId(checkedId)).toBeFalsy()
61
+ fireEvent(checkbox, 'press')
62
+ expect(queryByTestId(checkedId)).toBeFalsy()
63
+ })
64
+
65
+ describe('when uncontrolled', () => {
66
+ it('uses `defaultChecked` as the initial value', () => {
67
+ const { queryByTestId } = setup({ defaultChecked: true })
68
+
69
+ expect(queryByTestId(checkedId)).toBeTruthy()
70
+ })
71
+
72
+ it('changes value', () => {
73
+ const { getByRole, queryByTestId } = setup({ defaultChecked: false })
74
+
75
+ const checkbox = getByRole('checkbox')
76
+ expect(queryByTestId(checkedId)).toBeFalsy()
77
+ fireEvent(checkbox, 'press')
78
+ expect(queryByTestId(checkedId)).toBeTruthy()
79
+ })
80
+ })
81
+
82
+ describe('when controlled', () => {
83
+ it('calls `onChange` with the new value', () => {
84
+ const onChange = jest.fn()
85
+ const { getByRole, queryByTestId } = setup({ onChange, checked: false })
86
+
87
+ const checkbox = getByRole('checkbox')
88
+ expect(queryByTestId(checkedId)).toBeFalsy()
89
+ fireEvent(checkbox, 'press', { nativeEvent: 'example' })
90
+ expect(onChange).toHaveBeenCalledTimes(1)
91
+ expect(onChange).toHaveBeenCalledWith(true, { nativeEvent: 'example' })
92
+ })
93
+ })
94
+ })
@@ -0,0 +1,246 @@
1
+ import React from 'react'
2
+ import { render, fireEvent } from '@testing-library/react-native'
3
+ import { toHaveTextContent } from '@testing-library/jest-native'
4
+
5
+ import Theme from '../../__fixtures__/Theme'
6
+ import CheckboxGroup from '../../src/Checkbox/CheckboxGroup'
7
+
8
+ const items = [
9
+ { label: 'One', id: 'one' },
10
+ { label: 'Two', id: 'two' },
11
+ { label: 'Three', id: 'three' },
12
+ { label: 'Four', id: 'four' }
13
+ ]
14
+ const checked = { checked: true }
15
+
16
+ // expect().toHaveTextContent doesn't work on arrays, expect().toContain etc doesn't match elements
17
+ const containsText = (queryResult, text) =>
18
+ queryResult.some((testInstance) => toHaveTextContent(testInstance, text).pass)
19
+
20
+ describe('CheckboxGroup', () => {
21
+ // eslint-disable-next-line no-console
22
+ const consoleError = console.error
23
+ beforeEach(() => {
24
+ // eslint-disable-next-line no-console
25
+ console.error = () => {}
26
+ })
27
+ afterEach(() => {
28
+ // eslint-disable-next-line no-console
29
+ console.error = consoleError
30
+ })
31
+
32
+ it('Throws if has `checkedIds` without `onChange`', () => {
33
+ expect(() =>
34
+ render(
35
+ <Theme>
36
+ <CheckboxGroup items={items} checkedIds={['one']} />
37
+ </Theme>
38
+ )
39
+ ).toThrow(/values.+without.+onChange/)
40
+ })
41
+ it("Doesn't throw if has `checkedIds` without `onChange` and is read only", () => {
42
+ expect(() =>
43
+ render(
44
+ <Theme>
45
+ <CheckboxGroup items={items} checkedIds={['one']} readOnly />
46
+ </Theme>
47
+ )
48
+ ).not.toThrow()
49
+ })
50
+ it('Throws if has both `checkedIds` and `initialCheckedIds`', () => {
51
+ expect(() =>
52
+ render(
53
+ <Theme>
54
+ <CheckboxGroup
55
+ items={items}
56
+ checkedIds={['one']}
57
+ initialCheckedIds={['one']}
58
+ onChange={() => {}}
59
+ />
60
+ </Theme>
61
+ )
62
+ ).toThrow(/both(?=.*initialValues)(?=.*values){2}/)
63
+ })
64
+ })
65
+
66
+ describe('CheckboxGroup (uncontrolled)', () => {
67
+ it('Selects unlimited items', async () => {
68
+ const { getByText, queryAllByA11yState } = render(
69
+ <Theme>
70
+ <CheckboxGroup items={items} />
71
+ </Theme>
72
+ )
73
+
74
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
75
+
76
+ const one = getByText('One')
77
+ await fireEvent.press(one)
78
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
79
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
80
+
81
+ const two = getByText('Two')
82
+ await fireEvent.press(two)
83
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
84
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
85
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
86
+
87
+ const three = getByText('Three')
88
+ await fireEvent.press(three)
89
+ expect(queryAllByA11yState(checked)).toHaveLength(3)
90
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
91
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
92
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
93
+
94
+ const four = getByText('Four')
95
+ await fireEvent.press(four)
96
+ expect(queryAllByA11yState(checked)).toHaveLength(4)
97
+ expect(containsText(queryAllByA11yState(checked), 'Four')).toBeTruthy()
98
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
99
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
100
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
101
+ })
102
+
103
+ it('Deselects if the selected item is pressed', async () => {
104
+ const { getByText, queryAllByA11yState } = render(
105
+ <Theme>
106
+ <CheckboxGroup items={items} />
107
+ </Theme>
108
+ )
109
+
110
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
111
+
112
+ const three = getByText('Three')
113
+ await fireEvent.press(three)
114
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
115
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
116
+
117
+ await fireEvent.press(three)
118
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
119
+ expect(containsText(queryAllByA11yState(checked), 'Three')).not.toBeTruthy()
120
+ })
121
+
122
+ it('Is accessible as checkboxes button', async () => {
123
+ const { queryAllByA11yRole, queryAllByA11yState } = render(
124
+ <Theme>
125
+ <CheckboxGroup items={items} />
126
+ </Theme>
127
+ )
128
+
129
+ expect(queryAllByA11yRole('radiogroup')).toHaveLength(0)
130
+ expect(queryAllByA11yRole('radio')).toHaveLength(0)
131
+
132
+ const checks = queryAllByA11yRole('checkbox')
133
+ expect(checks).toHaveLength(4)
134
+
135
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
136
+ await fireEvent.press(checks[0])
137
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
138
+ })
139
+
140
+ it('Auto-selects any provided initialCheckedIds', async () => {
141
+ const { getByText, queryAllByA11yState } = render(
142
+ <Theme>
143
+ <CheckboxGroup items={items} initialCheckedIds={['one', 'two']} />
144
+ </Theme>
145
+ )
146
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
147
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
148
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
149
+
150
+ const three = getByText('Three')
151
+ await fireEvent.press(three)
152
+
153
+ expect(queryAllByA11yState(checked)).toHaveLength(3)
154
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
155
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
156
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
157
+ })
158
+ })
159
+
160
+ describe('CheckboxGroup (controlled)', () => {
161
+ it('Calls onChange handler on press in controlled mode, providing pressed id', async () => {
162
+ const handleChange = jest.fn((arg) => arg)
163
+ const { getByText } = render(
164
+ <Theme>
165
+ <CheckboxGroup items={items} checkedIds={[]} onChange={handleChange} />
166
+ </Theme>
167
+ )
168
+
169
+ expect(handleChange).toHaveBeenCalledTimes(0)
170
+
171
+ const one = getByText('One')
172
+ await fireEvent(one, 'press', { nativeEvent: 'example' })
173
+ expect(handleChange).toHaveBeenCalledTimes(1)
174
+ expect(handleChange).toHaveBeenLastCalledWith(['one'], { nativeEvent: 'example' })
175
+
176
+ const two = getByText('Two')
177
+ await fireEvent(two, 'press', { nativeEvent: 'example2' })
178
+ expect(handleChange).toHaveBeenCalledTimes(2)
179
+ expect(handleChange).toHaveBeenLastCalledWith(['two'], { nativeEvent: 'example2' })
180
+ })
181
+
182
+ it("Doesn't change its own selection if `checkedIds` is passed", async () => {
183
+ const { getByText, queryAllByA11yState } = render(
184
+ <Theme>
185
+ <CheckboxGroup items={items} checkedIds={['one']} onChange={() => {}} />
186
+ </Theme>
187
+ )
188
+
189
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
190
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
191
+
192
+ const one = getByText('One')
193
+ await fireEvent.press(one)
194
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
195
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
196
+
197
+ const two = getByText('Two')
198
+ await fireEvent.press(two)
199
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
200
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
201
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
202
+ })
203
+ })
204
+
205
+ describe('CheckboxGroup (read-only)', () => {
206
+ it("Doesn't call onChange handler when read-only", async () => {
207
+ const handleChange = jest.fn((arg) => arg)
208
+ const { getByText } = render(
209
+ <Theme>
210
+ <CheckboxGroup items={items} checkedIds={[]} onChange={handleChange} readOnly />
211
+ </Theme>
212
+ )
213
+
214
+ expect(handleChange).toHaveBeenCalledTimes(0)
215
+
216
+ const one = getByText('One')
217
+ await fireEvent.press(one)
218
+ expect(handleChange).toHaveBeenCalledTimes(0)
219
+
220
+ const two = getByText('Two')
221
+ await fireEvent.press(two)
222
+ expect(handleChange).toHaveBeenCalledTimes(0)
223
+ })
224
+
225
+ it("Doesn't change its selection on press", async () => {
226
+ const { getByText, queryAllByA11yState } = render(
227
+ <Theme>
228
+ <CheckboxGroup items={items} checkedIds={['one']} readOnly />
229
+ </Theme>
230
+ )
231
+
232
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
233
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
234
+
235
+ const one = getByText('One')
236
+ await fireEvent.press(one)
237
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
238
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
239
+
240
+ const two = getByText('Two')
241
+ await fireEvent.press(two)
242
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
243
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
244
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
245
+ })
246
+ })