@telus-uds/components-base 0.0.2-prerelease.7 → 1.0.1

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 (445) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.ultra.cache.json +1 -1
  3. package/CHANGELOG.md +71 -0
  4. package/README.md +4 -2
  5. package/__fixtures__/Accessible.js +33 -0
  6. package/__fixtures__/Accessible.native.js +32 -0
  7. package/__fixtures__/test-utils.js +25 -0
  8. package/__fixtures__/testTheme.js +438 -31
  9. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  10. package/__tests__/Button/ButtonGroup.test.jsx +6 -7
  11. package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
  12. package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
  13. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  14. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  15. package/__tests__/Icon/Icon.test.jsx +3 -3
  16. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  17. package/__tests__/Link/LinkBase.test.jsx +0 -14
  18. package/__tests__/Modal/Modal.test.jsx +47 -0
  19. package/__tests__/Notification/Notification.test.jsx +20 -0
  20. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  21. package/__tests__/Progress/Progress.test.jsx +79 -0
  22. package/__tests__/Radio/Radio.test.jsx +2 -2
  23. package/__tests__/Radio/RadioGroup.test.jsx +220 -0
  24. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  25. package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
  26. package/__tests__/Search/Search.test.jsx +73 -0
  27. package/__tests__/Select/Select.test.jsx +3 -2
  28. package/__tests__/Skeleton/Skeleton.test.jsx +1 -1
  29. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  30. package/__tests__/Tabs/Tabs.test.jsx +40 -0
  31. package/__tests__/Tags/Tags.test.jsx +5 -6
  32. package/__tests__/TextInput/TextArea.test.jsx +3 -2
  33. package/__tests__/TextInput/TextInputBase.test.jsx +10 -5
  34. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  35. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
  36. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  37. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  38. package/__tests__/utils/children.test.jsx +128 -0
  39. package/__tests__/utils/input.test.js +59 -1
  40. package/__tests__/utils/semantics.test.jsx +43 -0
  41. package/__tests__/utils/useCopy.test.js +14 -3
  42. package/babel.config.js +20 -0
  43. package/jest.config.js +6 -3
  44. package/lib/A11yInfoProvider/index.js +54 -26
  45. package/lib/A11yText/index.js +45 -17
  46. package/lib/ActivityIndicator/Spinner.js +81 -0
  47. package/lib/ActivityIndicator/Spinner.native.js +129 -91
  48. package/lib/ActivityIndicator/index.js +28 -12
  49. package/lib/ActivityIndicator/shared.js +27 -12
  50. package/lib/BaseProvider/index.js +34 -11
  51. package/lib/Box/Box.js +153 -35
  52. package/lib/Box/index.js +13 -2
  53. package/lib/Button/Button.js +38 -16
  54. package/lib/Button/ButtonBase.js +93 -79
  55. package/lib/Button/ButtonGroup.js +112 -73
  56. package/lib/Button/ButtonLink.js +45 -19
  57. package/lib/Button/index.js +31 -4
  58. package/lib/Button/propTypes.js +32 -9
  59. package/lib/Card/Card.js +38 -41
  60. package/lib/Card/CardBase.js +86 -0
  61. package/lib/Card/PressableCardBase.js +141 -0
  62. package/lib/Card/index.js +40 -2
  63. package/lib/Checkbox/Checkbox.js +158 -111
  64. package/lib/Checkbox/CheckboxGroup.js +241 -0
  65. package/lib/Checkbox/CheckboxInput.js +74 -0
  66. package/lib/Checkbox/CheckboxInput.native.js +9 -1
  67. package/lib/Checkbox/index.js +21 -2
  68. package/lib/Divider/Divider.js +59 -28
  69. package/lib/Divider/index.js +13 -2
  70. package/lib/ExpandCollapse/Accordion.js +26 -7
  71. package/lib/ExpandCollapse/Control.js +60 -31
  72. package/lib/ExpandCollapse/ExpandCollapse.js +50 -28
  73. package/lib/ExpandCollapse/Panel.js +83 -44
  74. package/lib/ExpandCollapse/index.js +25 -7
  75. package/lib/Feedback/Feedback.js +77 -43
  76. package/lib/Feedback/index.js +13 -2
  77. package/lib/Fieldset/Fieldset.js +165 -0
  78. package/lib/Fieldset/FieldsetContainer.js +46 -0
  79. package/lib/Fieldset/FieldsetContainer.native.js +38 -0
  80. package/lib/Fieldset/Legend.js +38 -0
  81. package/lib/Fieldset/Legend.native.js +48 -0
  82. package/lib/Fieldset/cssReset.js +21 -0
  83. package/lib/Fieldset/index.js +13 -0
  84. package/lib/FlexGrid/Col/Col.js +73 -41
  85. package/lib/FlexGrid/Col/index.js +13 -2
  86. package/lib/FlexGrid/FlexGrid.js +99 -49
  87. package/lib/FlexGrid/Row/Row.js +58 -30
  88. package/lib/FlexGrid/Row/index.js +13 -2
  89. package/lib/FlexGrid/helpers/index.js +9 -1
  90. package/lib/FlexGrid/index.js +13 -2
  91. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  92. package/lib/HorizontalScroll/HorizontalScroll.js +200 -0
  93. package/lib/HorizontalScroll/HorizontalScrollButton.js +127 -0
  94. package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
  95. package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
  96. package/lib/HorizontalScroll/dictionary.js +18 -0
  97. package/lib/HorizontalScroll/index.js +35 -0
  98. package/lib/HorizontalScroll/itemPositions.js +128 -0
  99. package/lib/Icon/Icon.js +57 -48
  100. package/lib/Icon/IconText.js +54 -25
  101. package/lib/Icon/index.js +31 -4
  102. package/lib/IconButton/IconButton.js +140 -0
  103. package/lib/IconButton/index.js +13 -0
  104. package/lib/InputLabel/InputLabel.js +102 -40
  105. package/lib/InputLabel/LabelContent.js +41 -0
  106. package/lib/InputLabel/LabelContent.native.js +32 -6
  107. package/lib/InputLabel/index.js +13 -2
  108. package/lib/InputSupports/InputSupports.js +71 -52
  109. package/lib/InputSupports/index.js +13 -2
  110. package/lib/InputSupports/propTypes.js +19 -8
  111. package/lib/InputSupports/useInputSupports.js +41 -0
  112. package/lib/Link/ChevronLink.js +44 -20
  113. package/lib/Link/InlinePressable.js +56 -0
  114. package/lib/Link/InlinePressable.native.js +39 -15
  115. package/lib/Link/Link.js +36 -13
  116. package/lib/Link/LinkBase.js +98 -61
  117. package/lib/Link/TextButton.js +41 -17
  118. package/lib/Link/index.js +39 -5
  119. package/lib/List/List.js +55 -26
  120. package/lib/List/ListItem.js +79 -41
  121. package/lib/List/index.js +13 -2
  122. package/lib/Modal/Modal.js +231 -0
  123. package/lib/Modal/dictionary.js +16 -0
  124. package/lib/Modal/index.js +13 -0
  125. package/lib/Notification/Notification.js +216 -0
  126. package/lib/Notification/dictionary.js +15 -0
  127. package/lib/Notification/index.js +13 -0
  128. package/lib/Pagination/PageButton.js +61 -28
  129. package/lib/Pagination/Pagination.js +78 -43
  130. package/lib/Pagination/SideButton.js +73 -42
  131. package/lib/Pagination/dictionary.js +9 -2
  132. package/lib/Pagination/index.js +13 -2
  133. package/lib/Pagination/usePagination.js +12 -2
  134. package/lib/Progress/Progress.js +104 -0
  135. package/lib/Progress/ProgressBar.js +157 -0
  136. package/lib/Progress/ProgressBarBackground.js +61 -0
  137. package/lib/Progress/index.js +16 -0
  138. package/lib/Radio/Radio.js +116 -114
  139. package/lib/Radio/RadioButton.js +152 -0
  140. package/lib/Radio/RadioGroup.js +244 -0
  141. package/lib/Radio/RadioInput.js +76 -0
  142. package/lib/Radio/RadioInput.native.js +9 -1
  143. package/lib/Radio/index.js +21 -2
  144. package/lib/RadioCard/RadioCard.js +244 -0
  145. package/lib/RadioCard/RadioCardGroup.js +252 -0
  146. package/lib/RadioCard/index.js +21 -0
  147. package/lib/Search/Search.js +254 -0
  148. package/lib/Search/dictionary.js +19 -0
  149. package/lib/Search/index.js +13 -0
  150. package/lib/Select/Group.js +33 -0
  151. package/lib/Select/Group.native.js +16 -5
  152. package/lib/Select/Item.js +29 -0
  153. package/lib/Select/Item.native.js +14 -4
  154. package/lib/Select/Picker.js +84 -0
  155. package/lib/Select/Picker.native.js +73 -30
  156. package/lib/Select/Select.js +155 -85
  157. package/lib/Select/index.js +19 -6
  158. package/lib/SideNav/Item.js +63 -37
  159. package/lib/SideNav/ItemContent.js +41 -15
  160. package/lib/SideNav/ItemsGroup.js +55 -31
  161. package/lib/SideNav/SideNav.js +100 -73
  162. package/lib/SideNav/index.js +15 -1
  163. package/lib/Skeleton/Skeleton.js +64 -46
  164. package/lib/Skeleton/index.js +13 -2
  165. package/lib/Skeleton/skeleton.constant.js +12 -0
  166. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  167. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  168. package/lib/Spacer/Spacer.js +49 -18
  169. package/lib/Spacer/index.js +13 -2
  170. package/lib/StackView/StackView.js +72 -31
  171. package/lib/StackView/StackWrap.js +43 -13
  172. package/lib/StackView/StackWrap.native.js +13 -2
  173. package/lib/StackView/StackWrapBox.js +77 -29
  174. package/lib/StackView/StackWrapGap.js +56 -26
  175. package/lib/StackView/common.js +23 -6
  176. package/lib/StackView/getStackedContent.js +47 -17
  177. package/lib/StackView/index.js +29 -5
  178. package/lib/StepTracker/Step.js +245 -0
  179. package/lib/StepTracker/StepTracker.js +202 -0
  180. package/lib/StepTracker/dictionary.js +17 -0
  181. package/lib/StepTracker/index.js +13 -0
  182. package/lib/Tabs/Tabs.js +124 -0
  183. package/lib/Tabs/TabsItem.js +238 -0
  184. package/lib/Tabs/index.js +13 -0
  185. package/lib/Tags/Tags.js +148 -99
  186. package/lib/Tags/index.js +13 -2
  187. package/lib/TextInput/TextArea.js +57 -28
  188. package/lib/TextInput/TextInput.js +50 -23
  189. package/lib/TextInput/TextInputBase.js +90 -63
  190. package/lib/TextInput/index.js +23 -3
  191. package/lib/TextInput/propTypes.js +18 -7
  192. package/lib/ThemeProvider/ThemeProvider.js +46 -18
  193. package/lib/ThemeProvider/index.js +61 -6
  194. package/lib/ThemeProvider/useSetTheme.js +19 -5
  195. package/lib/ThemeProvider/useTheme.js +13 -4
  196. package/lib/ThemeProvider/useThemeTokens.js +32 -16
  197. package/lib/ThemeProvider/utils/index.js +31 -2
  198. package/lib/ThemeProvider/utils/styles.js +50 -14
  199. package/lib/ThemeProvider/utils/theme-tokens.js +121 -12
  200. package/lib/ToggleSwitch/ToggleSwitch.js +85 -56
  201. package/lib/ToggleSwitch/index.js +13 -2
  202. package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +20 -8
  203. package/lib/Tooltip/Backdrop.native.js +39 -15
  204. package/lib/Tooltip/Tooltip.js +117 -74
  205. package/lib/Tooltip/dictionary.js +9 -2
  206. package/lib/Tooltip/getTooltipPosition.js +9 -1
  207. package/lib/Tooltip/index.js +13 -2
  208. package/lib/TooltipButton/TooltipButton.js +57 -38
  209. package/lib/TooltipButton/index.js +13 -2
  210. package/lib/Typography/Typography.js +87 -41
  211. package/lib/Typography/index.js +13 -2
  212. package/lib/ViewportProvider/ViewportProvider.js +34 -13
  213. package/lib/ViewportProvider/index.js +28 -3
  214. package/lib/ViewportProvider/useViewport.js +15 -3
  215. package/lib/ViewportProvider/useViewportListener.js +24 -10
  216. package/lib/index.js +539 -33
  217. package/lib/utils/a11y/index.js +31 -1
  218. package/lib/utils/a11y/semantics.js +173 -0
  219. package/lib/utils/a11y/textSize.js +23 -7
  220. package/lib/utils/animation/index.js +15 -2
  221. package/lib/utils/animation/useVerticalExpandAnimation.js +27 -10
  222. package/lib/utils/children.js +134 -0
  223. package/lib/utils/index.js +163 -10
  224. package/lib/utils/info/index.js +18 -6
  225. package/lib/utils/info/platform/index.js +19 -7
  226. package/lib/utils/info/platform/platform.android.js +8 -1
  227. package/lib/utils/info/platform/platform.ios.js +8 -1
  228. package/lib/utils/info/platform/platform.js +8 -0
  229. package/lib/utils/info/platform/platform.native.js +8 -1
  230. package/lib/utils/info/versions.js +15 -4
  231. package/lib/utils/input.js +53 -25
  232. package/lib/utils/pressability.js +38 -10
  233. package/lib/utils/propTypes.js +287 -141
  234. package/lib/utils/useCopy.js +40 -5
  235. package/lib/utils/useHash.js +52 -0
  236. package/lib/utils/useHash.native.js +15 -0
  237. package/lib/utils/useResponsiveProp.js +21 -9
  238. package/lib/utils/useSpacingScale.js +19 -9
  239. package/lib/utils/useUniqueId.js +12 -3
  240. package/package.json +14 -9
  241. package/release-context.json +4 -4
  242. package/src/A11yText/index.jsx +6 -4
  243. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +5 -3
  244. package/src/ActivityIndicator/Spinner.native.jsx +5 -3
  245. package/src/Box/Box.jsx +132 -39
  246. package/src/Button/Button.jsx +10 -6
  247. package/src/Button/ButtonBase.jsx +99 -99
  248. package/src/Button/ButtonGroup.jsx +81 -69
  249. package/src/Button/ButtonLink.jsx +21 -15
  250. package/src/Button/propTypes.js +12 -2
  251. package/src/Card/Card.jsx +5 -31
  252. package/src/Card/CardBase.jsx +59 -0
  253. package/src/Card/PressableCardBase.jsx +119 -0
  254. package/src/Card/index.js +3 -0
  255. package/src/Checkbox/Checkbox.jsx +121 -112
  256. package/src/Checkbox/CheckboxGroup.jsx +206 -0
  257. package/src/Checkbox/{CheckboxInput.web.jsx → CheckboxInput.jsx} +0 -0
  258. package/src/Checkbox/index.js +2 -0
  259. package/src/Divider/Divider.jsx +7 -4
  260. package/src/ExpandCollapse/Accordion.jsx +3 -2
  261. package/src/ExpandCollapse/Control.jsx +40 -43
  262. package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
  263. package/src/ExpandCollapse/Panel.jsx +69 -63
  264. package/src/Feedback/Feedback.jsx +36 -33
  265. package/src/Fieldset/Fieldset.jsx +136 -0
  266. package/src/Fieldset/FieldsetContainer.jsx +31 -0
  267. package/src/Fieldset/FieldsetContainer.native.jsx +19 -0
  268. package/src/Fieldset/Legend.jsx +21 -0
  269. package/src/Fieldset/Legend.native.jsx +27 -0
  270. package/src/Fieldset/cssReset.js +14 -0
  271. package/src/Fieldset/index.js +3 -0
  272. package/src/FlexGrid/Col/Col.jsx +139 -132
  273. package/src/FlexGrid/FlexGrid.jsx +79 -51
  274. package/src/FlexGrid/Row/Row.jsx +55 -48
  275. package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
  276. package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
  277. package/src/HorizontalScroll/ScrollViewEnd.jsx +53 -0
  278. package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
  279. package/src/HorizontalScroll/dictionary.js +11 -0
  280. package/src/HorizontalScroll/index.js +17 -0
  281. package/src/HorizontalScroll/itemPositions.js +101 -0
  282. package/src/Icon/Icon.jsx +43 -50
  283. package/src/Icon/IconText.jsx +23 -18
  284. package/src/Icon/index.js +2 -2
  285. package/src/IconButton/IconButton.jsx +114 -0
  286. package/src/IconButton/index.js +3 -0
  287. package/src/InputLabel/InputLabel.jsx +57 -35
  288. package/src/InputLabel/LabelContent.jsx +21 -0
  289. package/src/InputLabel/LabelContent.native.jsx +11 -2
  290. package/src/InputSupports/InputSupports.jsx +29 -45
  291. package/src/InputSupports/useInputSupports.js +30 -0
  292. package/src/Link/ChevronLink.jsx +26 -16
  293. package/src/Link/{InlinePressable.web.jsx → InlinePressable.jsx} +5 -3
  294. package/src/Link/InlinePressable.native.jsx +5 -3
  295. package/src/Link/Link.jsx +22 -16
  296. package/src/Link/LinkBase.jsx +76 -65
  297. package/src/Link/TextButton.jsx +30 -23
  298. package/src/List/List.jsx +5 -4
  299. package/src/List/ListItem.jsx +77 -82
  300. package/src/Modal/Modal.jsx +190 -0
  301. package/src/Modal/dictionary.js +9 -0
  302. package/src/Modal/index.js +3 -0
  303. package/src/Notification/Notification.jsx +164 -0
  304. package/src/Notification/dictionary.js +8 -0
  305. package/src/Notification/index.js +3 -0
  306. package/src/Pagination/PageButton.jsx +42 -35
  307. package/src/Pagination/Pagination.jsx +88 -92
  308. package/src/Pagination/SideButton.jsx +44 -41
  309. package/src/Progress/Progress.jsx +78 -0
  310. package/src/Progress/ProgressBar.jsx +123 -0
  311. package/src/Progress/ProgressBarBackground.jsx +36 -0
  312. package/src/Progress/index.js +6 -0
  313. package/src/Radio/Radio.jsx +82 -112
  314. package/src/Radio/RadioButton.jsx +142 -0
  315. package/src/Radio/RadioGroup.jsx +209 -0
  316. package/src/Radio/{RadioInput.web.jsx → RadioInput.jsx} +0 -0
  317. package/src/Radio/index.js +2 -0
  318. package/src/RadioCard/RadioCard.jsx +198 -0
  319. package/src/RadioCard/RadioCardGroup.jsx +218 -0
  320. package/src/RadioCard/index.js +5 -0
  321. package/src/Search/Search.jsx +225 -0
  322. package/src/Search/dictionary.js +12 -0
  323. package/src/Search/index.js +3 -0
  324. package/src/Select/{Group.web.jsx → Group.jsx} +0 -0
  325. package/src/Select/{Item.web.jsx → Item.jsx} +0 -0
  326. package/src/Select/Picker.jsx +74 -0
  327. package/src/Select/Picker.native.jsx +56 -49
  328. package/src/Select/Select.jsx +125 -92
  329. package/src/SideNav/Item.jsx +54 -47
  330. package/src/SideNav/ItemsGroup.jsx +50 -43
  331. package/src/SideNav/SideNav.jsx +68 -60
  332. package/src/Skeleton/Skeleton.jsx +25 -32
  333. package/src/Skeleton/skeleton.constant.js +3 -0
  334. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  335. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  336. package/src/Spacer/Spacer.jsx +11 -4
  337. package/src/StackView/StackView.jsx +54 -23
  338. package/src/StackView/StackWrap.jsx +16 -7
  339. package/src/StackView/StackWrapBox.jsx +63 -28
  340. package/src/StackView/StackWrapGap.jsx +46 -24
  341. package/src/StackView/common.jsx +3 -2
  342. package/src/StackView/getStackedContent.jsx +8 -2
  343. package/src/StepTracker/Step.jsx +202 -0
  344. package/src/StepTracker/StepTracker.jsx +174 -0
  345. package/src/StepTracker/dictionary.js +10 -0
  346. package/src/StepTracker/index.js +3 -0
  347. package/src/Tabs/Tabs.jsx +97 -0
  348. package/src/Tabs/TabsItem.jsx +212 -0
  349. package/src/Tabs/index.js +3 -0
  350. package/src/Tags/Tags.jsx +115 -102
  351. package/src/TextInput/TextArea.jsx +5 -4
  352. package/src/TextInput/TextInput.jsx +5 -4
  353. package/src/TextInput/TextInputBase.jsx +95 -98
  354. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  355. package/src/ThemeProvider/useSetTheme.js +4 -0
  356. package/src/ThemeProvider/useThemeTokens.js +2 -2
  357. package/src/ThemeProvider/utils/styles.js +18 -5
  358. package/src/ThemeProvider/utils/theme-tokens.js +74 -5
  359. package/src/ToggleSwitch/ToggleSwitch.jsx +50 -52
  360. package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
  361. package/src/Tooltip/Tooltip.jsx +135 -131
  362. package/src/TooltipButton/TooltipButton.jsx +23 -27
  363. package/src/Typography/Typography.jsx +71 -47
  364. package/src/index.js +23 -2
  365. package/src/utils/a11y/index.js +1 -0
  366. package/src/utils/a11y/semantics.js +162 -0
  367. package/src/utils/children.jsx +119 -0
  368. package/src/utils/index.js +3 -0
  369. package/src/utils/info/platform/platform.js +1 -0
  370. package/src/utils/info/versions.js +2 -2
  371. package/src/utils/input.js +36 -25
  372. package/src/utils/pressability.js +4 -0
  373. package/src/utils/propTypes.js +199 -72
  374. package/src/utils/useCopy.js +30 -4
  375. package/src/utils/useHash.js +39 -0
  376. package/src/utils/useHash.native.js +6 -0
  377. package/stories/A11yText/A11yText.stories.jsx +6 -10
  378. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
  379. package/stories/Box/Box.stories.jsx +1 -1
  380. package/stories/Button/Button.stories.jsx +2 -2
  381. package/stories/Button/ButtonGroup.stories.jsx +1 -1
  382. package/stories/Button/ButtonLink.stories.jsx +1 -1
  383. package/stories/Card/Card.stories.jsx +1 -1
  384. package/stories/Checkbox/Checkbox.stories.jsx +24 -1
  385. package/stories/Divider/Divider.stories.jsx +1 -1
  386. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
  387. package/stories/Feedback/Feedback.stories.jsx +1 -1
  388. package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
  389. package/stories/FlexGrid/02 Row.stories.jsx +1 -1
  390. package/stories/FlexGrid/03 Col.stories.jsx +1 -1
  391. package/stories/Icon/Icon.stories.jsx +27 -7
  392. package/stories/IconButton/IconButton.stories.jsx +50 -0
  393. package/stories/InputLabel/InputLabel.stories.jsx +1 -1
  394. package/stories/Link/ChevronLink.stories.jsx +1 -1
  395. package/stories/Link/Link.stories.jsx +17 -21
  396. package/stories/Link/TextButton.stories.jsx +1 -1
  397. package/stories/List/List.stories.jsx +1 -1
  398. package/stories/Modal/Modal.stories.jsx +29 -0
  399. package/stories/Notification/Notification.stories.jsx +82 -0
  400. package/stories/Pagination/Pagination.stories.jsx +1 -1
  401. package/stories/Progress/Progress.stories.jsx +93 -0
  402. package/stories/Radio/Radio.stories.jsx +23 -36
  403. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  404. package/stories/Search/Search.stories.jsx +16 -0
  405. package/stories/Select/Select.stories.jsx +1 -1
  406. package/stories/SideNav/SideNav.stories.jsx +1 -1
  407. package/stories/SideNav/SideNavItem.stories.jsx +1 -1
  408. package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
  409. package/stories/Skeleton/Skeleton.stories.jsx +2 -2
  410. package/stories/Spacer/Spacer.stories.jsx +1 -1
  411. package/stories/StackView/StackView.stories.jsx +1 -1
  412. package/stories/StackView/StackWrap.stories.jsx +1 -1
  413. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  414. package/stories/Tabs/Tabs.stories.jsx +97 -0
  415. package/stories/Tags/Tags.stories.jsx +1 -1
  416. package/stories/TextInput/TextArea.stories.jsx +1 -1
  417. package/stories/TextInput/TextInput.stories.jsx +1 -1
  418. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
  419. package/stories/Tooltip/Tooltip.stories.jsx +1 -1
  420. package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
  421. package/stories/Typography/Typography.stories.jsx +1 -1
  422. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  423. package/stories/supports.jsx +37 -3
  424. package/__fixtures__/accessible.icon.svg +0 -6
  425. package/babel.config.json +0 -8
  426. package/docs/Contributing.stories.mdx +0 -9
  427. package/docs/Fonts.stories.mdx +0 -104
  428. package/docs/Icons.stories.mdx +0 -144
  429. package/docs/Introduction.stories.mdx +0 -9
  430. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  431. package/lib/Checkbox/CheckboxInput.web.js +0 -57
  432. package/lib/InputLabel/LabelContent.web.js +0 -17
  433. package/lib/Link/InlinePressable.web.js +0 -32
  434. package/lib/Radio/RadioInput.web.js +0 -59
  435. package/lib/Select/Group.web.js +0 -18
  436. package/lib/Select/Item.web.js +0 -15
  437. package/lib/Select/Picker.web.js +0 -63
  438. package/lib/config/svgr-icons-web.js +0 -9
  439. package/lib/config/svgr-icons.js +0 -52
  440. package/lib/utils/info/platform/platform.web.js +0 -1
  441. package/src/InputLabel/LabelContent.web.jsx +0 -13
  442. package/src/Select/Picker.web.jsx +0 -67
  443. package/src/config/svgr-icons-web.js +0 -11
  444. package/src/config/svgr-icons.js +0 -46
  445. package/src/utils/info/platform/platform.web.js +0 -1
