@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
@@ -1,3 +1,7 @@
1
+ import PropTypes from 'prop-types'
2
+ import semVerSatisfies from 'semver/functions/satisfies'
3
+ import pkg from '../../../package.json'
4
+
1
5
  /**
2
6
  * @typedef {import('../../utils/propTypes.js').AppearanceSet} AppearanceSet
3
7
  * @typedef {import('../../utils/propTypes.js').TokensProp} TokensProp
@@ -37,15 +41,22 @@ export const doesThemeRuleApply = (rule, appearances) =>
37
41
  Object.entries(rule.if).every((condition) => doesThemeConditionApply(condition, appearances))
38
42
 
39
43
  /**
40
- * Turns a tokens prop and an optional tokens override prop (either or both of which may be a tokens getter function)
41
- * into one tokens set object where overrides are applied over the resolved default tokens.
44
+ * Turns a tokens prop (which may be either a tokens object or a tokens getter function)
45
+ * into one resolved tokens object, based on current appearances state.
46
+ *
47
+ * This is used inside `useThemeTokens` and `useThemeTokensCallback` for handling the `tokens`
48
+ * props of themed components. It may also be used directly in cases where a non-themed component
49
+ * needs to resolve a tokens prop that may be a tokens getter function or a resolved tokens object.
50
+ *
51
+ * A second tokens prop of tokens overrides may optionally be passed; it will be resolved to an object
52
+ * based on provided appearance state and then shallow-merged over the first set of tokens.
42
53
  *
43
54
  * @param {TokensProp} defaultTokens - a set of tokens or tokens getter function which may be overridden
44
- * @param {TokensProp} [tokenOverrides] - optional set of tokens or tokens getter function to override the default
45
55
  * @param {AppearanceSet} [appearances] - optional appearance set to pass to tokens getter functions
56
+ * @param {TokensProp} [tokenOverrides] - optional set of tokens or tokens getter function to override the default
46
57
  * @returns {TokensSet} - object containing resolved tokens with overrides applied
47
58
  */
48
- export const resolveTokens = (defaultTokens, tokenOverrides, appearances = {}) => {
59
+ export const resolveThemeTokens = (defaultTokens, appearances = {}, tokenOverrides) => {
49
60
  const resolve = (tokens) => (typeof tokens === 'function' ? tokens(appearances) : tokens)
50
61
  if (!tokenOverrides) return resolve(defaultTokens)
51
62
 
@@ -56,6 +67,27 @@ export const resolveTokens = (defaultTokens, tokenOverrides, appearances = {}) =
56
67
  )
57
68
  }
58
69
 
70
+ /**
71
+ * Gives a prop types error if a set of resolved tokens doesn't match a provided prop
72
+ * types validator.
73
+ *
74
+ * In production, this is a no-op (PropTypes.checkPropTypes is automatically replaced
75
+ * with a no-op function).
76
+ *
77
+ * @param {TokensSet} themeTokens - object containing resolved theme tokens
78
+ * @param {function} validator - PropTypes validator function
79
+ * @param {string} componentName - identifier to display in PropType error messages
80
+ */
81
+ export const validateThemeTokens = (themeTokens, validator, componentName) => {
82
+ PropTypes.checkPropTypes(
83
+ { tokens: validator },
84
+ { tokens: themeTokens },
85
+ 'resolved token',
86
+ componentName
87
+ )
88
+ return themeTokens
89
+ }
90
+
59
91
  /**
60
92
  * Merges variants over states. Must be merged in that order to allow static showcases of a state,
61
93
  * e.g. `<Button variant={{ pressed: true }} />` where button's pressed state is `false` by default.
@@ -68,6 +100,17 @@ export const resolveTokens = (defaultTokens, tokenOverrides, appearances = {}) =
68
100
  export const mergeAppearances = (variants = {}, states) =>
69
101
  states ? { ...states, ...variants } : variants
70
102
 
103
+ /**
104
+ * Get a set of theme tokens by applying a theme's component rules based on a component's variants and state.
105
+ *
106
+ * This is used internally in `useThemeTokens` and `useThemeTokensCallback` and should not normally be called directly.
107
+ *
108
+ * @param {object} componentTheme - object containing a theme's `tokens` and `rules` for a component
109
+ * @param {object|function} [tokensProp] - UDS tokens prop containing theming overrides
110
+ * @param {object} [variants] - UDS variant prop containing the variant options for this component instance
111
+ * @param {object} [states] - object containing current state options for this component instance
112
+ * @returns {object} Set of resolved theme tokens
113
+ */
71
114
  export const getThemeTokens = (
72
115
  { rules = [], tokens: defaultThemeTokens = {} },
73
116
  tokensProp,
@@ -88,7 +131,33 @@ export const getThemeTokens = (
88
131
  : mergedTokens,
89
132
  defaultThemeTokens
90
133
  )
91
- return resolveTokens(themeTokens, tokensProp, appearances)
134
+ return resolveThemeTokens(themeTokens, appearances, tokensProp)
92
135
  }
