@telus-uds/components-base 3.9.0 → 3.11.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.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,22 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Tue, 10 Jun 2025 20:18:03 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 26 Jun 2025 23:47:29 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.11.0
8
+
9
+ Thu, 26 Jun 2025 23:47:29 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Carousel`: add dots style variant to progressBarVariant (guillermo.peitzner@telus.com)
14
+ - `ButtonGroup`: equalWidth variant added (35577399+JoshHC@users.noreply.github.com)
15
+ - Bump @telus-uds/system-theme-tokens to v4.9.0
16
+
7
17
  ## 3.9.0
8
18
 
9
- Tue, 10 Jun 2025 20:18:03 GMT
19
+ Tue, 10 Jun 2025 20:25:05 GMT
10
20
 
11
21
  ### Minor changes
12
22
 
@@ -408,7 +408,10 @@ const dictionaryContentShape = _propTypes.default.shape({
408
408
  Autocomplete.propTypes = {
409
409
  ...selectedSystemPropTypes,
410
410
  /**
411
- * Can be used to provide a function that renders a custom input:
411
+ * Can be used to provide a function that renders a custom input.
412
+ *
413
+ * @example
414
+ * ```jsx
412
415
  * <Autocomplete items={items} value={currentValue}>
413
416
  * {({ inputId, inputRef, onChange, onKeyPress, readOnly, tokens, value }) => (
414
417
  * <Search
@@ -422,6 +425,7 @@ Autocomplete.propTypes = {
422
425
  * />
423
426
  * )}
424
427
  * </Autocomplete>
428
+ * ```
425
429
  */
426
430
  children: _propTypes.default.func,
427
431
  tokens: (0, _utils.getTokensPropType)('Autocomplete'),
@@ -24,7 +24,23 @@ const getOuterBorderOffset = _ref => {
24
24
  } = _ref;
25
25
  return outerBorderGap + outerBorderWidth;
26
26
  };
27
- const selectOuterContainerStyles = _ref2 => {
27
+ const selectFlexAndWidthStyles = _ref2 => {
28
+ let {
29
+ width,
30
+ flex
31
+ } = _ref2;
32
+ const styles = {};
33
+ if (width !== undefined && width !== null) {
34
+ styles.width = width;
35
+ }
36
+ if (width === '100%') {
37
+ styles.flex = 1;
38
+ } else if (flex !== undefined && flex !== null) {
39
+ styles.flex = flex;
40
+ }
41
+ return styles;
42
+ };
43
+ const selectOuterContainerStyles = _ref3 => {
28
44
  let {
29
45
  opacity,
30
46
  outerBorderColor,
@@ -32,7 +48,7 @@ const selectOuterContainerStyles = _ref2 => {
32
48
  outerBorderGap,
33
49
  borderRadius,
34
50
  outerBackgroundColor
35
- } = _ref2;
51
+ } = _ref3;
36
52
  return {
37
53
  ..._Platform.default.select({
38
54
  native: {
@@ -49,13 +65,13 @@ const selectOuterContainerStyles = _ref2 => {
49
65
  })
50
66
  };
51
67
  };
52
- const selectOuterSizeStyles = _ref3 => {
68
+ const selectOuterSizeStyles = _ref4 => {
53
69
  let {
54
70
  outerBorderGap,
55
71
  outerBorderWidth,
56
72
  width,
57
73
  height
58
- } = _ref3;
74
+ } = _ref4;
59
75
  // The inner container's bounding box is the bounding box of the button overall
60
76
  // so this many device pixels will sit outside of the overall bounding box
61
77
  const outerBorderOffset = getOuterBorderOffset({
@@ -100,7 +116,7 @@ const selectOuterSizeStyles = _ref3 => {
100
116
  sizeStyles.height = height;
101
117
  return sizeStyles;
102
118
  };
103
- const selectInnerContainerStyles = _ref4 => {
119
+ const selectInnerContainerStyles = _ref5 => {
104
120
  let {
105
121
  backgroundColor,
106
122
  paddingLeft,
@@ -114,14 +130,14 @@ const selectInnerContainerStyles = _ref4 => {
114
130
  borderTopWidth,
115
131
  borderBottomWidth,
116
132
  minWidth
117
- } = _ref4;
133
+ } = _ref5;
118
134
  // Subtract border width from padding so overall button width/height doesn't
119
135
  // jump around if the border width changes (avoiding NaN and negative padding)
120
- const offsetBorder = _ref5 => {
136
+ const offsetBorder = _ref6 => {
121
137
  let {
122
138
  value,
123
139
  borderSize = borderWidth
124
- } = _ref5;
140
+ } = _ref6;
125
141
  return typeof value === 'number' && typeof borderSize === 'number' ? Math.max(0, value - borderSize) : value;
126
142
  };
127
143
  return {
@@ -146,7 +162,7 @@ const selectInnerContainerStyles = _ref4 => {
146
162
  ...(0, _ThemeProvider.applyShadowToken)(shadow)
147
163
  };
148
164
  };
149
- const selectBorderStyles = _ref6 => {
165
+ const selectBorderStyles = _ref7 => {
150
166
  let {
151
167
  borderColor,
152
168
  borderWidth,
@@ -155,7 +171,7 @@ const selectBorderStyles = _ref6 => {
155
171
  borderRightWidth,
156
172
  borderTopWidth,
157
173
  borderBottomWidth
158
- } = _ref6;
174
+ } = _ref7;
159
175
  return {
160
176
  borderColor,
161
177
  borderWidth,
@@ -166,7 +182,7 @@ const selectBorderStyles = _ref6 => {
166
182
  borderBottomWidth
167
183
  };
168
184
  };
169
- const selectTextStyles = (_ref7, themeOptions) => {
185
+ const selectTextStyles = (_ref8, themeOptions) => {
170
186
  let {
171
187
  fontSize,
172
188
  color,
@@ -176,7 +192,7 @@ const selectTextStyles = (_ref7, themeOptions) => {
176
192
  textAlign,
177
193
  textLine,
178
194
  textLineStyle
179
- } = _ref7;
195
+ } = _ref8;
180
196
  return (0, _ThemeProvider.applyTextStyles)({
181
197
  fontSize,
182
198
  color,
@@ -189,10 +205,10 @@ const selectTextStyles = (_ref7, themeOptions) => {
189
205
  textDecorationStyle: textLineStyle
190
206
  });
191
207
  };
192
- const selectWebOnlyStyles = (inactive, themeTokens, _ref8) => {
208
+ const selectWebOnlyStyles = (inactive, themeTokens, _ref9) => {
193
209
  let {
194
210
  accessibilityRole
195
- } = _ref8;
211
+ } = _ref9;
196
212
  return _Platform.default.select({
197
213
  web: {
198
214
  // if it would overflow the container, wraps instead
@@ -205,27 +221,27 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref8) => {
205
221
  default: {}
206
222
  });
207
223
  };
208
- const selectButtonStyles = _ref9 => {
224
+ const selectButtonStyles = _ref10 => {
209
225
  let {
210
226
  textAlign
211
- } = _ref9;
227
+ } = _ref10;
212
228
  return {
213
229
  flexDirection: 'row',
214
230
  justifyContent: textAlign
215
231
  };
216
232
  };
217
- const selectItemIconTokens = _ref10 => {
233
+ const selectItemIconTokens = _ref11 => {
218
234
  let {
219
235
  color,
220
236
  iconColor,
221
237
  iconSize
222
- } = _ref10;
238
+ } = _ref11;
223
239
  return {
224
240
  size: iconSize,
225
241
  color: iconColor || color
226
242
  };
227
243
  };
228
- const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref11, ref) => {
244
+ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref12, ref) => {
229
245
  let {
230
246
  id,
231
247
  href,
@@ -240,7 +256,7 @@ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref11, ref) => {
240
256
  iconPosition = icon ? 'left' : undefined,
241
257
  iconProps,
242
258
  ...rawRest
243
- } = _ref11;
259
+ } = _ref12;
244
260
  const {
245
261
  onPress,
246
262
  ...rest
@@ -254,7 +270,9 @@ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref11, ref) => {
254
270
  const systemProps = selectProps(rest);
255
271
  const getPressableStyle = pressableState => {
256
272
  const themeTokens = resolveButtonTokens(pressableState);
257
- return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens), selectOuterSizeStyles(themeTokens)];
273
+ // Only apply flex and width styles when they are explicitly set (e.g., from ButtonGroup with width: 'equal') to not to affect other use cases
274
+ const flexAndWidthStyles = themeTokens.width === '100%' && themeTokens.flex === 1 ? selectFlexAndWidthStyles(themeTokens) : {};
275
+ return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens), ...(Object.keys(flexAndWidthStyles).length > 0 ? [flexAndWidthStyles] : []), selectOuterSizeStyles(themeTokens)];
258
276
  };
259
277
  const {
260
278
  themeOptions
@@ -19,6 +19,15 @@ var _jsxRuntime = require("react/jsx-runtime");
19
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
20
  const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
21
21
  const [selectItemProps, selectedItemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.focusHandlerProps, _utils.pressProps, _utils.viewProps]);
22
+ const getStackWrapTokens = variant => {
23
+ return _Platform.default.select({
24
+ web: {
25
+ justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start',
26
+ width: variant?.width === 'equal' ? '100%' : 'auto'
27
+ },
28
+ default: {}
29
+ });
30
+ };
22
31
  const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
23
32
  let {
24
33
  variant,
@@ -51,7 +60,12 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
51
60
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('ButtonGroup', tokens, variant, {
52
61
  viewport
53
62
  });
54
- const stackTokens = (0, _utils.selectTokens)('StackView', themeTokens);
63
+ const themeStackTokens = (0, _utils.selectTokens)('StackView', themeTokens);
64
+ const variantStackTokens = getStackWrapTokens(variant);
65
+ const stackTokens = {
66
+ ...themeStackTokens,
67
+ ...variantStackTokens
68
+ };
55
69
  const {
56
70
  direction,
57
71
  space,
@@ -61,7 +75,15 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
61
75
  padding,
62
76
  gap
63
77
  } = themeTokens;
64
- const getButtonTokens = (0, _ThemeProvider.useThemeTokensCallback)('ButtonGroupItem', tokens, variant);
78
+ const themeButtonTokensCallback = (0, _ThemeProvider.useThemeTokensCallback)('ButtonGroupItem', tokens, variant);
79
+ const getButtonTokens = state => {
80
+ const themeButtonTokens = themeButtonTokensCallback(state);
81
+ return {
82
+ ...themeButtonTokens,
83
+ width: variant?.width === 'equal' ? '100%' : 'auto',
84
+ flex: variant?.width === 'equal' ? 1 : undefined
85
+ };
86
+ };
65
87
  const {
66
88
  currentValues,
67
89
  toggleOneValue
@@ -104,7 +126,7 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
104
126
  padding,
105
127
  ...(_Platform.default.OS === 'web' ? {
106
128
  gap,
107
- width: 'fit-content'
129
+ width: variant?.width === 'equal' ? '100%' : 'fit-content'
108
130
  } : {
109
131
  alignSelf: 'flex-start'
110
132
  })
@@ -44,7 +44,8 @@ const CarouselStepTracker = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =
44
44
  containerPaddingTop: themeTokens.spaceBetweenSlideAndPanelNavigation
45
45
  };
46
46
  const steps = Array.from(Array(totalItems)).map((_, index) => String(index));
47
- if (enableDisplayMultipleItemsPerSlide) {
47
+ const showProgressBar = enableDisplayMultipleItemsPerSlide && progressBarVariant?.style !== 'dots';
48
+ if (showProgressBar) {
48
49
  if (totalItems === 1) {
49
50
  return null;
50
51
  }
@@ -71,6 +72,9 @@ const CarouselStepTracker = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =
71
72
  })]
72
73
  });
73
74
  }
75
+ if (enableDisplayMultipleItemsPerSlide && totalItems === 1) {
76
+ return null;
77
+ }
74
78
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
75
79
  direction: "row",
76
80
  tokens: stackViewTokens,
@@ -80,7 +84,7 @@ const CarouselStepTracker = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =
80
84
  steps: steps,
81
85
  copy: {
82
86
  stepLabel: getCopyWithPlaceholders('stepLabel'),
83
- stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
87
+ stepTrackerLabel: enableDisplayMultipleItemsPerSlide ? '' : getCopyWithPlaceholders('stepTrackerLabel')
84
88
  },
85
89
  tokens: stepTrackerTokens,
86
90
  variant: stepTrackerVariant
@@ -401,7 +401,10 @@ const dictionaryContentShape = PropTypes.shape({
401
401
  Autocomplete.propTypes = {
402
402
  ...selectedSystemPropTypes,
403
403
  /**
404
- * Can be used to provide a function that renders a custom input:
404
+ * Can be used to provide a function that renders a custom input.
405
+ *
406
+ * @example
407
+ * ```jsx
405
408
  * <Autocomplete items={items} value={currentValue}>
406
409
  * {({ inputId, inputRef, onChange, onKeyPress, readOnly, tokens, value }) => (
407
410
  * <Search
@@ -415,6 +418,7 @@ Autocomplete.propTypes = {
415
418
  * />
416
419
  * )}
417
420
  * </Autocomplete>
421
+ * ```
418
422
  */
419
423
  children: PropTypes.func,
420
424
  tokens: getTokensPropType('Autocomplete'),
@@ -17,7 +17,23 @@ const getOuterBorderOffset = _ref => {
17
17
  } = _ref;
18
18
  return outerBorderGap + outerBorderWidth;
19
19
  };
20
- const selectOuterContainerStyles = _ref2 => {
20
+ const selectFlexAndWidthStyles = _ref2 => {
21
+ let {
22
+ width,
23
+ flex
24
+ } = _ref2;
25
+ const styles = {};
26
+ if (width !== undefined && width !== null) {
27
+ styles.width = width;
28
+ }
29
+ if (width === '100%') {
30
+ styles.flex = 1;
31
+ } else if (flex !== undefined && flex !== null) {
32
+ styles.flex = flex;
33
+ }
34
+ return styles;
35
+ };
36
+ const selectOuterContainerStyles = _ref3 => {
21
37
  let {
22
38
  opacity,
23
39
  outerBorderColor,
@@ -25,7 +41,7 @@ const selectOuterContainerStyles = _ref2 => {
25
41
  outerBorderGap,
26
42
  borderRadius,
27
43
  outerBackgroundColor
28
- } = _ref2;
44
+ } = _ref3;
29
45
  return {
30
46
  ...Platform.select({
31
47
  native: {
@@ -42,13 +58,13 @@ const selectOuterContainerStyles = _ref2 => {
42
58
  })
43
59
  };
44
60
  };
45
- const selectOuterSizeStyles = _ref3 => {
61
+ const selectOuterSizeStyles = _ref4 => {
46
62
  let {
47
63
  outerBorderGap,
48
64
  outerBorderWidth,
49
65
  width,
50
66
  height
51
- } = _ref3;
67
+ } = _ref4;
52
68
  // The inner container's bounding box is the bounding box of the button overall
53
69
  // so this many device pixels will sit outside of the overall bounding box
54
70
  const outerBorderOffset = getOuterBorderOffset({
@@ -93,7 +109,7 @@ const selectOuterSizeStyles = _ref3 => {
93
109
  sizeStyles.height = height;
94
110
  return sizeStyles;
95
111
  };
96
- const selectInnerContainerStyles = _ref4 => {
112
+ const selectInnerContainerStyles = _ref5 => {
97
113
  let {
98
114
  backgroundColor,
99
115
  paddingLeft,
@@ -107,14 +123,14 @@ const selectInnerContainerStyles = _ref4 => {
107
123
  borderTopWidth,
108
124
  borderBottomWidth,
109
125
  minWidth
110
- } = _ref4;
126
+ } = _ref5;
111
127
  // Subtract border width from padding so overall button width/height doesn't
112
128
  // jump around if the border width changes (avoiding NaN and negative padding)
113
- const offsetBorder = _ref5 => {
129
+ const offsetBorder = _ref6 => {
114
130
  let {
115
131
  value,
116
132
  borderSize = borderWidth
117
- } = _ref5;
133
+ } = _ref6;
118
134
  return typeof value === 'number' && typeof borderSize === 'number' ? Math.max(0, value - borderSize) : value;
119
135
  };
120
136
  return {
@@ -139,7 +155,7 @@ const selectInnerContainerStyles = _ref4 => {
139
155
  ...applyShadowToken(shadow)
140
156
  };
141
157
  };
142
- const selectBorderStyles = _ref6 => {
158
+ const selectBorderStyles = _ref7 => {
143
159
  let {
144
160
  borderColor,
145
161
  borderWidth,
@@ -148,7 +164,7 @@ const selectBorderStyles = _ref6 => {
148
164
  borderRightWidth,
149
165
  borderTopWidth,
150
166
  borderBottomWidth
151
- } = _ref6;
167
+ } = _ref7;
152
168
  return {
153
169
  borderColor,
154
170
  borderWidth,
@@ -159,7 +175,7 @@ const selectBorderStyles = _ref6 => {
159
175
  borderBottomWidth
160
176
  };
161
177
  };
162
- const selectTextStyles = (_ref7, themeOptions) => {
178
+ const selectTextStyles = (_ref8, themeOptions) => {
163
179
  let {
164
180
  fontSize,
165
181
  color,
@@ -169,7 +185,7 @@ const selectTextStyles = (_ref7, themeOptions) => {
169
185
  textAlign,
170
186
  textLine,
171
187
  textLineStyle
172
- } = _ref7;
188
+ } = _ref8;
173
189
  return applyTextStyles({
174
190
  fontSize,
175
191
  color,
@@ -182,10 +198,10 @@ const selectTextStyles = (_ref7, themeOptions) => {
182
198
  textDecorationStyle: textLineStyle
183
199
  });
184
200
  };
185
- const selectWebOnlyStyles = (inactive, themeTokens, _ref8) => {
201
+ const selectWebOnlyStyles = (inactive, themeTokens, _ref9) => {
186
202
  let {
187
203
  accessibilityRole
188
- } = _ref8;
204
+ } = _ref9;
189
205
  return Platform.select({
190
206
  web: {
191
207
  // if it would overflow the container, wraps instead
@@ -198,27 +214,27 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref8) => {
198
214
  default: {}
199
215
  });
200
216
  };
201
- const selectButtonStyles = _ref9 => {
217
+ const selectButtonStyles = _ref10 => {
202
218
  let {
203
219
  textAlign
204
- } = _ref9;
220
+ } = _ref10;
205
221
  return {
206
222
  flexDirection: 'row',
207
223
  justifyContent: textAlign
208
224
  };
209
225
  };
210
- const selectItemIconTokens = _ref10 => {
226
+ const selectItemIconTokens = _ref11 => {
211
227
  let {
212
228
  color,
213
229
  iconColor,
214
230
  iconSize
215
- } = _ref10;
231
+ } = _ref11;
216
232
  return {
217
233
  size: iconSize,
218
234
  color: iconColor || color
219
235
  };
220
236
  };
221
- const ButtonBase = /*#__PURE__*/React.forwardRef((_ref11, ref) => {
237
+ const ButtonBase = /*#__PURE__*/React.forwardRef((_ref12, ref) => {
222
238
  let {
223
239
  id,
224
240
  href,
@@ -233,7 +249,7 @@ const ButtonBase = /*#__PURE__*/React.forwardRef((_ref11, ref) => {
233
249
  iconPosition = icon ? 'left' : undefined,
234
250
  iconProps,
235
251
  ...rawRest
236
- } = _ref11;
252
+ } = _ref12;
237
253
  const {
238
254
  onPress,
239
255
  ...rest
@@ -247,7 +263,9 @@ const ButtonBase = /*#__PURE__*/React.forwardRef((_ref11, ref) => {
247
263
  const systemProps = selectProps(rest);
248
264
  const getPressableStyle = pressableState => {
249
265
  const themeTokens = resolveButtonTokens(pressableState);
250
- return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens), selectOuterSizeStyles(themeTokens)];
266
+ // Only apply flex and width styles when they are explicitly set (e.g., from ButtonGroup with width: 'equal') to not to affect other use cases
267
+ const flexAndWidthStyles = themeTokens.width === '100%' && themeTokens.flex === 1 ? selectFlexAndWidthStyles(themeTokens) : {};
268
+ return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens), ...(Object.keys(flexAndWidthStyles).length > 0 ? [flexAndWidthStyles] : []), selectOuterSizeStyles(themeTokens)];
251
269
  };
252
270
  const {
253
271
  themeOptions
@@ -12,6 +12,15 @@ import { getPressHandlersWithArgs } from '../utils/pressability';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
14
14
  const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, pressProps, viewProps]);
15
+ const getStackWrapTokens = variant => {
16
+ return Platform.select({
17
+ web: {
18
+ justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start',
19
+ width: variant?.width === 'equal' ? '100%' : 'auto'
20
+ },
21
+ default: {}
22
+ });
23
+ };
15
24
  const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
16
25
  let {
17
26
  variant,
@@ -44,7 +53,12 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
44
53
  const themeTokens = useThemeTokens('ButtonGroup', tokens, variant, {
45
54
  viewport
46
55
  });
47
- const stackTokens = selectTokens('StackView', themeTokens);
56
+ const themeStackTokens = selectTokens('StackView', themeTokens);
57
+ const variantStackTokens = getStackWrapTokens(variant);
58
+ const stackTokens = {
59
+ ...themeStackTokens,
60
+ ...variantStackTokens
61
+ };
48
62
  const {
49
63
  direction,
50
64
  space,
@@ -54,7 +68,15 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
54
68
  padding,
55
69
  gap
56
70
  } = themeTokens;
57
- const getButtonTokens = useThemeTokensCallback('ButtonGroupItem', tokens, variant);
71
+ const themeButtonTokensCallback = useThemeTokensCallback('ButtonGroupItem', tokens, variant);
72
+ const getButtonTokens = state => {
73
+ const themeButtonTokens = themeButtonTokensCallback(state);
74
+ return {
75
+ ...themeButtonTokens,
76
+ width: variant?.width === 'equal' ? '100%' : 'auto',
77
+ flex: variant?.width === 'equal' ? 1 : undefined
78
+ };
79
+ };
58
80
  const {
59
81
  currentValues,
60
82
  toggleOneValue
@@ -97,7 +119,7 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
97
119
  padding,
98
120
  ...(Platform.OS === 'web' ? {
99
121
  gap,
100
- width: 'fit-content'
122
+ width: variant?.width === 'equal' ? '100%' : 'fit-content'
101
123
  } : {
102
124
  alignSelf: 'flex-start'
103
125
  })
@@ -37,7 +37,8 @@ const CarouselStepTracker = /*#__PURE__*/React.forwardRef((_ref, ref) => {
37
37
  containerPaddingTop: themeTokens.spaceBetweenSlideAndPanelNavigation
38
38
  };
39
39
  const steps = Array.from(Array(totalItems)).map((_, index) => String(index));
40
- if (enableDisplayMultipleItemsPerSlide) {
40
+ const showProgressBar = enableDisplayMultipleItemsPerSlide && progressBarVariant?.style !== 'dots';
41
+ if (showProgressBar) {
41
42
  if (totalItems === 1) {
42
43
  return null;
43
44
  }
@@ -64,6 +65,9 @@ const CarouselStepTracker = /*#__PURE__*/React.forwardRef((_ref, ref) => {
64
65
  })]
65
66
  });
66
67
  }
68
+ if (enableDisplayMultipleItemsPerSlide && totalItems === 1) {
69
+ return null;
70
+ }
67
71
  return /*#__PURE__*/_jsx(StackView, {
68
72
  direction: "row",
69
73
  tokens: stackViewTokens,
@@ -73,7 +77,7 @@ const CarouselStepTracker = /*#__PURE__*/React.forwardRef((_ref, ref) => {
73
77
  steps: steps,
74
78
  copy: {
75
79
  stepLabel: getCopyWithPlaceholders('stepLabel'),
76
- stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
80
+ stepTrackerLabel: enableDisplayMultipleItemsPerSlide ? '' : getCopyWithPlaceholders('stepTrackerLabel')
77
81
  },
78
82
  tokens: stepTrackerTokens,
79
83
  variant: stepTrackerVariant
package/lib/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.9.0",
14
14
  "@telus-uds/system-constants": "^3.0.0",
15
- "@telus-uds/system-theme-tokens": "^4.7.0",
15
+ "@telus-uds/system-theme-tokens": "^4.9.0",
16
16
  "airbnb-prop-types": "^2.16.0",
17
17
  "css-mediaquery": "^0.1.2",
18
18
  "expo-document-picker": "^13.0.1",
@@ -84,6 +84,6 @@
84
84
  "standard-engine": {
85
85
  "skip": true
86
86
  },
87
- "version": "3.9.0",
87
+ "version": "3.11.0",
88
88
  "types": "types/index.d.ts"
89
89
  }
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.9.0",
14
14
  "@telus-uds/system-constants": "^3.0.0",
15
- "@telus-uds/system-theme-tokens": "^4.7.0",
15
+ "@telus-uds/system-theme-tokens": "^4.9.0",
16
16
  "airbnb-prop-types": "^2.16.0",
17
17
  "css-mediaquery": "^0.1.2",
18
18
  "expo-document-picker": "^13.0.1",
@@ -84,6 +84,6 @@
84
84
  "standard-engine": {
85
85
  "skip": true
86
86
  },
87
- "version": "3.9.0",
87
+ "version": "3.11.0",
88
88
  "types": "types/index.d.ts"
89
89
  }
@@ -423,7 +423,10 @@ const dictionaryContentShape = PropTypes.shape({
423
423
  Autocomplete.propTypes = {
424
424
  ...selectedSystemPropTypes,
425
425
  /**
426
- * Can be used to provide a function that renders a custom input:
426
+ * Can be used to provide a function that renders a custom input.
427
+ *
428
+ * @example
429
+ * ```jsx
427
430
  * <Autocomplete items={items} value={currentValue}>
428
431
  * {({ inputId, inputRef, onChange, onKeyPress, readOnly, tokens, value }) => (
429
432
  * <Search
@@ -437,6 +440,7 @@ Autocomplete.propTypes = {
437
440
  * />
438
441
  * )}
439
442
  * </Autocomplete>
443
+ * ```
440
444
  */
441
445
  children: PropTypes.func,
442
446
  tokens: getTokensPropType('Autocomplete'),
@@ -31,6 +31,22 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([
31
31
  const getOuterBorderOffset = ({ outerBorderGap = 0, outerBorderWidth = 0 }) =>
32
32
  outerBorderGap + outerBorderWidth
33
33
 
34
+ const selectFlexAndWidthStyles = ({ width, flex }) => {
35
+ const styles = {}
36
+
37
+ if (width !== undefined && width !== null) {
38
+ styles.width = width
39
+ }
40
+
41
+ if (width === '100%') {
42
+ styles.flex = 1
43
+ } else if (flex !== undefined && flex !== null) {
44
+ styles.flex = flex
45
+ }
46
+
47
+ return styles
48
+ }
49
+
34
50
  const selectOuterContainerStyles = ({
35
51
  opacity,
36
52
  outerBorderColor,
@@ -214,10 +230,17 @@ const ButtonBase = React.forwardRef(
214
230
 
215
231
  const getPressableStyle = (pressableState) => {
216
232
  const themeTokens = resolveButtonTokens(pressableState)
233
+ // Only apply flex and width styles when they are explicitly set (e.g., from ButtonGroup with width: 'equal') to not to affect other use cases
234
+ const flexAndWidthStyles =
235
+ themeTokens.width === '100%' && themeTokens.flex === 1
236
+ ? selectFlexAndWidthStyles(themeTokens)
237
+ : {}
238
+
217
239
  return [
218
240
  staticStyles.row,
219
241
  selectWebOnlyStyles(inactive, themeTokens, systemProps),
220
242
  selectOuterContainerStyles(themeTokens),
243
+ ...(Object.keys(flexAndWidthStyles).length > 0 ? [flexAndWidthStyles] : []),
221
244
  selectOuterSizeStyles(themeTokens)
222
245
  ]
223
246
  }
@@ -30,6 +30,16 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
30
30
  viewProps
31
31
  ])
32
32
 
33
+ const getStackWrapTokens = (variant) => {
34
+ return Platform.select({
35
+ web: {
36
+ justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start',
37
+ width: variant?.width === 'equal' ? '100%' : 'auto'
38
+ },
39
+ default: {}
40
+ })
41
+ }
42
+
33
43
  const ButtonGroup = React.forwardRef(
34
44
  (
35
45
  {
@@ -62,11 +72,25 @@ const ButtonGroup = React.forwardRef(
62
72
  ) => {
63
73
  const viewport = useViewport()
64
74
  const themeTokens = useThemeTokens('ButtonGroup', tokens, variant, { viewport })
65
- const stackTokens = selectTokens('StackView', themeTokens)
75
+ const themeStackTokens = selectTokens('StackView', themeTokens)
76
+ const variantStackTokens = getStackWrapTokens(variant)
77
+ const stackTokens = {
78
+ ...themeStackTokens,
79
+ ...variantStackTokens
80
+ }
66
81
  const { direction, space, fieldSpace, borderRadius, backgroundColor, padding, gap } =
67
82
  themeTokens
68
83
 
69
- const getButtonTokens = useThemeTokensCallback('ButtonGroupItem', tokens, variant)
84
+ const themeButtonTokensCallback = useThemeTokensCallback('ButtonGroupItem', tokens, variant)
85
+
86
+ const getButtonTokens = (state) => {
87
+ const themeButtonTokens = themeButtonTokensCallback(state)
88
+ return {
89
+ ...themeButtonTokens,
90
+ width: variant?.width === 'equal' ? '100%' : 'auto',
91
+ flex: variant?.width === 'equal' ? 1 : undefined
92
+ }
93
+ }
70
94
 
71
95
  const { currentValues, toggleOneValue } = useMultipleInputValues({
72
96
  initialValues,
@@ -110,7 +134,9 @@ const ButtonGroup = React.forwardRef(
110
134
  borderRadius,
111
135
  backgroundColor,
112
136
  padding,
113
- ...(Platform.OS === 'web' ? { gap, width: 'fit-content' } : { alignSelf: 'flex-start' })
137
+ ...(Platform.OS === 'web'
138
+ ? { gap, width: variant?.width === 'equal' ? '100%' : 'fit-content' }
139
+ : { alignSelf: 'flex-start' })
114
140
  }}
115
141
  {...selectProps(rest)}
116
142
  >
@@ -32,7 +32,10 @@ const CarouselStepTracker = React.forwardRef(
32
32
 
33
33
  const steps = Array.from(Array(totalItems)).map((_, index) => String(index))
34
34
 
35
- if (enableDisplayMultipleItemsPerSlide) {
35
+ const showProgressBar =
36
+ enableDisplayMultipleItemsPerSlide && progressBarVariant?.style !== 'dots'
37
+
38
+ if (showProgressBar) {
36
39
  if (totalItems === 1) {
37
40
  return null
38
41
  }
@@ -56,6 +59,9 @@ const CarouselStepTracker = React.forwardRef(
56
59
  </>
57
60
  )
58
61
  }
62
+ if (enableDisplayMultipleItemsPerSlide && totalItems === 1) {
63
+ return null
64
+ }
59
65
  return (
60
66
  <StackView direction="row" tokens={stackViewTokens} ref={ref}>
61
67
  <StepTracker
@@ -63,7 +69,9 @@ const CarouselStepTracker = React.forwardRef(
63
69
  steps={steps}
64
70
  copy={{
65
71
  stepLabel: getCopyWithPlaceholders('stepLabel'),
66
- stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
72
+ stepTrackerLabel: enableDisplayMultipleItemsPerSlide
73
+ ? ''
74
+ : getCopyWithPlaceholders('stepTrackerLabel')
67
75
  }}
68
76
  tokens={stepTrackerTokens}
69
77
  variant={stepTrackerVariant}