@telus-uds/components-base 0.0.2-prerelease.4 → 0.0.2-prerelease.8

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 (447) hide show
  1. package/.ultra.cache.json +1 -0
  2. package/CHANGELOG.md +76 -0
  3. package/__fixtures__/Accessible.js +33 -0
  4. package/__fixtures__/Accessible.native.js +32 -0
  5. package/__fixtures__/testTheme.js +940 -54
  6. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  7. package/__tests__/Button/ButtonBase.test.jsx +3 -32
  8. package/__tests__/Button/ButtonGroup.test.jsx +2 -2
  9. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  10. package/__tests__/Checkbox/CheckboxGroup.test.jsx +247 -0
  11. package/__tests__/Divider/Divider.test.jsx +26 -5
  12. package/__tests__/Feedback/Feedback.test.jsx +42 -0
  13. package/__tests__/Icon/Icon.test.jsx +3 -3
  14. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  15. package/__tests__/List/List.test.jsx +60 -0
  16. package/__tests__/Modal/Modal.test.jsx +47 -0
  17. package/__tests__/Notification/Notification.test.jsx +20 -0
  18. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  19. package/__tests__/Progress/Progress.test.jsx +79 -0
  20. package/__tests__/Radio/Radio.test.jsx +87 -0
  21. package/__tests__/Radio/RadioGroup.test.jsx +221 -0
  22. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  23. package/__tests__/RadioCard/RadioCardGroup.test.jsx +247 -0
  24. package/__tests__/Search/Search.test.jsx +72 -0
  25. package/__tests__/Select/Select.test.jsx +93 -0
  26. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  27. package/__tests__/Spacer/Spacer.test.jsx +63 -0
  28. package/__tests__/StackView/StackView.test.jsx +216 -0
  29. package/__tests__/StackView/StackWrap.test.jsx +47 -0
  30. package/__tests__/StackView/getStackedContent.test.jsx +295 -0
  31. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  32. package/__tests__/Tabs/Tabs.test.jsx +200 -0
  33. package/__tests__/Tags/Tags.test.jsx +328 -0
  34. package/__tests__/TextInput/TextArea.test.jsx +34 -0
  35. package/__tests__/TextInput/TextInputBase.test.jsx +120 -0
  36. package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
  37. package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
  38. package/__tests__/utils/input.test.js +58 -0
  39. package/__tests__/utils/useCopy.test.js +42 -0
  40. package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
  41. package/__tests__/utils/{spacing.test.jsx → useSpacingScale.test.jsx} +1 -1
  42. package/__tests__/utils/useUniqueId.test.js +31 -0
  43. package/babel.config.js +20 -0
  44. package/jest.config.js +8 -2
  45. package/lib/A11yInfoProvider/index.js +54 -26
  46. package/lib/A11yText/index.js +37 -14
  47. package/lib/ActivityIndicator/Spinner.js +78 -0
  48. package/lib/ActivityIndicator/Spinner.native.js +121 -87
  49. package/lib/ActivityIndicator/index.js +28 -12
  50. package/lib/ActivityIndicator/shared.js +27 -12
  51. package/lib/BaseProvider/index.js +34 -11
  52. package/lib/Box/Box.js +56 -28
  53. package/lib/Box/index.js +13 -2
  54. package/lib/Button/Button.js +38 -10
  55. package/lib/Button/ButtonBase.js +120 -109
  56. package/lib/Button/ButtonGroup.js +98 -99
  57. package/lib/Button/ButtonLink.js +41 -13
  58. package/lib/Button/index.js +31 -4
  59. package/lib/Button/propTypes.js +32 -9
  60. package/lib/Card/Card.js +36 -41
  61. package/lib/Card/CardBase.js +78 -0
  62. package/lib/Card/PressableCardBase.js +137 -0
  63. package/lib/Card/index.js +40 -2
  64. package/lib/Checkbox/Checkbox.js +344 -0
  65. package/lib/Checkbox/CheckboxGroup.js +231 -0
  66. package/lib/Checkbox/CheckboxInput.js +74 -0
  67. package/lib/Checkbox/CheckboxInput.native.js +14 -0
  68. package/lib/Checkbox/index.js +21 -0
  69. package/lib/Divider/Divider.js +81 -17
  70. package/lib/Divider/index.js +13 -2
  71. package/lib/ExpandCollapse/Accordion.js +20 -7
  72. package/lib/ExpandCollapse/Control.js +50 -27
  73. package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
  74. package/lib/ExpandCollapse/Panel.js +75 -37
  75. package/lib/ExpandCollapse/index.js +25 -7
  76. package/lib/Feedback/Feedback.js +161 -0
  77. package/lib/Feedback/index.js +13 -0
  78. package/lib/Fieldset/Fieldset.js +160 -0
  79. package/lib/Fieldset/FieldsetContainer.js +41 -0
  80. package/lib/Fieldset/FieldsetContainer.native.js +33 -0
  81. package/lib/Fieldset/Legend.js +33 -0
  82. package/lib/Fieldset/Legend.native.js +43 -0
  83. package/lib/Fieldset/cssReset.js +21 -0
  84. package/lib/Fieldset/index.js +13 -0
  85. package/lib/FlexGrid/Col/Col.js +67 -38
  86. package/lib/FlexGrid/Col/index.js +13 -2
  87. package/lib/FlexGrid/FlexGrid.js +70 -45
  88. package/lib/FlexGrid/Row/Row.js +48 -27
  89. package/lib/FlexGrid/Row/index.js +13 -2
  90. package/lib/FlexGrid/helpers/index.js +9 -1
  91. package/lib/FlexGrid/index.js +13 -2
  92. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  93. package/lib/Icon/Icon.js +52 -47
  94. package/lib/Icon/IconText.js +100 -0
  95. package/lib/Icon/index.js +31 -3
  96. package/lib/InputLabel/InputLabel.js +122 -0
  97. package/lib/InputLabel/LabelContent.js +31 -0
  98. package/lib/InputLabel/LabelContent.native.js +16 -0
  99. package/lib/InputLabel/index.js +13 -0
  100. package/lib/InputSupports/InputSupports.js +104 -0
  101. package/lib/InputSupports/index.js +13 -0
  102. package/lib/InputSupports/propTypes.js +66 -0
  103. package/lib/InputSupports/useInputSupports.js +41 -0
  104. package/lib/Link/ChevronLink.js +57 -15
  105. package/lib/Link/InlinePressable.js +50 -0
  106. package/lib/Link/InlinePressable.native.js +101 -0
  107. package/lib/Link/Link.js +30 -13
  108. package/lib/Link/LinkBase.js +121 -146
  109. package/lib/Link/TextButton.js +47 -17
  110. package/lib/Link/index.js +39 -4
  111. package/lib/List/List.js +80 -0
  112. package/lib/List/ListItem.js +237 -0
  113. package/lib/List/index.js +13 -0
  114. package/lib/Modal/Modal.js +226 -0
  115. package/lib/Modal/dictionary.js +16 -0
  116. package/lib/Modal/index.js +13 -0
  117. package/lib/Notification/Notification.js +200 -0
  118. package/lib/Notification/dictionary.js +15 -0
  119. package/lib/Notification/index.js +13 -0
  120. package/lib/Pagination/PageButton.js +45 -46
  121. package/lib/Pagination/Pagination.js +70 -40
  122. package/lib/Pagination/SideButton.js +74 -58
  123. package/lib/Pagination/dictionary.js +9 -2
  124. package/lib/Pagination/index.js +13 -2
  125. package/lib/Pagination/usePagination.js +12 -2
  126. package/lib/Progress/Progress.js +99 -0
  127. package/lib/Progress/ProgressBar.js +146 -0
  128. package/lib/Progress/ProgressBarBackground.js +57 -0
  129. package/lib/Progress/index.js +16 -0
  130. package/lib/Radio/Radio.js +292 -0
  131. package/lib/Radio/RadioButton.js +141 -0
  132. package/lib/Radio/RadioGroup.js +233 -0
  133. package/lib/Radio/RadioInput.js +76 -0
  134. package/lib/Radio/RadioInput.native.js +14 -0
  135. package/lib/Radio/index.js +21 -0
  136. package/lib/RadioCard/RadioCard.js +240 -0
  137. package/lib/RadioCard/RadioCardGroup.js +251 -0
  138. package/lib/RadioCard/index.js +21 -0
  139. package/lib/Search/Search.js +243 -0
  140. package/lib/Search/dictionary.js +19 -0
  141. package/lib/Search/index.js +13 -0
  142. package/lib/Select/Group.js +33 -0
  143. package/lib/Select/Group.native.js +25 -0
  144. package/lib/Select/Item.js +29 -0
  145. package/lib/Select/Item.native.js +19 -0
  146. package/lib/Select/Picker.js +79 -0
  147. package/lib/Select/Picker.native.js +115 -0
  148. package/lib/Select/Select.js +300 -0
  149. package/lib/Select/index.js +19 -0
  150. package/lib/SideNav/Item.js +54 -33
  151. package/lib/SideNav/ItemContent.js +41 -15
  152. package/lib/SideNav/ItemsGroup.js +46 -27
  153. package/lib/SideNav/SideNav.js +92 -69
  154. package/lib/SideNav/index.js +15 -1
  155. package/lib/Skeleton/Skeleton.js +137 -0
  156. package/lib/Skeleton/index.js +13 -0
  157. package/lib/Skeleton/skeleton.constant.js +12 -0
  158. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  159. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  160. package/lib/Spacer/Spacer.js +117 -0
  161. package/lib/Spacer/index.js +13 -0
  162. package/lib/StackView/StackView.js +129 -0
  163. package/lib/StackView/StackWrap.js +55 -0
  164. package/lib/StackView/StackWrap.native.js +14 -0
  165. package/lib/StackView/StackWrapBox.js +112 -0
  166. package/lib/StackView/StackWrapGap.js +71 -0
  167. package/lib/StackView/common.js +45 -0
  168. package/lib/StackView/getStackedContent.js +141 -0
  169. package/lib/StackView/index.js +29 -0
  170. package/lib/StepTracker/Step.js +245 -0
  171. package/lib/StepTracker/StepTracker.js +197 -0
  172. package/lib/StepTracker/dictionary.js +17 -0
  173. package/lib/StepTracker/index.js +13 -0
  174. package/lib/Tabs/HorizontalScroll.js +199 -0
  175. package/lib/Tabs/ScrollViewEnd.js +66 -0
  176. package/lib/Tabs/ScrollViewEnd.native.js +41 -0
  177. package/lib/Tabs/Tabs.js +117 -0
  178. package/lib/Tabs/TabsItem.js +234 -0
  179. package/lib/Tabs/TabsScrollButton.js +121 -0
  180. package/lib/Tabs/dictionary.js +18 -0
  181. package/lib/Tabs/index.js +13 -0
  182. package/lib/Tabs/itemPositions.js +128 -0
  183. package/lib/Tags/Tags.js +250 -0
  184. package/lib/Tags/index.js +13 -0
  185. package/lib/TextInput/TextArea.js +109 -0
  186. package/lib/TextInput/TextInput.js +75 -0
  187. package/lib/TextInput/TextInputBase.js +252 -0
  188. package/lib/TextInput/index.js +23 -0
  189. package/lib/TextInput/propTypes.js +42 -0
  190. package/lib/ThemeProvider/ThemeProvider.js +38 -14
  191. package/lib/ThemeProvider/index.js +61 -6
  192. package/lib/ThemeProvider/useSetTheme.js +14 -5
  193. package/lib/ThemeProvider/useTheme.js +13 -4
  194. package/lib/ThemeProvider/useThemeTokens.js +86 -19
  195. package/lib/ThemeProvider/utils/index.js +31 -2
  196. package/lib/ThemeProvider/utils/styles.js +52 -16
  197. package/lib/ThemeProvider/utils/theme-tokens.js +94 -16
  198. package/lib/ToggleSwitch/ToggleSwitch.js +76 -52
  199. package/lib/ToggleSwitch/index.js +13 -2
  200. package/lib/Tooltip/Backdrop.js +56 -0
  201. package/lib/Tooltip/Backdrop.native.js +59 -0
  202. package/lib/Tooltip/Tooltip.js +357 -0
  203. package/lib/Tooltip/dictionary.js +15 -0
  204. package/lib/Tooltip/getTooltipPosition.js +172 -0
  205. package/lib/Tooltip/index.js +13 -0
  206. package/lib/TooltipButton/TooltipButton.js +83 -0
  207. package/lib/TooltipButton/index.js +13 -0
  208. package/lib/Typography/Typography.js +58 -47
  209. package/lib/Typography/index.js +13 -2
  210. package/lib/ViewportProvider/ViewportProvider.js +46 -0
  211. package/lib/ViewportProvider/index.js +22 -38
  212. package/lib/ViewportProvider/useViewport.js +15 -0
  213. package/lib/ViewportProvider/useViewportListener.js +57 -0
  214. package/lib/index.js +509 -19
  215. package/lib/utils/a11y/index.js +18 -0
  216. package/lib/utils/a11y/textSize.js +49 -0
  217. package/lib/utils/animation/index.js +15 -2
  218. package/lib/utils/animation/useVerticalExpandAnimation.js +28 -11
  219. package/lib/utils/children.js +87 -0
  220. package/lib/utils/index.js +163 -4
  221. package/lib/utils/info/index.js +19 -0
  222. package/lib/utils/info/platform/index.js +23 -0
  223. package/lib/utils/info/platform/platform.android.js +8 -0
  224. package/lib/utils/info/platform/platform.ios.js +8 -0
  225. package/lib/utils/info/platform/platform.js +8 -0
  226. package/lib/utils/info/platform/platform.native.js +11 -0
  227. package/lib/utils/info/versions.js +16 -0
  228. package/lib/utils/input.js +54 -34
  229. package/lib/utils/pressability.js +120 -0
  230. package/lib/utils/propTypes.js +269 -108
  231. package/lib/utils/useCopy.js +51 -0
  232. package/lib/utils/useHash.js +48 -0
  233. package/lib/utils/useHash.native.js +15 -0
  234. package/lib/utils/useResponsiveProp.js +59 -0
  235. package/lib/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +45 -12
  236. package/lib/utils/useUniqueId.js +21 -0
  237. package/package.json +11 -8
  238. package/release-context.json +4 -4
  239. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
  240. package/src/Box/Box.jsx +13 -4
  241. package/src/Button/Button.jsx +9 -5
  242. package/src/Button/ButtonBase.jsx +74 -86
  243. package/src/Button/ButtonGroup.jsx +24 -41
  244. package/src/Button/ButtonLink.jsx +14 -4
  245. package/src/Button/propTypes.js +12 -2
  246. package/src/Card/Card.jsx +4 -30
  247. package/src/Card/CardBase.jsx +57 -0
  248. package/src/Card/PressableCardBase.jsx +112 -0
  249. package/src/Card/index.js +3 -0
  250. package/src/Checkbox/Checkbox.jsx +274 -0
  251. package/src/Checkbox/CheckboxGroup.jsx +196 -0
  252. package/src/Checkbox/CheckboxInput.jsx +55 -0
  253. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  254. package/src/Checkbox/index.js +5 -0
  255. package/src/Divider/Divider.jsx +38 -3
  256. package/src/ExpandCollapse/Control.jsx +1 -1
  257. package/src/Feedback/Feedback.jsx +108 -0
  258. package/src/Feedback/index.js +3 -0
  259. package/src/Fieldset/Fieldset.jsx +129 -0
  260. package/src/Fieldset/FieldsetContainer.jsx +22 -0
  261. package/src/Fieldset/FieldsetContainer.native.jsx +16 -0
  262. package/src/Fieldset/Legend.jsx +16 -0
  263. package/src/Fieldset/Legend.native.jsx +22 -0
  264. package/src/Fieldset/cssReset.js +14 -0
  265. package/src/Fieldset/index.js +3 -0
  266. package/src/Icon/Icon.jsx +23 -27
  267. package/src/Icon/IconText.jsx +63 -0
  268. package/src/Icon/index.js +3 -2
  269. package/src/InputLabel/InputLabel.jsx +106 -0
  270. package/src/InputLabel/LabelContent.jsx +13 -0
  271. package/src/InputLabel/LabelContent.native.jsx +6 -0
  272. package/src/InputLabel/index.js +3 -0
  273. package/src/InputSupports/InputSupports.jsx +75 -0
  274. package/src/InputSupports/index.js +3 -0
  275. package/src/InputSupports/propTypes.js +44 -0
  276. package/src/InputSupports/useInputSupports.js +30 -0
  277. package/src/Link/ChevronLink.jsx +28 -7
  278. package/src/Link/InlinePressable.jsx +37 -0
  279. package/src/Link/InlinePressable.native.jsx +73 -0
  280. package/src/Link/Link.jsx +17 -13
  281. package/src/Link/LinkBase.jsx +71 -146
  282. package/src/Link/TextButton.jsx +25 -11
  283. package/src/Link/index.js +2 -1
  284. package/src/List/List.jsx +47 -0
  285. package/src/List/ListItem.jsx +187 -0
  286. package/src/List/index.js +3 -0
  287. package/src/Modal/Modal.jsx +185 -0
  288. package/src/Modal/dictionary.js +9 -0
  289. package/src/Modal/index.js +3 -0
  290. package/src/Notification/Notification.jsx +149 -0
  291. package/src/Notification/dictionary.js +8 -0
  292. package/src/Notification/index.js +3 -0
  293. package/src/Pagination/PageButton.jsx +3 -17
  294. package/src/Pagination/SideButton.jsx +27 -38
  295. package/src/Progress/Progress.jsx +77 -0
  296. package/src/Progress/ProgressBar.jsx +110 -0
  297. package/src/Progress/ProgressBarBackground.jsx +34 -0
  298. package/src/Progress/index.js +6 -0
  299. package/src/Radio/Radio.jsx +233 -0
  300. package/src/Radio/RadioButton.jsx +131 -0
  301. package/src/Radio/RadioGroup.jsx +198 -0
  302. package/src/Radio/RadioInput.jsx +57 -0
  303. package/src/Radio/RadioInput.native.jsx +6 -0
  304. package/src/Radio/index.js +5 -0
  305. package/src/RadioCard/RadioCard.jsx +191 -0
  306. package/src/RadioCard/RadioCardGroup.jsx +211 -0
  307. package/src/RadioCard/index.js +5 -0
  308. package/src/Search/Search.jsx +204 -0
  309. package/src/Search/dictionary.js +12 -0
  310. package/src/Search/index.js +3 -0
  311. package/src/Select/Group.jsx +15 -0
  312. package/src/Select/Group.native.jsx +14 -0
  313. package/src/Select/Item.jsx +11 -0
  314. package/src/Select/Item.native.jsx +10 -0
  315. package/src/Select/Picker.jsx +67 -0
  316. package/src/Select/Picker.native.jsx +95 -0
  317. package/src/Select/Select.jsx +255 -0
  318. package/src/Select/index.js +8 -0
  319. package/src/SideNav/Item.jsx +2 -2
  320. package/src/Skeleton/Skeleton.jsx +98 -0
  321. package/src/Skeleton/index.js +3 -0
  322. package/src/Skeleton/skeleton.constant.js +3 -0
  323. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  324. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  325. package/src/Spacer/Spacer.jsx +91 -0
  326. package/src/Spacer/index.js +3 -0
  327. package/src/StackView/StackView.jsx +111 -0
  328. package/src/StackView/StackWrap.jsx +41 -0
  329. package/src/StackView/StackWrap.native.jsx +4 -0
  330. package/src/StackView/StackWrapBox.jsx +94 -0
  331. package/src/StackView/StackWrapGap.jsx +49 -0
  332. package/src/StackView/common.jsx +28 -0
  333. package/src/StackView/getStackedContent.jsx +112 -0
  334. package/src/StackView/index.js +6 -0
  335. package/src/StepTracker/Step.jsx +202 -0
  336. package/src/StepTracker/StepTracker.jsx +163 -0
  337. package/src/StepTracker/dictionary.js +10 -0
  338. package/src/StepTracker/index.js +3 -0
  339. package/src/Tabs/HorizontalScroll.jsx +165 -0
  340. package/src/Tabs/ScrollViewEnd.jsx +53 -0
  341. package/src/Tabs/ScrollViewEnd.native.jsx +24 -0
  342. package/src/Tabs/Tabs.jsx +89 -0
  343. package/src/Tabs/TabsItem.jsx +204 -0
  344. package/src/Tabs/TabsScrollButton.jsx +100 -0
  345. package/src/Tabs/dictionary.js +11 -0
  346. package/src/Tabs/index.js +3 -0
  347. package/src/Tabs/itemPositions.js +101 -0
  348. package/src/Tags/Tags.jsx +207 -0
  349. package/src/Tags/index.js +3 -0
  350. package/src/TextInput/TextArea.jsx +78 -0
  351. package/src/TextInput/TextInput.jsx +52 -0
  352. package/src/TextInput/TextInputBase.jsx +210 -0
  353. package/src/TextInput/index.js +4 -0
  354. package/src/TextInput/propTypes.js +29 -0
  355. package/src/ThemeProvider/useThemeTokens.js +56 -5
  356. package/src/ThemeProvider/utils/styles.js +18 -5
  357. package/src/ThemeProvider/utils/theme-tokens.js +46 -5
  358. package/src/ToggleSwitch/ToggleSwitch.jsx +3 -4
  359. package/src/Tooltip/Backdrop.jsx +60 -0
  360. package/src/Tooltip/Backdrop.native.jsx +33 -0
  361. package/src/Tooltip/Tooltip.jsx +294 -0
  362. package/src/Tooltip/dictionary.js +8 -0
  363. package/src/Tooltip/getTooltipPosition.js +161 -0
  364. package/src/Tooltip/index.js +3 -0
  365. package/src/TooltipButton/TooltipButton.jsx +49 -0
  366. package/src/TooltipButton/index.js +3 -0
  367. package/src/Typography/Typography.jsx +10 -24
  368. package/src/ViewportProvider/ViewportProvider.jsx +21 -0
  369. package/src/ViewportProvider/index.jsx +2 -41
  370. package/src/ViewportProvider/useViewport.js +5 -0
  371. package/src/ViewportProvider/useViewportListener.js +43 -0
  372. package/src/index.js +34 -2
  373. package/src/utils/a11y/index.js +1 -0
  374. package/src/utils/a11y/textSize.js +30 -0
  375. package/src/utils/children.jsx +66 -0
  376. package/src/utils/index.js +11 -1
  377. package/src/utils/info/index.js +8 -0
  378. package/src/utils/info/platform/index.js +11 -0
  379. package/src/utils/info/platform/platform.android.js +1 -0
  380. package/src/utils/info/platform/platform.ios.js +1 -0
  381. package/src/utils/info/platform/platform.js +1 -0
  382. package/src/utils/info/platform/platform.native.js +4 -0
  383. package/src/utils/info/versions.js +6 -0
  384. package/src/utils/input.js +22 -13
  385. package/src/utils/pressability.js +96 -0
  386. package/src/utils/propTypes.js +195 -47
  387. package/src/utils/useCopy.js +39 -0
  388. package/src/utils/useHash.js +34 -0
  389. package/src/utils/useHash.native.js +6 -0
  390. package/src/utils/useResponsiveProp.js +50 -0
  391. package/src/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +25 -10
  392. package/src/utils/useUniqueId.js +14 -0
  393. package/stories/A11yText/A11yText.stories.jsx +15 -13
  394. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +11 -2
  395. package/stories/Box/Box.stories.jsx +29 -2
  396. package/stories/Button/Button.stories.jsx +21 -20
  397. package/stories/Button/ButtonGroup.stories.jsx +2 -1
  398. package/stories/Button/ButtonLink.stories.jsx +6 -4
  399. package/stories/Card/Card.stories.jsx +13 -1
  400. package/stories/Checkbox/Checkbox.stories.jsx +94 -0
  401. package/stories/Divider/Divider.stories.jsx +26 -2
  402. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +74 -79
  403. package/stories/Feedback/Feedback.stories.jsx +96 -0
  404. package/stories/FlexGrid/01 FlexGrid.stories.jsx +20 -7
  405. package/stories/Icon/Icon.stories.jsx +15 -6
  406. package/stories/InputLabel/InputLabel.stories.jsx +42 -0
  407. package/stories/Link/ChevronLink.stories.jsx +20 -4
  408. package/stories/Link/Link.stories.jsx +39 -3
  409. package/stories/Link/TextButton.stories.jsx +24 -2
  410. package/stories/List/List.stories.jsx +117 -0
  411. package/stories/Modal/Modal.stories.jsx +29 -0
  412. package/stories/Notification/Notification.stories.jsx +82 -0
  413. package/stories/Pagination/Pagination.stories.jsx +28 -14
  414. package/stories/Progress/Progress.stories.jsx +93 -0
  415. package/stories/Radio/Radio.stories.jsx +100 -0
  416. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  417. package/stories/Search/Search.stories.jsx +16 -0
  418. package/stories/Select/Select.stories.jsx +55 -0
  419. package/stories/SideNav/SideNav.stories.jsx +17 -2
  420. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  421. package/stories/Spacer/Spacer.stories.jsx +38 -0
  422. package/stories/StackView/StackView.stories.jsx +75 -0
  423. package/stories/StackView/StackWrap.stories.jsx +64 -0
  424. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  425. package/stories/Tabs/Tabs.stories.jsx +97 -0
  426. package/stories/Tags/Tags.stories.jsx +69 -0
  427. package/stories/TextInput/TextArea.stories.jsx +100 -0
  428. package/stories/TextInput/TextInput.stories.jsx +103 -0
  429. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +16 -3
  430. package/stories/Tooltip/Tooltip.stories.jsx +81 -0
  431. package/stories/TooltipButton/TooltipButton.stories.jsx +11 -0
  432. package/stories/Typography/Typography.stories.jsx +12 -3
  433. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  434. package/stories/supports.jsx +110 -14
  435. package/__fixtures__/accessible.icon.svg +0 -6
  436. package/babel.config.json +0 -8
  437. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  438. package/lib/Pagination/useCopy.js +0 -10
  439. package/lib/config/svgr-icons-web.js +0 -9
  440. package/lib/config/svgr-icons.js +0 -52
  441. package/lib/utils/spacing/index.js +0 -2
  442. package/lib/utils/spacing/utils.js +0 -32
  443. package/src/Pagination/useCopy.js +0 -7
  444. package/src/config/svgr-icons-web.js +0 -11
  445. package/src/config/svgr-icons.js +0 -46
  446. package/src/utils/spacing/index.js +0 -3
  447. package/src/utils/spacing/utils.js +0 -28