93
136
 
94
137
  export const toArray = (strOrArr) => (Array.isArray(strOrArr) ? strOrArr : [strOrArr])
138
+
139
+ /**
140
+ * Throws an error if the theme was built with an incompatible version of @telus-uds/system-theme-tokens
141
+ *
142
+ * This is used internally by the ThemeProvider to force a fast failure when an incompatible version is detected.
143
+ *
144
+ * Version compatibility is calculated with semver.satisfies.
145
+ * Refer to https://github.com/npm/node-semver and https://semver.npmjs.com/ for details about how
146
+ * semver compatibility.
147
+ *
148
+ * @param {object} theme - UDS theme built for react-native
149
+ */
150
+ export const validateThemeTokensVersion = (theme) => {
151
+ const expectedThemeTokensVersion = pkg.dependencies['@telus-uds/system-theme-tokens']
152
+ const actualThemeTokensVersion = theme?.metadata?.themeTokensVersion
153
+
154
+ if (!semVerSatisfies(actualThemeTokensVersion, expectedThemeTokensVersion)) {
155
+ throw new Error(
156
+ `Invalid UDS token schema version detected.
157
+
158
+ The UDS base components ${pkg.name} v${pkg.version} are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ${expectedThemeTokensVersion}. The current theme was built with @telus-uds/system-theme-tokens v${actualThemeTokensVersion}.
159
+
160
+ If you see this error than most likely you have attempted to install ${pkg.name} and a UDS theme manually because you are building a multi-brand application. If you are building a single brand application, consider installing the brand specific design system package such as @telus-uds/ds-allium. For more information, see https://github.com/telus/universal-design-system/blob/main/packages/docs-uds/docs/multi-brand-usage.md`
161
+ )
162
+ }
163
+ }
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { Platform, View, StyleSheet } from 'react-native'
4
4
 
@@ -21,8 +21,7 @@ const selectButtonTokens = (tokens) =>
21
21
  })
22
22
 
23
23
  // Map and rename icon-specific tokens to name used within Icon
24
- const selectIconTokens = ({ iconSize, iconColor, iconOpacity }) => ({
25
- opacity: iconOpacity,
24
+ const selectIconTokens = ({ iconSize, iconColor }) => ({
26
25
  size: iconSize,
27
26
  color: iconColor
28
27
  })
@@ -55,62 +54,61 @@ const selectSwitchStyles = ({
55
54
  })
56
55
  })
57
56
 
