@telus-uds/components-base 0.0.2-prerelease.9 → 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 (282) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.ultra.cache.json +1 -1
  3. package/CHANGELOG.md +32 -0
  4. package/README.md +4 -2
  5. package/__fixtures__/test-utils.js +25 -0
  6. package/__fixtures__/testTheme.js +4 -2
  7. package/__tests__/Button/ButtonGroup.test.jsx +4 -5
  8. package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
  9. package/__tests__/Checkbox/CheckboxGroup.test.jsx +4 -5
  10. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  11. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  12. package/__tests__/Link/LinkBase.test.jsx +0 -14
  13. package/__tests__/Radio/Radio.test.jsx +2 -2
  14. package/__tests__/Radio/RadioGroup.test.jsx +4 -5
  15. package/__tests__/RadioCard/RadioCard.test.jsx +2 -2
  16. package/__tests__/RadioCard/RadioCardGroup.test.jsx +4 -5
  17. package/__tests__/Search/Search.test.jsx +9 -8
  18. package/__tests__/Select/Select.test.jsx +3 -2
  19. package/__tests__/Tabs/Tabs.test.jsx +1 -161
  20. package/__tests__/Tags/Tags.test.jsx +4 -5
  21. package/__tests__/TextInput/TextArea.test.jsx +3 -2
  22. package/__tests__/TextInput/TextInputBase.test.jsx +10 -5
  23. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  24. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
  25. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  26. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  27. package/__tests__/utils/children.test.jsx +128 -0
  28. package/__tests__/utils/input.test.js +1 -1
  29. package/__tests__/utils/semantics.test.jsx +43 -0
  30. package/lib/A11yText/index.js +10 -5
  31. package/lib/ActivityIndicator/Spinner.js +16 -13
  32. package/lib/ActivityIndicator/Spinner.native.js +12 -8
  33. package/lib/Box/Box.js +102 -8
  34. package/lib/Button/Button.js +9 -8
  35. package/lib/Button/ButtonBase.js +14 -7
  36. package/lib/Button/ButtonGroup.js +25 -10
  37. package/lib/Button/ButtonLink.js +10 -7
  38. package/lib/Card/Card.js +2 -0
  39. package/lib/Card/CardBase.js +12 -5
  40. package/lib/Card/PressableCardBase.js +12 -8
  41. package/lib/Checkbox/Checkbox.js +25 -14
  42. package/lib/Checkbox/CheckboxGroup.js +22 -12
  43. package/lib/Divider/Divider.js +12 -7
  44. package/lib/ExpandCollapse/Accordion.js +10 -4
  45. package/lib/ExpandCollapse/Control.js +12 -6
  46. package/lib/ExpandCollapse/ExpandCollapse.js +10 -5
  47. package/lib/ExpandCollapse/Panel.js +8 -7
  48. package/lib/Feedback/Feedback.js +10 -5
  49. package/lib/Fieldset/Fieldset.js +10 -5
  50. package/lib/Fieldset/FieldsetContainer.js +10 -5
  51. package/lib/Fieldset/FieldsetContainer.native.js +10 -5
  52. package/lib/Fieldset/Legend.js +10 -5
  53. package/lib/Fieldset/Legend.native.js +10 -5
  54. package/lib/FlexGrid/Col/Col.js +8 -5
  55. package/lib/FlexGrid/FlexGrid.js +31 -6
  56. package/lib/FlexGrid/Row/Row.js +12 -5
  57. package/lib/{Tabs → HorizontalScroll}/HorizontalScroll.js +5 -4
  58. package/lib/{Tabs/TabsScrollButton.js → HorizontalScroll/HorizontalScrollButton.js} +14 -8
  59. package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.js +0 -0
  60. package/lib/{Tabs → HorizontalScroll}/ScrollViewEnd.native.js +0 -0
  61. package/lib/{Tabs → HorizontalScroll}/dictionary.js +0 -0
  62. package/lib/HorizontalScroll/index.js +35 -0
  63. package/lib/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
  64. package/lib/Icon/Icon.js +16 -9
  65. package/lib/Icon/IconText.js +8 -7
  66. package/lib/IconButton/IconButton.js +10 -5
  67. package/lib/InputLabel/InputLabel.js +33 -5
  68. package/lib/InputLabel/LabelContent.js +22 -12
  69. package/lib/InputLabel/LabelContent.native.js +23 -5
  70. package/lib/InputSupports/InputSupports.js +10 -5
  71. package/lib/Link/ChevronLink.js +12 -5
  72. package/lib/Link/InlinePressable.js +10 -4
  73. package/lib/Link/InlinePressable.native.js +5 -4
  74. package/lib/Link/Link.js +12 -5
  75. package/lib/Link/LinkBase.js +12 -5
  76. package/lib/Link/TextButton.js +10 -5
  77. package/lib/List/List.js +5 -4
  78. package/lib/List/ListItem.js +16 -8
  79. package/lib/Modal/Modal.js +10 -5
  80. package/lib/Notification/Notification.js +21 -5
  81. package/lib/Pagination/PageButton.js +21 -10
  82. package/lib/Pagination/Pagination.js +12 -7
  83. package/lib/Pagination/SideButton.js +12 -7
  84. package/lib/Pagination/usePagination.js +2 -2
  85. package/lib/Progress/Progress.js +10 -5
  86. package/lib/Progress/ProgressBar.js +21 -10
  87. package/lib/Progress/ProgressBarBackground.js +12 -8
  88. package/lib/Radio/Radio.js +14 -13
  89. package/lib/Radio/RadioButton.js +20 -9
  90. package/lib/Radio/RadioGroup.js +24 -13
  91. package/lib/RadioCard/RadioCard.js +14 -10
  92. package/lib/RadioCard/RadioCardGroup.js +13 -12
  93. package/lib/Search/Search.js +29 -18
  94. package/lib/Select/Picker.js +11 -6
  95. package/lib/Select/Picker.native.js +21 -6
  96. package/lib/Select/Select.js +46 -4
  97. package/lib/SideNav/Item.js +10 -5
  98. package/lib/SideNav/ItemsGroup.js +10 -5
  99. package/lib/SideNav/SideNav.js +11 -7
  100. package/lib/Skeleton/Skeleton.js +15 -15
  101. package/lib/Skeleton/skeletonWebAnimation.js +1 -1
  102. package/lib/Spacer/Spacer.js +19 -7
  103. package/lib/StackView/StackView.js +25 -7
  104. package/lib/StackView/StackWrap.js +16 -9
  105. package/lib/StackView/StackWrapBox.js +33 -8
  106. package/lib/StackView/StackWrapGap.js +16 -7
  107. package/lib/StackView/common.js +4 -2
  108. package/lib/StackView/getStackedContent.js +2 -2
  109. package/lib/StepTracker/StepTracker.js +10 -5
  110. package/lib/Tabs/Tabs.js +26 -19
  111. package/lib/Tabs/TabsItem.js +16 -12
  112. package/lib/Tags/Tags.js +27 -11
  113. package/lib/TextInput/TextArea.js +7 -5
  114. package/lib/TextInput/TextInput.js +12 -6
  115. package/lib/TextInput/TextInputBase.js +12 -8
  116. package/lib/ThemeProvider/ThemeProvider.js +14 -10
  117. package/lib/ThemeProvider/useSetTheme.js +6 -1
  118. package/lib/ThemeProvider/utils/styles.js +2 -2
  119. package/lib/ThemeProvider/utils/theme-tokens.js +39 -8
  120. package/lib/ToggleSwitch/ToggleSwitch.js +11 -6
  121. package/lib/Tooltip/Backdrop.js +10 -2
  122. package/lib/Tooltip/Tooltip.js +5 -4
  123. package/lib/Typography/Typography.js +40 -24
  124. package/lib/index.js +21 -0
  125. package/lib/utils/a11y/index.js +13 -0
  126. package/lib/utils/a11y/semantics.js +173 -0
  127. package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
  128. package/lib/utils/children.js +55 -8
  129. package/lib/utils/input.js +27 -17
  130. package/lib/utils/propTypes.js +82 -29
  131. package/lib/utils/useCopy.js +1 -1
  132. package/lib/utils/useHash.js +8 -4
  133. package/lib/utils/useSpacingScale.js +1 -3
  134. package/lib/utils/useUniqueId.js +1 -1
  135. package/package.json +9 -5
  136. package/release-context.json +4 -4
  137. package/src/A11yText/index.jsx +6 -4
  138. package/src/ActivityIndicator/Spinner.jsx +5 -3
  139. package/src/ActivityIndicator/Spinner.native.jsx +5 -3
  140. package/src/Box/Box.jsx +124 -39
  141. package/src/Button/Button.jsx +7 -4
  142. package/src/Button/ButtonBase.jsx +86 -77
  143. package/src/Button/ButtonGroup.jsx +81 -69
  144. package/src/Button/ButtonLink.jsx +18 -13
  145. package/src/Card/Card.jsx +2 -2
  146. package/src/Card/CardBase.jsx +5 -4
  147. package/src/Card/PressableCardBase.jsx +71 -64
  148. package/src/Checkbox/Checkbox.jsx +118 -108
  149. package/src/Checkbox/CheckboxGroup.jsx +72 -62
  150. package/src/Divider/Divider.jsx +7 -4
  151. package/src/ExpandCollapse/Accordion.jsx +3 -2
  152. package/src/ExpandCollapse/Control.jsx +40 -43
  153. package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
  154. package/src/ExpandCollapse/Panel.jsx +69 -63
  155. package/src/Feedback/Feedback.jsx +36 -33
  156. package/src/Fieldset/Fieldset.jsx +63 -56
  157. package/src/Fieldset/FieldsetContainer.jsx +14 -5
  158. package/src/Fieldset/FieldsetContainer.native.jsx +7 -4
  159. package/src/Fieldset/Legend.jsx +7 -2
  160. package/src/Fieldset/Legend.native.jsx +7 -2
  161. package/src/FlexGrid/Col/Col.jsx +139 -132
  162. package/src/FlexGrid/FlexGrid.jsx +79 -51
  163. package/src/FlexGrid/Row/Row.jsx +55 -48
  164. package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
  165. package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
  166. package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.jsx +0 -0
  167. package/src/{Tabs → HorizontalScroll}/ScrollViewEnd.native.jsx +0 -0
  168. package/src/{Tabs → HorizontalScroll}/dictionary.js +0 -0
  169. package/src/HorizontalScroll/index.js +17 -0
  170. package/src/{Tabs → HorizontalScroll}/itemPositions.js +0 -0
  171. package/src/Icon/Icon.jsx +37 -35
  172. package/src/Icon/IconText.jsx +22 -17
  173. package/src/IconButton/IconButton.jsx +49 -42
  174. package/src/InputLabel/InputLabel.jsx +53 -38
  175. package/src/InputLabel/LabelContent.jsx +14 -6
  176. package/src/InputLabel/LabelContent.native.jsx +11 -2
  177. package/src/InputSupports/InputSupports.jsx +29 -34
  178. package/src/Link/ChevronLink.jsx +26 -16
  179. package/src/Link/InlinePressable.jsx +5 -3
  180. package/src/Link/InlinePressable.native.jsx +5 -3
  181. package/src/Link/Link.jsx +22 -16
  182. package/src/Link/LinkBase.jsx +67 -58
  183. package/src/Link/TextButton.jsx +30 -23
  184. package/src/List/List.jsx +5 -4
  185. package/src/List/ListItem.jsx +77 -82
  186. package/src/Modal/Modal.jsx +9 -4
  187. package/src/Notification/Notification.jsx +58 -43
  188. package/src/Pagination/PageButton.jsx +42 -35
  189. package/src/Pagination/Pagination.jsx +88 -92
  190. package/src/Pagination/SideButton.jsx +44 -41
  191. package/src/Progress/Progress.jsx +5 -4
  192. package/src/Progress/ProgressBar.jsx +42 -29
  193. package/src/Progress/ProgressBarBackground.jsx +5 -3
  194. package/src/Radio/Radio.jsx +85 -78
  195. package/src/Radio/RadioButton.jsx +54 -43
  196. package/src/Radio/RadioGroup.jsx +74 -63
  197. package/src/RadioCard/RadioCard.jsx +75 -68
  198. package/src/RadioCard/RadioCardGroup.jsx +82 -75
  199. package/src/Search/Search.jsx +127 -106
  200. package/src/Select/Picker.jsx +49 -42
  201. package/src/Select/Picker.native.jsx +56 -49
  202. package/src/Select/Select.jsx +115 -72
  203. package/src/SideNav/Item.jsx +53 -46
  204. package/src/SideNav/ItemsGroup.jsx +50 -43
  205. package/src/SideNav/SideNav.jsx +68 -60
  206. package/src/Skeleton/Skeleton.jsx +9 -13
  207. package/src/Spacer/Spacer.jsx +11 -4
  208. package/src/StackView/StackView.jsx +46 -23
  209. package/src/StackView/StackWrap.jsx +7 -6
  210. package/src/StackView/StackWrapBox.jsx +61 -28
  211. package/src/StackView/StackWrapGap.jsx +46 -24
  212. package/src/StackView/common.jsx +3 -2
  213. package/src/StepTracker/StepTracker.jsx +73 -62
  214. package/src/Tabs/Tabs.jsx +70 -62
  215. package/src/Tabs/TabsItem.jsx +111 -103
  216. package/src/Tags/Tags.jsx +114 -102
  217. package/src/TextInput/TextArea.jsx +5 -4
  218. package/src/TextInput/TextInput.jsx +5 -4
  219. package/src/TextInput/TextInputBase.jsx +84 -77
  220. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  221. package/src/ThemeProvider/useSetTheme.js +4 -0
  222. package/src/ThemeProvider/utils/theme-tokens.js +28 -0
  223. package/src/ToggleSwitch/ToggleSwitch.jsx +49 -50
  224. package/src/Tooltip/Tooltip.jsx +134 -130
  225. package/src/Typography/Typography.jsx +67 -44
  226. package/src/index.js +2 -0
  227. package/src/utils/a11y/index.js +1 -0
  228. package/src/utils/a11y/semantics.js +162 -0
  229. package/src/utils/children.jsx +60 -7
  230. package/src/utils/input.js +20 -17
  231. package/src/utils/propTypes.js +101 -39
  232. package/src/utils/useCopy.js +1 -1
  233. package/src/utils/useHash.js +8 -3
  234. package/stories/A11yText/A11yText.stories.jsx +2 -2
  235. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
  236. package/stories/Box/Box.stories.jsx +1 -1
  237. package/stories/Button/Button.stories.jsx +2 -2
  238. package/stories/Button/ButtonGroup.stories.jsx +1 -1
  239. package/stories/Button/ButtonLink.stories.jsx +1 -1
  240. package/stories/Card/Card.stories.jsx +1 -1
  241. package/stories/Checkbox/Checkbox.stories.jsx +1 -1
  242. package/stories/Divider/Divider.stories.jsx +1 -1
  243. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
  244. package/stories/Feedback/Feedback.stories.jsx +1 -1
  245. package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
  246. package/stories/FlexGrid/02 Row.stories.jsx +1 -1
  247. package/stories/FlexGrid/03 Col.stories.jsx +1 -1
  248. package/stories/Icon/Icon.stories.jsx +1 -1
  249. package/stories/IconButton/IconButton.stories.jsx +1 -1
  250. package/stories/InputLabel/InputLabel.stories.jsx +1 -1
  251. package/stories/Link/ChevronLink.stories.jsx +1 -1
  252. package/stories/Link/Link.stories.jsx +1 -1
  253. package/stories/Link/TextButton.stories.jsx +1 -1
  254. package/stories/List/List.stories.jsx +1 -1
  255. package/stories/Modal/Modal.stories.jsx +1 -1
  256. package/stories/Notification/Notification.stories.jsx +1 -1
  257. package/stories/Pagination/Pagination.stories.jsx +1 -1
  258. package/stories/Progress/Progress.stories.jsx +1 -1
  259. package/stories/Radio/Radio.stories.jsx +1 -1
  260. package/stories/RadioCard/RadioCard.stories.jsx +1 -1
  261. package/stories/Search/Search.stories.jsx +1 -1
  262. package/stories/Select/Select.stories.jsx +1 -1
  263. package/stories/SideNav/SideNav.stories.jsx +1 -1
  264. package/stories/SideNav/SideNavItem.stories.jsx +1 -1
  265. package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
  266. package/stories/Skeleton/Skeleton.stories.jsx +2 -2
  267. package/stories/Spacer/Spacer.stories.jsx +1 -1
  268. package/stories/StackView/StackView.stories.jsx +1 -1
  269. package/stories/StackView/StackWrap.stories.jsx +1 -1
  270. package/stories/StepTracker/StepTracker.stories.jsx +1 -1
  271. package/stories/Tabs/Tabs.stories.jsx +1 -1
  272. package/stories/Tags/Tags.stories.jsx +1 -1
  273. package/stories/TextInput/TextArea.stories.jsx +1 -1
  274. package/stories/TextInput/TextInput.stories.jsx +1 -1
  275. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
  276. package/stories/Tooltip/Tooltip.stories.jsx +1 -1
  277. package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
  278. package/stories/Typography/Typography.stories.jsx +1 -1
  279. package/stories/platform-supports.jsx +1 -1
  280. package/stories/supports.jsx +2 -2
  281. package/src/Tabs/HorizontalScroll.jsx +0 -165
  282. package/src/Tabs/TabsScrollButton.jsx +0 -100
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telus-uds/components-base",
3
- "version": "0.0.2-prerelease.9",
3
+ "version": "1.0.0",
4
4
  "description": "Base components",