@@ -0,0 +1,200 @@
1
+ import React, { useState } from 'react'
2
+ import { Pressable, View, Text } from 'react-native'
3
+ import { fireEvent, render } from '@testing-library/react-native'
4
+
5
+ import { Tabs } from '../../src'
6
+ import {
7
+ getItemPositionLayoutHandler,
8
+ useItemPositions,
9
+ getItemPositionScrollTarget
10
+ } from '../../src/Tabs/itemPositions'
11
+ import Theme from '../../__fixtures__/Theme'
12
+
13
+ // ScrollViewRef.scrollTo doesn't work in Jest - unit-test the utilities instead
14
+ describe('Tabs getItemPositionScrollTarget', () => {
15
+ const positionsWithoutSpacing = {
16
+ 0: { start: 0, end: 100 },
17
+ 1: { start: 100, end: 200 },
18
+ 2: { start: 200, end: 300 }
19
+ }
20
+ const positions = {
21
+ 0: { start: 0, end: 50 },
22
+ 1: { start: 100, end: 150 },
23
+ 2: { start: 200, end: 250 }
24
+ }
25
+ it('scrolls to the start of an item rather than chopping it', () => {
26
+ const x = getItemPositionScrollTarget(150, 300, positionsWithoutSpacing)
27
+ expect(x).toBe(100)
28
+ })
29
+ it('offsets the position by a button clearance', () => {
30
+ const x = getItemPositionScrollTarget(150, 300, positionsWithoutSpacing, 20)
31
+ expect(x).toBe(80)
32
+ })
33
+ it('scrolls exactly if landing on a gap', () => {
34
+ const x = getItemPositionScrollTarget(170, 300, positions)
35
+ expect(x).toBe(170)
36
+ })
37
+ it('applies button clearance if landing on a gap', () => {
38
+ const x = getItemPositionScrollTarget(170, 300, positions, 40)
39
+ expect(x).toBe(130)
40
+ })
41
+ it('does not apply button clearance on reaching the end', () => {
42
+ const x = getItemPositionScrollTarget(300, 300, positions, 40)
43
+ expect(x).toBe(300)
44
+ })
45
+ it('does not exceed the maximum', () => {
46
+ const x = getItemPositionScrollTarget(320, 300, positions, 40)
47
+ expect(x).toBe(300)
48
+ })
49
+ it('does not go below 0', () => {
50
+ const x = getItemPositionScrollTarget(-420, 300, positions, 40)
51
+ expect(x).toBe(0)
52
+ })
53
+ })
54
+
55
+ // onLayout also doesn't work naturally in jest
56
+ describe('Tabs getItemPositionLayoutHandler', () => {
57
+ // Test component using useItemPositions with getItemPositionLayoutHandler
58
+ // that can be rerendered manually and that outputs itemPositions value
59
+ const MockComponent = () => {
60
+ const [num, setNum] = useState()
61
+ const [{ positions }] = useItemPositions()
62
+ return (
63
+ <View>
64
+ <View testID="onlayout[0]" onLayout={getItemPositionLayoutHandler(positions, 0)} />
65
+ <View testID="onlayout[1]" onLayout={getItemPositionLayoutHandler(positions, 1)} />
66
+ <Text testID="output">{JSON.stringify(positions)}</Text>
67
+ <Pressable testID="rerender" onPress={() => setNum(num + 1)}>
68
+ <Text>{num}</Text>
69
+ </Pressable>
70
+ </View>
71
+ )
72
+ }
73
+ it('gets width and x positions from onLayout events', async () => {
74
+ const { getByTestId } = render(<MockComponent />)
75
+
76
+ // onLayout doesn't work in jest but can be called directly as an event, but we
77
+ // have to pass the event object. Can't test that it gets them correctly from style
78
+ await fireEvent(getByTestId('onlayout[0]'), 'layout', {
79
+ nativeEvent: {
80
+ layout: {
81
+ width: 200,
82
+ x: 0
83
+ }
84
+ }
85
+ })
86
+ await fireEvent(getByTestId('onlayout[1]'), 'layout', {
87
+ nativeEvent: {
88
+ layout: {
89
+ width: 100,
90
+ x: 250
91
+ }
92
+ }
93
+ })
94
+ await fireEvent.press(getByTestId('rerender'))
95
+ expect(getByTestId('output')).toHaveTextContent(
96
+ '{"0":{"start":0,"end":200},"1":{"start":250,"end":350}}'
97
+ )
98
+ })
99
+ it('does not cause a rerender from onLayout events alone', async () => {
100
+ const { getByTestId } = render(<MockComponent />)
101
+
102
+ expect(getByTestId('output')).toHaveTextContent('{}')
103
+ await fireEvent(getByTestId('onlayout[0]'), 'layout', {
104
+ nativeEvent: {
105
+ layout: {
106
+ width: 200,
107
+ x: 0
108
+ }
109
+ }
110
+ })
111
+ await fireEvent(getByTestId('onlayout[1]'), 'layout', {
112
+ nativeEvent: {
113
+ layout: {
114
+ width: 100,
115
+ x: 250
116
+ }
117
+ }
118
+ })
119
+ expect(getByTestId('output')).toHaveTextContent('{}')
120
+ })
121
+ })
122
+
123
+ describe('useItemPositions', () => {
124
+ // Again we're limited in what we can test; we can't test natural onLayout
125
+ // or page load timing, but we can affirm that calling `setIsReady` after layout
126
+ // events causes a re-render that can access positions data
127
+ const IsReadyMockComponent = () => {
128
+ const [{ positions, setIsReady }] = useItemPositions()
129
+ return (
130
+ <View testID="container" onLayout={setIsReady}>
131
+ <View testID="onlayout[0]" onLayout={getItemPositionLayoutHandler(positions, 0)} />
132
+ <View testID="onlayout[1]" onLayout={getItemPositionLayoutHandler(positions, 1)} />
133
+ <Text testID="output">{JSON.stringify(positions)}</Text>
134
+ </View>
135
+ )
136
+ }
137
+ it('causes a rerender when setIsReady is called', async () => {
138
+ const { getByTestId } = render(<IsReadyMockComponent />)
139
+
140
+ expect(getByTestId('output')).toHaveTextContent('{}')
141
+ await fireEvent(getByTestId('onlayout[0]'), 'layout', {
142
+ nativeEvent: {
143
+ layout: {
144
+ width: 200,
145
+ x: 0
146
+ }
147
+ }
148
+ })
149
+ await fireEvent(getByTestId('onlayout[1]'), 'layout', {
150
+ nativeEvent: {
151
+ layout: {
152
+ width: 100,
153
+ x: 250
154
+ }
155
+ }
156
+ })
157
+ await fireEvent(getByTestId('container'), 'layout', {
158
+ nativeEvent: { layout: {} }
159
+ })
160
+
161
+ expect(getByTestId('output')).toHaveTextContent(
162
+ '{"0":{"start":0,"end":200},"1":{"start":250,"end":350}}'
163
+ )
164
+ })
165
+ })
166
+
167
+ describe('Tabs', () => {
168
+ const items = [{ label: 'one' }, { label: 'two' }, { label: 'three' }, { label: 'four' }]
169
+ const linkItems = items.map((item) => ({ ...item, href: 'https://telus.com' }))
170
+
171
+ it('renders a menu', () => {
172
+ const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
173
+ expect(queryAllByA11yRole('tablist')).toHaveLength(1)
174
+ })
175
+
176
+ it('renders menuitems by default', () => {
177
+ const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
178
+ expect(queryAllByA11yRole('tab')).toHaveLength(4)
179
+ expect(queryAllByA11yRole('link')).toHaveLength(0)
180
+ })
181
+
182
+ it('renders links by if hrefs are passed', () => {
183
+ const { queryAllByA11yRole } = render(<Tabs items={linkItems} />, { wrapper: Theme })
184
+ expect(queryAllByA11yRole('tab')).toHaveLength(0)
185
+ expect(queryAllByA11yRole('link')).toHaveLength(4)
186
+ })
187
+
188
+ it('is selected when pressed', () => {
189
+ const { queryByA11yState, getByText } = render(<Tabs items={items} />, { wrapper: Theme })
190
+ let selected
191
+ selected = queryByA11yState({ selected: true })
192
+ expect(selected).toBeFalsy()
193
+
194
+ fireEvent.press(getByText('two'))
195
+
196
+ selected = queryByA11yState({ selected: true })
197
+ expect(selected).toBeTruthy()
198
+ expect(selected).toHaveTextContent('two')
199
+ })
200
+ })
@@ -0,0 +1,328 @@
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 Tags from '../../src/Tags'
7
+
8
+ const items = [
9
+ { label: 'One', id: 'one', accessibilityLabel: 'Option one' },
10
+ { label: 'Two', id: 'two', accessibilityLabel: 'Option two' },
11
+ { label: 'Three', id: 'three', accessibilityLabel: 'Option three' },
12
+ { label: 'Four', id: 'four', accessibilityLabel: 'Option 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('Tags', () => {
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 `values` without `onChange`', () => {
33
+ expect(() =>
34
+ render(
35
+ <Theme>
36
+ <Tags items={items} values={['one']} />
37
+ </Theme>
38
+ )
39
+ ).toThrow(/values.+without.+onChange/)
40
+ })
41
+ it("Doesn't throw if has `values` without `onChange` and is read only", () => {
42
+ expect(() =>
43
+ render(
44
+ <Theme>
45
+ <Tags items={items} values={['one']} readOnly />
46
+ </Theme>
47
+ )
48
+ ).not.toThrow()
49
+ })
50
+ it('Throws if has both `values` and `initialValues`', () => {
51
+ expect(() =>
52
+ render(
53
+ <Theme>
54
+ <Tags items={items} values={['one']} initialValues={['one']} onChange={() => {}} />
55
+ </Theme>
56
+ )
57
+ ).toThrow(/both(?=.*initialValues)(?=.*values){2}/)
58
+ })
59
+ })
60
+
61
+ describe('Tags (uncontrolled)', () => {
62
+ // These tests are almost the same as ButtonGroup while Tags-specific behaviours are still TBC
63
+ it('Selects one and only one item if maxValues is passed', async () => {
64
+ const { getByText, queryAllByA11yState } = render(
65
+ <Theme>
66
+ <Tags items={items} maxValues={1} />
67
+ </Theme>
68
+ )
69
+
70
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
71
+
72
+ const one = getByText('One')
73
+ await fireEvent.press(one)
74
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
75
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
76
+
77
+ const two = getByText('Two')
78
+ await fireEvent.press(two)
79
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
80
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
81
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
82
+ })
83
+
84
+ it('Deselects if the selected item is pressed', async () => {
85
+ const { getByText, queryAllByA11yState } = render(
86
+ <Theme>
87
+ <Tags items={items} />
88
+ </Theme>
89
+ )
90
+
91
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
92
+
93
+ const three = getByText('Three')
94
+ await fireEvent.press(three)
95
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
96
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
97
+
98
+ await fireEvent.press(three)
99
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
100
+ expect(containsText(queryAllByA11yState(checked), 'Three')).not.toBeTruthy()
101
+ })
102
+
103
+ it('Selects <= two items when maxValues === 2', async () => {
104
+ const { getByText, queryAllByA11yState } = render(
105
+ <Theme>
106
+ <Tags items={items} maxValues={2} />
107
+ </Theme>
108
+ )
109
+
110
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
111
+
112
+ const one = getByText('One')
113
+ await fireEvent.press(one)
114
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
115
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
116
+
117
+ const two = getByText('Two')
118
+ await fireEvent.press(two)
119
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
120
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
121
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
122
+
123
+ const three = getByText('Three')
124
+ await fireEvent.press(three)
125
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
126
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
127
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
128
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
129
+
130
+ const four = getByText('Four')
131
+ await fireEvent.press(four)
132
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
133
+ expect(containsText(queryAllByA11yState(checked), 'Four')).toBeTruthy()
134
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
135
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
136
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
137
+ })
138
+
139
+ it('Is accessible as checkboxes by default', async () => {
140
+ const { queryAllByA11yRole, queryAllByA11yState } = render(
141
+ <Theme>
142
+ <Tags items={items} />
143
+ </Theme>
144
+ )
145
+
146
+ expect(queryAllByA11yRole('radiogroup')).toHaveLength(0)
147
+ expect(queryAllByA11yRole('radio')).toHaveLength(0)
148
+
149
+ const checks = queryAllByA11yRole('checkbox')
150
+ expect(checks).toHaveLength(4)
151
+
152
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
153
+ await fireEvent.press(checks[0])
154
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
155
+ })
156
+
157
+ it('Selects unlimited items by default', async () => {
158
+ const { getByText, queryAllByA11yState } = render(
159
+ <Theme>
160
+ <Tags items={items} />
161
+ </Theme>
162
+ )
163
+
164
+ expect(queryAllByA11yState(checked)).toHaveLength(0)
165
+
166
+ const one = getByText('One')
167
+ await fireEvent.press(one)
168
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
169
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
170
+
171
+ const two = getByText('Two')
172
+ await fireEvent.press(two)
173
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
174
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
175
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
176
+
177
+ const three = getByText('Three')
178
+ await fireEvent.press(three)
179
+ expect(queryAllByA11yState(checked)).toHaveLength(3)
180
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
181
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
182
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
183
+
184
+ const four = getByText('Four')
185
+ await fireEvent.press(four)
186
+ expect(queryAllByA11yState(checked)).toHaveLength(4)
187
+ expect(containsText(queryAllByA11yState(checked), 'Four')).toBeTruthy()
188
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
189
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
190
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
191
+ })
192
+
193
+ it('Auto-selects any provided initialValues', async () => {
194
+ const { getByText, queryAllByA11yState } = render(
195
+ <Theme>
196
+ <Tags items={items} initialValues={['one', 'two']} maxValues={3} />
197
+ </Theme>
198
+ )
199
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
200
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
201
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
202
+
203
+ const three = getByText('Three')
204
+ await fireEvent.press(three)
205
+
206
+ expect(queryAllByA11yState(checked)).toHaveLength(3)
207
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
208
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
209
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
210
+
211
+ const four = getByText('Four')
212
+ await fireEvent.press(four)
213
+ expect(queryAllByA11yState(checked)).toHaveLength(3)
214
+ expect(containsText(queryAllByA11yState(checked), 'Four')).toBeTruthy()
215
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
216
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
217
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
218
+
219
+ const two = getByText('Two')
220
+ await fireEvent.press(two)
221
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
222
+ expect(containsText(queryAllByA11yState(checked), 'Four')).toBeTruthy()
223
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
224
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
225
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
226
+ })
227
+ })
228
+
229
+ describe('Tags (controlled)', () => {
230
+ it('Calls onChange handler on press in controlled mode, providing pressed id', async () => {
231
+ const handleChange = jest.fn((arg) => arg)
232
+ const { getByText } = render(
233
+ <Theme>
234
+ <Tags items={items} values={[]} onChange={handleChange} />
235
+ </Theme>
236
+ )
237
+
238
+ expect(handleChange).toHaveBeenCalledTimes(0)
239
+
240
+ const one = getByText('One')
241
+ await fireEvent.press(one)
242
+ expect(handleChange).toHaveBeenCalledTimes(1)
243
+
244
+ expect(handleChange.mock.calls[0][0]).toEqual(['one'])
245
+
246
+ const two = getByText('Two')
247
+ await fireEvent.press(two)
248
+ expect(handleChange).toHaveBeenCalledTimes(2)
249
+ expect(handleChange.mock.calls[1][0]).toEqual(['two'])
250
+ })
251
+
252
+ it("Doesn't change its own selection if `values` is passed", async () => {
253
+ const { getByText, queryAllByA11yState } = render(
254
+ <Theme>
255
+ <Tags items={items} values={['one']} onChange={() => {}} />
256
+ </Theme>
257
+ )
258
+
259
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
260
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
261
+
262
+ const one = getByText('One')
263
+ await fireEvent.press(one)
264
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
265
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
266
+
267
+ const two = getByText('Two')
268
+ await fireEvent.press(two)
269
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
270
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
271
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
272
+ })
273
+
274
+ it('Does not render an invalid `values` invalidly', async () => {
275
+ const { queryAllByA11yState } = render(
276
+ <Theme>
277
+ <Tags items={items} values={['one', 'two', 'three']} maxValues={2} onChange={() => {}} />
278
+ </Theme>
279
+ )
280
+ expect(queryAllByA11yState(checked)).toHaveLength(2)
281
+ expect(containsText(queryAllByA11yState(checked), 'One')).not.toBeTruthy()
282
+ expect(containsText(queryAllByA11yState(checked), 'Two')).toBeTruthy()
283
+ expect(containsText(queryAllByA11yState(checked), 'Three')).toBeTruthy()
284
+ })
285
+ })
286
+
287
+ describe('Tags (read-only)', () => {
288
+ it("Doesn't call onChange handler when read-only", async () => {
289
+ const handleChange = jest.fn((arg) => arg)
290
+ const { getByText } = render(
291
+ <Theme>
292
+ <Tags items={items} values={[]} onChange={handleChange} readOnly />
293
+ </Theme>
294
+ )
295
+
296
+ expect(handleChange).toHaveBeenCalledTimes(0)
297
+
298
+ const one = getByText('One')
299
+ await fireEvent.press(one)
300
+ expect(handleChange).toHaveBeenCalledTimes(0)
301
+
302
+ const two = getByText('Two')
303
+ await fireEvent.press(two)
304
+ expect(handleChange).toHaveBeenCalledTimes(0)
305
+ })
306
+
307
+ it("Doesn't change its selection on press", async () => {
308
+ const { getByText, queryAllByA11yState } = render(
309
+ <Theme>
310
+ <Tags items={items} values={['one']} readOnly />
311
+ </Theme>
312
+ )
313
+
314
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
315
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
316
+
317
+ const one = getByText('One')
318
+ await fireEvent.press(one)
319
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
320
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
321
+
322
+ const two = getByText('Two')
323
+ await fireEvent.press(two)
324
+ expect(queryAllByA11yState(checked)).toHaveLength(1)
325
+ expect(containsText(queryAllByA11yState(checked), 'Two')).not.toBeTruthy()
326
+ expect(containsText(queryAllByA11yState(checked), 'One')).toBeTruthy()
327
+ })
328
+ })
@@ -0,0 +1,34 @@
1
+ import React from 'react'
2
+ import { fireEvent, render } from '@testing-library/react-native'
3
+
4
+ import { Platform } from 'react-native'
5
+ import { TextArea } from '../../src'
6
+ import Theme from '../../__fixtures__/Theme'
7
+
8
+ describe('TextArea', () => {
9
+ it('renders', () => {
10
+ // at least one called test is required in a suite
11
+ render(<TextArea />, { wrapper: Theme })
12
+ })
13
+
14
+ // TODO: this won't be called until cross-platform Jest tests are configured
15
+ // see https://github.com/telus/universal-design-system/issues/319
16
+ if (Platform.OS === 'web') {
17
+ it('grows in size on input', () => {
18
+ const { getByTestId } = render(
19
+ <TextArea tokens={{ minLines: 1, maxLines: 5, lineHeight: 20 }} testID="textarea" />,
20
+ {
21
+ wrapper: Theme
22
+ }
23
+ )
24
+
25
+ const textarea = getByTestId('textarea')
26
+
27
+ expect(textarea).toHaveStyle({ height: 20 })
28
+
29
+ fireEvent.changeText(textarea, '\n\n\n')
30
+
31
+ expect(textarea).toHaveStyle({ height: 60 })
32
+ })
33
+ }
34
+ })
@@ -0,0 +1,120 @@
1
+ import { fireEvent, render } from '@testing-library/react-native'
2
+ import React from 'react'
3
+ import TextInputBase from '../../src/TextInput/TextInputBase'
4
+ import Viewport from '../../__fixtures__/Viewport'
5
+ import Theme from '../../__fixtures__/Theme'
6
+
7
+ // eslint-disable-next-line react/prop-types
8
+ const Wrapper = ({ children }) => (
9
+ <Viewport viewport="xs">
10
+ <Theme>{children}</Theme>
11
+ </Viewport>
12
+ )
13
+
14
+ describe('TextInputBaseBase', () => {
15
+ it('triggers the interactive callbacks', () => {
16
+ const onFocus = jest.fn()
17
+ const onBlur = jest.fn()
18
+ const onMouseOver = jest.fn()
19
+ const onMouseOut = jest.fn()
20
+
21
+ const { getByA11yLabel } = render(
22
+ <TextInputBase
23
+ accessibilityLabel="Input label"
24
+ onFocus={onFocus}
25
+ onBlur={onBlur}
26
+ onMouseOver={onMouseOver}
27
+ onMouseOut={onMouseOut}
28
+ />,
29
+ {
30
+ wrapper: Wrapper
31
+ }
32
+ )
33
+
34
+ const input = getByA11yLabel('Input label')
35
+
36
+ expect(onFocus).not.toHaveBeenCalled()
37
+ fireEvent(input, 'focus')
38
+ expect(onFocus).toHaveBeenCalledTimes(1)
39
+
40
+ expect(onBlur).not.toHaveBeenCalled()
41
+ fireEvent(input, 'blur')
42
+ expect(onBlur).toHaveBeenCalledTimes(1)
43
+
44
+ expect(onMouseOver).not.toHaveBeenCalled()
45
+ fireEvent(input, 'mouseOver')
46
+ expect(onMouseOver).toHaveBeenCalledTimes(1)
47
+
48
+ expect(onMouseOut).not.toHaveBeenCalled()
49
+ fireEvent(input, 'mouseOut')
50
+ expect(onMouseOut).toHaveBeenCalledTimes(1)
51
+ })
52
+
53
+ it("can't be edited when inactive", () => {
54
+ const { getByA11yLabel } = render(<TextInputBase accessibilityLabel="Input label" inactive />, {
55
+ wrapper: Wrapper
56
+ })
57
+
58
+ const input = getByA11yLabel('Input label')
59
+
60
+ expect(input).toHaveProp('editable', false)
61
+ })
62
+
63
+ it('changes value when uncontrolled', () => {
64
+ const onChange = jest.fn()
65
+
66
+ const { getByA11yLabel } = render(
67
+ <TextInputBase accessibilityLabel="Input label" onChange={onChange} />,
68
+ {
69
+ wrapper: Wrapper
70
+ }
71
+ )
72
+
73
+ const input = getByA11yLabel('Input label')
74
+
75
+ expect(onChange).not.toHaveBeenCalled()
76
+ fireEvent.changeText(input, 'new value')
77
+ expect(onChange).toHaveBeenCalledTimes(1)
78
+ expect(onChange).toHaveBeenLastCalledWith('new value')
79
+ })
80
+
81
+ it('changes value when controlled', () => {
82
+ const onChange = jest.fn()
83
+
84
+ const { getByA11yLabel } = render(
85
+ <TextInputBase accessibilityLabel="Input label" onChange={onChange} value="initial value" />,
86
+ {
87
+ wrapper: Wrapper
88
+ }
89
+ )
90
+
91
+ const input = getByA11yLabel('Input label')
92
+
93
+ expect(onChange).not.toHaveBeenCalled()
94
+ fireEvent.changeText(input, 'new value')
95
+ expect(onChange).toHaveBeenCalledTimes(1)
96
+ expect(onChange).toHaveBeenLastCalledWith('new value')
97
+ })
98
+
99
+ it("doesn't change value when readOnly", () => {
100
+ const onChange = jest.fn()
101
+
102
+ const { getByA11yLabel } = render(
103
+ <TextInputBase
104
+ accessibilityLabel="Input label"
105
+ onChange={onChange}
106
+ value="initial value"
107
+ readOnly
108
+ />,
109
+ {
110
+ wrapper: Wrapper
111
+ }
112
+ )
113
+
114
+ const input = getByA11yLabel('Input label')
115
+
116
+ expect(onChange).not.toHaveBeenCalled()
117
+ fireEvent.changeText(input, 'new value')
118
+ expect(onChange).not.toHaveBeenCalled()
119
+ })
120
+ })