58
- const ToggleSwitch = ({
59
- value,
60
- initialValue,
61
- onChange,
62
- inactive,
63
- tokens,
64
- variant,
65
- accessibilityRole = 'switch'
66
- }) => {
67
- const getTokens = useThemeTokensCallback('ToggleSwitch', tokens, variant)
57
+ const ToggleSwitch = forwardRef(
58
+ (
59
+ { value, initialValue, onChange, inactive, tokens, variant, accessibilityRole = 'switch' },
60
+ ref
61
+ ) => {
62
+ const getTokens = useThemeTokensCallback('ToggleSwitch', tokens, variant)
68
63
 
69
- const { currentValue, setValue } = useInputValue({
70
- value,
71
- initialValue,
72
- onChange
73
- })
64
+ const { currentValue, setValue } = useInputValue({
65
+ value,
66
+ initialValue,
67
+ onChange
68
+ })
74
69
 
75
- const handlePress = () => setValue(!currentValue)
70
+ const handlePress = (event) => setValue(!currentValue, event)
76
71
 
77
- const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
72
+ const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
78
73
 
79
- return (
80
- <ButtonBase
81
- selected={currentValue}
82
- inactive={inactive}
83
- tokens={getButtonTokens}
84
- accessibilityRole={accessibilityRole}
85
- accessibilityState={{ checked: currentValue }}
86
- onPress={handlePress}
87
- >
88
- {(buttonState) => {
89
- const themeTokens = getTokens(buttonState)
90
- const IconComponent = themeTokens.icon
91
- const switchStyles = selectSwitchStyles(themeTokens)
92
- const trackStyles = selectTrackStyles(themeTokens)
93
- const iconTokens = selectIconTokens(themeTokens)
74
+ return (
75
+ <ButtonBase
76
+ ref={ref}
77
+ selected={currentValue}
78
+ inactive={inactive}
79
+ tokens={getButtonTokens}
80
+ accessibilityRole={accessibilityRole}
81
+ accessibilityState={{ checked: currentValue }}
82
+ onPress={handlePress}
83
+ >
84
+ {(buttonState) => {
85
+ const themeTokens = getTokens(buttonState)
86
+ const IconComponent = themeTokens.icon
87
+ const switchStyles = selectSwitchStyles(themeTokens)
88
+ const trackStyles = selectTrackStyles(themeTokens)
89
+ const iconTokens = selectIconTokens(themeTokens)
94
90
 
95
- // If drag-slide support is needed, use a PanResponder and apply these to an Animated value.
96
- // Use translate transforms for smoothest non-thread-blocking animations and to allow drag.
97
- const slideStart = 0
98
- const slideEnd =
99
- themeTokens.width - themeTokens.switchSize - themeTokens.trackBorderWidth * 2
100
- const switchOffset = buttonState.selected ? slideEnd : slideStart
101
- const switchPositionStyle = { transform: [{ translateX: switchOffset }] }
91
+ // If drag-slide support is needed, use a PanResponder and apply these to an Animated value.
92
+ // Use translate transforms for smoothest non-thread-blocking animations and to allow drag.
93
+ const slideStart = 0
94
+ const slideEnd =
95
+ themeTokens.width - themeTokens.switchSize - themeTokens.trackBorderWidth * 2
96
+ const switchOffset = buttonState.selected ? slideEnd : slideStart
97
+ const switchPositionStyle = { transform: [{ translateX: switchOffset }] }
102
98
 
103
- return (
104
- <View style={[staticStyles.track, trackStyles]}>
105
- <View style={[staticStyles.switch, switchStyles, switchPositionStyle]}>
106
- {IconComponent && <IconComponent tokens={iconTokens} />}
99
+ return (
100
+ <View style={[staticStyles.track, trackStyles]}>
101
+ <View style={[staticStyles.switch, switchStyles, switchPositionStyle]}>
102
+ {IconComponent && <IconComponent {...iconTokens} />}
103
+ </View>
107
104
  </View>
108
- </View>
109
- )
110
- }}
111
- </ButtonBase>
112
- )
113
- }
105
+ )
106
+ }}
107
+ </ButtonBase>
108
+ )
109
+ }
110
+ )
111
+ ToggleSwitch.displayName = 'ToggleSwitch'
114
112
 
