@telus-uds/components-base 0.0.2-prerelease.6 → 1.0.0

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 (458) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.ultra.cache.json +1 -1
  3. package/CHANGELOG.md +85 -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 +851 -57
  9. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  10. package/__tests__/Button/ButtonBase.test.jsx +2 -31
  11. package/__tests__/Button/ButtonGroup.test.jsx +6 -7
  12. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  13. package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
  14. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  15. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  16. package/__tests__/Icon/Icon.test.jsx +3 -3
  17. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  18. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  19. package/__tests__/Link/LinkBase.test.jsx +0 -14
  20. package/__tests__/List/List.test.jsx +60 -0
  21. package/__tests__/Modal/Modal.test.jsx +47 -0
  22. package/__tests__/Notification/Notification.test.jsx +20 -0
  23. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  24. package/__tests__/Progress/Progress.test.jsx +79 -0
  25. package/__tests__/Radio/Radio.test.jsx +87 -0
  26. package/__tests__/Radio/RadioGroup.test.jsx +220 -0
  27. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  28. package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
  29. package/__tests__/Search/Search.test.jsx +73 -0
  30. package/__tests__/Select/Select.test.jsx +94 -0
  31. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  32. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  33. package/__tests__/Tabs/Tabs.test.jsx +40 -0
  34. package/__tests__/Tags/Tags.test.jsx +327 -0
  35. package/__tests__/TextInput/TextArea.test.jsx +35 -0
  36. package/__tests__/TextInput/{TextInput.test.jsx → TextInputBase.test.jsx} +29 -50
  37. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  38. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
  39. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  40. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  41. package/__tests__/utils/children.test.jsx +128 -0
  42. package/__tests__/utils/input.test.js +59 -1
  43. package/__tests__/utils/semantics.test.jsx +43 -0
  44. package/__tests__/utils/useCopy.test.js +14 -3
  45. package/babel.config.js +20 -0
  46. package/jest.config.js +8 -3
  47. package/lib/A11yInfoProvider/index.js +54 -26
  48. package/lib/A11yText/index.js +45 -17
  49. package/lib/ActivityIndicator/Spinner.js +81 -0
  50. package/lib/ActivityIndicator/Spinner.native.js +129 -91
  51. package/lib/ActivityIndicator/index.js +28 -12
  52. package/lib/ActivityIndicator/shared.js +27 -12
  53. package/lib/BaseProvider/index.js +34 -11
  54. package/lib/Box/Box.js +152 -35
  55. package/lib/Box/index.js +13 -2
  56. package/lib/Button/Button.js +41 -12
  57. package/lib/Button/ButtonBase.js +125 -97
  58. package/lib/Button/ButtonGroup.js +112 -89
  59. package/lib/Button/ButtonLink.js +48 -17
  60. package/lib/Button/index.js +31 -4
  61. package/lib/Button/propTypes.js +32 -9
  62. package/lib/Card/Card.js +38 -41
  63. package/lib/Card/CardBase.js +85 -0
  64. package/lib/Card/PressableCardBase.js +141 -0
  65. package/lib/Card/index.js +40 -2
  66. package/lib/Checkbox/Checkbox.js +355 -0
  67. package/lib/Checkbox/CheckboxGroup.js +241 -0
  68. package/lib/Checkbox/CheckboxInput.js +74 -0
  69. package/lib/Checkbox/CheckboxInput.native.js +14 -0
  70. package/lib/Checkbox/index.js +21 -0
  71. package/lib/Divider/Divider.js +59 -28
  72. package/lib/Divider/index.js +13 -2
  73. package/lib/ExpandCollapse/Accordion.js +26 -7
  74. package/lib/ExpandCollapse/Control.js +60 -31
  75. package/lib/ExpandCollapse/ExpandCollapse.js +50 -28
  76. package/lib/ExpandCollapse/Panel.js +83 -44
  77. package/lib/ExpandCollapse/index.js +25 -7
  78. package/lib/Feedback/Feedback.js +90 -39
  79. package/lib/Feedback/index.js +13 -2
  80. package/lib/Fieldset/Fieldset.js +165 -0
  81. package/lib/Fieldset/FieldsetContainer.js +46 -0
  82. package/lib/Fieldset/FieldsetContainer.native.js +38 -0
  83. package/lib/Fieldset/Legend.js +38 -0
  84. package/lib/Fieldset/Legend.native.js +48 -0
  85. package/lib/Fieldset/cssReset.js +21 -0
  86. package/lib/Fieldset/index.js +13 -0
  87. package/lib/FlexGrid/Col/Col.js +73 -41
  88. package/lib/FlexGrid/Col/index.js +13 -2
  89. package/lib/FlexGrid/FlexGrid.js +99 -49
  90. package/lib/FlexGrid/Row/Row.js +58 -30
  91. package/lib/FlexGrid/Row/index.js +13 -2
  92. package/lib/FlexGrid/helpers/index.js +9 -1
  93. package/lib/FlexGrid/index.js +13 -2
  94. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  95. package/lib/HorizontalScroll/HorizontalScroll.js +200 -0
  96. package/lib/HorizontalScroll/HorizontalScrollButton.js +127 -0
  97. package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
  98. package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
  99. package/lib/HorizontalScroll/dictionary.js +18 -0
  100. package/lib/HorizontalScroll/index.js +35 -0
  101. package/lib/HorizontalScroll/itemPositions.js +128 -0
  102. package/lib/Icon/Icon.js +62 -50
  103. package/lib/Icon/IconText.js +101 -0
  104. package/lib/Icon/index.js +31 -3
  105. package/lib/IconButton/IconButton.js +140 -0
  106. package/lib/IconButton/index.js +13 -0
  107. package/lib/InputLabel/InputLabel.js +102 -40
  108. package/lib/InputLabel/LabelContent.js +41 -0
  109. package/lib/InputLabel/LabelContent.native.js +32 -6
  110. package/lib/InputLabel/index.js +13 -2
  111. package/lib/InputSupports/InputSupports.js +109 -0
  112. package/lib/InputSupports/index.js +13 -0
  113. package/lib/InputSupports/propTypes.js +66 -0
  114. package/lib/InputSupports/useInputSupports.js +41 -0
  115. package/lib/Link/ChevronLink.js +58 -31
  116. package/lib/Link/InlinePressable.js +56 -0
  117. package/lib/Link/InlinePressable.native.js +102 -0
  118. package/lib/Link/Link.js +39 -15
  119. package/lib/Link/LinkBase.js +126 -150
  120. package/lib/Link/TextButton.js +53 -18
  121. package/lib/Link/index.js +39 -4
  122. package/lib/List/List.js +81 -0
  123. package/lib/List/ListItem.js +245 -0
  124. package/lib/List/index.js +13 -0
  125. package/lib/Modal/Modal.js +231 -0
  126. package/lib/Modal/dictionary.js +16 -0
  127. package/lib/Modal/index.js +13 -0
  128. package/lib/Notification/Notification.js +216 -0
  129. package/lib/Notification/dictionary.js +15 -0
  130. package/lib/Notification/index.js +13 -0
  131. package/lib/Pagination/PageButton.js +58 -48
  132. package/lib/Pagination/Pagination.js +78 -43
  133. package/lib/Pagination/SideButton.js +79 -58
  134. package/lib/Pagination/dictionary.js +9 -2
  135. package/lib/Pagination/index.js +13 -2
  136. package/lib/Pagination/usePagination.js +12 -2
  137. package/lib/Progress/Progress.js +104 -0
  138. package/lib/Progress/ProgressBar.js +157 -0
  139. package/lib/Progress/ProgressBarBackground.js +61 -0
  140. package/lib/Progress/index.js +16 -0
  141. package/lib/Radio/Radio.js +293 -0
  142. package/lib/Radio/RadioButton.js +152 -0
  143. package/lib/Radio/RadioGroup.js +244 -0
  144. package/lib/Radio/RadioInput.js +76 -0
  145. package/lib/Radio/RadioInput.native.js +14 -0
  146. package/lib/Radio/index.js +21 -0
  147. package/lib/RadioCard/RadioCard.js +244 -0
  148. package/lib/RadioCard/RadioCardGroup.js +252 -0
  149. package/lib/RadioCard/index.js +21 -0
  150. package/lib/Search/Search.js +254 -0
  151. package/lib/Search/dictionary.js +19 -0
  152. package/lib/Search/index.js +13 -0
  153. package/lib/Select/Group.js +33 -0
  154. package/lib/Select/Group.native.js +25 -0
  155. package/lib/Select/Item.js +29 -0
  156. package/lib/Select/Item.native.js +19 -0
  157. package/lib/Select/Picker.js +84 -0
  158. package/lib/Select/Picker.native.js +130 -0
  159. package/lib/Select/Select.js +342 -0
  160. package/lib/Select/index.js +19 -0
  161. package/lib/SideNav/Item.js +63 -37
  162. package/lib/SideNav/ItemContent.js +41 -15
  163. package/lib/SideNav/ItemsGroup.js +55 -31
  164. package/lib/SideNav/SideNav.js +100 -73
  165. package/lib/SideNav/index.js +15 -1
  166. package/lib/Skeleton/Skeleton.js +137 -0
  167. package/lib/Skeleton/index.js +13 -0
  168. package/lib/Skeleton/skeleton.constant.js +12 -0
  169. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  170. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  171. package/lib/Spacer/Spacer.js +49 -18
  172. package/lib/Spacer/index.js +13 -2
  173. package/lib/StackView/StackView.js +71 -31
  174. package/lib/StackView/StackWrap.js +43 -13
  175. package/lib/StackView/StackWrap.native.js +13 -2
  176. package/lib/StackView/StackWrapBox.js +76 -29
  177. package/lib/StackView/StackWrapGap.js +56 -26
  178. package/lib/StackView/common.js +23 -6
  179. package/lib/StackView/getStackedContent.js +47 -17
  180. package/lib/StackView/index.js +29 -5
  181. package/lib/StepTracker/Step.js +245 -0
  182. package/lib/StepTracker/StepTracker.js +202 -0
  183. package/lib/StepTracker/dictionary.js +17 -0
  184. package/lib/StepTracker/index.js +13 -0
  185. package/lib/Tabs/Tabs.js +124 -0
  186. package/lib/Tabs/TabsItem.js +238 -0
  187. package/lib/Tabs/index.js +13 -0
  188. package/lib/Tags/Tags.js +266 -0
  189. package/lib/Tags/index.js +13 -0
  190. package/lib/TextInput/TextArea.js +111 -0
  191. package/lib/TextInput/TextInput.js +50 -304
  192. package/lib/TextInput/TextInputBase.js +256 -0
  193. package/lib/TextInput/index.js +23 -2
  194. package/lib/TextInput/propTypes.js +42 -0
  195. package/lib/ThemeProvider/ThemeProvider.js +46 -18
  196. package/lib/ThemeProvider/index.js +61 -6
  197. package/lib/ThemeProvider/useSetTheme.js +19 -5
  198. package/lib/ThemeProvider/useTheme.js +13 -4
  199. package/lib/ThemeProvider/useThemeTokens.js +86 -19
  200. package/lib/ThemeProvider/utils/index.js +31 -2
  201. package/lib/ThemeProvider/utils/styles.js +50 -14
  202. package/lib/ThemeProvider/utils/theme-tokens.js +121 -12
  203. package/lib/ToggleSwitch/ToggleSwitch.js +86 -57
  204. package/lib/ToggleSwitch/index.js +13 -2
  205. package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +20 -8
  206. package/lib/Tooltip/Backdrop.native.js +39 -15
  207. package/lib/Tooltip/Tooltip.js +117 -74
  208. package/lib/Tooltip/dictionary.js +9 -2
  209. package/lib/Tooltip/getTooltipPosition.js +9 -1
  210. package/lib/Tooltip/index.js +13 -2
  211. package/lib/TooltipButton/TooltipButton.js +57 -38
  212. package/lib/TooltipButton/index.js +13 -2
  213. package/lib/Typography/Typography.js +86 -55
  214. package/lib/Typography/index.js +13 -2
  215. package/lib/ViewportProvider/ViewportProvider.js +34 -13
  216. package/lib/ViewportProvider/index.js +28 -3
  217. package/lib/ViewportProvider/useViewport.js +15 -3
  218. package/lib/ViewportProvider/useViewportListener.js +24 -10
  219. package/lib/index.js +539 -26
  220. package/lib/utils/a11y/index.js +31 -0
  221. package/lib/utils/a11y/semantics.js +173 -0
  222. package/lib/utils/a11y/textSize.js +49 -0
  223. package/lib/utils/animation/index.js +15 -2
  224. package/lib/utils/animation/useVerticalExpandAnimation.js +27 -10
  225. package/lib/utils/children.js +134 -0
  226. package/lib/utils/index.js +163 -7
  227. package/lib/utils/info/index.js +19 -0
  228. package/lib/utils/info/platform/index.js +23 -0
  229. package/lib/utils/info/platform/platform.android.js +8 -0
  230. package/lib/utils/info/platform/platform.ios.js +8 -0
  231. package/lib/utils/info/platform/platform.js +8 -0
  232. package/lib/utils/info/platform/platform.native.js +11 -0
  233. package/lib/utils/info/versions.js +16 -0
  234. package/lib/utils/input.js +53 -25
  235. package/lib/utils/pressability.js +120 -0
  236. package/lib/utils/propTypes.js +338 -132
  237. package/lib/utils/useCopy.js +40 -5
  238. package/lib/utils/useHash.js +52 -0
  239. package/lib/utils/useHash.native.js +15 -0
  240. package/lib/utils/useResponsiveProp.js +21 -9
  241. package/lib/utils/useSpacingScale.js +19 -9
  242. package/lib/utils/useUniqueId.js +12 -3
  243. package/package.json +16 -10
  244. package/release-context.json +4 -4
  245. package/src/A11yText/index.jsx +6 -4
  246. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +5 -3
  247. package/src/ActivityIndicator/Spinner.native.jsx +5 -3
  248. package/src/Box/Box.jsx +131 -39
  249. package/src/Button/Button.jsx +13 -6
  250. package/src/Button/ButtonBase.jsx +134 -125
  251. package/src/Button/ButtonGroup.jsx +85 -86
  252. package/src/Button/ButtonLink.jsx +22 -7
  253. package/src/Button/propTypes.js +12 -2
  254. package/src/Card/Card.jsx +5 -31
  255. package/src/Card/CardBase.jsx +58 -0
  256. package/src/Card/PressableCardBase.jsx +119 -0
  257. package/src/Card/index.js +3 -0
  258. package/src/Checkbox/Checkbox.jsx +284 -0
  259. package/src/Checkbox/CheckboxGroup.jsx +206 -0
  260. package/src/Checkbox/CheckboxInput.jsx +55 -0
  261. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  262. package/src/Checkbox/index.js +5 -0
  263. package/src/Divider/Divider.jsx +7 -4
  264. package/src/ExpandCollapse/Accordion.jsx +3 -2
  265. package/src/ExpandCollapse/Control.jsx +40 -43
  266. package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
  267. package/src/ExpandCollapse/Panel.jsx +69 -63
  268. package/src/Feedback/Feedback.jsx +42 -30
  269. package/src/Fieldset/Fieldset.jsx +136 -0
  270. package/src/Fieldset/FieldsetContainer.jsx +31 -0
  271. package/src/Fieldset/FieldsetContainer.native.jsx +19 -0
  272. package/src/Fieldset/Legend.jsx +21 -0
  273. package/src/Fieldset/Legend.native.jsx +27 -0
  274. package/src/Fieldset/cssReset.js +14 -0
  275. package/src/Fieldset/index.js +3 -0
  276. package/src/FlexGrid/Col/Col.jsx +139 -132
  277. package/src/FlexGrid/FlexGrid.jsx +79 -51
  278. package/src/FlexGrid/Row/Row.jsx +55 -48
  279. package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
  280. package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
  281. package/src/HorizontalScroll/ScrollViewEnd.jsx +53 -0
  282. package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
  283. package/src/HorizontalScroll/dictionary.js +11 -0
  284. package/src/HorizontalScroll/index.js +17 -0
  285. package/src/HorizontalScroll/itemPositions.js +101 -0
  286. package/src/Icon/Icon.jsx +46 -49
  287. package/src/Icon/IconText.jsx +68 -0
  288. package/src/Icon/index.js +3 -2
  289. package/src/IconButton/IconButton.jsx +114 -0
  290. package/src/IconButton/index.js +3 -0
  291. package/src/InputLabel/InputLabel.jsx +57 -35
  292. package/src/InputLabel/LabelContent.jsx +21 -0
  293. package/src/InputLabel/LabelContent.native.jsx +11 -2
  294. package/src/InputSupports/InputSupports.jsx +70 -0
  295. package/src/InputSupports/index.js +3 -0
  296. package/src/InputSupports/propTypes.js +44 -0
  297. package/src/InputSupports/useInputSupports.js +30 -0
  298. package/src/Link/ChevronLink.jsx +34 -21
  299. package/src/Link/InlinePressable.jsx +39 -0
  300. package/src/Link/InlinePressable.native.jsx +75 -0
  301. package/src/Link/Link.jsx +23 -13
  302. package/src/Link/LinkBase.jsx +98 -170
  303. package/src/Link/TextButton.jsx +37 -16
  304. package/src/Link/index.js +2 -1
  305. package/src/List/List.jsx +48 -0
  306. package/src/List/ListItem.jsx +182 -0
  307. package/src/List/index.js +3 -0
  308. package/src/Modal/Modal.jsx +190 -0
  309. package/src/Modal/dictionary.js +9 -0
  310. package/src/Modal/index.js +3 -0
  311. package/src/Notification/Notification.jsx +164 -0
  312. package/src/Notification/dictionary.js +8 -0
  313. package/src/Notification/index.js +3 -0
  314. package/src/Pagination/PageButton.jsx +42 -49
  315. package/src/Pagination/Pagination.jsx +88 -92
  316. package/src/Pagination/SideButton.jsx +58 -66
  317. package/src/Progress/Progress.jsx +78 -0
  318. package/src/Progress/ProgressBar.jsx +123 -0
  319. package/src/Progress/ProgressBarBackground.jsx +36 -0
  320. package/src/Progress/index.js +6 -0
  321. package/src/Radio/Radio.jsx +240 -0
  322. package/src/Radio/RadioButton.jsx +142 -0
  323. package/src/Radio/RadioGroup.jsx +209 -0
  324. package/src/Radio/RadioInput.jsx +57 -0
  325. package/src/Radio/RadioInput.native.jsx +6 -0
  326. package/src/Radio/index.js +5 -0
  327. package/src/RadioCard/RadioCard.jsx +198 -0
  328. package/src/RadioCard/RadioCardGroup.jsx +218 -0
  329. package/src/RadioCard/index.js +5 -0
  330. package/src/Search/Search.jsx +225 -0
  331. package/src/Search/dictionary.js +12 -0
  332. package/src/Search/index.js +3 -0
  333. package/src/Select/Group.jsx +15 -0
  334. package/src/Select/Group.native.jsx +14 -0
  335. package/src/Select/Item.jsx +11 -0
  336. package/src/Select/Item.native.jsx +10 -0
  337. package/src/Select/Picker.jsx +74 -0
  338. package/src/Select/Picker.native.jsx +102 -0
  339. package/src/Select/Select.jsx +298 -0
  340. package/src/Select/index.js +8 -0
  341. package/src/SideNav/Item.jsx +54 -47
  342. package/src/SideNav/ItemsGroup.jsx +50 -43
  343. package/src/SideNav/SideNav.jsx +68 -60
  344. package/src/Skeleton/Skeleton.jsx +94 -0
  345. package/src/Skeleton/index.js +3 -0
  346. package/src/Skeleton/skeleton.constant.js +3 -0
  347. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  348. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  349. package/src/Spacer/Spacer.jsx +11 -4
  350. package/src/StackView/StackView.jsx +53 -23
  351. package/src/StackView/StackWrap.jsx +16 -7
  352. package/src/StackView/StackWrapBox.jsx +62 -28
  353. package/src/StackView/StackWrapGap.jsx +46 -24
  354. package/src/StackView/common.jsx +3 -2
  355. package/src/StackView/getStackedContent.jsx +8 -2
  356. package/src/StepTracker/Step.jsx +202 -0
  357. package/src/StepTracker/StepTracker.jsx +174 -0
  358. package/src/StepTracker/dictionary.js +10 -0
  359. package/src/StepTracker/index.js +3 -0
  360. package/src/Tabs/Tabs.jsx +97 -0
  361. package/src/Tabs/TabsItem.jsx +212 -0
  362. package/src/Tabs/index.js +3 -0
  363. package/src/Tags/Tags.jsx +219 -0
  364. package/src/Tags/index.js +3 -0
  365. package/src/TextInput/TextArea.jsx +79 -0
  366. package/src/TextInput/TextInput.jsx +18 -284
  367. package/src/TextInput/TextInputBase.jsx +217 -0
  368. package/src/TextInput/index.js +2 -1
  369. package/src/TextInput/propTypes.js +29 -0
  370. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  371. package/src/ThemeProvider/useSetTheme.js +4 -0
  372. package/src/ThemeProvider/useThemeTokens.js +56 -5
  373. package/src/ThemeProvider/utils/styles.js +18 -5
  374. package/src/ThemeProvider/utils/theme-tokens.js +74 -5
  375. package/src/ToggleSwitch/ToggleSwitch.jsx +51 -53
  376. package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
  377. package/src/Tooltip/Tooltip.jsx +135 -131
  378. package/src/TooltipButton/TooltipButton.jsx +23 -27
  379. package/src/Typography/Typography.jsx +72 -59
  380. package/src/index.js +31 -3
  381. package/src/utils/a11y/index.js +2 -0
  382. package/src/utils/a11y/semantics.js +162 -0
  383. package/src/utils/a11y/textSize.js +30 -0
  384. package/src/utils/children.jsx +119 -0
  385. package/src/utils/index.js +6 -0
  386. package/src/utils/info/index.js +8 -0
  387. package/src/utils/info/platform/index.js +11 -0
  388. package/src/utils/info/platform/platform.android.js +1 -0
  389. package/src/utils/info/platform/platform.ios.js +1 -0
  390. package/src/utils/info/platform/platform.js +1 -0
  391. package/src/utils/info/platform/platform.native.js +4 -0
  392. package/src/utils/info/versions.js +6 -0
  393. package/src/utils/input.js +36 -25
  394. package/src/utils/pressability.js +96 -0
  395. package/src/utils/propTypes.js +291 -90
  396. package/src/utils/useCopy.js +30 -4
  397. package/src/utils/useHash.js +39 -0
  398. package/src/utils/useHash.native.js +6 -0
  399. package/stories/A11yText/A11yText.stories.jsx +6 -10
  400. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
  401. package/stories/Box/Box.stories.jsx +1 -1
  402. package/stories/Button/Button.stories.jsx +7 -2
  403. package/stories/Button/ButtonGroup.stories.jsx +1 -1
  404. package/stories/Button/ButtonLink.stories.jsx +1 -1
  405. package/stories/Card/Card.stories.jsx +1 -1
  406. package/stories/Checkbox/Checkbox.stories.jsx +94 -0
  407. package/stories/Divider/Divider.stories.jsx +1 -1
  408. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
  409. package/stories/Feedback/Feedback.stories.jsx +5 -6
  410. package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
  411. package/stories/FlexGrid/02 Row.stories.jsx +1 -1
  412. package/stories/FlexGrid/03 Col.stories.jsx +1 -1
  413. package/stories/Icon/Icon.stories.jsx +27 -7
  414. package/stories/IconButton/IconButton.stories.jsx +50 -0
  415. package/stories/InputLabel/InputLabel.stories.jsx +1 -1
  416. package/stories/Link/ChevronLink.stories.jsx +1 -1
  417. package/stories/Link/Link.stories.jsx +28 -18
  418. package/stories/Link/TextButton.stories.jsx +1 -1
  419. package/stories/List/List.stories.jsx +117 -0
  420. package/stories/Modal/Modal.stories.jsx +29 -0
  421. package/stories/Notification/Notification.stories.jsx +82 -0
  422. package/stories/Pagination/Pagination.stories.jsx +1 -1
  423. package/stories/Progress/Progress.stories.jsx +93 -0
  424. package/stories/Radio/Radio.stories.jsx +100 -0
  425. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  426. package/stories/Search/Search.stories.jsx +16 -0
  427. package/stories/Select/Select.stories.jsx +55 -0
  428. package/stories/SideNav/SideNav.stories.jsx +1 -1
  429. package/stories/SideNav/SideNavItem.stories.jsx +1 -1
  430. package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
  431. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  432. package/stories/Spacer/Spacer.stories.jsx +1 -1
  433. package/stories/StackView/StackView.stories.jsx +1 -1
  434. package/stories/StackView/StackWrap.stories.jsx +1 -1
  435. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  436. package/stories/Tabs/Tabs.stories.jsx +97 -0
  437. package/stories/Tags/Tags.stories.jsx +69 -0
  438. package/stories/TextInput/TextArea.stories.jsx +100 -0
  439. package/stories/TextInput/TextInput.stories.jsx +1 -1
  440. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
  441. package/stories/Tooltip/Tooltip.stories.jsx +1 -1
  442. package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
  443. package/stories/Typography/Typography.stories.jsx +1 -1
  444. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  445. package/stories/supports.jsx +38 -4
  446. package/__fixtures__/accessible.icon.svg +0 -6
  447. package/babel.config.json +0 -8
  448. package/docs/Contributing.stories.mdx +0 -9
  449. package/docs/Fonts.stories.mdx +0 -104
  450. package/docs/Icons.stories.mdx +0 -144
  451. package/docs/Introduction.stories.mdx +0 -9
  452. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  453. package/lib/InputLabel/LabelContent.web.js +0 -17
  454. package/lib/config/svgr-icons-web.js +0 -9
  455. package/lib/config/svgr-icons.js +0 -52
  456. package/src/InputLabel/LabelContent.web.jsx +0 -13
  457. package/src/config/svgr-icons-web.js +0 -11
  458. package/src/config/svgr-icons.js +0 -46
