@telus-uds/components-base 1.6.1 → 1.8.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 (97) hide show
  1. package/.storybook/main.js +7 -0
  2. package/.turbo/turbo-build.log +3 -3
  3. package/.turbo/turbo-lint.log +3 -13
  4. package/CHANGELOG.json +112 -1
  5. package/CHANGELOG.md +41 -2
  6. package/__fixtures__/Accessible.js +1 -2
  7. package/__fixtures__/Accessible.native.js +1 -2
  8. package/__tests__/FlexGrid/Col.test.jsx +5 -0
  9. package/__tests__/InputLabel/InputLabel.test.jsx +28 -0
  10. package/__tests__/InputLabel/__snapshots__/InputLabel.test.jsx.snap +3 -0
  11. package/__tests__/InputSupports/InputSupports.test.jsx +10 -0
  12. package/component-docs.json +278 -40
  13. package/lib/Button/ButtonGroup.js +118 -45
  14. package/lib/Checkbox/CheckboxGroup.js +3 -3
  15. package/lib/ExpandCollapse/Panel.js +2 -1
  16. package/lib/Fieldset/Fieldset.js +7 -0
  17. package/lib/InputLabel/InputLabel.js +8 -1
  18. package/lib/InputSupports/InputSupports.js +7 -0
  19. package/lib/List/ListItem.js +22 -12
  20. package/lib/Notification/Notification.js +1 -1
  21. package/lib/Radio/RadioGroup.js +12 -5
  22. package/lib/RadioCard/RadioCardGroup.js +7 -0
  23. package/lib/Search/Search.js +28 -20
  24. package/lib/Skeleton/Skeleton.js +48 -2
  25. package/lib/TextInput/TextArea.js +1 -1
  26. package/lib/TextInput/TextInput.js +1 -1
  27. package/lib/TextInput/TextInputBase.js +1 -1
  28. package/lib/ToggleSwitch/ToggleSwitch.js +7 -0
  29. package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  30. package/lib/Tooltip/Tooltip.js +1 -1
  31. package/lib/Typography/Typography.js +12 -10
  32. package/lib/index.js +22 -1
  33. package/lib/utils/animation/useVerticalExpandAnimation.js +26 -13
  34. package/lib/utils/input.js +5 -6
  35. package/lib/utils/props/index.js +18 -0
  36. package/lib/utils/props/inputSupportsProps.js +7 -0
  37. package/lib/utils/props/textInputProps.js +207 -0
  38. package/lib/utils/props/textProps.js +72 -0
  39. package/lib-module/Button/ButtonGroup.js +117 -45
  40. package/lib-module/Checkbox/CheckboxGroup.js +3 -3
  41. package/lib-module/ExpandCollapse/Panel.js +2 -1
  42. package/lib-module/Fieldset/Fieldset.js +7 -0
  43. package/lib-module/InputLabel/InputLabel.js +8 -1
  44. package/lib-module/InputSupports/InputSupports.js +7 -0
  45. package/lib-module/List/ListItem.js +22 -12
  46. package/lib-module/Notification/Notification.js +1 -1
  47. package/lib-module/Radio/RadioGroup.js +12 -5
  48. package/lib-module/RadioCard/RadioCardGroup.js +7 -0
  49. package/lib-module/Search/Search.js +30 -22
  50. package/lib-module/Skeleton/Skeleton.js +49 -3
  51. package/lib-module/TextInput/TextArea.js +2 -2
  52. package/lib-module/TextInput/TextInput.js +2 -2
  53. package/lib-module/TextInput/TextInputBase.js +2 -2
  54. package/lib-module/ToggleSwitch/ToggleSwitch.js +7 -0
  55. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  56. package/lib-module/Tooltip/Tooltip.js +1 -1
  57. package/lib-module/Typography/Typography.js +13 -11
  58. package/lib-module/index.js +1 -1
  59. package/lib-module/utils/animation/useVerticalExpandAnimation.js +26 -14
  60. package/lib-module/utils/input.js +6 -6
  61. package/lib-module/utils/props/index.js +2 -0
  62. package/lib-module/utils/props/inputSupportsProps.js +7 -0
  63. package/lib-module/utils/props/textInputProps.js +194 -0
  64. package/lib-module/utils/props/textProps.js +59 -0
  65. package/package.json +9 -4
  66. package/src/Button/ButtonGroup.jsx +106 -41
  67. package/src/Checkbox/Checkbox.jsx +7 -4
  68. package/src/Checkbox/CheckboxGroup.jsx +3 -3
  69. package/src/ExpandCollapse/Panel.jsx +3 -1
  70. package/src/Fieldset/Fieldset.jsx +6 -0
  71. package/src/InputLabel/InputLabel.jsx +17 -2
  72. package/src/InputSupports/InputSupports.jsx +9 -1
  73. package/src/List/ListItem.jsx +17 -9
  74. package/src/Notification/Notification.jsx +1 -1
  75. package/src/Radio/Radio.jsx +5 -1
  76. package/src/Radio/RadioGroup.jsx +11 -5
  77. package/src/RadioCard/RadioCard.jsx +5 -1
  78. package/src/RadioCard/RadioCardGroup.jsx +6 -0
  79. package/src/Search/Search.jsx +34 -22
  80. package/src/Skeleton/Skeleton.jsx +56 -3
  81. package/src/TextInput/TextArea.jsx +2 -0
  82. package/src/TextInput/TextInput.jsx +2 -0
  83. package/src/TextInput/TextInputBase.jsx +2 -0
  84. package/src/ToggleSwitch/ToggleSwitch.jsx +6 -0
  85. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
  86. package/src/Tooltip/Tooltip.jsx +1 -1
  87. package/src/Typography/Typography.jsx +13 -9
  88. package/src/index.js +4 -1
  89. package/src/utils/animation/useVerticalExpandAnimation.js +25 -12
  90. package/src/utils/input.js +5 -7
  91. package/src/utils/props/index.js +2 -0
  92. package/src/utils/props/inputSupportsProps.js +6 -1
  93. package/src/utils/props/textInputProps.js +178 -0
  94. package/src/utils/props/textProps.js +58 -0
  95. package/src/utils/props/tokens.js +21 -19
  96. package/stories/Search/Search.stories.jsx +49 -2
  97. package/stories/Tabs/Tabs.stories.jsx +4 -3