@@ -0,0 +1,94 @@
1
+ import React from 'react'
2
+ import { render, within } from '@testing-library/react-native'
3
+
4
+ import { StepTracker } from '../../src'
5
+ import Theme from '../../__fixtures__/Theme'
6
+ import Viewport from '../../__fixtures__/Viewport'
7
+ import dictionary from '../../src/StepTracker/dictionary'
8
+
9
+ const defaultSteps = [...Array(5).keys()].map((key) => `Some Step Title ${key + 1}`)
10
+
11
+ const setup = ({ current, steps = defaultSteps, tokens, viewport }) =>
12
+ render(
13
+ <Theme>
14
+ <Viewport viewport={viewport}>
15
+ <StepTracker current={current} steps={steps} tokens={tokens} />
16
+ </Viewport>
17
+ </Theme>
18
+ )
19
+
20
+ describe('StepTracker', () => {
21
+ const currentStep = 2
22
+
23
+ it('renders the steps properly', () => {
24
+ const { getAllByTestId, getByA11yLabel } = setup({ current: currentStep })
25
+
26
+ expect(getAllByTestId(/StepTracker-Step/).length).toBe(defaultSteps.length)
27
+ expect(getAllByTestId(/StepTracker-Step-Completed/).length).toBe(
28
+ defaultSteps.length - currentStep - 1
29
+ )
30
+ expect(
31
+ within(getByA11yLabel(defaultSteps[currentStep])).getByTestId('StepTracker-Step-Current')
32
+ ).toBeTruthy()
33
+ })
34
+
35
+ it('only displays the step tracker label and no step labels on small screens', () => {
36
+ const { getByText, queryByText } = setup({
37
+ viewport: 'sm'
38
+ })
39
+
40
+ const stepTrackerLabel = dictionary.en.stepTrackerLabel
41
+ .replace('%{stepNumber}', 1)
42
+ .replace('%{stepCount}', defaultSteps.length)
43
+ .replace('%{stepLabel}', defaultSteps[0])
44
+ expect(getByText(stepTrackerLabel)).toBeTruthy()
45
+ expect(queryByText(defaultSteps[1])).toBeFalsy()
46
+ })
47
+
48
+ it('only displays the step labels and no step tracker label on large screens', () => {
49
+ const { getByText, queryByText } = setup({
50
+ viewport: 'lg'
51
+ })
52
+
53
+ const stepTrackerLabel = dictionary.en.stepTrackerLabel
54
+ .replace('%{stepNumber}', 1)
55
+ .replace('%{stepCount}', defaultSteps.length)
56
+ .replace('%{stepLabel}', defaultSteps[0])
57
+ expect(queryByText(stepTrackerLabel)).toBeFalsy()
58
+ expect(getByText(defaultSteps[1])).toBeTruthy()
59
+ })
60
+
61
+ it('displays the step tracker label if requested', () => {
62
+ const { getByText, queryByText } = setup({
63
+ current: currentStep,
64
+ tokens: { showStepTrackerLabel: true }
65
+ })
66
+
67
+ defaultSteps.forEach((stepTitle) => {
68
+ if (defaultSteps.indexOf(stepTitle) === currentStep) {
69
+ const stepTrackerLabel = dictionary.en.stepTrackerLabel
70
+ .replace('%{stepNumber}', currentStep + 1)
71
+ .replace('%{stepCount}', defaultSteps.length)
72
+ .replace('%{stepLabel}', stepTitle)
73
+ expect(getByText(stepTrackerLabel)).toBeTruthy()
74
+ } else {
75
+ expect(queryByText(stepTitle)).toBeFalsy()
76
+ }
77
+ })
78
+ })
79
+
80
+ it('displays the step names and titles if requested', () => {
81
+ const { getByText } = setup({ tokens: { showStepLabel: true } })
82
+
83
+ defaultSteps.forEach((stepTitle, index) => {
84
+ expect(getByText(dictionary.en.stepLabel.replace('%{stepNumber}', index + 1))).toBeTruthy()
85
+ expect(getByText(stepTitle)).toBeTruthy()
86
+ })
87
+ })
88
+
89
+ it('hides step names if requested', () => {
90
+ const { getByText } = setup({ tokens: { showStepLabel: true, showStepName: false } })
91
+
92
+ defaultSteps.forEach((stepTitle) => expect(getByText(stepTitle)).toBeTruthy())
93
+ })
94
+ })
@@ -0,0 +1,40 @@
1
+ import React from 'react'
2
+ import { fireEvent, render } from '@testing-library/react-native'
3
+
4
+ import { Tabs } from '../../src'
5
+ import Theme from '../../__fixtures__/Theme'
6
+
7
+ describe('Tabs', () => {
8
+ const items = [{ label: 'one' }, { label: 'two' }, { label: 'three' }, { label: 'four' }]
9
+ const linkItems = items.map((item) => ({ ...item, href: 'https://telus.com' }))
10
+
11
+ it('renders a menu', () => {
12
+ const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
13
+ expect(queryAllByA11yRole('tablist')).toHaveLength(1)
14
+ })
15
+
16
+ it('renders menuitems by default', () => {
17
+ const { queryAllByA11yRole } = render(<Tabs items={items} />, { wrapper: Theme })
18
+ expect(queryAllByA11yRole('tab')).toHaveLength(4)
19
+ expect(queryAllByA11yRole('link')).toHaveLength(0)
20
+ })
21
+
22
+ it('renders links by if hrefs are passed', () => {
23
+ const { queryAllByA11yRole } = render(<Tabs items={linkItems} />, { wrapper: Theme })
24
+ expect(queryAllByA11yRole('tab')).toHaveLength(0)
25
+ expect(queryAllByA11yRole('link')).toHaveLength(4)
26
+ })
27
+
28
+ it('is selected when pressed', () => {
29
+ const { queryByA11yState, getByText } = render(<Tabs items={items} />, { wrapper: Theme })
30
+ let selected
31
+ selected = queryByA11yState({ selected: true })
32
+ expect(selected).toBeFalsy()
33
+
34
+ fireEvent.press(getByText('two'))
35
+
36
+ selected = queryByA11yState({ selected: true })
37
+ expect(selected).toBeTruthy()
38
+ expect(selected).toHaveTextContent('two')
39
+ })
40
+ })
@@ -143,7 +143,7 @@ describe('Tags (uncontrolled)', () => {
143
143
  </Theme>
144
144
  )
145
145
 
146
- expect(queryAllByA11yRole('radioGroup')).toHaveLength(0)
146
+ expect(queryAllByA11yRole('radiogroup')).toHaveLength(0)
147
147
  expect(queryAllByA11yRole('radio')).toHaveLength(0)
148
148
 
149
149
  const checks = queryAllByA11yRole('checkbox')
@@ -238,15 +238,14 @@ describe('Tags (controlled)', () => {
238
238
  expect(handleChange).toHaveBeenCalledTimes(0)
239
239
 
240
240
  const one = getByText('One')
241
- await fireEvent.press(one)
241
+ await fireEvent(one, 'press', { nativeEvent: 'example' })
242
242
  expect(handleChange).toHaveBeenCalledTimes(1)
243
-
244
- expect(handleChange.mock.calls[0][0]).toEqual(['one'])
243
+ expect(handleChange).toHaveBeenLastCalledWith(['one'], { nativeEvent: 'example' })
245
244
 
246
245
  const two = getByText('Two')
247
- await fireEvent.press(two)
246
+ await fireEvent(two, 'press', { nativeEvent: 'example2' })
248
247
  expect(handleChange).toHaveBeenCalledTimes(2)
249
- expect(handleChange.mock.calls[1][0]).toEqual(['two'])
248
+ expect(handleChange).toHaveBeenLastCalledWith(['two'], { nativeEvent: 'example2' })
250
249
  })
251
250
 
252
251
  it("Doesn't change its own selection if `values` is passed", async () => {
@@ -1,9 +1,10 @@
1
1
  import React from 'react'
2
- import { fireEvent, render } from '@testing-library/react-native'
2
+ import { render } from '@testing-library/react-native'
3
3
 
4
4
  import { Platform } from 'react-native'
5
5
  import { TextArea } from '../../src'
6
6
  import Theme from '../../__fixtures__/Theme'
7
+ import { fireChange } from '../../__fixtures__/test-utils'
7
8
 
8
9
  describe('TextArea', () => {
9
10
  it('renders', () => {
@@ -26,7 +27,7 @@ describe('TextArea', () => {
26
27
 
27
28
  expect(textarea).toHaveStyle({ height: 20 })
28
29
 
29
- fireEvent.changeText(textarea, '\n\n\n')
30
+ fireChange(textarea, '\n\n\n')
30
31
 
31
32
  expect(textarea).toHaveStyle({ height: 60 })
32
33
  })
@@ -3,6 +3,7 @@ import React from 'react'
3
3
  import TextInputBase from '../../src/TextInput/TextInputBase'
4
4
  import Viewport from '../../__fixtures__/Viewport'
5
5
  import Theme from '../../__fixtures__/Theme'
6
+ import { getMockEvent, fireChange } from '../../__fixtures__/test-utils'
6
7
 
7
8
  // eslint-disable-next-line react/prop-types
8
9
  const Wrapper = ({ children }) => (
@@ -11,6 +12,9 @@ const Wrapper = ({ children }) => (
11
12
  </Viewport>
12
13
  )
13
14
 
15
+ const text = 'new value'
16
+ const changeEvent = getMockEvent({ text })
17
+
14
18
  describe('TextInputBaseBase', () => {
15
19
  it('triggers the interactive callbacks', () => {
16
20
  const onFocus = jest.fn()
@@ -73,9 +77,9 @@ describe('TextInputBaseBase', () => {
73
77
  const input = getByA11yLabel('Input label')
74
78
 
75
79
  expect(onChange).not.toHaveBeenCalled()
76
- fireEvent.changeText(input, 'new value')
80
+ fireChange(input, text)
77
81
  expect(onChange).toHaveBeenCalledTimes(1)
78
- expect(onChange).toHaveBeenLastCalledWith('new value')
82
+ expect(onChange).toHaveBeenLastCalledWith(text, changeEvent)
79
83
  })
80
84
 
81
85
  it('changes value when controlled', () => {
@@ -91,9 +95,10 @@ describe('TextInputBaseBase', () => {
91
95
  const input = getByA11yLabel('Input label')
92
96
 
93
97
  expect(onChange).not.toHaveBeenCalled()
94
- fireEvent.changeText(input, 'new value')
98
+
99
+ fireChange(input, text)
95
100
  expect(onChange).toHaveBeenCalledTimes(1)
96
- expect(onChange).toHaveBeenLastCalledWith('new value')
101
+ expect(onChange).toHaveBeenLastCalledWith(text, changeEvent)
97
102
  })
98
103
 
99
104
  it("doesn't change value when readOnly", () => {
@@ -114,7 +119,7 @@ describe('TextInputBaseBase', () => {
114
119
  const input = getByA11yLabel('Input label')
115
120
 
116
121
  expect(onChange).not.toHaveBeenCalled()
117
- fireEvent.changeText(input, 'new value')
122
+ fireChange(input, text)
118
123
  expect(onChange).not.toHaveBeenCalled()
119
124
  })
120
125
  })
@@ -0,0 +1,77 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { renderHook } from '@testing-library/react-hooks'
4
+ import semVerSatisfies from 'semver/functions/satisfies'
5
+ import ThemeProvider, { useTheme, useSetTheme } from '../../src/ThemeProvider'
6
+ import pkg from '../../package.json'
7
+
8
+ jest.mock('semver/functions/satisfies')
9
+
10
+ const expectedThemeTokensVersion = 'expected'
11
+ const actualThemeTokensVersion = 'actual'
12
+ pkg.dependencies['@telus-uds/system-theme-tokens'] = expectedThemeTokensVersion
13
+ const theme = {
14
+ metadata: {
15
+ name: 'tokens-test',
16
+ themeTokensVersion: actualThemeTokensVersion
17
+ },
18
+ components: {}
19
+ }
20
+
21
+ beforeEach(() => {
22
+ semVerSatisfies.mockReset()
23
+ })
24
+
25
+ describe('Uninitialized ThemeProvider context', () => {
26
+ test('throws on useTheme', () => {
27
+ const { result } = renderHook(useTheme)
28
+ expect(() => result.current).toThrow('Theme context used outside of ThemeProvider')
29
+ })
30
+
31
+ test('error useSetTheme hook without provider', () => {
32
+ const { result } = renderHook(useSetTheme)
33
+ expect(() => result.current).toThrow('Theme context used outside of ThemeProvider')
34
+ })
35
+ })
36
+
37
+ describe('ThemeProvider theme tokens version validation', () => {
38
+ const renderThemeHook = (hookFn) => {
39
+ const ThemeWrapper = ({ children }) => (
40
+ <ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
41
+ )
42
+ ThemeWrapper.propTypes = { children: PropTypes.node.isRequired }
43
+
44
+ return renderHook(hookFn, {
45
+ wrapper: ThemeWrapper
46
+ })
47
+ }
48
+
49
+ test('validates theme tokens version with semver', () => {
50
+ semVerSatisfies.mockImplementationOnce(() => true)
51
+
52
+ const { result } = renderThemeHook(useTheme)
53
+
54
+ expect(result.current).toEqual(theme)
55
+ expect(semVerSatisfies).toHaveBeenCalledWith(
56
+ actualThemeTokensVersion,
57
+ expectedThemeTokensVersion
58
+ )
59
+ })
60
+
61
+ test('warning if theme tokens version does not match', () => {
62
+ semVerSatisfies.mockImplementationOnce(() => false)
63
+
64
+ const { result } = renderThemeHook(useTheme)
65
+
66
+ expect(() => result.current).toThrow('Invalid UDS token schema version detected')
67
+ })
68
+
69
+ test('validates on every render', () => {
70
+ semVerSatisfies.mockImplementationOnce(() => true)
71
+
72
+ const { rerender } = renderThemeHook(useTheme)
73
+ rerender()
74
+
75
+ expect(semVerSatisfies).toHaveBeenCalledTimes(2)
76
+ })
77
+ })
@@ -4,10 +4,13 @@ import { renderHook } from '@testing-library/react-hooks'
4
4
 
5
5
  import ThemeProvider from '../../src/ThemeProvider'
6
6
  import { useThemeTokens, useThemeTokensCallback } from '../../src/ThemeProvider/useThemeTokens'
7
- import {
8
- doesThemeRuleApply,
9
- doesThemeConditionApply
10
- } from '../../src/ThemeProvider/utils/theme-tokens'
7
+ import * as tokenUtils from '../../src/ThemeProvider/utils/theme-tokens'
8
+
9
+ // Mock out the function that checks the theme version
10
+ const validateThemeTokensVersion = jest.spyOn(tokenUtils, 'validateThemeTokensVersion')
11
+ validateThemeTokensVersion.mockImplementation(() => undefined)
12
+
13
+ const { doesThemeRuleApply, doesThemeConditionApply } = tokenUtils
11
14
 
12
15
  const componentName = 'TestComponent'
13
16
 
@@ -48,7 +51,8 @@ const defaultTokens = {
48
51
 
49
52
  const theme = {
50
53
  metadata: {
51
- name: 'tokens-test'
54
+ name: 'tokens-test',
55
+ themeTokensVersion: 'test-version'
52
56
  },
53
57
  components: {
54
58
  [componentName]: {
@@ -0,0 +1,41 @@
1
+ import pkg from '../../../package.json'
2
+ import { validateThemeTokensVersion } from '../../../src/ThemeProvider/utils/theme-tokens'
3
+
4
+ function validate({ expectedVersion, actualVersion }) {
5
+ pkg.dependencies['@telus-uds/system-theme-tokens'] = expectedVersion
6
+ const theme = {
7
+ metadata: {
8
+ themeTokensVersion: actualVersion
9
+ }
10
+ }
11
+ validateThemeTokensVersion(theme)
12
+ }
13
+
14
+ describe('validateThemeTokensVersion', () => {
15
+ test('No error on matching version', async () => {
16
+ const expectedVersion = '1.2.3'
17
+ const actualVersion = '1.2.3'
18
+
19
+ validate({ expectedVersion, actualVersion })
20
+
21
+ // No errors, no problem...
22
+ })
23
+
24
+ test('Throws if theme version is old', async () => {
25
+ const expectedVersion = '^2.3.4'
26
+ const actualVersion = '2.3.3'
27
+
28
+ expect(() => validate({ expectedVersion, actualVersion })).toThrow(
29
+ 'Invalid UDS token schema version detected.'
30
+ )
31
+ })
32
+
33
+ test('Throws if theme version is new', async () => {
34
+ const expectedVersion = '^1.2.3'
35
+ const actualVersion = '2.3.4'
36
+
37
+ expect(() => validate({ expectedVersion, actualVersion })).toThrow(
38
+ 'Invalid UDS token schema version detected.'
39
+ )
40
+ })
41
+ })
@@ -63,9 +63,10 @@ describe('ToggleSwitch', () => {
63
63
  expect(handleChange).toHaveBeenCalledTimes(0)
64
64
  const toggleSwitch = getByA11yRole('switch')
65
65
  expect(queryAllByA11yState(checked)).toHaveLength(0)
66
- await fireEvent.press(toggleSwitch)
66
+
67
+ await fireEvent(toggleSwitch, 'press', { nativeEvent: 'example' })
67
68
  expect(handleChange).toHaveBeenCalledTimes(1)
68
- expect(handleChange.mock.calls[0][0]).toEqual(true)
69
+ expect(handleChange).toHaveBeenLastCalledWith(true, { nativeEvent: 'example' })
69
70
  expect(queryAllByA11yState(checked)).toHaveLength(0)
70
71
  })
71
72
  })
@@ -0,0 +1,128 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { render } from '@testing-library/react-native'
4
+ import { Text, View } from 'react-native'
5
+
6
+ import { wrapStringsInText } from '../../src/utils'
7
+ import A11yText from '../../src/A11yText'
8
+
9
+ const TestComponent = ({ children }) => (
10
+ <View testID="wrapper">{wrapStringsInText(children, { testID: 'text' })}</View>
11
+ )
12
+ TestComponent.propTypes = {
13
+ children: PropTypes.node
14
+ }
15
+
16
+ describe('wrapStringsInText', () => {
17
+ it('combines adjacent strings into one text', () => {
18
+ const secondString = 'Second string'
19
+ const { queryAllByTestId } = render(
20
+ <TestComponent>
21
+ First string
22
+ {secondString}
23
+ Third string
24
+ </TestComponent>
25
+ )
26
+ expect(queryAllByTestId('text')).toHaveLength(1)
27
+ })
28
+ it('combines adjacent strings and numbers into one `Text`', () => {
29
+ const { queryAllByTestId } = render(
30
+ <TestComponent>
31
+ First string
32
+ {12345}
33
+ Third string
34
+ </TestComponent>
35
+ )
36
+ expect(queryAllByTestId('text')).toHaveLength(1)
37
+ })
38
+ it('combines adjacent strings, numbers and A11yText into one `Text`', () => {
39
+ const { queryAllByTestId } = render(
40
+ <TestComponent>
41
+ First string
42
+ <A11yText text="Some inserted A11yText" />
43
+ Third string
44
+ </TestComponent>
45
+ )
46
+ expect(queryAllByTestId('text')).toHaveLength(1)
47
+ })
48
+ it('combines clusters seperated by another component into multiple `Text`s', () => {
49
+ const { queryAllByTestId } = render(
50
+ <TestComponent>
51
+ First string
52
+ {12345}
53
+ Third string
54
+ <View />
55
+ Fourth string
56
+ <A11yText text="Some inserted A11yText" />
57
+ Fifth string
58
+ <View />
59
+ Sixth string
60
+ {12345}
61
+ <A11yText text="Some inserted A11yText" />
62
+ Seventh string
63
+ </TestComponent>
64
+ )
65
+ expect(queryAllByTestId('text')).toHaveLength(3)
66
+ })
67
+ it('does not wrap elements that do not need wrapping', () => {
68
+ const { getByTestId, queryAllByTestId } = render(
69
+ <TestComponent>
70
+ Unwrapped text
71
+ {12345}
72
+ <View>
73
+ <Text>
74
+ Wrapped text inside View
75
+ {12345}
76
+ </Text>
77
+ </View>
78
+ More unwrapped text
79
+ {12345}
80
+ <Text>
81
+ Wrapped text separate from above unwrapped text
82
+ {12345}
83
+ </Text>
84
+ </TestComponent>
85
+ )
86
+ expect(queryAllByTestId('text')).toHaveLength(2)
87
+ expect(getByTestId('wrapper').children.map((child) => child.type)).toEqual([
88
+ Text,
89
+ View,
90
+ Text,
91
+ Text
92
+ ])
93
+ })
94
+ it('does not wrap a singular A11yText in `Text`', () => {
95
+ const { queryAllByTestId } = render(
96
+ <TestComponent>
97
+ <A11yText text="Some inserted A11yText" />
98
+ </TestComponent>
99
+ )
100
+ expect(queryAllByTestId('text')).toHaveLength(0)
101
+ })
102
+ it('does not wrap an A11yText in `Text` if it is sandwiched by non-text', () => {
103
+ const { queryAllByTestId } = render(
104
+ <TestComponent>
105
+ First string
106
+ {12345}
107
+ Third string
108
+ <View />
109
+ <A11yText text="Some inserted A11yText" />
110
+ <View />
111
+ Sixth string
112
+ {12345}
113
+ <A11yText text="Some inserted A11yText" />
114
+ Seventh string
115
+ </TestComponent>
116
+ )
117
+ expect(queryAllByTestId('text')).toHaveLength(2)
118
+ })
119
+ it('does not double-wrap already wrapped `Text`', () => {
120
+ const { queryAllByTestId } = render(
121
+ <TestComponent>
122
+ <Text>Already wrapped</Text>
123
+ <Text>Also already wrapped</Text>
124
+ </TestComponent>
125
+ )
126
+ expect(queryAllByTestId('text')).toHaveLength(0)
127
+ })
128
+ })
@@ -1,6 +1,6 @@
1
1
  import { renderHook, act } from '@testing-library/react-hooks'
2
2
 
3
- import { useInputValue, useMultipleInputValues } from '../../lib/utils'
3
+ import { useInputValue, useMultipleInputValues } from '../../src/utils'
4
4
 
5
5
  /**
6
6
  * Tests for errors thrown on incorrect props usage
@@ -90,6 +90,17 @@ describe('useInputValue (uncontrolled)', () => {
90
90
  expect(result.current.currentValue).toBe('some value')
91
91
  })
92
92
 
93
+ it('Changes currentValue based on old value when `setValue` is passed a function', () => {
94
+ const { result } = renderHook(() => useInputValue({ initialValue: 1 }))
95
+ expect(result.current.currentValue).toBe(1)
96
+
97
+ act(() => result.current.setValue((oldValue) => oldValue + 1))
98
+ expect(result.current.currentValue).toBe(2)
99
+
100
+ act(() => result.current.setValue((oldValue) => oldValue + 2))
101
+ expect(result.current.currentValue).toBe(4)
102
+ })
103
+
93
104
  it('Sets currentValue to initialValue if provided, which may be changed', () => {
94
105
  const { result } = renderHook(() => useInputValue({ initialValue: 'first value' }))
95
106
  expect(result.current.currentValue).toBe('first value')
@@ -210,6 +221,29 @@ describe('useMultipleInputValues (uncontrolled)', () => {
210
221
  expect(result.current.currentValues).toEqual(['second value', 'third value'])
211
222
  })
212
223
 
224
+ it('Replaces values on calling setValues', () => {
225
+ const { result } = renderHook(() =>
226
+ useMultipleInputValues({
227
+ initialValues: ['first value', 'second value', 'third value']
228
+ })
229
+ )
230
+ act(() => result.current.setValues(['new value', 'another value']))
231
+ expect(result.current.currentValues).toEqual(['new value', 'another value'])
232
+ })
233
+
234
+ it('Replaces values based on old values on passing function to setValues', () => {
235
+ const { result } = renderHook(() =>
236
+ useMultipleInputValues({
237
+ initialValues: [1, 2, 3, 4]
238
+ })
239
+ )
240
+ act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 1)))
241
+ expect(result.current.currentValues).toEqual([2, 3, 4, 5])
242
+
243
+ act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 2)))
244
+ expect(result.current.currentValues).toEqual([4, 5, 6, 7])
245
+ })
246
+
213
247
  it('Empties values on calling unsetValues', () => {
214
248
  const { result } = renderHook(() =>
215
249
  useMultipleInputValues({
@@ -237,6 +271,18 @@ describe('useInputValue (controlled)', () => {
237
271
  expect(onChange.mock.calls[0][0]).toEqual('second value')
238
272
  })
239
273
 
274
+ it('Calls `onChange` with result from old value when `setValue` is passed a function', () => {
275
+ const onChange = jest.fn((arg) => arg)
276
+ const { result } = renderHook(() => useInputValue({ value: 1, onChange }))
277
+ expect(result.current.currentValue).toBe(1)
278
+ expect(onChange).toHaveBeenCalledTimes(0)
279
+
280
+ act(() => result.current.setValue((oldValue) => oldValue + 1))
281
+ expect(result.current.currentValue).toBe(1)
282
+ expect(onChange).toHaveBeenCalledTimes(1)
283
+ expect(onChange.mock.calls[0][0]).toEqual(2)
284
+ })
285
+
240
286
  it('Returns updated `currentValue` when non-undefined `value` prop changes', () => {
241
287
  const onChange = () => {}
242
288
  const { result, rerender } = renderHook(({ value }) => useInputValue({ value, onChange }), {
@@ -296,6 +342,18 @@ describe('useMultipleInputValues (controlled)', () => {
296
342
  expect(onChange.mock.calls[0][0]).toEqual(['second value', 'third value'])
297
343
  })
298
344
 
345
+ it('Calls `onChange` with results from old values when `setValues` is passed a function', () => {
346
+ const onChange = jest.fn((arg) => arg)
347
+ const { result } = renderHook(() => useMultipleInputValues({ values: [1, 2, 3, 4], onChange }))
348
+ expect(result.current.currentValues).toEqual([1, 2, 3, 4])
349
+ expect(onChange).toHaveBeenCalledTimes(0)
350
+
351
+ act(() => result.current.setValues((oldValues) => oldValues.map((value) => value + 1)))
352
+ expect(result.current.currentValues).toEqual([1, 2, 3, 4])
353
+ expect(onChange).toHaveBeenCalledTimes(1)
354
+ expect(onChange.mock.calls[0][0]).toEqual([2, 3, 4, 5])
355
+ })
356
+
299
357
  it('Calls onChange with an empty array on calling unsetValues', () => {
300
358
  const onChange = jest.fn((arg) => arg)
301
359
  const { result, rerender } = renderHook(
@@ -0,0 +1,43 @@
1
+ import { Platform } from 'react-native'
2
+
3
+ import { getA11yPropsFromHtmlTag, tagsToRoles, supportedTags } from '../../src'
4
+
5
+ // Note that currently all tests run as ios so only native logic can be tested here
6
+ // until cross-platform tests are set up. See issue:
7
+ // https://github.com/telus/universal-design-system/issues/319
8
+
9
+ // As a temporary measure, there are tests on web-context HTML output for Box component
10
+ // in @telus-uds/ds-allium which test the actual output when the tags are rendered.
11
+
12
+ // These tests will therefore just test the values returned in a native context.
13
+ describe('getA11yPropsFromHtmlTag', () => {
14
+ it.each(Object.entries(tagsToRoles))(
15
+ 'responds to tag "%s" with accessibilityRole "%s"',
16
+ (tag, role) => {
17
+ expect(getA11yPropsFromHtmlTag(tag)).toEqual({ accessibilityRole: role })
18
+ }
19
+ )
20
+
21
+ it.each([
22
+ [1, 'h1'],
23
+ [2, 'h2'],
24
+ [3, 'h3'],
25
+ [4, 'h4'],
26
+ [5, 'h5'],
27
+ [6, 'h6']
28
+ ])('returns accessibility role "header" and level "%s" for header tag "%s"', (level, tag) => {
29
+ expect(getA11yPropsFromHtmlTag(tag)).toEqual({
30
+ accessibilityRole: 'header',
31
+ accessibilityLevel: level
32
+ })
33
+ })
34
+
35
+ if (Platform.OS !== 'web') {
36
+ it.each(supportedTags.map((tag) => [tag]))(
37
+ 'responds to tag "%s" and an arbitrary nativeRole with given nativeRole override',
38
+ (tag) => {
39
+ expect(getA11yPropsFromHtmlTag(tag, 'link')).toEqual({ accessibilityRole: 'link' })
40
+ }
41
+ )
42
+ }
43
+ })