@telus-uds/components-base 3.23.0 → 3.25.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 (73) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/lib/cjs/Button/ButtonGroup.js +9 -2
  3. package/lib/cjs/Card/CardBase.js +97 -17
  4. package/lib/cjs/Card/PressableCardBase.js +12 -8
  5. package/lib/cjs/Carousel/Carousel.js +35 -4
  6. package/lib/cjs/FlexGrid/FlexGrid.js +31 -35
  7. package/lib/cjs/HorizontalScroll/HorizontalScroll.js +5 -2
  8. package/lib/cjs/Icon/Icon.js +3 -0
  9. package/lib/cjs/IconButton/IconButton.js +15 -5
  10. package/lib/cjs/Listbox/GroupControl.js +12 -6
  11. package/lib/cjs/Listbox/Listbox.js +41 -7
  12. package/lib/cjs/Listbox/ListboxGroup.js +139 -8
  13. package/lib/cjs/Listbox/ListboxOverlay.js +10 -5
  14. package/lib/cjs/Listbox/SecondLevelHeader.js +201 -0
  15. package/lib/cjs/Listbox/dictionary.js +14 -0
  16. package/lib/cjs/Shortcuts/Shortcuts.js +169 -0
  17. package/lib/cjs/Shortcuts/ShortcutsItem.js +280 -0
  18. package/lib/cjs/Shortcuts/index.js +16 -0
  19. package/lib/cjs/TextInput/TextInputBase.js +2 -3
  20. package/lib/cjs/Tooltip/Tooltip.native.js +2 -0
  21. package/lib/cjs/index.js +15 -0
  22. package/lib/cjs/utils/index.js +9 -1
  23. package/lib/cjs/utils/resolveContentMaxWidth.js +30 -0
  24. package/lib/esm/Button/ButtonGroup.js +9 -2
  25. package/lib/esm/Card/CardBase.js +97 -17
  26. package/lib/esm/Card/PressableCardBase.js +10 -8
  27. package/lib/esm/Carousel/Carousel.js +37 -6
  28. package/lib/esm/FlexGrid/FlexGrid.js +31 -35
  29. package/lib/esm/HorizontalScroll/HorizontalScroll.js +6 -3
  30. package/lib/esm/Icon/Icon.js +3 -0
  31. package/lib/esm/IconButton/IconButton.js +15 -5
  32. package/lib/esm/Listbox/GroupControl.js +12 -6
  33. package/lib/esm/Listbox/Listbox.js +41 -7
  34. package/lib/esm/Listbox/ListboxGroup.js +141 -10
  35. package/lib/esm/Listbox/ListboxOverlay.js +10 -5
  36. package/lib/esm/Listbox/SecondLevelHeader.js +194 -0
  37. package/lib/esm/Listbox/dictionary.js +8 -0
  38. package/lib/esm/Shortcuts/Shortcuts.js +160 -0
  39. package/lib/esm/Shortcuts/ShortcutsItem.js +273 -0
  40. package/lib/esm/Shortcuts/index.js +3 -0
  41. package/lib/esm/TextInput/TextInputBase.js +2 -3
  42. package/lib/esm/Tooltip/Tooltip.native.js +2 -0
  43. package/lib/esm/index.js +1 -0
  44. package/lib/esm/utils/index.js +2 -1
  45. package/lib/esm/utils/resolveContentMaxWidth.js +24 -0
  46. package/lib/package.json +2 -2
  47. package/package.json +2 -2
  48. package/src/Button/ButtonGroup.jsx +20 -3
  49. package/src/Card/CardBase.jsx +113 -14
  50. package/src/Card/PressableCardBase.jsx +17 -5
  51. package/src/Carousel/Carousel.jsx +38 -6
  52. package/src/FlexGrid/FlexGrid.jsx +30 -39
  53. package/src/HorizontalScroll/HorizontalScroll.jsx +6 -3
  54. package/src/Icon/Icon.jsx +3 -0
  55. package/src/IconButton/IconButton.jsx +12 -5
  56. package/src/Listbox/GroupControl.jsx +41 -33
  57. package/src/Listbox/Listbox.jsx +41 -2
  58. package/src/Listbox/ListboxGroup.jsx +158 -26
  59. package/src/Listbox/ListboxOverlay.jsx +18 -5
  60. package/src/Listbox/SecondLevelHeader.jsx +182 -0
  61. package/src/Listbox/dictionary.js +8 -0
  62. package/src/Shortcuts/Shortcuts.jsx +174 -0
  63. package/src/Shortcuts/ShortcutsItem.jsx +297 -0
  64. package/src/Shortcuts/index.js +4 -0
  65. package/src/TextInput/TextInputBase.jsx +2 -2
  66. package/src/Tooltip/Tooltip.native.jsx +2 -1
  67. package/src/index.js +1 -0
  68. package/src/utils/index.js +1 -0
  69. package/src/utils/resolveContentMaxWidth.js +28 -0
  70. package/types/Listbox.d.ts +24 -0
  71. package/types/Shortcuts.d.ts +136 -0
  72. package/types/Status.d.ts +42 -0
  73. package/types/index.d.ts +15 -0