@@ -17,6 +17,8 @@ var _ButtonBase = _interopRequireDefault(require("./ButtonBase"));
17
17
 
18
18
  var _StackView = require("../StackView");
19
19
 
20
+ var _Fieldset = _interopRequireDefault(require("../Fieldset"));
21
+
20
22
  var _ViewportProvider = require("../ViewportProvider");
21
23
 
22
24
  var _ThemeProvider = require("../ThemeProvider");
@@ -45,6 +47,13 @@ const ButtonGroup = /*#__PURE__*/(0, _react.forwardRef)(({
45
47
  onChange,
46
48
  readOnly = false,
47
49
  inactive = false,
50
+ legend,
51
+ tooltip,
52
+ hint,
53
+ validation,
54
+ feedback,
55
+ name: inputGroupName,
56
+ copy,
48
57
  accessibilityRole = maxValues === 1 ? 'radiogroup' // radiogroup is cross-platform; only web aria has generic groups
49
58
  : _Platform.default.select({
50
59
  web: 'group',
@@ -59,7 +68,8 @@ const ButtonGroup = /*#__PURE__*/(0, _react.forwardRef)(({
59
68
  const stackTokens = (0, _utils.selectTokens)('StackView', themeTokens);
60
69
  const {
61
70
  direction,
62
- space
71
+ space,
72
+ fieldSpace
63
73
  } = themeTokens;
64
74
  const getButtonTokens = (0, _ThemeProvider.useThemeTokensCallback)('ButtonGroupItem', tokens, variant);
65
75
  const {
@@ -81,54 +91,71 @@ const ButtonGroup = /*#__PURE__*/(0, _react.forwardRef)(({
81
91
 
82
92
  if (!(0, _utils.containUniqueFields)(items, uniqueFields)) {
83
93
  throw new Error(`ButtonGroup items must have unique ${uniqueFields.join(', ')}`);
84
- }
94
+ } // Some web screenreaders e.g. MacOS Voiceover don't handle radiogroups properly unless radio is direct child of radiogroup
95
+
85
96
 
86
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.StackWrap, { ...systemProps,
87
- space: space,
88
- direction: direction,
89
- tokens: stackTokens,
97
+ const innerRole = _Platform.default.OS === 'web' && accessibilityRole === 'radiogroup' ? accessibilityRole : undefined;
98
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Fieldset.default, { ...systemProps,
90
99
  ref: ref,
91
- children: items.map(({
92
- label,
93
- id = label,
94
- accessibilityLabel,
95
- ref: itemRef,
96
- ...itemRest
97
- }, index) => {
98
- const isSelected = currentValues.includes(id); // Pass an object of relevant component state as first argument for any passed-in press handlers
99
-
100
- const pressHandlers = (0, _pressability.getPressHandlersWithArgs)(rest, [{
101
- id,
100
+ name: inputGroupName,
101
+ legend: legend,
102
+ tooltip: tooltip,
103
+ hint: hint,
104
+ space: fieldSpace,
105
+ feedback: feedback,
106
+ readOnly: readOnly,
107
+ inactive: inactive,
108
+ validation: validation,
109
+ accessibilityRole: accessibilityRole,
110
+ ...selectProps(rest),
111
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.StackWrap, {
112
+ accessibilityRole: innerRole,
113
+ space: space,
114
+ direction: direction,
115
+ tokens: stackTokens,
116
+ ref: ref,
117
+ children: items.map(({
102
118
  label,
103
- currentValues
104
- }]);
105
-
106
- const handlePress = event => {
107
- if (pressHandlers.onPress) pressHandlers.onPress(event);
108
- toggleOneValue(id, event);
109
- };
110
-
111
- const itemA11y = {
112
- accessibilityState: {
113
- checked: isSelected
114
- },
115
- accessibilityRole: itemA11yRole,
119
+ id = label,
116
120
  accessibilityLabel,
117
- ..._utils.a11yProps.getPositionInSet(items.length, index)
118
- }; // Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
119
- // "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
120
-
121
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ButtonBase.default, {
122
121
  ref: itemRef,
123
- ...pressHandlers,
124
- onPress: handlePress,
125
- tokens: getButtonTokens,
126
- selected: isSelected,
127
- inactive: inactive,
128
- ...itemA11y,
129
- ...selectItemProps(itemRest),
130
- children: label
131
- }, id);
122
+ ...itemRest
123
+ }, index) => {
124
+ const isSelected = currentValues.includes(id); // Pass an object of relevant component state as first argument for any passed-in press handlers
125
+
126
+ const pressHandlers = (0, _pressability.getPressHandlersWithArgs)(rest, [{
127
+ id,
128
+ label,
129
+ currentValues
130
+ }]);
131
+
132
+ const handlePress = event => {
133
+ if (pressHandlers.onPress) pressHandlers.onPress(event);
134
+ toggleOneValue(id, event);
135
+ };
136
+
137
+ const itemA11y = {
138
+ accessibilityState: {
139
+ checked: isSelected
140
+ },
141
+ accessibilityRole: itemA11yRole,
142
+ accessibilityLabel,
143
+ ..._utils.a11yProps.getPositionInSet(items.length, index)
144
+ }; // Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
145
+ // "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
146
+
147
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ButtonBase.default, {
148
+ ref: itemRef,
149
+ ...pressHandlers,
150
+ onPress: handlePress,
151
+ tokens: getButtonTokens,
152
+ selected: isSelected,
153
+ inactive: inactive,
154
+ ...itemA11y,
155
+ ...selectItemProps(itemRest),
156
+ children: label
157
+ }, id);
158
+ })
132
159
  })
133
160
  });
134
161
  });
@@ -192,7 +219,53 @@ ButtonGroup.propTypes = { ...selectedSystemPropTypes,
192
219
  * managing its own selected state, a default set of selections may be provided.
193
220
  * Changing the `initialValues` does not change the user's selections.
194
221
  */
195
- initialValues: _propTypes.default.arrayOf(_propTypes.default.string)
222
+ initialValues: _propTypes.default.arrayOf(_propTypes.default.string),
223
+
224
+ /**
225
+ * Main text used to describe this group, used in Fieldset's Legend element.
226
+ */
227
+ legend: _propTypes.default.string,
228
+
229
+ /**
230
+ * Optional additional text giving more detail to help a user make a choice.
231
+ */
232
+ hint: _propTypes.default.string,
233
+
234
+ /**
235
+ * Optional tooltip text content to include alongside the legend and hint.
236
+ */
237
+ tooltip: _propTypes.default.string,
238
+
239
+ /**
240
+ * Current validation status of the group, passed to the feedback element if there is one.
241
+ */
242
+ validation: _propTypes.default.oneOf(['error', 'success']),
243
+
244
+ /**
245
+ * If provided, a Feedback element is rendered containing this text.
246
+ */
247
+ feedback: _propTypes.default.string,
248
+
249
+ /**
250
+ * If true, the buttons cannot be selected by the user and simply show their current state.
251
+ */
252
+ readOnly: _propTypes.default.bool,
253
+
254
+ /**
255
+ * If true, the buttons cannot be interacted with, elements are set as `disabled` and if the
256
+ * theme supports `inactive` appearances rules, these are applied.
257
+ */
258
+ inactive: _propTypes.default.bool,
259
+
260
+ /**
261
+ * On Web, this is passed to the `name` attribute of the fieldset.
262
+ */
263
+ name: _propTypes.default.string,
264
+
265
+ /**
266
+ * Sets the language of microcopy in subcomponents (e.g. Tooltip's default accessibility label).
267
+ */
268
+ copy: _propTypes.default.oneOf(['en', 'fr'])
196
269
  };
197
270
  var _default = ButtonGroup;
198
271
  exports.default = _default;
@@ -236,18 +236,18 @@ CheckboxGroup.propTypes = { ...selectedSystemPropTypes,
236
236
  onChange: _propTypes.default.func,
237
237
 
238
238
  /**
239
- * If true, the radio cards cannot be selected by the user and simply show their current state.
239
+ * If true, the checkboxes cannot be selected by the user and simply show their current state.
240
240
  */
241
241
  readOnly: _propTypes.default.bool,
242
242
 
243
243
  /**
244
- * If true, the checkbox cannot be interacted with, elements are set as `disabled` and if the
244
+ * If true, the checkboxes cannot be interacted with, elements are set as `disabled` and if the
245
245
  * theme supports `inactive` appearances rules, these are applied.
246
246
  */
247
247
  inactive: _propTypes.default.bool,
248
248
 
249
249
  /**
250
- * On Web, this is passed to the `name` attribute of the fieldset and each radio input.
250
+ * On Web, this is passed to the `name` attribute of the fieldset and each checkbox input.
251
251
  */
252
252
  name: _propTypes.default.string
253
253
  };
@@ -97,7 +97,7 @@ const ExpandCollapsePanel = /*#__PURE__*/(0, _react.forwardRef)(({
97
97
  }
98
98
  };
99
99
 
100
- const animatedStyles = (0, _utils.useVerticalExpandAnimation)({
100
+ const [animatedStyles, animatedRef] = (0, _utils.useVerticalExpandAnimation)({
101
101
  containerHeight,
102
102
  isExpanded,
103
103
  tokens: themeTokens
@@ -118,6 +118,7 @@ const ExpandCollapsePanel = /*#__PURE__*/(0, _react.forwardRef)(({
118
118
  onPress: handleControlPress,
119
119
  children: control
120
120
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Animated.default.View, {
121
+ ref: animatedRef,
121
122
  style: [overflowContainerStyles, animatedStyles, staticStyles.itemsContainer],
122
123
  ...focusabilityProps,
123
124
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
@@ -38,6 +38,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
38
38
  * Follows the same theming and most of the same props as InputSupports.
39
39
  */
40
40
  const Fieldset = /*#__PURE__*/(0, _react.forwardRef)(({
41
+ copy = 'en',
41
42
  space,
42
43
  feedback,
43
44
  feedbackPosition = 'top',
@@ -64,6 +65,7 @@ const Fieldset = /*#__PURE__*/(0, _react.forwardRef)(({
64
65
  });
65
66
  const legendContent = legend && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Legend.default, {
66
67
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputLabel.default, {
68
+ copy: copy,
67
69
  label: legend,
68
70
  hint: hint,
69
71
  hintPosition: hintPosition,
@@ -100,6 +102,11 @@ Fieldset.displayName = 'Fieldset';
100
102
  Fieldset.propTypes = {
101
103
  children: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]),
102
104
 
105
+ /**
106
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
107
+ */
108
+ copy: _propTypes.default.oneOf(['en', 'fr']),
109
+
103
110
  /**
104
111
  * The accessibility role of the `<fieldset>` element itself. Other React Native accessibility
105
112
  * props are not supported because there is not an appropriate counterpart for Fieldsets.
@@ -56,6 +56,7 @@ const selectGapStyles = ({
56
56
  });
57
57
 
58
58
  const InputLabel = /*#__PURE__*/(0, _react.forwardRef)(({
59
+ copy = 'en',
59
60
  label,
60
61
  forId,
61
62
  hint,
@@ -89,7 +90,8 @@ const InputLabel = /*#__PURE__*/(0, _react.forwardRef)(({
89
90
  height: themeTokens.fontSize * themeTokens.lineHeight
90
91
  }],
91
92
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
92
- content: tooltip
93
+ content: tooltip,
94
+ copy: copy
93
95
  })
94
96
  })]
95
97
  }), hint && !isHintInline && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
@@ -102,6 +104,11 @@ const InputLabel = /*#__PURE__*/(0, _react.forwardRef)(({
102
104
  InputLabel.displayName = 'InputLabel';
103
105
  InputLabel.propTypes = { ...selectedSystemPropTypes,
104
106
 
107
+ /**
108
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
109
+ */
110
+ copy: _propTypes.default.oneOf(['en', 'fr']),
111
+
105
112
  /**
106
113
  * The input label.
107
114
  */
@@ -29,6 +29,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
29
29
 
30
30
  const InputSupports = /*#__PURE__*/(0, _react.forwardRef)(({
31
31
  children,
32
+ copy = 'en',
32
33
  label,
33
34
  hint,
34
35
  hintPosition = 'inline',
@@ -54,6 +55,7 @@ const InputSupports = /*#__PURE__*/(0, _react.forwardRef)(({
54
55
  space: space,
55
56
  ref: ref,
56
57
  children: [label && /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputLabel.default, {
58
+ copy: copy,
57
59
  label: label,
58
60
  hint: hint,
59
61
  hintPosition: hintPosition,
@@ -74,6 +76,11 @@ InputSupports.displayName = 'InputSupports';
74
76
  InputSupports.propTypes = {
75
77
  children: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]),
76
78
 
79
+ /**
80
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
81
+ */
82
+ copy: _propTypes.default.oneOf(['en', 'fr']),
83
+
77
84
  /**
78
85
  * The input label.
79
86
  */
@@ -45,8 +45,7 @@ const selectBulletContainerStyles = ({
45
45
  itemBulletContainerAlign
46
46
  }) => ({
47
47
  width: itemBulletContainerWidth,
48
- alignItems: itemBulletContainerAlign,
49
- justifyContent: itemBulletContainerAlign
48
+ alignItems: itemBulletContainerAlign
50
49
  });
51
50
 
52
51
  const selectItemIconTokens = ({
@@ -57,16 +56,20 @@ const selectItemIconTokens = ({
57
56
  color: itemIconColor
58
57
  });
59
58
 
60
- const selectCommonIconStyles = ({
59
+ const selectSideItemContainerStyles = ({
60
+ listGutter,
61
61
  iconMarginTop
62
62
  }) => ({
63
- marginTop: iconMarginTop
64
- });
63
+ marginTop: iconMarginTop,
64
+ marginRight: listGutter
65
+ }); // Align bullets with the top line of text the same way icons are aligned
65
66
 
66
- const selectSideItemContainerStyles = ({
67
- listGutter
67
+
68
+ const selectBulletPositioningStyles = ({
69
+ itemIconSize
68
70
  }) => ({
69
- marginRight: listGutter
71
+ width: itemIconSize,
72
+ height: itemIconSize
70
73
  });
71
74
 
72
75
  const selectItemStyles = ({
@@ -119,8 +122,8 @@ const ListItem = /*#__PURE__*/(0, _react.forwardRef)(({
119
122
  const dividerStyles = selectDividerStyles(themeTokens);
120
123
  const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens);
121
124
  const itemBulletStyles = selectBulletStyles(themeTokens);
125
+ const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens);
122
126
  const iconTokens = selectItemIconTokens(themeTokens);
123
- const commonIconStyles = selectCommonIconStyles(themeTokens);
124
127
  const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens);
125
128
 
126
129
  const accessibilityRole = _Platform.default.select({
@@ -164,7 +167,7 @@ const ListItem = /*#__PURE__*/(0, _react.forwardRef)(({
164
167
 
165
168
  if (icon) {
166
169
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
167
- style: [sideItemContainerStyles, commonIconStyles],
170
+ style: sideItemContainerStyles,
168
171
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
169
172
  size: iconSize || iconTokens.size,
170
173
  color: iconColor || iconTokens.color
@@ -175,8 +178,11 @@ const ListItem = /*#__PURE__*/(0, _react.forwardRef)(({
175
178
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
176
179
  style: [sideItemContainerStyles, itemBulletContainerStyles],
177
180
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
178
- style: itemBulletStyles,
179
- testID: "unordered-item-bullet"
181
+ style: [staticStyles.bulletPositioning, itemBulletPositioningStyles],
182
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
183
+ style: itemBulletStyles,
184
+ testID: "unordered-item-bullet"
185
+ })
180
186
  })
181
187
  });
182
188
  };
@@ -197,6 +203,10 @@ const staticStyles = _StyleSheet.default.create({
197
203
  },
198
204
  wrap: {
199
205
  flex: 1
206
+ },
207
+ bulletPositioning: {
208
+ alignItems: 'center',
209
+ justifyContent: 'center'
200
210
  }
201
211
  });
202
212
 
@@ -199,7 +199,7 @@ Notification.propTypes = { ...selectedSystemPropTypes,
199
199
  dismissible: _propTypes.default.bool,
200
200
 
201
201
  /**
202
- * Select english or french copy for the accessible label of the dismiss button.
202
+ * Select English or French copy for the accessible label of the dismiss button.
203
203
  */
204
204
  copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), _propTypes.default.shape({
205
205
  dismiss: _propTypes.default.string
@@ -52,7 +52,7 @@ const [selectItemProps, selectedItemPropTypes] = (0, _utils.selectSystemProps)([
52
52
  * ### Uncontrolled version
53
53
  *
54
54
  * If the RadioGroup manages its own state, you can use `initialCheckedId` prop to provide the initial value.
55
- * Whenever the radio card gets toggled, it calls the `onChange` callback with the new value (string).
55
+ * Whenever the radio gets toggled, it calls the `onChange` callback with the new value (string).
56
56
  *
57
57
  * ### Use in forms
58
58
  *
@@ -83,6 +83,7 @@ const [selectItemProps, selectedItemPropTypes] = (0, _utils.selectSystemProps)([
83
83
  */
84
84
 
85
85
  const RadioGroup = /*#__PURE__*/(0, _react.forwardRef)(({
86
+ copy = 'en',
86
87
  tokens,
87
88
  radioTokens,
88
89
  variant,
@@ -151,6 +152,7 @@ const RadioGroup = /*#__PURE__*/(0, _react.forwardRef)(({
151
152
  }, radioId);
152
153
  });
153
154
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Fieldset.default, {
155
+ copy: copy,
154
156
  ref: ref,
155
157
  name: inputGroupName,
156
158
  legend: legend,
@@ -171,6 +173,11 @@ const RadioGroup = /*#__PURE__*/(0, _react.forwardRef)(({
171
173
  RadioGroup.displayName = 'RadioGroup';
172
174
  RadioGroup.propTypes = { ...selectedSystemPropTypes,
173
175
 
176
+ /**
177
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
178
+ */
179
+ copy: _propTypes.default.oneOf(['en', 'fr']),
180
+
174
181
  /**
175
182
  * Optional theme token overrides for the outer RadioGroup component
176
183
  */
@@ -222,12 +229,12 @@ RadioGroup.propTypes = { ...selectedSystemPropTypes,
222
229
  feedback: _propTypes.default.string,
223
230
 
224
231
  /**
225
- * If provided, the radio card with this id is selected on first render.
232
+ * If provided, the radio with this id is selected on first render.
226
233
  */
227
234
  initialCheckedId: _propTypes.default.string,
228
235
 
229
236
  /**
230
- * If not undefined, the radio card with this id is selected (or none is selected if `null`), and the
237
+ * If not undefined, the radio with this id is selected (or none is selected if `null`), and the
231
238
  * element's selection state will be controlled by its parent using the `onChange` function.
232
239
  */
233
240
  checkedId: _propTypes.default.string,
@@ -239,12 +246,12 @@ RadioGroup.propTypes = { ...selectedSystemPropTypes,
239
246
  onChange: _propTypes.default.func,
240
247
 
241
248
  /**
242
- * If true, the radio cards cannot be selected by the user and simply show their current state.
249
+ * If true, the radios cannot be selected by the user and simply show their current state.
243
250
  */
244
251
  readOnly: _propTypes.default.bool,
245
252
 
246
253
  /**
247
- * If true, the radio card cannot be interacted with, elements are set as `disabled` and if the
254
+ * If true, the radios cannot be interacted with, elements are set as `disabled` and if the
248
255
  * theme supports `inactive` appearances rules, these are applied.
249
256
  */
250
257
  inactive: _propTypes.default.bool,
@@ -83,6 +83,7 @@ const [selectItemProps, selectedItemPropTypes] = (0, _utils.selectSystemProps)([
83
83
  */
84
84
 
85
85
  const RadioCardGroup = /*#__PURE__*/(0, _react.forwardRef)(({
86
+ copy = 'en',
86
87
  tokens,
87
88
  radioCardTokens,
88
89
  variant,
@@ -128,6 +129,7 @@ const RadioCardGroup = /*#__PURE__*/(0, _react.forwardRef)(({
128
129
  }
129
130
 
130
131
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Fieldset.default, {
132
+ copy: copy,
131
133
  ref: ref,
132
134
  name: inputGroupName,
133
135
  legend: legend,
@@ -177,6 +179,11 @@ const RadioCardGroup = /*#__PURE__*/(0, _react.forwardRef)(({
177
179
  RadioCardGroup.displayName = 'RadioCardGroup';
178
180
  RadioCardGroup.propTypes = { ...selectedSystemPropTypes,
179
181
 
182
+ /**
183
+ * Whether the English or French copy will be used (e.g. for accessibility labels).
184
+ */
185
+ copy: _propTypes.default.oneOf(['en', 'fr']),
186
+
180
187
  /**
181
188
  * Optional theme token overrides for the outer RadioCardGroup component
182
189
  */
@@ -35,7 +35,8 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
35
35
 
36
36
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
37
 
38
- const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
38
+ const [selectContainerProps, selectedContainerPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
39
+ const [selectInputProps, selectedInputPropTypes] = (0, _utils.selectSystemProps)([_utils.textInputHandlerProps, _utils.textInputProps]);
39
40
 
40
41
  const selectInputTokens = ({
41
42
  searchTokens,
@@ -90,8 +91,9 @@ const selectIconTokens = ({
90
91
 
91
92
 
92
93
  const Search = /*#__PURE__*/(0, _react.forwardRef)(({
93
- initialValue = '',
94
- placeholder = 'Search',
94
+ initialValue,
95
+ value,
96
+ placeholder,
95
97
  inactive,
96
98
  onChange,
97
99
  onSubmit,
@@ -102,7 +104,14 @@ const Search = /*#__PURE__*/(0, _react.forwardRef)(({
102
104
  variant,
103
105
  ...rest
104
106
  }, ref) => {
105
- const [value, setValue] = (0, _react.useState)(initialValue);
107
+ const {
108
+ currentValue = '',
109
+ setValue
110
+ } = (0, _utils.useInputValue)({
111
+ value,
112
+ initialValue,
113
+ onChange
114
+ });
106
115
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('Search', tokens, variant);
107
116
  const buttonTokens = (0, _ThemeProvider.useThemeTokens)('SearchButton', tokens, variant);
108
117
  const getThemeTokens = (0, _ThemeProvider.useThemeTokensCallback)('Search', tokens, variant);
@@ -123,26 +132,24 @@ const Search = /*#__PURE__*/(0, _react.forwardRef)(({
123
132
 
124
133
  const handleSubmit = event => {
125
134
  if (onSubmit !== undefined) {
126
- onSubmit(value, event);
135
+ onSubmit(currentValue, event);
127
136
  }
128
137
  };
129
138
 
130
- const handleChange = (currentValue, event) => {
131
- setValue(currentValue, event);
132
- if (onChange !== undefined) onChange(currentValue, event);
133
- };
134
-
135
139
  const handleClear = event => {
136
140
  setValue('', event);
137
141
  if (onClear !== undefined) onClear('', event);
138
- if (onChange !== undefined) onChange('', event);
139
142
  };
140
143
 
141
- const isEmpty = value === '';
144
+ const isEmpty = currentValue === ''; // Accessibility label should always be present and correctly localised
145
+
146
+ const a11yLabelText = accessibilityLabel || getCopy('accessibilityLabel'); // Placeholder is optional and may be unset by passing an empty string
147
+
148
+ const placeholderText = placeholder ?? a11yLabelText;
142
149
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
143
150
  style: staticStyles.container,
144
- ...selectProps(rest),
145
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInputBase.default, {
151
+ ...selectContainerProps(rest),
152
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInputBase.default, { ...selectInputProps(rest),
146
153
  ref: ref,
147
154
  tokens: appearances => selectInputTokens({
148
155
  searchTokens: getThemeTokens(appearances),
@@ -150,15 +157,15 @@ const Search = /*#__PURE__*/(0, _react.forwardRef)(({
150
157
  buttonsGapSize,
151
158
  isEmpty
152
159
  }),
153
- placeholder: placeholder,
160
+ placeholder: placeholderText,
154
161
  placeholderTextColor: placeholderColor,
155
162
  inactive: inactive,
156
163
  enablesReturnKeyAutomatically: true,
157
164
  returnKeyType: "search",
158
- value: value,
159
- onChange: handleChange,
165
+ value: currentValue,
166
+ onChange: setValue,
160
167
  onSubmitEditing: handleSubmit,
161
- accessibilityLabel: accessibilityLabel || getCopy('accessibilityLabel')
168
+ accessibilityLabel: a11yLabelText
162
169
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
163
170
  style: [staticStyles.iconsContainer, selectIconsContainerStyle(themeTokens)],
164
171
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_StackView.default, {
@@ -190,7 +197,8 @@ const Search = /*#__PURE__*/(0, _react.forwardRef)(({
190
197
  });
191
198
  });
192
199
  Search.displayName = 'Search';
193
- Search.propTypes = { ...selectedSystemPropTypes,
200
+ Search.propTypes = { ...selectedContainerPropTypes,
201
+ ...selectedInputPropTypes,
194
202
 
195
203
  /**
196
204
  * Use this to set the initial value of the search input.
@@ -232,7 +240,7 @@ Search.propTypes = { ...selectedSystemPropTypes,
232
240
  accessibilityLabel: _propTypes.default.string,
233
241
 
234
242
  /**
235
- * Select english or french copy for the accessible labels.
243
+ * Select English or French copy for the accessible labels.
236
244
  * You may also pass in a custom dictionary object.
237
245
  */
238
246
  copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), _propTypes.default.shape({