@telus-uds/components-base 1.7.0 → 1.8.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 (183) hide show
  1. package/CHANGELOG.md +38 -2
  2. package/component-docs.json +264 -18
  3. package/lib/Button/ButtonGroup.js +118 -45
  4. package/lib/Checkbox/CheckboxGroup.js +3 -3
  5. package/lib/ExpandCollapse/Panel.js +2 -1
  6. package/lib/Fieldset/Fieldset.js +7 -0
  7. package/lib/InputLabel/InputLabel.js +8 -1
  8. package/lib/InputSupports/InputSupports.js +7 -0
  9. package/lib/Notification/Notification.js +1 -1
  10. package/lib/Radio/RadioGroup.js +12 -5
  11. package/lib/RadioCard/RadioCardGroup.js +7 -0
  12. package/lib/Search/Search.js +1 -1
  13. package/lib/Skeleton/Skeleton.js +48 -2
  14. package/lib/ToggleSwitch/ToggleSwitch.js +7 -0
  15. package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  16. package/lib/Tooltip/Tooltip.js +1 -1
  17. package/lib/utils/animation/useVerticalExpandAnimation.js +26 -13
  18. package/lib/utils/props/inputSupportsProps.js +7 -0
  19. package/lib/utils/props/textInputProps.js +2 -1
  20. package/lib-module/Button/ButtonGroup.js +117 -45
  21. package/lib-module/Checkbox/CheckboxGroup.js +3 -3
  22. package/lib-module/ExpandCollapse/Panel.js +2 -1
  23. package/lib-module/Fieldset/Fieldset.js +7 -0
  24. package/lib-module/InputLabel/InputLabel.js +8 -1
  25. package/lib-module/InputSupports/InputSupports.js +7 -0
  26. package/lib-module/Notification/Notification.js +1 -1
  27. package/lib-module/Radio/RadioGroup.js +12 -5
  28. package/lib-module/RadioCard/RadioCardGroup.js +7 -0
  29. package/lib-module/Search/Search.js +1 -1
  30. package/lib-module/Skeleton/Skeleton.js +49 -3
  31. package/lib-module/ToggleSwitch/ToggleSwitch.js +7 -0
  32. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  33. package/lib-module/Tooltip/Tooltip.js +1 -1
  34. package/lib-module/utils/animation/useVerticalExpandAnimation.js +26 -14
  35. package/lib-module/utils/props/inputSupportsProps.js +7 -0
  36. package/lib-module/utils/props/textInputProps.js +2 -1
  37. package/package.json +11 -6
  38. package/src/Button/ButtonGroup.jsx +106 -41
  39. package/src/Checkbox/Checkbox.jsx +7 -4
  40. package/src/Checkbox/CheckboxGroup.jsx +3 -3
  41. package/src/ExpandCollapse/Panel.jsx +3 -1
  42. package/src/Fieldset/Fieldset.jsx +6 -0
  43. package/src/InputLabel/InputLabel.jsx +17 -2
  44. package/src/InputSupports/InputSupports.jsx +9 -1
  45. package/src/Notification/Notification.jsx +1 -1
  46. package/src/Radio/Radio.jsx +5 -1
  47. package/src/Radio/RadioGroup.jsx +11 -5
  48. package/src/RadioCard/RadioCard.jsx +5 -1
  49. package/src/RadioCard/RadioCardGroup.jsx +6 -0
  50. package/src/Search/Search.jsx +1 -1
  51. package/src/Skeleton/Skeleton.jsx +56 -3
  52. package/src/ToggleSwitch/ToggleSwitch.jsx +6 -0
  53. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
  54. package/src/Tooltip/Tooltip.jsx +1 -1
  55. package/src/utils/animation/useVerticalExpandAnimation.js +25 -12
  56. package/src/utils/props/inputSupportsProps.js +6 -1
  57. package/src/utils/props/textInputProps.js +2 -1
  58. package/src/utils/props/tokens.js +21 -19
  59. package/.storybook/main.js +0 -4
  60. package/.storybook/preview.js +0 -37
  61. package/.turbo/turbo-build.log +0 -8
  62. package/.turbo/turbo-lint.log +0 -13
  63. package/CHANGELOG.json +0 -235
  64. package/__fixtures__/Accessible.js +0 -35
  65. package/__fixtures__/Accessible.native.js +0 -35
  66. package/__fixtures__/Theme.jsx +0 -13
  67. package/__fixtures__/Viewport.jsx +0 -17
  68. package/__fixtures__/test-utils.js +0 -25
  69. package/__fixtures__/testTheme.js +0 -1830
  70. package/__tests__/A11yText/A11yText.test.jsx +0 -34
  71. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +0 -68
  72. package/__tests__/ActivityIndicator/__snapshots__/ActivityIndicator.test.jsx.snap +0 -287
  73. package/__tests__/Box/Box.test.jsx +0 -111
  74. package/__tests__/Button/Button.test.jsx +0 -86
  75. package/__tests__/Button/ButtonBase.test.jsx +0 -82
  76. package/__tests__/Button/ButtonGroup.test.jsx +0 -347
  77. package/__tests__/Button/ButtonLink.test.jsx +0 -61
  78. package/__tests__/Card/Card.test.jsx +0 -63
  79. package/__tests__/Checkbox/Checkbox.test.jsx +0 -94
  80. package/__tests__/Checkbox/CheckboxGroup.test.jsx +0 -246
  81. package/__tests__/Divider/Divider.test.jsx +0 -91
  82. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +0 -109
  83. package/__tests__/Feedback/Feedback.test.jsx +0 -42
  84. package/__tests__/FlexGrid/Col.test.jsx +0 -256
  85. package/__tests__/FlexGrid/FlexGrid.test.jsx +0 -136
  86. package/__tests__/FlexGrid/Row.test.jsx +0 -273
  87. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +0 -165
  88. package/__tests__/Icon/Icon.test.jsx +0 -61
  89. package/__tests__/IconButton/IconButton.test.jsx +0 -52
  90. package/__tests__/InputSupports/InputSupports.test.jsx +0 -50
  91. package/__tests__/Link/Link.test.jsx +0 -63
  92. package/__tests__/Link/TextButton.test.jsx +0 -35
  93. package/__tests__/List/List.test.jsx +0 -60
  94. package/__tests__/Modal/Modal.test.jsx +0 -47
  95. package/__tests__/Notification/Notification.test.jsx +0 -20
  96. package/__tests__/Pagination/Pagination.test.jsx +0 -160
  97. package/__tests__/Progress/Progress.test.jsx +0 -79
  98. package/__tests__/Radio/Radio.test.jsx +0 -87
  99. package/__tests__/Radio/RadioGroup.test.jsx +0 -220
  100. package/__tests__/RadioCard/RadioCard.test.jsx +0 -87
  101. package/__tests__/RadioCard/RadioCardGroup.test.jsx +0 -246
  102. package/__tests__/Search/Search.test.jsx +0 -73
  103. package/__tests__/Select/Select.test.jsx +0 -94
  104. package/__tests__/SideNav/SideNav.test.jsx +0 -110
  105. package/__tests__/Skeleton/Skeleton.test.jsx +0 -61
  106. package/__tests__/Spacer/Spacer.test.jsx +0 -63
  107. package/__tests__/StackView/StackView.test.jsx +0 -216
  108. package/__tests__/StackView/StackWrap.test.jsx +0 -47
  109. package/__tests__/StackView/getStackedContent.test.jsx +0 -295
  110. package/__tests__/StepTracker/StepTracker.test.jsx +0 -94
  111. package/__tests__/Tabs/Tabs.test.jsx +0 -40
  112. package/__tests__/Tags/Tags.test.jsx +0 -327
  113. package/__tests__/TextInput/TextArea.test.jsx +0 -35
  114. package/__tests__/TextInput/TextInputBase.test.jsx +0 -125
  115. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +0 -77
  116. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +0 -514
  117. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +0 -41
  118. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +0 -82
  119. package/__tests__/ToggleSwitch/ToggleSwitchGroup.test.jsx +0 -192
  120. package/__tests__/Tooltip/Tooltip.test.jsx +0 -65
  121. package/__tests__/Tooltip/getTooltipPosition.test.js +0 -79
  122. package/__tests__/Typography/typography.test.jsx +0 -90
  123. package/__tests__/utils/children.test.jsx +0 -128
  124. package/__tests__/utils/containUniqueFields.test.js +0 -25
  125. package/__tests__/utils/input.test.js +0 -375
  126. package/__tests__/utils/props.test.js +0 -36
  127. package/__tests__/utils/semantics.test.jsx +0 -34
  128. package/__tests__/utils/useCopy.test.js +0 -42
  129. package/__tests__/utils/useResponsiveProp.test.jsx +0 -202
  130. package/__tests__/utils/useSpacingScale.test.jsx +0 -273
  131. package/__tests__/utils/useUniqueId.test.js +0 -31
  132. package/babel.config.js +0 -35
  133. package/generate-component-docs.js +0 -72
  134. package/jest.config.js +0 -32
  135. package/stories/A11yText/A11yText.stories.jsx +0 -71
  136. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +0 -22
  137. package/stories/Box/Box.stories.jsx +0 -143
  138. package/stories/Button/Button.stories.jsx +0 -72
  139. package/stories/Button/ButtonGroup.stories.jsx +0 -81
  140. package/stories/Button/ButtonLink.stories.jsx +0 -30
  141. package/stories/Card/Card.stories.jsx +0 -62
  142. package/stories/Checkbox/Checkbox.stories.jsx +0 -94
  143. package/stories/Divider/Divider.stories.jsx +0 -68
  144. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +0 -112
  145. package/stories/Feedback/Feedback.stories.jsx +0 -96
  146. package/stories/FlexGrid/01 FlexGrid.stories.jsx +0 -54
  147. package/stories/FlexGrid/02 Row.stories.jsx +0 -41
  148. package/stories/FlexGrid/03 Col.stories.jsx +0 -141
  149. package/stories/Icon/Icon.stories.jsx +0 -79
  150. package/stories/IconButton/IconButton.stories.jsx +0 -50
  151. package/stories/InputLabel/InputLabel.stories.jsx +0 -39
  152. package/stories/Link/ChevronLink.stories.jsx +0 -48
  153. package/stories/Link/Link.stories.jsx +0 -90
  154. package/stories/Link/TextButton.stories.jsx +0 -79
  155. package/stories/List/List.stories.jsx +0 -117
  156. package/stories/Modal/Modal.stories.jsx +0 -54
  157. package/stories/Notification/Notification.stories.jsx +0 -82
  158. package/stories/Pagination/Pagination.stories.jsx +0 -64
  159. package/stories/Progress/Progress.stories.jsx +0 -93
  160. package/stories/Radio/Radio.stories.jsx +0 -100
  161. package/stories/RadioCard/RadioCard.stories.jsx +0 -98
  162. package/stories/Search/Search.stories.jsx +0 -66
  163. package/stories/Select/Select.stories.jsx +0 -55
  164. package/stories/SideNav/SideNav.stories.jsx +0 -42
  165. package/stories/SideNav/SideNavItem.stories.jsx +0 -9
  166. package/stories/SideNav/SideNavItemsGroup.stories.jsx +0 -17
  167. package/stories/Skeleton/Skeleton.stories.jsx +0 -36
  168. package/stories/Spacer/Spacer.stories.jsx +0 -38
  169. package/stories/StackView/StackView.stories.jsx +0 -75
  170. package/stories/StackView/StackWrap.stories.jsx +0 -64
  171. package/stories/StepTracker/StepTracker.stories.jsx +0 -71
  172. package/stories/Tabs/Tabs.stories.jsx +0 -97
  173. package/stories/Tags/Tags.stories.jsx +0 -69
  174. package/stories/TextInput/TextArea.stories.jsx +0 -101
  175. package/stories/TextInput/TextInput.stories.jsx +0 -141
  176. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +0 -64
  177. package/stories/ToggleSwitch/ToggleSwitchGroup.stories.jsx +0 -81
  178. package/stories/Tooltip/Tooltip.stories.jsx +0 -81
  179. package/stories/TooltipButton/TooltipButton.stories.jsx +0 -11
  180. package/stories/Typography/Typography.stories.jsx +0 -49
  181. package/stories/platform-supports.jsx +0 -32
  182. package/stories/platform-supports.native.jsx +0 -3
  183. package/stories/supports.jsx +0 -236