@@ -1,34 +1,47 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
- import { useThemeTokens } from '../ThemeProvider'
5
- import Link from './Link'
4
+ import { useThemeTokensCallback } from '../ThemeProvider'
5
+ import { selectTokens, getTokensPropType } from '../utils'
6
+ import LinkBase from './LinkBase'
6
7
 
7
8
  /**
8
9
  * `ChevronLink` is a convenience wrapper around the `Link` component to enable "directional" links.
9
10
  * It effectively pre-binds left and right icons, and a directional translation of the icon on hover.
10
11
  *
11
- * ChevronLink is not intended to be deeply themable. If you have a use case outside of the above you are better off constructing theme variants of `Link`.
12
- * In that vein, note that the `tokens` and `variant` system props for `ChevronLink` are passed directly to the underlying `Link` component: ChevronLink itself does not support further customisation using these system props.
12
+ * ChevronLink is not intended to be deeply themable; variants passed to ChevronLink are forwarded to Link.
13
13
  */
14
- const ChevronLink = ({ direction = 'right', children, tokens, ...linkProps }) => {
15
- const { iconDisplace, leftIcon, rightIcon } = useThemeTokens('ChevronLink', {}, {})
16
- const icon = direction === 'right' ? rightIcon : leftIcon
17
- const tokensCallback = (linkState) => ({
18
- ...(typeof tokens === 'function' ? tokens(linkState) : tokens),
19
- iconGapBefore: 0,
20
- iconGapAfter: 0,
21
- iconTranslateX: linkState.hover ? iconDisplace * (direction === 'right' ? 1 : -1) : 0
22
- })
23
- return (
24
- <Link iconPosition={direction} icon={icon} {...linkProps} tokens={tokensCallback}>
25
- {children}
26
- </Link>
27
- )
28
- }
14
+ const ChevronLink = forwardRef(
15
+ ({ direction = 'right', children, tokens, variant, dataSet, ...linkProps }, ref) => {
16
+ const getChevronTokens = useThemeTokensCallback('ChevronLink', tokens, variant)
17
+ const applyChevronTokens = (linkState) => {
18
+ const { leftIcon, rightIcon, iconDisplace, ...otherTokens } = getChevronTokens(linkState)
19
+ return {
20
+ ...selectTokens('Link', otherTokens),
21
+ icon: direction === 'right' ? rightIcon : leftIcon,
22
+ iconTranslateX: iconDisplace * (direction === 'right' ? 1 : -1) || 0
23
+ }
24
+ }
25
+
26
+ const getTokens = useThemeTokensCallback('Link', applyChevronTokens, variant)
27
+ return (
28
+ <LinkBase
29
+ {...linkProps}
30
+ iconPosition={direction}
31
+ tokens={getTokens}
32
+ dataSet={dataSet}
33
+ ref={ref}
34
+ >
35
+ {children}
36
+ </LinkBase>
37
+ )
38
+ }
39
+ )
29
40
 