5
5
  "keywords": [
6
6
  "base"
@@ -25,7 +25,7 @@
25
25
  "format": "prettier --write .",
26
26
  "build": "babel src -d lib",
27
27
  "dev": "yarn build --watch",
28
- "release": "standard-version"
28
+ "release": "standard-version --release-as major"
29
29
  },
30
30
  "bugs": {
31
31
  "url": "https://github.com/telus/universal-design-system/issues"
@@ -33,6 +33,9 @@
33
33
  "standard-engine": {
34
34
  "skip": true
35
35
  },
36
+ "browserslist": [
37
+ "extends @telus-uds/browserslist-config"
38
+ ],
36
39
  "peerDependencies": {
37
40
  "react": "^17.0.2",
38
41
  "react-dom": "*",
@@ -47,11 +50,12 @@
47
50
  },
48
51
  "dependencies": {
49
52
  "airbnb-prop-types": "^2.16.0",
50
- "@telus-uds/system-constants": "^0.0.2-prerelease.2",
51
- "@telus-uds/system-themes": "^0.0.2-prerelease.2",
53
+ "@telus-uds/system-constants": "^1.0.0",
54
+ "@telus-uds/system-theme-tokens": "^1.0.0",
52
55
  "lodash.debounce": "^4.0.8",
53
56
  "lodash.merge": "^4.6.2",
54
57
  "prop-types": "^15.7.2",
55
- "react-native-picker-select": "^8.0.4"
58
+ "react-native-picker-select": "^8.0.4",
59
+ "semver": "^7.3.5"
56
60
  }
57
61
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "previousReleaseTag": "@telus-uds/components-base/v0.0.2-prerelease.8",
3
- "changelog": "### [0.0.2-prerelease.9](https://github.com/telus/universal-design-system/compare/@telus-uds/components-base/v0.0.2-prerelease.8...@telus-uds/components-base/v0.0.2-prerelease.9) (2021-12-29)\n\n\n### Features\n\n* **base:** implement IconButton ([#958](https://github.com/telus/universal-design-system/issues/958)) ([c3ff7dd](https://github.com/telus/universal-design-system/commit/c3ff7dd9fb76123d3ff8409e507c89ad91b7fef2))\n",
4
- "releaseTag": "@telus-uds/components-base/v0.0.2-prerelease.9",
5
- "newVersion": "0.0.2-prerelease.9",
2
+ "previousReleaseTag": "@telus-uds/components-base/v0.0.2-prerelease.10",
3
+ "changelog": "## [1.0.0](https://github.com/telus/universal-design-system/compare/@telus-uds/components-base/v0.0.2-prerelease.10...@telus-uds/components-base/v1.0.0) (2022-02-03)\n\n\n### Features\n\n* add dataSet prop ([#1156](https://github.com/telus/universal-design-system/issues/1156)) ([21f49f6](https://github.com/telus/universal-design-system/commit/21f49f6c898118bb94c45f07a52c163b61e4cbaa))\n* **base:** add forwardRef to remaining components ([#1218](https://github.com/telus/universal-design-system/issues/1218)) ([49ccc42](https://github.com/telus/universal-design-system/commit/49ccc4217a68613f23dd7a23dd99e0f61fd6f121))\n* **base:** add tag prop for semantic HTML ([#1222](https://github.com/telus/universal-design-system/issues/1222)) ([581d070](https://github.com/telus/universal-design-system/commit/581d070782dfe569ffcf20c34de6e4409cdd8dfa))\n* **themes:** validate theme token types ([#1221](https://github.com/telus/universal-design-system/issues/1221)) ([dae382d](https://github.com/telus/universal-design-system/commit/dae382d19f86b88cd5de9df8c94f8200aee5b33f))\n\n\n### Bug Fixes\n\n* **base:** avoid errors in apps and update demo app ([#1215](https://github.com/telus/universal-design-system/issues/1215)) ([df6897a](https://github.com/telus/universal-design-system/commit/df6897a4918342e9859e596b9578bcdefc1a5702))\n",
4
+ "releaseTag": "@telus-uds/components-base/v1.0.0",
5
+ "newVersion": "1.0.0",
6
6
  "packageName": "@telus-uds/components-base"
7
7
  }
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { Platform, StyleSheet, View } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
 