115
113
  ToggleSwitch.propTypes = {
116
114
  ...a11yProps.propTypes,
File without changes
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React, { forwardRef, useEffect, useRef, useState } from 'react'
2
2
  import { Dimensions, Platform, Pressable, StyleSheet, Text, View } from 'react-native'
3
3
 
4
4
  import PropTypes from 'prop-types'
@@ -81,7 +81,7 @@ const selectArrowStyles = (
81
81
 
82
82
  const selectTextStyles = (tokens) => applyTextStyles(selectTokens('Typography', tokens))
83
83
  const defaultControl = (pressableState, variant) => (
84
- <TooltipButton variant={{ ...pressableState, ...variant }} />
84
+ <TooltipButton pressableState={pressableState} variant={variant} />
85
85
  )
86
86
 
87
87
  /**
@@ -99,157 +99,161 @@ const defaultControl = (pressableState, variant) => (
99
99
  * - You may use one when the information is useful only to a small percentage of users (ie. tech savvy people wouldn't need this info).
100
100
  * - Tooltips may also be useful when vertical space is an issue.
101
101
  */
102
- const Tooltip = ({ children, content, position = 'auto', copy = 'en', tokens, variant }) => {
103
- const [isOpen, setIsOpen] = useState(false)
102
+ const Tooltip = forwardRef(
103
+ ({ children, content, position = 'auto', copy = 'en', tokens, variant }, ref) => {
104
+ const [isOpen, setIsOpen] = useState(false)
104
105
 
105
- const controlRef = useRef()
106
- const [controlLayout, setControlLayout] = useState(null)
107
- const [tooltipDimensions, setTooltipDimensions] = useState(null)
108
- const [windowDimensions, setWindowDimensions] = useState(Dimensions.get('window'))
109
- const [tooltipPosition, setTooltipPosition] = useState(null)
106
+ const controlRef = useRef()
107
+ const [controlLayout, setControlLayout] = useState(null)
108
+ const [tooltipDimensions, setTooltipDimensions] = useState(null)
109
+ const [windowDimensions, setWindowDimensions] = useState(Dimensions.get('window'))
110
+ const [tooltipPosition, setTooltipPosition] = useState(null)
110
111
 
111
- const getCopy = useCopy({ dictionary, copy })
112
- const themeTokens = useThemeTokens('Tooltip', tokens, variant)
112
+ const getCopy = useCopy({ dictionary, copy })
113
+ const themeTokens = useThemeTokens('Tooltip', tokens, variant)
113
114
 
114
- const { arrowWidth, arrowOffset } = themeTokens
115
+ const { arrowWidth, arrowOffset } = themeTokens
115
116
 
116
- useEffect(() => {
117
- const subscription = Dimensions.addEventListener('change', ({ window }) => {
118
- setWindowDimensions(window)
119
- })
117
+ useEffect(() => {
118
+ const subscription = Dimensions.addEventListener('change', ({ window }) => {
119
+ setWindowDimensions(window)
120
+ })
120
121
 
121
- return () => subscription?.remove()
122
- })
122
+ return () => subscription?.remove()
123
+ })
123
124
 
124
- const toggleIsOpen = () => setIsOpen(!isOpen)
125
- const close = () => setIsOpen(false)
125
+ const toggleIsOpen = () => setIsOpen(!isOpen)
126
+ const close = () => setIsOpen(false)
126
127
 
127
- const getPressableState = ({ pressed, hovered, focused }) => ({
128
- pressed,
129
- hover: hovered,
130
- focus: focused
131
- })
128
+ const getPressableState = ({ pressed, hovered, focused }) => ({
129
+ pressed,
130
+ hover: hovered,
131
+ focus: focused
132
+ })
132
133
 
133
- const onTooltipLayout = ({
134
- nativeEvent: {
135
- layout: { width, height }
136
- }
137
- }) => {
138
- if (
139
- tooltipDimensions === null ||
140
- tooltipDimensions.width !== width ||
141
- tooltipDimensions.height !== height
142
- ) {
143
- setTooltipDimensions({
144
- width: Platform.select({
145
- web: width + 0.3, // avoids often unnecessary line breaks due to subpixel rendering of fonts
146
- native: width
147
- }),
148
- height
149
- })
134
+ const onTooltipLayout = ({
135
+ nativeEvent: {
136
+ layout: { width, height }
137
+ }
138
+ }) => {
139
+ if (
140
+ tooltipDimensions === null ||
141
+ tooltipDimensions.width !== width ||
142
+ tooltipDimensions.height !== height
143
+ ) {
144
+ setTooltipDimensions({
145
+ width: Platform.select({
146
+ web: width + 0.3, // avoids often unnecessary line breaks due to subpixel rendering of fonts
147
+ native: width
148
+ }),
149
+ height
150
+ })
151
+ }
150
152
  }
151
- }
152
153
 
153
- useEffect(() => {
154
- if (isOpen) {
155
- controlRef.current.measureInWindow((x, y, width, height) => {
156
- setControlLayout({ x, y, width, height })
157
- })
158
- } else {
159
- setControlLayout(null)
160
- setTooltipDimensions(null)
161
- setTooltipPosition(null)
162
- }
163
- }, [isOpen])
154
+ useEffect(() => {
155
+ if (isOpen) {
156
+ controlRef.current.measureInWindow((x, y, width, height) => {
157
+ setControlLayout({ x, y, width, height })
158
+ })
159
+ } else {
160
+ setControlLayout(null)
161
+ setTooltipDimensions(null)
162
+ setTooltipPosition(null)
163
+ }
164
+ }, [isOpen])
164
165
 
165
- useEffect(() => {
166
- setIsOpen(false)
167
- }, [windowDimensions])
166
+ useEffect(() => {
167
+ setIsOpen(false)
168
+ }, [windowDimensions])
168
169
 
169
- useEffect(() => {
170
- if (
171
- (tooltipPosition !== null && !tooltipPosition?.isNormalized) ||
172
- !isOpen ||
173
- controlLayout === null ||
174
- tooltipDimensions == null
175
- ) {
176
- return
177
- }
170
+ useEffect(() => {
171
+ if (
172
+ (tooltipPosition !== null && !tooltipPosition?.isNormalized) ||
173
+ !isOpen ||
174
+ controlLayout === null ||
175
+ tooltipDimensions == null
176
+ ) {
177
+ return
178
+ }
178
179
 
179
- const updatedPosition = getTooltipPosition(position, {
180
- controlLayout,
180
+ const updatedPosition = getTooltipPosition(position, {
181
+ controlLayout,
182
+ tooltipDimensions,
183
+ windowDimensions,
184
+ arrowWidth,
185
+ arrowOffset
186
+ })
187
+
188
+ // avoid ending up in an infinite normalization loop
189
+ if (tooltipPosition?.isNormalized && updatedPosition.isNormalized) {
190
+ return
191
+ }
192
+
193
+ setTooltipPosition(updatedPosition)
194
+ }, [
195
+ isOpen,
196
+ position,
181
197
  tooltipDimensions,
198
+ controlLayout,
182
199
  windowDimensions,
183
200
  arrowWidth,
184
- arrowOffset
185
- })
201
+ arrowOffset,
202
+ tooltipPosition
203
+ ])
186
204
 
187
- // avoid ending up in an infinite normalization loop
188
- if (tooltipPosition?.isNormalized && updatedPosition.isNormalized) {
189
- return
190
- }
205
+ const control = children !== undefined ? children : defaultControl
206
+ const pressableStyles =
207
+ control === defaultControl ? Platform.select({ web: { outline: 'none' } }) : undefined
208
+ const pressableHitSlop =
209
+ control === defaultControl ? { top: 10, bottom: 10, left: 10, right: 10 } : undefined
191
210
 
192
- setTooltipPosition(updatedPosition)
193
- }, [
194
- isOpen,
195
- position,
196
- tooltipDimensions,
197
- controlLayout,
198
- windowDimensions,
199
- arrowWidth,
200
- arrowOffset,
201
- tooltipPosition
202
- ])
203
-
204
- const control = children !== undefined ? children : defaultControl
205
- const pressableStyles =
206
- control === defaultControl ? Platform.select({ web: { outline: 'none' } }) : undefined
207
- const pressableHitSlop =
208
- control === defaultControl ? { top: 10, bottom: 10, left: 10, right: 10 } : undefined
209
-
210
- return (
211
- <View style={staticStyles.container}>
212
- <Pressable
213
- onPress={toggleIsOpen}
214
- ref={controlRef}
215
- onBlur={close}
216
- style={pressableStyles}
217
- hitSlop={pressableHitSlop}
218
- accessibilityLabel={getCopy('a11yText')}
219
- accessibilityRole="button"
220
- >
221
- {typeof control === 'function'
222
- ? (pressableState) => control(getPressableState(pressableState), variant)
223
- : control}
224
- </Pressable>
225
- {isOpen && (
226
- <Backdrop onPress={close}>
227
- <View
228
- style={[
229
- staticStyles.tooltip,
230
- selectTooltipShadowStyles(themeTokens), // applied separately so that it doesn't cover the arrow
231
- tooltipPosition && selectTooltipPositionStyles(tooltipPosition),
232
- (tooltipPosition === null || tooltipPosition?.isNormalized) &&
233
- staticStyles.tooltipHidden // visually hide the tooltip until we have a final measurement
234
- ]}
235
- onLayout={onTooltipLayout}
236
- accessibilityRole="alert"
237
- >
211
+ return (
212
+ <View style={staticStyles.container}>
213
+ <Pressable
214
+ onPress={toggleIsOpen}
215
+ ref={controlRef}
216
+ onBlur={close}
217
+ style={pressableStyles}
218
+ hitSlop={pressableHitSlop}
219
+ accessibilityLabel={getCopy('a11yText')}
220
+ accessibilityRole="button"
221
+ >
222
+ {typeof control === 'function'
223
+ ? (pressableState) => control(getPressableState(pressableState), variant)
224
+ : control}
225
+ </Pressable>
226
+ {isOpen && (
227
+ <Backdrop onPress={close}>
238
228
  <View
229
+ ref={ref}
239
230
  style={[
240
- staticStyles.arrow,
241
- tooltipPosition && selectArrowStyles(themeTokens, tooltipPosition)
231
+ staticStyles.tooltip,
232
+ selectTooltipShadowStyles(themeTokens), // applied separately so that it doesn't cover the arrow
233
+ tooltipPosition && selectTooltipPositionStyles(tooltipPosition),
234
+ (tooltipPosition === null || tooltipPosition?.isNormalized) &&
235
+ staticStyles.tooltipHidden // visually hide the tooltip until we have a final measurement
242
236
  ]}
243
- />
244
- <View style={selectTooltipStyles(themeTokens)}>
245
- <Text style={selectTextStyles(themeTokens)}>{content}</Text>
237
+ onLayout={onTooltipLayout}
238
+ accessibilityRole="alert"
239
+ >
240
+ <View
241
+ style={[
242
+ staticStyles.arrow,
243
+ tooltipPosition && selectArrowStyles(themeTokens, tooltipPosition)
244
+ ]}
245
+ />
246
+ <View style={selectTooltipStyles(themeTokens)}>
247
+ <Text style={selectTextStyles(themeTokens)}>{content}</Text>
248
+ </View>
246
249
  </View>
247
- </View>
248
- </Backdrop>
249
- )}
250
- </View>
251
- )
252
- }
250
+ </Backdrop>
251
+ )}
252
+ </View>
253
+ )
254
+ }
255
+ )
256
+ Tooltip.displayName = 'Tooltip'
253
257
 
254
258
  Tooltip.propTypes = {
255
259
  /**
@@ -1,51 +1,47 @@
1
1
  import React from 'react'
2
2
  import { View } from 'react-native'
3
3
 
4
- import { useThemeTokens } from '../ThemeProvider'
4
+ import PropTypes from 'prop-types'
5
+ import { useThemeTokens, applyOuterBorder } from '../ThemeProvider'
5
6
  import { getTokensPropType, variantProp } from '../utils'
7
+ import Icon from '../Icon'
6
8
 
7
- const selectOuterContainerStyles = ({
8
- outerBorderColor,
9
- outerBorderWidth = 0,
10
- outerBorderGap = 0,
11
- outerBorderRadius
12
- }) => {
13
- const outerBorderOffset = -1 * (outerBorderWidth + outerBorderGap)
14
-
15
- return {
16
- marginTop: outerBorderOffset,
17
- marginLeft: outerBorderOffset,
18
- marginRight: outerBorderOffset,
19
- marginBottom: outerBorderOffset,
20
- borderColor: outerBorderColor,
21
- borderWidth: outerBorderWidth,
22
- padding: outerBorderGap,
23
- borderRadius: outerBorderRadius
24
- }
25
- }
26
9
  const selectInnerContainerStyles = ({ borderRadius, width }) => ({ borderRadius, width })
27
10
 
28
- const selectIconTokens = ({ iconSize, iconColor, iconScale = 1 }) => ({
11
+ const selectIconTokens = ({ iconSize, iconColor /* iconScale = 1 */ }) => ({
29
12
  size: iconSize,
30
- color: iconColor,
31
- scale: iconScale
13
+ color: iconColor
14
+ // scale: iconScale TODO re-enable with icon component
32
15
  })
33
16
 
34
- const TooltipButton = ({ tokens, variant }) => {
35
- const themeTokens = useThemeTokens('TooltipButton', tokens, variant)
17
+ /**
18
+ * `TooltipButton` is a helper component used as a default control for the `Tooltip` component.
19
+ * In fact though, it isn't actually a pressable - it's meant to be used as pressable's content.
20
+ * Due to this any interaction states (e.g. pressed, hover, etc.) has to be passed down to it as a prop.
21
+ */
22
+ const TooltipButton = ({ pressableState, tokens, variant }) => {
23
+ const themeTokens = useThemeTokens('TooltipButton', tokens, variant, pressableState)
36
24
 
37
25
  const { icon: IconComponent } = themeTokens
38
26
 
39
27
  return (
40
- <View style={selectOuterContainerStyles(themeTokens)}>
28
+ <View style={applyOuterBorder(themeTokens)}>
41
29
  <View style={selectInnerContainerStyles(themeTokens)}>
42
- {IconComponent && <IconComponent tokens={selectIconTokens(themeTokens)} />}
30
+ {IconComponent && <Icon icon={IconComponent} tokens={selectIconTokens(themeTokens)} />}
43
31
  </View>
44
32
  </View>
45
33
  )
46
34
  }
47
35
 
48
36
  TooltipButton.propTypes = {
37
+ /**
38
+ * Used as appearances when resolving theme tokens.
39
+ */
40
+ pressableState: PropTypes.shape({
41
+ pressed: PropTypes.bool,
42
+ hover: PropTypes.bool,
43
+ focus: PropTypes.bool
44
+ }),
49
45
  tokens: getTokensPropType('TooltipButton'),
50
46
  variant: variantProp.propType
51
47
  }