41
+ ChevronLink.displayName = 'ChevronLink'
30
42
  ChevronLink.propTypes = {
31
- ...Link.propTypes,
43
+ ...LinkBase.propTypes,
44
+ tokens: getTokensPropType('ChevronLink', 'Link'),
32
45
  direction: PropTypes.oneOf(['left', 'right'])
33
46
  }
34
47
 
@@ -0,0 +1,39 @@
1
+ import React, { forwardRef } from 'react'
2
+ import { Pressable, StyleSheet } from 'react-native'
3
+
4
+ /**
5
+ * @typedef {import('react-native').PressableProps} PressableProps
6
+ */
7
+
8
+ /**
9
+ * InlinePressable is an alternative to React Native's Pressable that works better when nested
10
+ * inline inside Text. It accepts the same props as React Native's Pressable.
11
+ *
12
+ * On Web it simply passes its props to Pressable and defaults to `inline-flex` instead of `flex`.
13
+ *
14
+ * @param {PressableProps} PressableProps
15
+ */
16
+ // React Native exports prop Types but not propTypes, use JSDoc types here rather than duplicate RN
17
+ // eslint-disable-next-line react/prop-types
18
+ const InlinePressable = forwardRef(({ children, style, ...props }, ref) => (
19
+ <Pressable
20
+ ref={ref}
21
+ style={(pressState) => [
22
+ staticStyles.inline,
23
+ typeof style === 'function' ? style(pressState) : style
24
+ ]}
25
+ {...props}
26
+ >
27
+ {(pressState) => (typeof children === 'function' ? children(pressState) : children)}
28
+ </Pressable>
29
+ ))
30
+ InlinePressable.displayName = 'InlinePressable'
31
+
32
+ const staticStyles = StyleSheet.create({
33
+ inline: {
34
+ // Stop Pressable defaulting to (block) flex
35
+ display: 'inline-flex'
36
+ }
37
+ })
38
+
39
+ export default InlinePressable
@@ -0,0 +1,75 @@
1
+ /* eslint-disable camelcase */
2
+ import React, { forwardRef, useState } from 'react'
3
+ import { Text, TouchableWithoutFeedback } from 'react-native'
4
+
5
+ /**
6
+ * @typedef {import('react-native').PressableProps} PressableProps
7
+ */
8
+
9
+ // TouchableWithoutFeedback and Pressable have similar but not identical props APIs
10
+ const pressablePropsToTouchable = ({
11
+ unstable_pressDelay,
12
+ android_disableSound,
13
+ android_ripple, // Unsupported, discard it
14
+ ...props
15
+ }) => ({
16
+ ...props,
17
+ touchSoundDisabled: android_disableSound,
18
+ delayPressIn: unstable_pressDelay
19
+ })
20
+
21
+ /**
22
+ * InlinePressable is an alternative to React Native's Pressable that works better when nested
23
+ * inline inside Text. It accepts the same props as React Native's Pressable.
24
+ *
25
+ * There are a lot of React Native bugs around Views/Pressables nested in Text, e.g.:
26
+ *
27
+ * - https://github.com/facebook/react-native/issues/23601#issuecomment-468069822
28
+ * - https://github.com/facebook/react-native/issues/30375
29
+ * - https://github.com/facebook/react-native/issues/31955
30
+ *
31
+ * On Native, these can be avoided using a `Text` wrapped in a `TouchableWithoutFeedback`; the latter
32
+ * injects additional handlers such as onPressIn to `Text`, resulting in a tree that is purely `Text`.
33
+ *
34
+ * Note that this should only be used on Native, not Web, because React Navigation's Web navigation
35
+ * functions don't work in Touchables (but do work in Pressable) due to different event handling.
36
+ *
37
+ * @param {PressableProps} PressableProps
38
+ */
39
+ // React Native exports prop Types but not propTypes, use JSDoc types here rather than duplicate RN
40
+ // eslint-disable-next-line react/prop-types
41
+ const InlinePressable = forwardRef(({ onPress, children, style, ...rest }, ref) => {
42
+ const [isFocused, setIsFocused] = useState(false)
43
+ const handleFocus = () => setIsFocused(true)
44
+ const handleBlur = () => setIsFocused(false)
45
+
46
+ const [isPressed, setIsPressed] = useState(false)
47
+ const handlePressIn = () => setIsPressed(true)
48
+ const handlePressOut = () => setIsPressed(false)
49
+
50
+ const pressState = {
51
+ pressed: isPressed,
52
+ focus: isFocused, // limited support on native
53
+ hover: false // not yet supported on native
54
+ }
55
+ const currentStyle = typeof style === 'function' ? style(pressState) : style
56
+
57
+ return (
58
+ <TouchableWithoutFeedback
59
+ onPress={onPress}
60
+ onPressIn={handlePressIn}
61
+ onPressOut={handlePressOut}
62
+ onFocus={handleFocus}
63
+ onBlur={handleBlur}
64
+ ref={ref}
65
+ {...pressablePropsToTouchable(rest)}
66
+ >
67
+ <Text style={currentStyle}>
68
+ {typeof children === 'function' ? children(pressState) : children}
69
+ </Text>
70
+ </TouchableWithoutFeedback>
71
+ )
72
+ })
73
+ InlinePressable.displayName = 'InlinePressable'
74
+
75
+ export default InlinePressable
package/src/Link/Link.jsx CHANGED
@@ -1,20 +1,30 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
 