@@ -10,7 +10,7 @@ import { a11yProps } from '../utils/propTypes'
10
10
  * It should be used to add selectable screen-reader-only text to the main document flow,
11
11
  * as a sibling to blocks of text like paragraphs and interactive elements like buttons.
12
12
  */
13
- const A11yText = ({ text, heading, ...rest }) => {
13
+ const A11yText = forwardRef(({ text, heading, ...rest }, ref) => {
14
14
  const a11y = a11yProps.select({
15
15
  // On iOS, needs `accessible` to be true to be focusable without non-a11y content.
16
16
  // On Web, `accessible` causes RNW to set attributes that may make the element be treated as a group.
@@ -21,8 +21,10 @@ const A11yText = ({ text, heading, ...rest }) => {
21
21
  accessibilityRole: heading ? 'header' : 'text',
22
22
  ...rest
23
23
  })
24
- return <View style={styles.invisible} {...a11y} />
25
- }
24
+ return <View style={styles.invisible} ref={ref} {...a11y} />
25
+ })
26
+
27
+ A11yText.displayName = 'A11yText'
26
28
 
27
29
  A11yText.propTypes = {
28
30
  text: PropTypes.string.isRequired,
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared'
3
3
 
4
4
  const SVG_RADIUS = 20
@@ -20,8 +20,9 @@ const bezierProps = {
20
20
  }
21
21
  // We're using svg rather than css here to define the animation to avoid needing to introduce css injection mechanism
22
22
  // It's possible to replicate this functionality with RNW animations, but it snags on chrome at least, see https://github.com/telus/universal-design-system/pull/477 for details.
23
- const Spinner = ({ size, color, thickness, label }) => (
23
+ const Spinner = forwardRef(({ size, color, thickness, label }, ref) => (
24
24
  <svg
25
+ ref={ref}
25
26
  width={`${size}px`}
26
27
  height={`${size}px`}
27
28
  viewBox="0 0 48 48"
@@ -62,7 +63,8 @@ const Spinner = ({ size, color, thickness, label }) => (
62
63
  </circle>
63
64
  </g>
64
65
  </svg>
65
- )
66
+ ))
67
+ Spinner.displayName = 'Spinner'
66
68
 
67
69
  Spinner.propTypes = propTypes
68
70
 
@@ -1,11 +1,11 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { Animated, Easing, StyleSheet, View } from 'react-native'
3
3
  import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared'
4
4
 
5
5
  const ea = MIN_EMPTY_ANGLE / 2
6
6
  const sa = MIN_STROKE_ANGLE / 2
7
7
 
8
- const Spinner = ({ size, color, thickness, label }) => {
8
+ const Spinner = forwardRef(({ size, color, thickness, label }, ref) => {
9
9
  const { current: timer } = React.useRef(new Animated.Value(0))
10
10
 
11
11
  React.useLayoutEffect(() => {
@@ -31,6 +31,7 @@ const Spinner = ({ size, color, thickness, label }) => {
31
31
  // Credit to https://github.com/n4kz/react-native-indicators and https://github.com/callstack/react-native-paper for this
32
32
  return (
33
33
  <View
34
+ ref={ref}
34
35
  style={[styles.container]}
35
36
  accessible
36
37
  accessibilityLabel={label}
@@ -109,7 +110,8 @@ const Spinner = ({ size, color, thickness, label }) => {
109
110
  </Animated.View>
110
111
  </View>
111
112
  )
112
- }
113
+ })
114
+ Spinner.displayName = 'Spinner'
113
115
 
114
116
  Spinner.propTypes = propTypes
115
117
 
package/src/Box/Box.jsx CHANGED
@@ -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 { View, ScrollView } from 'react-native'
4
4
  import { useThemeTokens } from '../ThemeProvider'
@@ -8,7 +8,9 @@ import {
8
8
  variantProp,
9
9
  getTokensPropType,
10
10
  useSpacingScale,
11
- viewProps
11
+ viewProps,
12
+ getA11yPropsFromHtmlTag,
13
+ layoutTags
12
14
  } from '../utils'
13
15
  /**
14
16
  * @typedef {import('../utils/propTypes.js').SpacingValue} SpacingValue
@@ -94,63 +96,146 @@ const selectBoxStyles = (tokens) => {
94
96
  * text content is inside a scrollable box, as screens are not scrollable by default and even very
95
97
  * short text will require scrolling on small devices at the highest accessibility text scaling settings.
96
98
  */
97
- const Box = ({
98
- space,
99
- horizontal = space,
100
- vertical = space,
101
- top = vertical,
102
- bottom = vertical,
103
- left = horizontal,
104
- right = horizontal,
105
- children,
106
- variant,
107
- tokens,
108
- scroll,
109
- testID,
110
- ...rest
111
- }) => {
112
- const props = { ...a11yProps.select(rest), ...viewProps.select(rest) }
99
+ const Box = forwardRef(
100
+ (
101
+ {
102
+ space,
103
+ horizontal = space,
104
+ vertical = space,
105
+ top = vertical,
106
+ bottom = vertical,
107
+ left = horizontal,
108
+ right = horizontal,
109
+ flex,
110
+ children,
111
+ variant,
112
+ tokens,
113
+ scroll,
114
+ tag,
115
+ accessibilityRole,
116
+ testID,
117
+ dataSet,
118
+ ...rest
119
+ },
120
+ ref
121
+ ) => {
122
+ const props = {
123
+ ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
124
+ ...a11yProps.select(rest),
125
+ ...viewProps.select(rest)
126
+ }
113
127
 
114
- const themeTokens = useThemeTokens('Box', tokens, variant)
115
- const styles = {
116
- paddingLeft: useSpacingScale(left),
117
- paddingRight: useSpacingScale(right),
118
- paddingTop: useSpacingScale(top),
119
- paddingBottom: useSpacingScale(bottom),
120
- ...selectBoxStyles(themeTokens)
121
- }
128
+ const themeTokens = useThemeTokens('Box', tokens, variant)
129
+ const styles = {
130
+ flex,
131
+ paddingLeft: useSpacingScale(left),
132
+ paddingRight: useSpacingScale(right),
133
+ paddingTop: useSpacingScale(top),
134
+ paddingBottom: useSpacingScale(bottom),
135
+ ...selectBoxStyles(themeTokens)
136
+ }
122
137
 
123
- if (scroll) {
124
- const scrollProps = typeof scroll === 'object' ? scroll : {}
125
- scrollProps.contentContainerStyle = [styles, scrollProps.contentContainerStyle]
138
+ if (scroll) {
139
+ const scrollProps = typeof scroll === 'object' ? scroll : {}
140
+ scrollProps.contentContainerStyle = [styles, scrollProps.contentContainerStyle]
141
+ return (
142
+ <ScrollView {...scrollProps} {...props} testID={testID} dataSet={dataSet} ref={ref}>
143
+ {children}
144
+ </ScrollView>
145
+ )
146
+ }
126
147
  return (
127
- <ScrollView {...scrollProps} {...props} testID={testID}>
148
+ <View {...props} style={styles} testID={testID} dataSet={dataSet} ref={ref}>
128
149
  {children}
129
- </ScrollView>
150
+ </View>
130
151
  )
131
152
  }
132
- return (
133
- <View {...props} style={styles} testID={testID}>
134
- {children}
135
- </View>
136
- )
137
- }
153
+ )
154
+ Box.displayName = 'Box'
138
155
 
139
156
  Box.propTypes = {
157
+ ...a11yProps.propTypes,
158
+ variant: variantProp.propType,
159
+ tokens: getTokensPropType('Box'),
160
+ /**
161
+ * Sets default padding on all sides of the box using the theme's spacing scale.
162
+ *
163
+ * @see {@link SpacingValue}
164
+ */
140
165
  space: spacingProps.types.spacingValue,
166
+ /**
167
+ * Sets top and bottom padding using the theme's spacing scale.
168
+ *
169
+ * @see {@link SpacingValue}
170
+ */
141
171
  vertical: spacingProps.types.spacingValue,
172
+ /**
173
+ * Sets left and right padding using the theme's spacing scale.
174
+ *
175
+ * @see {@link SpacingValue}
176
+ */
142
177
  horizontal: spacingProps.types.spacingValue,
178
+ /**
179
+ * Sets bottom padding using the theme's spacing scale.
180
+ *
181
+ * @see {@link SpacingValue}
182
+ */
143
183
  bottom: spacingProps.types.spacingValue,
184
+ /**
185
+ * Sets left padding using the theme's spacing scale.
186
+ *
187
+ * @see {@link SpacingValue}
188
+ */
144
189
  left: spacingProps.types.spacingValue,
190
+ /**
191
+ * Sets right padding using the theme's spacing scale.
192
+ *
193
+ * @see {@link SpacingValue}
194
+ */
145
195
  right: spacingProps.types.spacingValue,
196
+ /**
197
+ * Sets top padding using the theme's spacing scale.
198
+ *
199
+ * @see {@link SpacingValue}
200
+ */
146
201
  top: spacingProps.types.spacingValue,
202
+ /**
203
+ * Sets the `flex` style, which controls `flexGrow`, `flexShrink` and `flexBasis` styles.
204
+ *
205
+ * Set as 1 for the box to stretch and grow to fit in the available space, or another number to share
206
+ * space disproportionately with siblings. See https://reactnative.dev/docs/flexbox#flex for details.
207
+ *
208
+ * With the default `0`, the box takes its minimum width from its content.
209
+ */
210
+ flex: PropTypes.number,
211
+ /**
212
+ * Renders a scrollable ScrollView instead of an unscrollable View.
213
+ *
214
+ * May take an object of ScrollView props which are passed to the rendered ScrollView.
215
+ */
147
216
  scroll: PropTypes.oneOfType([
148
217
  PropTypes.bool,
149
218
  ScrollView.propTypes ? PropTypes.shape(ScrollView.propTypes) : PropTypes.object
150
219
  ]),
151
- variant: variantProp.propType,
152
- tokens: getTokensPropType('Box'),
220
+ /**
221
+ * Optional semantic HTML tag, to apply to the container on web. Does not change styling.
222
+ *
223
+ * In native apps, if a header tag is provided ("h1", "h2" etc) and accessibilityRole prop
224
+ * is not defined, the accessibilityRole will default to "heading".
225
+ */
226
+ tag: PropTypes.oneOf(layoutTags),
227
+ /**
228
+ * Use in tests if the box itself needs to be targetted and no other way of selecting the
229
+ * box is available (e.g. it cannot be targetted using an appropriate `accessibilityRole`).
230
+ */
153
231
  testID: PropTypes.string,
232
+ /**
233
+ * @ignore
234
+ */
235
+ dataSet: PropTypes.object,
236
+ /**
237
+ * Box accepts any content as children.
238
+ */
154
239
  children: PropTypes.node.isRequired
155
240
  }
156
241
 
@@ -1,14 +1,17 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
 
3
3
  import ButtonBase from './ButtonBase'
4
4
  import buttonPropTypes, { textAndA11yText } from './propTypes'
5
5
  import { useThemeTokensCallback } from '../ThemeProvider'
6
6
  import { a11yProps } from '../utils/propTypes'
7
7
 
8
- const Button = ({ accessibilityRole = 'button', tokens, variant, ...props }) => {
8
+ const Button = forwardRef(({ accessibilityRole = 'button', tokens, variant, ...props }, ref) => {
9
9
  const getTokens = useThemeTokensCallback('Button', tokens, variant)
10
- return <ButtonBase {...props} tokens={getTokens} accessibilityRole={accessibilityRole} />
11
- }
10
+ return (
11
+ <ButtonBase {...props} tokens={getTokens} accessibilityRole={accessibilityRole} ref={ref} />
12
+ )
13
+ })
14
+ Button.displayName = 'Button'
12
15
 
13
16
  Button.propTypes = {
14
17
  ...a11yProps.types,
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { Pressable, View, StyleSheet, Platform } from 'react-native'
3
3
 
4
4
  import { applyTextStyles, applyShadowToken, applyOuterBorder } from '../ThemeProvider/utils'
@@ -130,83 +130,92 @@ const selectWebOnlyStyles = (inactive, themeTokens, { accessibilityRole }) => {
130
130
  })
131
131
  }
132
132
 
133
- const ButtonBase = ({
134
- href,
135
- hrefAttrs,
136
- children,
137
- onPress,
138
- tokens = {},
139
- disabled = false, // alias for inactive
140
- inactive = disabled,
141
- selected = false,
142
- ...rest
143
- }) => {
144
- const extraButtonState = { inactive, selected }
145
- const resolveButtonTokens = (pressableState) =>
146
- resolvePressableTokens(tokens, pressableState, extraButtonState)
147
-
148
- const a11y = a11yProps.select(rest)
149
-
150
- const getPressableStyle = (pressableState) => {
151
- const themeTokens = resolveButtonTokens(pressableState)
152
- return [
153
- staticStyles.row,
154
- selectWebOnlyStyles(inactive, themeTokens, a11y),
155
- selectOuterContainerStyles(themeTokens),
156
- selectOuterWidthStyles(themeTokens)
157
- ]
158
- }
133
+ const ButtonBase = forwardRef(
134
+ (
135
+ {
136
+ href,
137
+ hrefAttrs,
138
+ children,
139
+ onPress,
140
+ tokens = {},
141
+ disabled = false, // alias for inactive
142
+ inactive = disabled,
143
+ selected = false,
144
+ dataSet,
145
+ ...rest
146
+ },
147
+ ref
148
+ ) => {
149
+ const extraButtonState = { inactive, selected }
150
+ const resolveButtonTokens = (pressableState) =>
151
+ resolvePressableTokens(tokens, pressableState, extraButtonState)
152
+
153
+ const a11y = a11yProps.select(rest)
154
+
155
+ const getPressableStyle = (pressableState) => {
156
+ const themeTokens = resolveButtonTokens(pressableState)
157
+ return [
158
+ staticStyles.row,
159
+ selectWebOnlyStyles(inactive, themeTokens, a11y),
160
+ selectOuterContainerStyles(themeTokens),
161
+ selectOuterWidthStyles(themeTokens)
162
+ ]
163
+ }
159
164
 
160
- return (
161
- <Pressable
162
- href={href}
163
- onPress={linkProps.handleHref({ href, onPress })}
164
- style={getPressableStyle}
165
- disabled={inactive}
166
- hrefAttrs={hrefAttrs}
167
- {...a11y}
168
- >
169
- {(pressableState) => {
170
- const themeTokens = resolveButtonTokens(pressableState)
171
- const containerStyles = selectInnerContainerStyles(themeTokens)
172
- const borderStyles = selectBorderStyles(themeTokens)
173
- const textStyles = [selectTextStyles(themeTokens), staticStyles.text]
174
-
175
- // If the container has a width set, fill it instead of sizing from content.
176
- // If in future we support text alignments other than center, add here.
177
- const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align
178
-
179
- return (
180
- <View
181
- style={[
182
- containerStyles,
183
- borderStyles,
184
- stretchStyles,
185
- staticStyles.row,
186
- Platform.select({
187
- web: {
188
- maxWidth: '100%', // ensure overflowing content wraps
189
- // TODO: https://github.com/telus/universal-design-system/issues/487
190
- transition: 'background-color 200ms, border-color 200ms'
191
- }
192
- })
193
- ]}
194
- >
195
- {wrapStringsInText(
196
- typeof children === 'function'
197
- ? children({
198
- ...resolvePressableState(pressableState, extraButtonState),
199
- textStyles
200
- })
201
- : children,
202
- { style: textStyles }
203
- )}
204
- </View>
205
- )
206
- }}
207
- </Pressable>
208
- )
209
- }
165
+ return (
166
+ <Pressable
167
+ ref={ref}
168
+ href={href}
169
+ onPress={linkProps.handleHref({ href, onPress })}
170
+ style={getPressableStyle}
171
+ disabled={inactive}
172
+ dataSet={dataSet}
173
+ hrefAttrs={hrefAttrs}
174
+ {...a11y}
175
+ >
176
+ {(pressableState) => {
177
+ const themeTokens = resolveButtonTokens(pressableState)
178
+ const containerStyles = selectInnerContainerStyles(themeTokens)
179
+ const borderStyles = selectBorderStyles(themeTokens)
180
+ const textStyles = [selectTextStyles(themeTokens), staticStyles.text]
181
+
182
+ // If the container has a width set, fill it instead of sizing from content.
183
+ // If in future we support text alignments other than center, add here.
184
+ const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align
185
+
186
+ return (
187
+ <View
188
+ style={[
189
+ containerStyles,
190
+ borderStyles,
191
+ stretchStyles,
192
+ staticStyles.row,
193
+ Platform.select({
194
+ web: {
195
+ maxWidth: '100%', // ensure overflowing content wraps
196
+ // TODO: https://github.com/telus/universal-design-system/issues/487
197
+ transition: 'background-color 200ms, border-color 200ms'
198
+ }
199
+ })
200
+ ]}
201
+ >
202
+ {wrapStringsInText(
203
+ typeof children === 'function'
204
+ ? children({
205
+ ...resolvePressableState(pressableState, extraButtonState),
206
+ textStyles
207
+ })
208
+ : children,
209
+ { style: textStyles }
210
+ )}
211
+ </View>
212
+ )
213
+ }}
214
+ </Pressable>
215
+ )
216
+ }
217
+ )
218
+ ButtonBase.displayName = 'ButtonBase'
210
219
 
211
220
  ButtonBase.propTypes = {
212
221
  ...a11yProps.types,