@@ -1,6 +1,11 @@
1
1
  import PropTypes from 'prop-types';
2
2
  export default {
3
3
  types: {
4
+ /**
5
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
6
+ */
7
+ copy: PropTypes.oneOf(['en', 'fr']),
8
+
4
9
  /**
5
10
  * The input label.
6
11
  */
@@ -33,6 +38,7 @@ export default {
33
38
  validation: PropTypes.oneOf(['error', 'success'])
34
39
  },
35
40
  select: ({
41
+ copy,
36
42
  label,
37
43
  hint,
38
44
  hintPosition,
@@ -41,6 +47,7 @@ export default {
41
47
  validation
42
48
  }) => ({
43
49
  supportsProps: {
50
+ copy,
44
51
  label,
45
52
  hint,
46
53
  hintPosition,
@@ -20,7 +20,8 @@ const textProps = {
20
20
  const inputValueProps = {
21
21
  value: PropTypes.string,
22
22
  initialValue: PropTypes.string,
23
- readOnly: PropTypes.bool
23
+ readOnly: PropTypes.bool,
24
+ inactive: PropTypes.bool
24
25
  };
25
26
  /**
26
27
  * This collection adds props that can be passed through to both React Native's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telus-uds/components-base",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "Base components",
5
5
  "keywords": [
6
6
  "base"
@@ -31,8 +31,7 @@
31
31
  "build:code": "yarn build:main && yarn build:module",
32
32
  "build:docs": "babel-node --plugins=@nearform/babel-plugin-react-docgen generate-component-docs.js",
33
33
  "storybook": "start-storybook",
34
- "dev": "yarn build:code --watch",
35
- "release": "standard-version"
34
+ "dev": "yarn build:code --watch"
36
35
  },
37
36
  "bugs": {
38
37
  "url": "https://github.com/telus/universal-design-system/issues"
@@ -50,7 +49,13 @@
50
49
  "react-native-web": "^0.17.0"
51
50
  },
52
51
  "devDependencies": {
53
- "@telus-uds/browserslist-config": "^1.0.1",
52
+ "@storybook/addon-a11y": "^6.5.6",
53
+ "@storybook/addon-essentials": "^6.5.6",
54
+ "@storybook/cli": "^6.5.6",
55
+ "@storybook/react": "^6.5.6",
56
+ "@storybook/builder-webpack5": "^6.5.6",
57
+ "@storybook/manager-webpack5": "^6.5.6",
58
+ "@telus-uds/browserslist-config": "^1.0.2",
54
59
  "@testing-library/jest-native": "^4.0.1",
55
60
  "@testing-library/react-hooks": "^7.0.1",
56
61
  "@testing-library/react-native": "^7.2.0",
@@ -58,8 +63,8 @@
58
63
  },
59
64
  "dependencies": {
60
65
  "airbnb-prop-types": "^2.16.0",
61
- "@telus-uds/system-constants": "^1.0.2",
62
- "@telus-uds/system-theme-tokens": "^1.5.0",
66
+ "@telus-uds/system-constants": "^1.0.3",
67
+ "@telus-uds/system-theme-tokens": "^2.0.1",
63
68
  "lodash.debounce": "^4.0.8",
64
69
  "lodash.merge": "^4.6.2",
65
70
  "prop-types": "^15.7.2",
@@ -5,6 +5,7 @@ import { Platform } from 'react-native'
5
5
 
6
6
  import ButtonBase from './ButtonBase'
7
7
  import { StackWrap } from '../StackView'
8
+ import Fieldset from '../Fieldset'
8
9
  import { useViewport } from '../ViewportProvider'
9
10
  import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
10
11
  import {
@@ -41,6 +42,13 @@ const ButtonGroup = forwardRef(
41
42
  onChange,
42
43
  readOnly = false,
43
44
  inactive = false,
45
+ legend,
46
+ tooltip,
47
+ hint,
48
+ validation,
49
+ feedback,
50
+ name: inputGroupName,
51
+ copy,
44
52
  accessibilityRole = maxValues === 1
45
53
  ? 'radiogroup' // radiogroup is cross-platform; only web aria has generic groups
46
54
  : Platform.select({ web: 'group', default: 'none' }),
@@ -51,7 +59,7 @@ const ButtonGroup = forwardRef(
51
59
  const viewport = useViewport()
52
60
  const themeTokens = useThemeTokens('ButtonGroup', tokens, variant, { viewport })
53
61
  const stackTokens = selectTokens('StackView', themeTokens)
54
- const { direction, space } = themeTokens
62
+ const { direction, space, fieldSpace } = themeTokens
55
63
 
56
64
  const getButtonTokens = useThemeTokensCallback('ButtonGroupItem', tokens, variant)
57
65
 
@@ -74,53 +82,73 @@ const ButtonGroup = forwardRef(
74
82
  throw new Error(`ButtonGroup items must have unique ${uniqueFields.join(', ')}`)
75
83
  }
76
84
 
85
+ // Some web screenreaders e.g. MacOS Voiceover don't handle radiogroups properly unless radio is direct child of radiogroup
86
+ const innerRole =
87
+ Platform.OS === 'web' && accessibilityRole === 'radiogroup' ? accessibilityRole : undefined
88
+
77
89
  return (
78
- <StackWrap
90
+ <Fieldset
79
91
  {...systemProps}
80
- space={space}
81
- direction={direction}
82
- tokens={stackTokens}
83
92
  ref={ref}
93
+ name={inputGroupName}
94
+ legend={legend}
95
+ tooltip={tooltip}
96
+ hint={hint}
97
+ space={fieldSpace}
98
+ feedback={feedback}
99
+ readOnly={readOnly}
100
+ inactive={inactive}
101
+ validation={validation}
102
+ accessibilityRole={accessibilityRole}
103
+ {...selectProps(rest)}
84
104
  >
85
- {items.map(
86
- ({ label, id = label, accessibilityLabel, ref: itemRef, ...itemRest }, index) => {
87
- const isSelected = currentValues.includes(id)
105
+ <StackWrap
106
+ accessibilityRole={innerRole}
107
+ space={space}
108
+ direction={direction}
109
+ tokens={stackTokens}
110
+ ref={ref}
111
+ >
112
+ {items.map(
113
+ ({ label, id = label, accessibilityLabel, ref: itemRef, ...itemRest }, index) => {
114
+ const isSelected = currentValues.includes(id)
88
115
 
89
- // Pass an object of relevant component state as first argument for any passed-in press handlers
90
- const pressHandlers = getPressHandlersWithArgs(rest, [{ id, label, currentValues }])
116
+ // Pass an object of relevant component state as first argument for any passed-in press handlers
117
+ const pressHandlers = getPressHandlersWithArgs(rest, [{ id, label, currentValues }])
91
118
 
92
- const handlePress = (event) => {
93
- if (pressHandlers.onPress) pressHandlers.onPress(event)
94
- toggleOneValue(id, event)
95
- }
119
+ const handlePress = (event) => {
120
+ if (pressHandlers.onPress) pressHandlers.onPress(event)
121
+ toggleOneValue(id, event)
122
+ }
96
123
 
97
- const itemA11y = {
98
- accessibilityState: { checked: isSelected },
99
- accessibilityRole: itemA11yRole,
100
- accessibilityLabel,
101
- ...a11yProps.getPositionInSet(items.length, index)
102
- }
124
+ const itemA11y = {
125
+ accessibilityState: { checked: isSelected },
126
+ accessibilityRole: itemA11yRole,
127
+ accessibilityLabel,
128
+ ...a11yProps.getPositionInSet(items.length, index)
129
+ }
103
130
 
104
- // Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
105
- // "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
106
- return (
107
- <ButtonBase
108
- ref={itemRef}
109
- key={id}
110
- {...pressHandlers}
111
- onPress={handlePress}
112
- tokens={getButtonTokens}
113
- selected={isSelected}
114
- inactive={inactive}
115
- {...itemA11y}
116
- {...selectItemProps(itemRest)}
117
- >
118
- {label}
119
- </ButtonBase>
120
- )
121
- }
122
- )}
123
- </StackWrap>
131
+ // Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
132
+ // "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
133
+ return (
134
+ <ButtonBase
135
+ ref={itemRef}
136
+ key={id}
137
+ {...pressHandlers}
138
+ onPress={handlePress}
139
+ tokens={getButtonTokens}
140
+ selected={isSelected}
141
+ inactive={inactive}
142
+ {...itemA11y}
143
+ {...selectItemProps(itemRest)}
144
+ >
145
+ {label}
146
+ </ButtonBase>
147
+ )
148
+ }
149
+ )}
150
+ </StackWrap>
151
+ </Fieldset>
124
152
  )
125
153
  }
126
154
  )
@@ -180,7 +208,44 @@ ButtonGroup.propTypes = {
180
208
  * managing its own selected state, a default set of selections may be provided.
181
209
  * Changing the `initialValues` does not change the user's selections.
182
210
  */
183
- initialValues: PropTypes.arrayOf(PropTypes.string)
211
+ initialValues: PropTypes.arrayOf(PropTypes.string),
212
+ /**
213
+ * Main text used to describe this group, used in Fieldset's Legend element.
214
+ */
215
+ legend: PropTypes.string,
216
+ /**
217
+ * Optional additional text giving more detail to help a user make a choice.
218
+ */
219
+ hint: PropTypes.string,
220
+ /**
221
+ * Optional tooltip text content to include alongside the legend and hint.
222
+ */
223
+ tooltip: PropTypes.string,
224
+ /**
225
+ * Current validation status of the group, passed to the feedback element if there is one.
226
+ */
227
+ validation: PropTypes.oneOf(['error', 'success']),
228
+ /**
229
+ * If provided, a Feedback element is rendered containing this text.
230
+ */
231
+ feedback: PropTypes.string,
232
+ /**
233
+ * If true, the buttons cannot be selected by the user and simply show their current state.
234
+ */
235
+ readOnly: PropTypes.bool,
236
+ /**
237
+ * If true, the buttons cannot be interacted with, elements are set as `disabled` and if the
238
+ * theme supports `inactive` appearances rules, these are applied.
239
+ */
240
+ inactive: PropTypes.bool,
241
+ /**
242
+ * On Web, this is passed to the `name` attribute of the fieldset.
243
+ */
244
+ name: PropTypes.string,
245
+ /**
246
+ * Sets the language of microcopy in subcomponents (e.g. Tooltip's default accessibility label).
247
+ */
248
+ copy: PropTypes.oneOf(['en', 'fr'])
184
249
  }
185
250
 
186
251
  export default ButtonGroup
@@ -137,7 +137,11 @@ const Checkbox = forwardRef(
137
137
  },
138
138
  ref
139
139
  ) => {
140
- const { currentValue: isChecked, setValue: setIsChecked, isControlled } = useInputValue(
140
+ const {
141
+ currentValue: isChecked,
142
+ setValue: setIsChecked,
143
+ isControlled
144
+ } = useInputValue(
141
145
  {
142
146
  value: checked,
143
147
  initialValue: defaultChecked,
@@ -152,9 +156,8 @@ const Checkbox = forwardRef(
152
156
  ...variant
153
157
  })
154
158
  const defaultTokens = getTokens()
155
- const { feedbackMarginBottom, feedbackMarginTop, feedbackPosition } = selectFeedbackTokens(
156
- defaultTokens
157
- )
159
+ const { feedbackMarginBottom, feedbackMarginTop, feedbackPosition } =
160
+ selectFeedbackTokens(defaultTokens)
158
161
  const styles = StyleSheet.create({
159
162
  feedbackContainer: { marginTop: feedbackMarginTop, marginBottom: feedbackMarginBottom }
160
163
  })
@@ -219,16 +219,16 @@ CheckboxGroup.propTypes = {
219
219
  */
220
220
  onChange: PropTypes.func,
221
221
  /**
222
- * If true, the radio cards cannot be selected by the user and simply show their current state.
222
+ * If true, the checkboxes cannot be selected by the user and simply show their current state.
223
223
  */
224
224
  readOnly: PropTypes.bool,
225
225
  /**
226
- * If true, the checkbox cannot be interacted with, elements are set as `disabled` and if the
226
+ * If true, the checkboxes cannot be interacted with, elements are set as `disabled` and if the
227
227
  * theme supports `inactive` appearances rules, these are applied.
228
228
  */
229
229
  inactive: PropTypes.bool,
230
230
  /**
231
- * On Web, this is passed to the `name` attribute of the fieldset and each radio input.
231
+ * On Web, this is passed to the `name` attribute of the fieldset and each checkbox input.
232
232
  */
233
233
  name: PropTypes.string
234
234
  }
@@ -79,7 +79,8 @@ const ExpandCollapsePanel = forwardRef(
79
79
  setContainerHeight(height)
80
80
  }
81
81
  }
82
- const animatedStyles = useVerticalExpandAnimation({
82
+
83
+ const [animatedStyles, animatedRef] = useVerticalExpandAnimation({
83
84
  containerHeight,
84
85
  isExpanded,
85
86
  tokens: themeTokens
@@ -105,6 +106,7 @@ const ExpandCollapsePanel = forwardRef(
105
106
  {control}
106
107
  </ExpandCollapseControl>
107
108
  <Animated.View
109
+ ref={animatedRef}
108
110
  style={[overflowContainerStyles, animatedStyles, staticStyles.itemsContainer]}
109
111
  {...focusabilityProps}
110
112
  >
@@ -18,6 +18,7 @@ import Legend from './Legend'
18
18
  const Fieldset = forwardRef(
19
19
  (
20
20
  {
21
+ copy = 'en',
21
22
  space,
22
23
  feedback,
23
24
  feedbackPosition = 'top',
@@ -44,6 +45,7 @@ const Fieldset = forwardRef(
44
45
  const legendContent = legend && (
45
46
  <Legend>
46
47
  <InputLabel
48
+ copy={copy}
47
49
  label={legend}
48
50
  hint={hint}
49
51
  hintPosition={hintPosition}
@@ -83,6 +85,10 @@ Fieldset.displayName = 'Fieldset'
83
85
 
84
86
  Fieldset.propTypes = {
85
87
  children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
88
+ /**
89
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
90
+ */
91
+ copy: PropTypes.oneOf(['en', 'fr']),
86
92
  /**
87
93
  * The accessibility role of the `<fieldset>` element itself. Other React Native accessibility
88
94
  * props are not supported because there is not an appropriate counterpart for Fieldsets.
@@ -38,7 +38,18 @@ const selectGapStyles = ({ gap }) => ({ marginRight: gap })
38
38
 
39
39
  const InputLabel = forwardRef(
40
40
  (
41
- { label, forId, hint, hintPosition = 'inline', hintId, tooltip, tokens, variant, ...rest },
41
+ {
42
+ copy = 'en',
43
+ label,
44
+ forId,
45
+ hint,
46
+ hintPosition = 'inline',
47
+ hintId,
48
+ tooltip,
49
+ tokens,
50
+ variant,
51
+ ...rest
52
+ },
42
53
  ref
43
54
  ) => {
44
55
  const themeTokens = useThemeTokens('InputLabel', tokens, variant)
@@ -77,7 +88,7 @@ const InputLabel = forwardRef(
77
88
  { height: themeTokens.fontSize * themeTokens.lineHeight }
78
89
  ]}
79
90
  >
80
- <Tooltip content={tooltip} />
91
+ <Tooltip content={tooltip} copy={copy} />
81
92
  </View>
82
93
  )}
83
94
  </View>
@@ -94,6 +105,10 @@ InputLabel.displayName = 'InputLabel'
94
105
 
95
106
  InputLabel.propTypes = {
96
107
  ...selectedSystemPropTypes,
108
+ /**
109
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
110
+ */
111
+ copy: PropTypes.oneOf(['en', 'fr']),
97
112
  /**
98
113
  * The input label.
99
114
  */
@@ -8,7 +8,10 @@ import { useThemeTokens } from '../ThemeProvider'
8
8
  import useInputSupports from './useInputSupports'
9
9
 
10
10
  const InputSupports = forwardRef(
11
- ({ children, label, hint, hintPosition = 'inline', feedback, tooltip, validation }, ref) => {
11
+ (
12
+ { children, copy = 'en', label, hint, hintPosition = 'inline', feedback, tooltip, validation },
13
+ ref
14
+ ) => {
12
15
  const { space } = useThemeTokens('InputSupports')
13
16
 
14
17
  const { inputId, hintId, feedbackId, a11yProps } = useInputSupports({
@@ -22,6 +25,7 @@ const InputSupports = forwardRef(
22
25
  <StackView space={space} ref={ref}>
23
26
  {label && (
24
27
  <InputLabel
28
+ copy={copy}
25
29
  label={label}
26
30
  hint={hint}
27
31
  hintPosition={hintPosition}
@@ -40,6 +44,10 @@ InputSupports.displayName = 'InputSupports'
40
44
 
41
45
  InputSupports.propTypes = {
42
46
  children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
47
+ /**
48
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
49
+ */
50
+ copy: PropTypes.oneOf(['en', 'fr']),
43
51
  /**
44
52
  * The input label.
45
53
  */
@@ -159,7 +159,7 @@ Notification.propTypes = {
159
159
  */
160
160
  dismissible: PropTypes.bool,
161
161
  /**
162
- * Select english or french copy for the accessible label of the dismiss button.
162
+ * Select English or French copy for the accessible label of the dismiss button.
163
163
  */
164
164
  copy: PropTypes.oneOfType([
165
165
  PropTypes.oneOf(['en', 'fr']),
@@ -121,7 +121,11 @@ const Radio = forwardRef(
121
121
  },
122
122
  ref
123
123
  ) => {
124
- const { currentValue: isChecked, setValue: setIsChecked, isControlled } = useInputValue(
124
+ const {
125
+ currentValue: isChecked,
126
+ setValue: setIsChecked,
127
+ isControlled
128
+ } = useInputValue(
125
129
  {
126
130
  value: checked,
127
131
  initialValue: defaultChecked,
@@ -44,7 +44,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
44
44
  * ### Uncontrolled version
45
45
  *
46
46
  * If the RadioGroup manages its own state, you can use `initialCheckedId` prop to provide the initial value.
47
- * Whenever the radio card gets toggled, it calls the `onChange` callback with the new value (string).
47
+ * Whenever the radio gets toggled, it calls the `onChange` callback with the new value (string).
48
48
  *
49
49
  * ### Use in forms
50
50
  *
@@ -76,6 +76,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
76
76
  const RadioGroup = forwardRef(
77
77
  (
78
78
  {
79
+ copy = 'en',
79
80
  tokens,
80
81
  radioTokens,
81
82
  variant,
@@ -142,6 +143,7 @@ const RadioGroup = forwardRef(
142
143
 
143
144
  return (
144
145
  <Fieldset
146
+ copy={copy}
145
147
  ref={ref}
146
148
  name={inputGroupName}
147
149
  legend={legend}
@@ -163,6 +165,10 @@ RadioGroup.displayName = 'RadioGroup'
163
165
 
164
166
  RadioGroup.propTypes = {
165
167
  ...selectedSystemPropTypes,
168
+ /**
169
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
170
+ */
171
+ copy: PropTypes.oneOf(['en', 'fr']),
166
172
  /**
167
173
  * Optional theme token overrides for the outer RadioGroup component
168
174
  */
@@ -208,11 +214,11 @@ RadioGroup.propTypes = {
208
214
  */
209
215
  feedback: PropTypes.string,
210
216
  /**
211
- * If provided, the radio card with this id is selected on first render.
217
+ * If provided, the radio with this id is selected on first render.
212
218
  */
213
219
  initialCheckedId: PropTypes.string,
214
220
  /**
215
- * If not undefined, the radio card with this id is selected (or none is selected if `null`), and the
221
+ * If not undefined, the radio with this id is selected (or none is selected if `null`), and the
216
222
  * element's selection state will be controlled by its parent using the `onChange` function.
217
223
  */
218
224
  checkedId: PropTypes.string,
@@ -222,11 +228,11 @@ RadioGroup.propTypes = {
222
228
  */
223
229
  onChange: PropTypes.func,
224
230
  /**
225
- * If true, the radio cards cannot be selected by the user and simply show their current state.
231
+ * If true, the radios cannot be selected by the user and simply show their current state.
226
232
  */
227
233
  readOnly: PropTypes.bool,
228
234
  /**
229
- * If true, the radio card cannot be interacted with, elements are set as `disabled` and if the
235
+ * If true, the radios cannot be interacted with, elements are set as `disabled` and if the
230
236
  * theme supports `inactive` appearances rules, these are applied.
231
237
  */
232
238
  inactive: PropTypes.bool,
@@ -77,7 +77,11 @@ const RadioCard = forwardRef(
77
77
  },
78
78
  ref
79
79
  ) => {
80
- const { currentValue: isChecked, setValue: setIsChecked, isControlled } = useInputValue({
80
+ const {
81
+ currentValue: isChecked,
82
+ setValue: setIsChecked,
83
+ isControlled
84
+ } = useInputValue({
81
85
  value: checked,
82
86
  initialValue: defaultChecked,
83
87
  onChange
@@ -77,6 +77,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
77
77
  const RadioCardGroup = forwardRef(
78
78
  (
79
79
  {
80
+ copy = 'en',
80
81
  tokens,
81
82
  radioCardTokens,
82
83
  variant,
@@ -120,6 +121,7 @@ const RadioCardGroup = forwardRef(
120
121
 
121
122
  return (
122
123
  <Fieldset
124
+ copy={copy}
123
125
  ref={ref}
124
126
  name={inputGroupName}
125
127
  legend={legend}
@@ -170,6 +172,10 @@ RadioCardGroup.displayName = 'RadioCardGroup'
170
172
 
171
173
  RadioCardGroup.propTypes = {
172
174
  ...selectedSystemPropTypes,
175
+ /**
176
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
177
+ */
178
+ copy: PropTypes.oneOf(['en', 'fr']),
173
179
  /**
174
180
  * Optional theme token overrides for the outer RadioCardGroup component
175
181
  */
@@ -218,7 +218,7 @@ Search.propTypes = {
218
218
  */
219
219
  accessibilityLabel: PropTypes.string,
220
220
  /**
221
- * Select english or french copy for the accessible labels.
221
+ * Select English or French copy for the accessible labels.
222
222
  * You may also pass in a custom dictionary object.
223
223
  */
224
224
  copy: PropTypes.oneOfType([
@@ -7,7 +7,10 @@ import {
7
7
  a11yProps,
8
8
  getTokensPropType,
9
9
  selectSystemProps,
10
+ responsiveProps,
11
+ useResponsiveProp,
10
12
  useSpacingScale,
13
+ spacingProps,
11
14
  variantProp,
12
15
  viewProps
13
16
  } from '../utils'
@@ -37,9 +40,29 @@ const selectSquareStyles = ({ radius }) => ({
37
40
  })
38
41
 
39
42
  const Skeleton = forwardRef(
40
- ({ tokens, variant, size, characters, lines, shape = 'line', ...rest }, ref) => {
43
+ (
44
+ {
45
+ tokens,
46
+ variant,
47
+ size,
48
+ sizeIndex = size,
49
+ sizePixels,
50
+ characters,
51
+ lines,
52
+ shape = 'line',
53
+ ...rest
54
+ },
55
+ ref
56
+ ) => {
41
57
  const themeTokens = useThemeTokens('Skeleton', tokens, variant)
42
- const skeletonHeight = useSpacingScale(size || themeTokens.size)
58
+ const pixels = useResponsiveProp(sizePixels)
59
+ const spacingScaleValue =
60
+ typeof pixels === 'number'
61
+ ? // Size by an exact number of pixels
62
+ { options: { size: pixels } }
63
+ : // Size by an index on the spacing scale (getting default index from theme if none provided)
64
+ sizeIndex || themeTokens.size
65
+ const skeletonHeight = useSpacingScale(spacingScaleValue)
43
66
  const nativeAnimation = useSkeletonNativeAnimation()
44
67
 
45
68
  const getAnimationBaseOnPlatform = () => {
@@ -97,9 +120,39 @@ Skeleton.propTypes = {
97
120
  ...selectedSystemPropTypes,
98
121
  tokens: getTokensPropType('Skeleton'),
99
122
  variant: variantProp.propType,
100
- size: propTypes.number,
123
+ /**
124
+ * Sets the size of Skeleton lines or shape according to the theme's spacing scale. For example, size={1} gives the smallest non-zero theme-defined spacing size.
125
+ *
126
+ * May also accept an object with responsive viewport keys or spacing scale options - see `useSpacingScale` for details.
127
+ */
128
+ sizeIndex: spacingProps.types.spacingValue,
129
+ /**
130
+ * @deprecated alias for `sizeIndex`
131
+ */
132
+ size: spacingProps.types.spacingValue,
133
+ /**
134
+ * Sets the size of Skeleton lines or shape to an exact number of pixels. Use when it's necessary to exactly match sizes of images or other boxes.
135
+ *
136
+ * Accepts a number or an object with responsive viewport keys, e.g. { xs: 32, lg: 64 } would be 32px at xs, sm and md and 64 at lg and xl viewports.
137
+ */
138
+ sizePixels: responsiveProps.getTypeOptionallyByViewport(propTypes.number),
139
+ /**
140
+ * Determines the width of simulated lines of text if the Skeleton's shape is 'line' (the default shape).
141
+ *
142
+ * Only has any affect if shape is line (the default). If unset, takes a default value from the theme.
143
+ */
101
144
  characters: propTypes.number,
145
+ /**
146
+ * Determines how many Skeleton items are rendered (default 1).
147
+ *
148
+ * Recommended usage is to simulate paragraphs of text when Skeleton's shape is 'line' (the default shape).
149
+ *
150
+ * The amount of spacing between multiple lines is controlled by theme tokens.
151
+ */
102
152
  lines: propTypes.number,
153
+ /**
154
+ * Determines if the skeleton should resemble lines of text (default), a circle, or a square box with themed rounded corners.
155
+ */
103
156
  shape: propTypes.oneOf(['line', 'circle', 'box'])
104
157
  }
105
158