3
+ import { useThemeTokensCallback } from '../ThemeProvider'
3
4
  import LinkBase from './LinkBase'
4
5
 
5
- const Link = ({ href, children, accessibilityRole = 'link', variant = {}, ...linkProps }) => (
6
- <LinkBase
7
- href={href}
8
- accessibilityRole={accessibilityRole}
9
- variant={{ component: 'Link', ...variant }}
10
- {...linkProps}
11
- >
12
- {children}
13
- </LinkBase>
6
+ const Link = forwardRef(
7
+ (
8
+ { href, children, accessibilityRole = 'link', variant = {}, tokens, dataSet, ...linkProps },
9
+ ref
10
+ ) => {
11
+ const getTokens = useThemeTokensCallback('Link', tokens, variant)
12
+ return (
13
+ <LinkBase
14
+ href={href}
15
+ accessibilityRole={accessibilityRole}
16
+ tokens={getTokens}
17
+ ref={ref}
18
+ dataSet={dataSet}
19
+ {...linkProps}
20
+ >
21
+ {children}
22
+ </LinkBase>
23
+ )
24
+ }
14
25
  )
26
+ Link.displayName = 'Link'
15
27
 
16
- Link.propTypes = {
17
- ...LinkBase.propTypes
18
- }
28
+ Link.propTypes = LinkBase.propTypes
19
29
 
20
30
  export default Link
@@ -1,14 +1,6 @@
1
- import React, { useState } from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
- import {
4
- Text,
5
- Platform,
6
- StyleSheet,
7
- Pressable,
8
- PixelRatio,
9
- View,
10
- TouchableWithoutFeedback
11
- } from 'react-native'
3
+ import { Text, Platform, StyleSheet } from 'react-native'
12
4
  import {
13
5
  a11yProps,
14
6
  hrefAttrsProp,
@@ -16,40 +8,47 @@ import {
16
8
  linkProps,
17
9
  getTokensPropType
18
10
  } from '../utils/propTypes'
11
+ import { resolvePressableTokens } from '../utils/pressability'
19
12
 
20
- import { useThemeTokens, applyTextStyles } from '../ThemeProvider'
21
-
22
- const selectContentStyles = ({ color }) => ({
23
- color
24
- })
13
+ import InlinePressable from './InlinePressable'
14
+ import { applyTextStyles, applyOuterBorder } from '../ThemeProvider'
15
+ import { IconText, iconComponentPropTypes } from '../Icon'
25
16
 
26
17
  const selectOuterBorderStyles = ({
27
18
  outerBorderColor,
28
19
  outerBorderWidth,
29
20
  outerBorderGap,
30
- outerBorderRadius,
21
+ borderRadius,
31
22
  outerBorderOutline
32
23
  }) =>
33
24
  // A view wrapper with a border on native messes up inline text alignment
34
25
  // so for now make focus styles strictly web-only
35
26
  Platform.OS === 'web'
36
27
  ? {
37
- margin: -1 * (outerBorderGap + outerBorderWidth) || 0,
38
- padding: outerBorderGap,
39
28
  // Allow theme to define outline, or, turn off outline and use border if rounded corners required
40
29
  outline: outerBorderOutline,
41
- borderWidth: outerBorderWidth,
42
- borderColor: outerBorderColor,
43
- borderRadius: outerBorderRadius,
30
+ ...applyOuterBorder({
31
+ outerBorderColor,
32
+ outerBorderWidth,
33
+ outerBorderGap,
34
+ borderRadius
35
+ }),
44
36
  // Stops focus ring stretching horizontally if parent has display: block
45
37
  // width: fit-content isn't supported on Firefox; can't cascade props like CSS `width: fit-content; width: --moz-fit-content;`
46
38
  display: 'inline-flex'
47
39
  }
48
40
  : {}
49
41
 
50
- const selectTextStyles = ({ textLine, textLineStyle }) => ({
42
+ const selectTextStyles = ({ color, textLine, textLineStyle }) => ({
43
+ color,
51
44
  textDecorationLine: textLine,
52
- textDecorationStyle: textLineStyle
45
+ textDecorationStyle: textLineStyle,
46
+ ...Platform.select({
47
+ web: {
48
+ // TODO: https://github.com/telus/universal-design-system/issues/487
49
+ transition: 'color 200ms'
50
+ }
51
+ })
53
52
  })
54
53
 
55
54
  const selectBlockStyles = ({ blockFontWeight, blockFontSize, blockLineHeight, blockFontName }) =>
@@ -60,20 +59,11 @@ const selectBlockStyles = ({ blockFontWeight, blockFontSize, blockLineHeight, bl
60
59
  fontName: blockFontName
61
60
  })
62
61
 
63
- const selectIconStyles = ({
64
- iconSize,
65
- iconGapBefore,
66
- iconGapAfter,
67
- iconScale,
68
- iconTranslateX,
69
- iconTranslateY
70
- }) => ({
71
- scale: iconScale,
62
+ const selectIconTokens = ({ color, iconSize, iconTranslateX, iconTranslateY }) => ({
63
+ color,
72
64
  translateX: iconTranslateX,
73
65
  translateY: iconTranslateY,
74
- size: iconSize,
75
- gapBefore: iconGapBefore,
76
- gapAfter: iconGapAfter
66
+ size: iconSize
77
67
  })
78
68
 
79
69
  /**
@@ -98,143 +88,78 @@ const selectIconStyles = ({
98
88
  * dropped in favour of investigating if a full-featured CSS-in-JS package could or
99
89
  * should be used more widely (e.g. styled components)
100
90
  */
101
- const LinkBase = ({
102
- href,
103
- onPress,
104
- icon,
105
- iconPosition = icon ? 'left' : undefined,
106
- iconVariant,
107
- variant,
108
- tokens,
109
- children,
110
- accessibilityRole = 'link',
111
- ...props
112
- }) => {
113
- const handlePress = linkProps.handleHref({ href, onPress })
114
-
115
- const [isFocused, setIsFocused] = useState(false)
116
- const handleFocus = () => setIsFocused(true)
117
- const handleBlur = () => setIsFocused(false)
118
-
119
- const [isHovered, setIsHovered] = useState(false)
120
- const handleHoverIn = () => setIsHovered(true)
121
- const handleHoverOut = () => setIsHovered(false)
122
-
123
- const [isPressed, setIsPressed] = useState(false)
124
- const handlePressIn = () => setIsPressed(true)
125
- const handlePressOut = () => setIsPressed(false)
126
-
127
- const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
128
- const linkPropSet = linkProps.select({
129
- accessibilityRole,
130
- href,
131
- onPress: handlePress,
132
- onPressIn: handlePressIn,
133
- onPressOut: handlePressOut,
134
- onFocus: handleFocus,
135
- onBlur: handleBlur,
136
- onMouseEnter: handleHoverIn,
137
- onMouseLeave: handleHoverOut,
138
- ...hrefAttrsProp.spread(hrefAttrs),
139
- ...rest
140
- })
141
-
142
- const themeTokens = useThemeTokens('Link', tokens, variant, {
143
- focus: isFocused,
144
- hover: isHovered,
145
- pressed: isPressed,
146
- iconPosition
147
- })
148
- const IconComponent = icon || themeTokens.icon
149
- const hasIcon = !!IconComponent
150
-
151
- const textStyles = selectTextStyles(themeTokens)
152
- const outerBorderStyles = selectOuterBorderStyles(themeTokens)
153
- const contentStyles = selectContentStyles(themeTokens)
154
- const blockStyles = selectBlockStyles(themeTokens)
155
- const iconStyles = selectIconStyles(themeTokens)
156
-
157
- // TODO: re-apply support for inline links
158
- const isNested = false
91
+ const LinkBase = forwardRef(
92
+ (
93
+ {
94
+ href,
95
+ onPress,
96
+ icon,
97
+ iconPosition = icon ? 'left' : undefined,
98
+ iconProps,
99
+ variant,
100
+ tokens = {},
101
+ children,
102
+ accessibilityRole = 'link',
103
+ dataSet,
104
+ ...props
105
+ },
106
+ ref
107
+ ) => {
108
+ const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
109
+ const linkPropSet = linkProps.select({
110
+ accessibilityRole,
111
+ href,
112
+ onPress: linkProps.handleHref({ href, onPress }),
113
+ hrefAttrs,
114
+ ...rest
115
+ })
116
+
117
+ const resolveLinkTokens = (pressState) =>
118
+ resolvePressableTokens(tokens, pressState, { iconPosition })
119
+
120
+ // On web, this makes focus rings wrap only the link, not the entire block
121
+ const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
159
122
 
160
- // On web, this makes focus rings wrap only the link, not the entire block
161
- const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
162
-
163
- // Apply typographic text styles if not inheriting, and block positioning if a block
164
- const blockTextStyles = !isNested && blockStyles
165
-
166
- if (!hasIcon) {
167
- // onPressIn / onPressOut only work if on TouchableWithoutFeedback, onFocus only works if on Text
168
- const { onPress: _onPress, onPressIn, onPressOut, ...textProps } = linkPropSet
169
123
  return (
170
- // TouchableWithoutFeedback modifies its child so this stack is all (touchable) Text: no Views
171
- <TouchableWithoutFeedback onPressIn={onPressIn} onPressOut={onPressOut} onPress={_onPress}>
172
- <Text
173
- {...textProps}
174
- style={[outerBorderStyles, blockLeftStyle, contentStyles, blockTextStyles, textStyles]}
175
- >
176
- {children}
177
- </Text>
178
- </TouchableWithoutFeedback>
124
+ <InlinePressable
125
+ {...linkPropSet}
126
+ ref={ref}
127
+ dataSet={dataSet}
128
+ style={(linkState) => {
129
+ const themeTokens = resolveLinkTokens(linkState)
130
+ const outerBorderStyles = selectOuterBorderStyles(themeTokens)
131
+ const hasIcon = Boolean(icon || themeTokens.icon)
132
+ return [outerBorderStyles, blockLeftStyle, hasIcon && staticStyles.rowContainer]
133
+ }}
134
+ >
135
+ {(linkState) => {
136
+ const themeTokens = resolveLinkTokens(linkState)
137
+ const textStyles = selectTextStyles(themeTokens)
138
+ const iconTokens = selectIconTokens(themeTokens)
139
+
140
+ // TODO: may need to apply some smarter text inheritance here if inline to avoid native
141
+ // issues like double-application of line heights breaking align-items: baseline
142
+ const blockTextStyles = selectBlockStyles(themeTokens)
143
+
144
+ const IconComponent = icon || themeTokens.icon
145
+ const { iconSpace } = themeTokens
146
+
147
+ return (
148
+ <IconText
149
+ icon={IconComponent}
150
+ iconPosition={iconPosition}
151
+ space={iconSpace}
152
+ iconProps={{ ...iconProps, tokens: iconTokens }}
153
+ >
154
+ <Text style={[textStyles, blockTextStyles, staticStyles.baseline]}>{children}</Text>
155
+ </IconText>
156
+ )
157
+ }}
158
+ </InlinePressable>
179
159
  )
180
160
  }
181
-
182
- // Scale icon with text, but with a cap so text isn't squashed at large scales
183
- const iconScale = Math.min(PixelRatio.getFontScale(), 2)
184
-
185
- const iconTokens = {
186
- size: iconStyles.size ? iconStyles.size * iconScale : undefined,
187
- color: contentStyles.color ?? undefined,
188
- scale: iconStyles.scale ?? undefined,
189
- translateX: iconStyles.translateX ?? undefined,
190
- translateY: iconStyles.translateY ?? undefined
191
- }
192
-
193
- const iconContent = <IconComponent tokens={iconTokens} variant={iconVariant} />
194
-
195
- const iconBlock = isNested ? (
196
- // TODO: when reimplementing inline support, insert an appropriate space character
197
- // based on the value of gapBefore and gapAfter on native (no inline margins/padding)
198
- iconContent
199
- ) : (
200
- <View
201
- style={[
202
- iconPosition === 'left' && { marginRight: iconStyles.gapAfter * iconScale },
203
- iconPosition === 'right' && { marginLeft: iconStyles.gapBefore * iconScale }
204
- ]}
205
- >
206
- {iconContent}
207
- </View>
208
- )
209
-
210
- // TODO: this doesn't work well when nested inline but does allow block-links to have icons align
211
- // properly on Android which purely inline links can't do. Add an isNested case that is similar to
212
- // https://github.com/telus/universal-design-system/pull/233
213
- return (
214
- <Pressable
215
- {...linkPropSet}
216
- style={[outerBorderStyles, blockLeftStyle, staticStyles.rowContainer]}
217
- >
218
- {iconPosition === 'left' && iconBlock}
219
- <Text
220
- style={[
221
- contentStyles,
222
- blockTextStyles,
223
- textStyles,
224
- Platform.select({
225
- web: {
226
- // TODO: https://github.com/telus/universal-design-system/issues/487
227
- transition: 'color 200ms'
228
- }
229
- })
230
- ]}
231
- >
232
- {children}
233
- </Text>
234
- {iconPosition === 'right' && iconBlock}
235
- </Pressable>
236
- )
237
- }
161
+ )
162
+ LinkBase.displayName = 'LinkBase'
238
163
 
239
164
  LinkBase.propTypes = {
240
165
  ...a11yProps.types,
@@ -244,7 +169,7 @@ LinkBase.propTypes = {
244
169
  /**
245
170
  * Optional variant that may be passed down to the link's icon if there is one
246
171
  */
247
- iconVariant: variantProp.propType,
172
+ iconProps: PropTypes.exact(iconComponentPropTypes),
248
173
  /**
249
174
  * A function component for an SVG icon to render inside the link. Inherits size and color from
250
175
  * the link and any Typography the link is nested inside.
@@ -256,7 +181,7 @@ LinkBase.propTypes = {
256
181
  iconPosition: PropTypes.oneOf(['left', 'right']),
257
182
  /**
258
183
  * On Web if href is passed, React Native Web maps this object's props to
259
- * `rel`, `target` and (>= RNW 0.15.0) `download` attrs.
184
+ * `rel`, `target` and `download` attrs.
260
185
  */
261
186
  hrefAttrs: PropTypes.shape(hrefAttrsProp.types)
262
187
  }
@@ -269,6 +194,9 @@ const staticStyles = StyleSheet.create({
269
194
  flexDirection: 'row',
270
195
  alignItems: 'center',
271
196
  justifyContent: 'flex-start'
197
+ },
198
+ baseline: {
199
+ alignSelf: 'baseline'
272
200
  }
273
201
  })
274
202
 
@@ -1,24 +1,43 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
+ import { useThemeTokensCallback } from '../ThemeProvider'
4
5
  import LinkBase from './LinkBase'
5
6
 
6
- const TextButton = ({
7
- onPress,
8
- children,
9
- variant = {},
10
- accessibilityRole = 'button',
11
- ...linkProps
12
- }) => (
13
- <LinkBase
14
- onPress={onPress}
15
- accessibilityRole={accessibilityRole}
16
- variant={{ component: 'TextButton', ...variant }}
17
- {...linkProps}
18
- >
19
- {children}
20
- </LinkBase>
7
+ /**
8
+ * `TextButton` is a button that looks like a Link. It uses the same theming and variants as
9
+ * Link but has the accessibility role of a `Button`. It should be used for actions that
10
+ * take place on the current page, or for navigation within an app.
11
+ */
12
+ const TextButton = forwardRef(
13
+ (
14
+ {
15
+ onPress,
16
+ children,
17
+ variant,
18
+ tokens,
19
+ // TODO: this may need to use `link` role on Web in the case of being passed both `href` and
20
+ // `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
21
+ accessibilityRole = 'button',
22
+ ...linkProps
23
+ },
24
+ ref
25
+ ) => {
26
+ const getTokens = useThemeTokensCallback('Link', tokens, variant)
27
+ return (
28
+ <LinkBase
29
+ onPress={onPress}
30
+ accessibilityRole={accessibilityRole}
31
+ tokens={getTokens}
32
+ ref={ref}
33
+ {...linkProps}
34
+ >
35
+ {children}
36
+ </LinkBase>
37
+ )
38
+ }
21
39
  )
40
+ TextButton.displayName = 'TextButton'
22
41
 
23
42
  TextButton.propTypes = {
24
43
  ...LinkBase.propTypes,
@@ -26,6 +45,8 @@ TextButton.propTypes = {
26
45
  }
27
46
 
28
47
  // Remove incompatible Link prop (if this build includes propTypes)
48
+ // TODO: test if this works with web navigation in omniplatform React Navigation
49
+ // https://github.com/telus/universal-design-system/issues/665
29
50
  // eslint-disable-next-line react/forbid-foreign-prop-types
30
51
  if (TextButton.propTypes?.href) delete TextButton.propTypes.href
31
52
 
package/src/Link/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import ChevronLink from './ChevronLink'
2
2
  import Link from './Link'
3
+ import LinkBase from './LinkBase'
3
4
  import TextButton from './TextButton'
4
5
 
5
- export { ChevronLink, Link, TextButton }
6
+ export { ChevronLink, Link, LinkBase, TextButton }