package/CHANGELOG.md CHANGED
@@ -1,9 +1,33 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Wed, 19 Nov 2025 05:51:39 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 12 Jan 2026 14:55:21 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.25.0
8
+
9
+ Mon, 12 Jan 2026 14:55:21 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Status`: Added typescript support for the component (shivam.gupta3@telus.com)
14
+ - `IconButton`: Update the UI to match the design intention, add an inactive prop and selected variant (guillermo.peitzner@telus.com)
15
+ - `FlexGrid`: rename contentMinWidth prop to contentMaxWidth (guillermo.peitzner@telus.com)
16
+ - `ButtonGroup`: add item inactive prop (guillermo.peitzner@telus.com)
17
+ - `Carousel`: add contentMaxWidth prop (guillermo.peitzner@telus.com)
18
+ - Bump @telus-uds/system-theme-tokens to v4.18.0
19
+
20
+ ## 3.24.0
21
+
22
+ Fri, 12 Dec 2025 05:37:22 GMT
23
+
24
+ ### Minor changes
25
+
26
+ - `Card`: interactive mode added for FullBleedContent (35577399+JoshHC@users.noreply.github.com)
27
+ - `Shortcuts`: add component (guillermo.peitzner@telus.com)
28
+ - `Listbox & NavigationBar`: add `secondLevel` variant (sergio.ramirez@telus.com)
29
+ - Bump @telus-uds/system-theme-tokens to v4.17.0
30
+
7
31
  ## 3.23.0
8
32
 
9
33
  Wed, 19 Nov 2025 05:51:39 GMT
@@ -138,6 +138,7 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
138
138
  id = label,
139
139
  accessibilityLabel,
140
140
  ref: itemRef,
141
+ inactive: itemInactive,
141
142
  ...itemRest
142
143
  } = _ref2;
143
144
  const isSelected = currentValues.includes(id);
@@ -161,6 +162,7 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
161
162
  accessibilityLabel,
162
163
  ..._utils.a11yProps.getPositionInSet(items.length, index)
163
164
  };
165
+ const isInactive = itemInactive !== undefined ? itemInactive : inactive;
164
166
 
165
167
  // Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
166
168
  // "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
@@ -171,7 +173,7 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
171
173
  onPress: handlePress,
172
174
  tokens: getButtonTokens,
173
175
  selected: isSelected,
174
- inactive: inactive,
176
+ inactive: isInactive,
175
177
  icon: iconProp,
176
178
  ...selectItemProps({
177
179
  ...itemRest,
@@ -225,7 +227,12 @@ ButtonGroup.propTypes = {
225
227
  /**
226
228
  * An optional ref for one individual button in the ButtonGroup
227
229
  */
228
- ref: _airbnbPropTypes.default.ref()
230
+ ref: _airbnbPropTypes.default.ref(),
231
+ /**
232
+ * If true, this individual button cannot be interacted with. Takes precedence
233
+ * over the group-level `inactive` prop. Useful for disabling specific options.
234
+ */
235
+ inactive: _propTypes.default.bool
229
236
  })),
230
237
  /**
231
238
  * If provided, this function is called when the current selection is changed
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.selectStyles = exports.default = void 0;
6
+ exports.selectStyles = exports.fullBleedContentPropTypes = exports.default = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
@@ -15,9 +15,16 @@ var _ThemeProvider = require("../ThemeProvider");
15
15
  var _utils = require("../utils");
16
16
  var _props = require("../utils/props");
17
17
  var _backgroundImageStylesMap = _interopRequireDefault(require("./backgroundImageStylesMap"));
18
+ var _FlexGrid = _interopRequireDefault(require("../FlexGrid/FlexGrid"));
19
+ var _Row = _interopRequireDefault(require("../FlexGrid/Row"));
20
+ var _Col = _interopRequireDefault(require("../FlexGrid/Col"));
18
21
  var _jsxRuntime = require("react/jsx-runtime");
19
22
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
23
  const [selectProps, selectedSystemPropTypes] = (0, _props.selectSystemProps)([_props.a11yProps, _props.viewProps]);
24
+ const GRID_COLUMNS = 12;
25
+ const isOverlayColor = color => {
26
+ return color && typeof color === 'string' && color.startsWith('rgba(');
27
+ };
21
28
  const setBackgroundImage = _ref => {
22
29
  let {
23
30
  src,
@@ -31,12 +38,9 @@ const setBackgroundImage = _ref => {
31
38
  const borderRadius = cardStyle?.borderRadius || 0;
32
39
  const borderWidth = cardStyle?.borderWidth || 0;
33
40
  const adjustedBorderRadius = Math.max(0, borderRadius - borderWidth);
34
-
35
- // For contain mode with position and align, use CSS background properties for web
36
41
  if (backgroundImageResizeMode === 'contain' && backgroundImagePosition && backgroundImageAlign) {
37
42
  const positionKey = `${backgroundImagePosition}-${backgroundImageAlign}`;
38
43
  if (_Platform.default.OS === 'web') {
39
- // Create background position based on position and align
40
44
  let backgroundPosition;
41
45
  switch (positionKey) {
42
46
  case 'top-start':
@@ -80,7 +84,6 @@ const setBackgroundImage = _ref => {
80
84
  children: content
81
85
  });
82
86
  }
83
- // For React Native, apply positioning styles with full dimensions
84
87
  const positionStyles = _backgroundImageStylesMap.default[positionKey] || {};
85
88
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
86
89
  style: [staticStyles.containContainer, {
@@ -99,8 +102,6 @@ const setBackgroundImage = _ref => {
99
102
  })]
100
103
  });
101
104
  }
102
-
103
- // Use ImageBackground for all other resize modes and React Native
104
105
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImageBackground.default, {
105
106
  source: src,
106
107
  imageStyle: {
@@ -126,6 +127,10 @@ const selectStyles = _ref2 => {
126
127
  paddingLeft,
127
128
  paddingRight,
128
129
  paddingTop,
130
+ marginTop,
131
+ marginBottom,
132
+ marginLeft,
133
+ marginRight,
129
134
  minWidth,
130
135
  shadow,
131
136
  backgroundGradient,
@@ -133,9 +138,18 @@ const selectStyles = _ref2 => {
133
138
  maxHeight,
134
139
  overflowY
135
140
  } = _ref2;
141
+ const hasGradient = (gradient || backgroundGradient) && _Platform.default.OS === 'web';
142
+ let backgroundImageValue = null;
143
+ if (hasGradient) {
144
+ const gradientObj = gradient || backgroundGradient;
145
+ const gradientString = `linear-gradient(${gradientObj.angle}deg, ${gradientObj.stops[0].color}, ${gradientObj.stops[1].color})`;
146
+ const shouldApplyOverlay = (gradient || backgroundGradient && backgroundColor && backgroundColor !== 'transparent') && isOverlayColor(backgroundColor);
147
+ backgroundImageValue = shouldApplyOverlay ? `linear-gradient(${backgroundColor}, ${backgroundColor}), ${gradientString}` : gradientString;
148
+ }
149
+ const boxShadowColor = isOverlayColor(backgroundColor) ? backgroundColor : 'white';
136
150
  return {
137
151
  flex,
138
- backgroundColor,
152
+ backgroundColor: hasGradient ? 'transparent' : backgroundColor,
139
153
  borderColor,
140
154
  borderRadius,
141
155
  borderWidth,
@@ -143,16 +157,20 @@ const selectStyles = _ref2 => {
143
157
  paddingLeft,
144
158
  paddingRight,
145
159
  paddingTop,
160
+ marginTop,
161
+ marginBottom,
162
+ marginLeft,
163
+ marginRight,
146
164
  minWidth,
147
165
  ...(0, _ThemeProvider.applyShadowToken)(shadow),
148
166
  ...(gradient && _Platform.default.OS === 'web' ? {
149
- backgroundImage: `linear-gradient(${gradient.angle}deg, ${gradient.stops[0].color}, ${gradient.stops[1].color})`,
167
+ backgroundImage: backgroundImageValue,
150
168
  backgroundOrigin: `border-box`,
151
- boxShadow: `inset 0 1000px white`,
169
+ boxShadow: `inset 0 1000px ${boxShadowColor}`,
152
170
  border: `${borderWidth}px solid transparent`
153
171
  } : {}),
154
172
  ...(backgroundGradient && _Platform.default.OS === 'web' ? {
155
- backgroundImage: `linear-gradient(${backgroundGradient.angle}deg, ${backgroundGradient.stops[0].color}, ${backgroundGradient.stops[1].color})`
173
+ backgroundImage: backgroundImageValue
156
174
  } : {}),
157
175
  ...(_Platform.default.OS === 'web' ? {
158
176
  maxHeight,
@@ -172,9 +190,11 @@ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
172
190
  tokens,
173
191
  dataSet,
174
192
  backgroundImage,
193
+ fullBleedContent,
194
+ cardState,
175
195
  ...rest
176
196
  } = _ref3;
177
- const cardStyle = selectStyles(typeof tokens === 'function' ? tokens() : tokens);
197
+ const cardStyle = selectStyles(typeof tokens === 'function' ? tokens(cardState) : tokens);
178
198
  const props = selectProps(rest);
179
199
  let content = children;
180
200
  const {
@@ -188,9 +208,13 @@ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
188
208
  const backgroundImagePosition = (0, _utils.useResponsiveProp)(position);
189
209
  const backgroundImageAlign = (0, _utils.useResponsiveProp)(align);
190
210
  const imageSourceViewport = (0, _utils.formatImageSource)((0, _utils.useResponsiveProp)(src));
211
+ const {
212
+ content: fullBleedImageContent,
213
+ position: fullBleedContentPosition,
214
+ imgCol
215
+ } = fullBleedContent || {};
216
+ const fullBleedPosition = (0, _utils.useResponsiveProp)(fullBleedContentPosition, 'bottom');
191
217
  if (backgroundImage && src) {
192
- // When there's a background image, separate the padding from the container style
193
- // so the image can fill the entire container without padding interference
194
218
  const {
195
219
  paddingTop,
196
220
  paddingBottom,
@@ -198,8 +222,6 @@ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
198
222
  paddingRight,
199
223
  ...containerStyle
200
224
  } = cardStyle;
201
-
202
- // Only create padding wrapper if there's actually padding defined
203
225
  const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
204
226
  const paddedContent = hasPadding ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
205
227
  style: {
@@ -227,6 +249,53 @@ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
227
249
  children: content
228
250
  });
229
251
  }
252
+ if (fullBleedContent && fullBleedImageContent) {
253
+ const {
254
+ paddingTop,
255
+ paddingBottom,
256
+ paddingLeft,
257
+ paddingRight,
258
+ ...containerStyle
259
+ } = cardStyle;
260
+ const imageColumns = imgCol || {
261
+ xs: GRID_COLUMNS
262
+ };
263
+ const textColumns = {};
264
+ Object.keys(imageColumns).forEach(breakpoint => {
265
+ textColumns[breakpoint] = GRID_COLUMNS - (imageColumns[breakpoint] || GRID_COLUMNS);
266
+ });
267
+ const imageFirst = fullBleedPosition === 'top' || fullBleedPosition === 'left';
268
+ const imageColContent = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Col.default, {
269
+ ...imageColumns,
270
+ style: staticStyles.fullBleedImageCol,
271
+ children: fullBleedImageContent
272
+ });
273
+ const textColContent = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Col.default, {
274
+ ...textColumns,
275
+ style: {
276
+ paddingTop,
277
+ paddingBottom,
278
+ paddingLeft,
279
+ paddingRight
280
+ },
281
+ children: children
282
+ });
283
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
284
+ style: containerStyle,
285
+ dataSet: dataSet,
286
+ ref: ref,
287
+ ...props,
288
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FlexGrid.default, {
289
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Row.default, {
290
+ children: imageFirst ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
291
+ children: [imageColContent, textColContent]
292
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
293
+ children: [textColContent, imageColContent]
294
+ })
295
+ })
296
+ })
297
+ });
298
+ }
230
299
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
231
300
  style: cardStyle,
232
301
  dataSet: dataSet,
@@ -236,6 +305,13 @@ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
236
305
  });
237
306
  });
238
307
  CardBase.displayName = 'CardBase';
308
+ const fullBleedContentPropTypes = exports.fullBleedContentPropTypes = _propTypes.default.shape({
309
+ content: _propTypes.default.node.isRequired,
310
+ alt: _propTypes.default.string,
311
+ position: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['bottom', 'left', 'right', 'top'])),
312
+ align: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['start', 'end', 'center', 'stretch'])),
313
+ imgCol: _propTypes.default.object
314
+ });
239
315
  const staticStyles = _StyleSheet.default.create({
240
316
  imageBackground: {
241
317
  width: '100%',
@@ -257,6 +333,9 @@ const staticStyles = _StyleSheet.default.create({
257
333
  position: 'absolute',
258
334
  width: '100%',
259
335
  height: '100%'
336
+ },
337
+ fullBleedImageCol: {
338
+ padding: 0
260
339
  }
261
340
  });
262
341
  CardBase.propTypes = {
@@ -274,6 +353,7 @@ CardBase.propTypes = {
274
353
  resizeMode: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])),
275
354
  position: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['bottom', 'left', 'right', 'top'])),
276
355
  align: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['start', 'end', 'center', 'stretch']))
277
- })
356
+ }),
357
+ fullBleedContent: fullBleedContentPropTypes
278
358
  };
279
359
  var _default = exports.default = CardBase;
@@ -13,11 +13,13 @@ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/expo
13
13
  var _ViewportProvider = require("../ViewportProvider");
14
14
  var _ThemeProvider = require("../ThemeProvider");
15
15
  var _utils = require("../utils");
16
- var _CardBase = _interopRequireDefault(require("./CardBase"));
16
+ var _CardBase = _interopRequireWildcard(require("./CardBase"));
17
17
  var _jsxRuntime = require("react/jsx-runtime");
18
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
19
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
21
  const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.focusHandlerProps, _utils.viewProps]);
20
- const tokenKeys = ['flex', 'backgroundColor', 'borderColor', 'gradient', 'borderRadius', 'borderWidth', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'minWidth', 'shadow', 'contentAlignItems', 'contentJustifyContent', 'contentFlexGrow', 'contentFlexShrink',
22
+ const tokenKeys = ['flex', 'backgroundColor', 'borderColor', 'gradient', 'borderRadius', 'borderWidth', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', 'minWidth', 'shadow', 'contentAlignItems', 'contentJustifyContent', 'contentFlexGrow', 'contentFlexShrink',
21
23
  // Outer border tokens. TODO: centralise common token sets like these as part of
22
24
  // https://github.com/telus/universal-design-system/issues/782
23
25
  'outerBorderColor', 'outerBorderWidth', 'outerBorderGap', 'icon', 'iconBackgroundColor', 'iconColor', 'iconSize', 'inputBackgroundColor', 'inputBorderColor', 'inputBorderRadius', 'inputBorderWidth', 'inputHeight', 'inputShadow', 'inputWidth'];
@@ -40,6 +42,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
40
42
  hrefAttrs,
41
43
  dataSet,
42
44
  backgroundImage,
45
+ fullBleedContent,
43
46
  accessibilityRole = href ? 'link' : undefined,
44
47
  ...rawRest
45
48
  } = _ref;
@@ -133,10 +136,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
133
136
  setFocused(false);
134
137
  setPressed(false);
135
138
  },
136
- style: {
137
- ...staticStyles.linkContainer,
138
- textDecoration: 'none'
139
- },
139
+ style: staticStyles.linkContainer,
140
140
  ...(hrefAttrs || {}),
141
141
  role: accessibilityRole,
142
142
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardBase.default, {
@@ -146,6 +146,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
146
146
  hovered
147
147
  }),
148
148
  backgroundImage: backgroundImage,
149
+ fullBleedContent: fullBleedContent,
149
150
  children: typeof children === 'function' ? children(getCardState({
150
151
  pressed,
151
152
  focused,
@@ -170,6 +171,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
170
171
  children: pressableState => /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardBase.default, {
171
172
  tokens: getCardTokens(pressableState),
172
173
  backgroundImage: backgroundImage,
174
+ fullBleedContent: fullBleedContent,
173
175
  children: typeof children === 'function' ? children(getCardState(pressableState)) : children
174
176
  })
175
177
  });
@@ -183,7 +185,8 @@ const staticStyles = _StyleSheet.default.create({
183
185
  flex: 1,
184
186
  display: 'flex',
185
187
  alignItems: 'stretch',
186
- justifyContent: 'flex-start'
188
+ justifyContent: 'flex-start',
189
+ textDecorationLine: 'none'
187
190
  }
188
191
  });
189
192
  PressableCardBase.displayName = 'PressableCardBase';
@@ -203,6 +206,7 @@ PressableCardBase.propTypes = {
203
206
  resizeMode: _propTypes.default.oneOfType([_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']), _propTypes.default.object]),
204
207
  position: _propTypes.default.oneOfType([_propTypes.default.oneOf(['bottom', 'left', 'right', 'top']), _propTypes.default.object]),
205
208
  align: _propTypes.default.oneOfType([_propTypes.default.oneOf(['start', 'end', 'center', 'stretch']), _propTypes.default.object])
206
- })
209
+ }),
210
+ fullBleedContent: _CardBase.fullBleedContentPropTypes
207
211
  };
208
212
  var _default = exports.default = (0, _utils.withLinkRouter)(PressableCardBase);
@@ -210,11 +210,18 @@ const selectRootContainerStyles = (enableHero, viewport) => {
210
210
  }
211
211
  return {};
212
212
  };
213
- const selectMainContainerStyles = (enableHero, viewport) => {
213
+ const selectMainContainerStyles = (enableHero, viewport, maxWidth) => {
214
214
  if (enableHero && viewport === 'xl' && _Platform.default.OS === 'web') {
215
215
  return {
216
216
  width: '100%',
217
- maxWidth: 1200
217
+ maxWidth: maxWidth || 1200
218
+ };
219
+ }
220
+ if (maxWidth !== null && maxWidth !== undefined) {
221
+ return {
222
+ maxWidth,
223
+ alignSelf: 'center',
224
+ width: '100%'
218
225
  };
219
226
  }
220
227
  return {};
@@ -361,11 +368,18 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
361
368
  loopDuration = transitionDuration,
362
369
  autoPlay = false,
363
370
  enablePeeking = false,
371
+ contentMaxWidth,
364
372
  ...rest
365
373
  } = _ref3;
366
374
  let childrenArray = (0, _utils.unpackFragment)(children);
367
375
  const isTransitioningRef = _react.default.useRef(false);
368
376
  const viewport = (0, _ViewportProvider.useViewport)();
377
+ const {
378
+ themeOptions
379
+ } = (0, _ThemeProvider.useTheme)();
380
+ const contentMaxWidthValue = (0, _utils.useResponsiveProp)(contentMaxWidth);
381
+ const responsiveWidth = (0, _utils.useResponsiveProp)(themeOptions?.contentMaxWidth);
382
+ const maxWidth = (0, _utils.resolveContentMaxWidth)(contentMaxWidthValue, responsiveWidth);
369
383
  const totalItems = getTotalItems(enableDisplayMultipleItemsPerSlide, childrenArray, viewport);
370
384
  const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && totalItems > 1;
371
385
  // if `Carousel` only has one `Carousel.Item`, convert this to a single-item array
@@ -896,7 +910,7 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
896
910
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
897
911
  style: selectRootContainerStyles(enableHero, viewport),
898
912
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
899
- style: selectMainContainerStyles(enableHero, viewport),
913
+ style: selectMainContainerStyles(enableHero, viewport, maxWidth),
900
914
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CarouselContext.CarouselProvider, {
901
915
  activeIndex: activeIndex,
902
916
  goTo: goTo,
@@ -1254,7 +1268,24 @@ Carousel.propTypes = {
1254
1268
  * If set to `true`, the Carousel will show multiple slides at once
1255
1269
  * - Default value is `false`
1256
1270
  */
1257
- enableDisplayMultipleItemsPerSlide: _propTypes.default.bool
1271
+ enableDisplayMultipleItemsPerSlide: _propTypes.default.bool,
1272
+ /**
1273
+ * The maximum width of the content in the Carousel.
1274
+ * This prop accepts responsive values for different viewports. If a number is provided,
1275
+ * it will be the max content width for the desired viewport.
1276
+ * - `xs`: 'max' | 'full' | <number>
1277
+ * - `sm`: 'max' | 'full' | <number>
1278
+ * - `md`: 'max' | 'full' | <number>
1279
+ * - `lg`: 'max' | 'full' | <number>
1280
+ * - `xl`: 'max' | 'full' | <number>
1281
+ */
1282
+ contentMaxWidth: _propTypes.default.shape({
1283
+ xl: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
1284
+ lg: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
1285
+ md: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
1286
+ sm: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
1287
+ xs: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number])
1288
+ })
1258
1289
  };
1259
1290
  Carousel.Item = _CarouselItem.default;
1260
1291
  Carousel.displayName = 'Carousel';
@@ -8,6 +8,7 @@ var _react = _interopRequireDefault(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _systemConstants = require("@telus-uds/system-constants");
10
10
  var _utils = require("../utils");
11
+ var _resolveContentMaxWidth = _interopRequireDefault(require("../utils/resolveContentMaxWidth"));
11
12
  var _Row = _interopRequireDefault(require("./Row"));
12
13
  var _Col = _interopRequireDefault(require("./Col"));
13
14
  var _GutterContext = _interopRequireDefault(require("./providers/GutterContext"));
@@ -17,47 +18,24 @@ var _ViewportProvider = require("../ViewportProvider");
17
18
  var _jsxRuntime = require("react/jsx-runtime");
18
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
20
  const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
20
- const CONTENT_MAX_WIDTH = 'max';
21
- const CONTENT_FULL_WIDTH = 'full';
22
21
 
23
22
  /**
24
- * Resolves the maximum width for content based on the provided value and responsive width.
25
- *
26
- * @param {number|string|null|undefined} contentMinWidthValue - The minimum width value for the content.
27
- * Can be a number, a special string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
28
- * @param {number} responsiveWidth - The responsive width to use when contentMinWidthValue is CONTENT_MAX_WIDTH.
29
- * @returns {number|string|null} The resolved maximum width value, or null if full width is desired.
30
- */
31
- const resolveContentMaxWidth = (contentMinWidthValue, responsiveWidth) => {
32
- if (!contentMinWidthValue || contentMinWidthValue === CONTENT_FULL_WIDTH) {
33
- return null;
34
- }
35
- if (Number.isFinite(contentMinWidthValue)) {
36
- return contentMinWidthValue;
37
- }
38
- if (contentMinWidthValue === CONTENT_MAX_WIDTH) {
39
- return responsiveWidth;
40
- }
41
- return contentMinWidthValue;
42
- };
43
-
44
- /**
45
- * Calculates the maximum width for a given viewport based on limitWidth and contentMinWidth settings.
23
+ * Calculates the maximum width for a given viewport based on limitWidth and contentMaxWidth settings.
46
24
  *
47
25
  * @param {string} viewportKey - The viewport key ('xs', 'sm', 'md', 'lg', 'xl')
48
26
  * @param {boolean} limitWidth - Whether to limit the width to viewport breakpoints
49
- * @param {any} contentMinWidth - The contentMinWidth prop value
27
+ * @param {any} contentWidthProp - The contentMaxWidth (or contentMinWidth) prop value
50
28
  * @param {number|string|null} maxWidth - The resolved max width value
51
29
  * @returns {number|string|null} The calculated maximum width for the viewport
52
30
  */
53
- const getMaxWidthForViewport = (viewportKey, limitWidth, contentMinWidth, maxWidth) => {
31
+ const getMaxWidthForViewport = (viewportKey, limitWidth, contentWidthProp, maxWidth) => {
54
32
  if (limitWidth) {
55
33
  if (viewportKey === 'xs') {
56
34
  return null;
57
35
  }
58
36
  return _systemConstants.viewports.map.get(viewportKey);
59
37
  }
60
- if (contentMinWidth) {
38
+ if (contentWidthProp) {
61
39
  return maxWidth;
62
40
  }
63
41
  return null;
@@ -81,6 +59,7 @@ const FlexGrid = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
81
59
  accessibilityRole,
82
60
  children,
83
61
  dataSet,
62
+ contentMaxWidth,
84
63
  contentMinWidth,
85
64
  ...rest
86
65
  } = _ref;
@@ -94,28 +73,31 @@ const FlexGrid = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
94
73
  } = (0, _ThemeProvider.useTheme)();
95
74
  let flexgridStyles;
96
75
  let mediaIds;
97
- const contentMinWidthValue = (0, _utils.useResponsiveProp)(contentMinWidth);
76
+
77
+ // Support both contentMaxWidth and deprecated contentMinWidth for backwards compatibility
78
+ const contentWidthProp = contentMaxWidth || contentMinWidth;
79
+ const contentWidthValue = (0, _utils.useResponsiveProp)(contentWidthProp);
98
80
  const responsiveWidth = (0, _utils.useResponsiveProp)(themeOptions?.contentMaxWidth);
99
- const maxWidth = resolveContentMaxWidth(contentMinWidthValue, responsiveWidth);
81
+ const maxWidth = (0, _resolveContentMaxWidth.default)(contentWidthValue, responsiveWidth);
100
82
  const stylesByViewport = {
101
83
  xs: {
102
- maxWidth: getMaxWidthForViewport('xs', limitWidth, contentMinWidth, maxWidth),
84
+ maxWidth: getMaxWidthForViewport('xs', limitWidth, contentWidthProp, maxWidth),
103
85
  flexDirection: reverseLevel[0] ? 'column-reverse' : 'column'
104
86
  },
105
87
  sm: {
106
- maxWidth: getMaxWidthForViewport('sm', limitWidth, contentMinWidth, maxWidth),
88
+ maxWidth: getMaxWidthForViewport('sm', limitWidth, contentWidthProp, maxWidth),
107
89
  flexDirection: reverseLevel[1] ? 'column-reverse' : 'column'
108
90
  },
109
91
  md: {
110
- maxWidth: getMaxWidthForViewport('md', limitWidth, contentMinWidth, maxWidth),
92
+ maxWidth: getMaxWidthForViewport('md', limitWidth, contentWidthProp, maxWidth),
111
93
  flexDirection: reverseLevel[2] ? 'column-reverse' : 'column'
112
94
  },
113
95
  lg: {
114
- maxWidth: getMaxWidthForViewport('lg', limitWidth, contentMinWidth, maxWidth),
96
+ maxWidth: getMaxWidthForViewport('lg', limitWidth, contentWidthProp, maxWidth),
115
97
  flexDirection: reverseLevel[3] ? 'column-reverse' : 'column'
116
98
  },
117
99
  xl: {
118
- maxWidth: getMaxWidthForViewport('xl', limitWidth, contentMinWidth, maxWidth),
100
+ maxWidth: getMaxWidthForViewport('xl', limitWidth, contentWidthProp, maxWidth),
119
101
  flexDirection: reverseLevel[4] ? 'column-reverse' : 'column'
120
102
  }
121
103
  };
@@ -211,7 +193,7 @@ FlexGrid.propTypes = {
211
193
  */
212
194
  children: _propTypes.default.node.isRequired,
213
195
  /**
214
- * The minimum width of the content in the FlexGrid.
196
+ * The maximum width of the content in the FlexGrid.
215
197
  * This prop accepts responsive values for different viewports. If a number is provided,
216
198
  * it will be the max content width for the desired viewport.
217
199
  * - `xs`: 'max' | 'full' | <number>
@@ -220,6 +202,20 @@ FlexGrid.propTypes = {
220
202
  * - `lg`: 'max' | 'full' | <number>
221
203
  * - `xl`: 'max' | 'full' | <number>
222
204
  */
205
+ contentMaxWidth: _propTypes.default.shape({
206
+ xl: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
207
+ lg: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
208
+ md: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
209
+ sm: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
210
+ xs: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number])
211
+ }),
212
+ /**
213
+ * @deprecated Use `contentMaxWidth` instead. This prop will be removed in a future version.
214
+ *
215
+ * The minimum width of the content in the FlexGrid.
216
+ * This prop accepts responsive values for different viewports. If a number is provided,
217
+ * it will be the max content width for the desired viewport.
218
+ */
223
219
  contentMinWidth: _propTypes.default.shape({
224
220
  xl: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
225
221
  lg: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
@@ -35,6 +35,7 @@ const HorizontalScroll = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
35
35
  ScrollButton,
36
36
  tokens,
37
37
  itemPositions,
38
+ variant,
38
39
  children,
39
40
  ...rest
40
41
  } = _ref;
@@ -78,8 +79,9 @@ const HorizontalScroll = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
78
79
  setScrollOffset(x);
79
80
  };
80
81
  const scrollMax = Math.max(0, contentWidth - containerWidth);
81
- const showNextButton = scrollOffset < scrollMax;
82
- const showPreviousButton = scrollOffset > 0;
82
+ const hideNavigationButtons = variant?.hideNavigationButtons || false;
83
+ const showNextButton = scrollOffset < scrollMax && !hideNavigationButtons;
84
+ const showPreviousButton = scrollOffset > 0 && !hideNavigationButtons;
83
85
  const scrollRef = _react.default.useRef(null);
84
86
  const scrollTo = targetX => {
85
87
  if (typeof scrollRef.current?.scrollTo === 'function') {
@@ -170,6 +172,7 @@ HorizontalScroll.propTypes = {
170
172
  tokens: (0, _utils.getTokensSetPropType)(tokenKeys, {
171
173
  allowFunction: true
172
174
  }),
175
+ variant: _utils.variantProp.propType,
173
176
  children: _propTypes.default.node
174
177
  };
175
178
  var _default = exports.default = HorizontalScroll;
@@ -21,6 +21,7 @@ const Icon = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
21
21
  tokens,
22
22
  scalesWithText = false,
23
23
  style = {},
24
+ testID,
24
25
  dataSet
25
26
  } = _ref;
26
27
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('Icon', tokens, variant);
@@ -44,6 +45,7 @@ const Icon = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
44
45
  };
45
46
  const getIconContentForMobile = () => {
46
47
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
48
+ testID: testID,
47
49
  style: {
48
50
  backgroundColor: themeTokens.backgroundColor,
49
51
  borderRadius: themeTokens.borderRadius,
@@ -53,6 +55,7 @@ const Icon = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
53
55
  });
54
56
  };
55
57
  return _Platform.default.OS === 'web' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
58
+ testID: testID,
56
59
  ref: ref
57
60
  // eslint-disable-next-line react-native/no-inline-styles
58
61
  ,