@telus-uds/components-web 4.16.0 → 4.18.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,9 +1,42 @@
1
1
  # Change Log - @telus-uds/components-web
2
2
 
3
- This log was last generated on Mon, 12 Jan 2026 14:55:22 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 29 Jan 2026 16:42:47 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 4.18.0
8
+
9
+ Thu, 29 Jan 2026 16:42:47 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `NavigationBar`: add contentMaxWidth prop (guillermo.peitzner@telus.com)
14
+ - `List`: new feature alignment for the icons added (josue.higueroscalderon@telus.com)
15
+ - `QuantitySelector`: add inactive prop (guillermo.peitzner@telus.com)
16
+ - `Card`: Add full-bleed content support to Card component allowing content to extend to card edges (josue.higueroscalderon@telus.com)
17
+ - `Card`: Unnecessary comments removed. (josue.higueroscalderon@telus.com)
18
+ - Bump @telus-uds/components-base to v3.27.0
19
+ - Bump @telus-uds/system-theme-tokens to v4.19.0
20
+
21
+ ### Patches
22
+
23
+ - `Card`: component enhaced to manage the hover, focus and pressed states of interactiveCard properly (josue.higueroscalderon@telus.com)
24
+ - `NavigationBar`: fix console warning (guillermo.peitzner@telus.com)
25
+ - `QuantitySelector`: spacer alignment issue fixed (josue.higueroscalderon@telus.com)
26
+
27
+ ## 4.17.0
28
+
29
+ Mon, 19 Jan 2026 20:01:22 GMT
30
+
31
+ ### Minor changes
32
+
33
+ - `PriceLockup`: Add inverse variant (david.melara1@telus.com)
34
+ - Bump @telus-uds/components-base to v3.26.0
35
+
36
+ ### Patches
37
+
38
+ - `NavigationBar`: Fix flickering from overlay overflow (david.melara1@telus.com)
39
+
7
40
  ## 4.16.0
8
41
 
9
42
  Mon, 12 Jan 2026 14:55:22 GMT
@@ -19,6 +19,63 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
19
19
  // Passes React Native-oriented system props through UDS Card
20
20
  const [selectProps, selectedSystemPropTypes] = (0, _componentsBase.selectSystemProps)([_componentsBase.a11yProps, _componentsBase.viewProps]);
21
21
  const GRID_COLUMNS = 12;
22
+ const POSITION = {
23
+ LEFT: 'left',
24
+ RIGHT: 'right',
25
+ TOP: 'top',
26
+ BOTTOM: 'bottom',
27
+ NONE: 'none'
28
+ };
29
+
30
+ /**
31
+ * Helper function to get StackView tokens
32
+ * @param {Object} columnFlex - Column flex properties
33
+ * @param {string} contentStackAlign - Alignment value for content stack
34
+ * @returns {Object} StackView tokens object
35
+ */
36
+ const getStackViewTokens = (columnFlex, contentStackAlign) => ({
37
+ ...columnFlex,
38
+ alignItems: contentStackAlign
39
+ });
40
+
41
+ /**
42
+ * Helper function to get CardContent tokens
43
+ * @param {Object} baseTokens - Base tokens to spread
44
+ * @param {Object} options - Options object
45
+ * @param {boolean} options.backgroundImage - Whether background image is present
46
+ * @param {string} options.fullBleedContentChildrenAlign - Alignment for full bleed content children
47
+ * @param {boolean} options.useTransparentBackground - Whether to use transparent background when no backgroundImage
48
+ * @returns {Object} CardContent tokens object
49
+ */
50
+ const getCardContentTokens = function (baseTokens) {
51
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
52
+ const {
53
+ backgroundImage,
54
+ fullBleedContentChildrenAlign,
55
+ useTransparentBackground
56
+ } = options;
57
+
58
+ // Determine background color based on conditions
59
+ let backgroundColorOverride = {};
60
+ if (useTransparentBackground) {
61
+ if (!backgroundImage) {
62
+ backgroundColorOverride = {
63
+ backgroundColor: 'transparent'
64
+ };
65
+ }
66
+ } else if (backgroundImage) {
67
+ backgroundColorOverride = {
68
+ backgroundColor: 'transparent'
69
+ };
70
+ }
71
+ return {
72
+ ...baseTokens,
73
+ ...backgroundColorOverride,
74
+ ...(fullBleedContentChildrenAlign && {
75
+ alignSelf: fullBleedContentChildrenAlign
76
+ })
77
+ };
78
+ };
22
79
 
23
80
  /**
24
81
  * A basic card component, unstyled by default.
@@ -77,6 +134,59 @@ const DynamicWidthContainer = /*#__PURE__*/_styledComponents.default.div.withCon
77
134
  alignSelf
78
135
  };
79
136
  });
137
+ const InteractiveCardWrapper = /*#__PURE__*/_styledComponents.default.div.withConfig({
138
+ displayName: "Card__InteractiveCardWrapper",
139
+ componentId: "components-web__sc-1elbtwd-1"
140
+ })(() => ({
141
+ position: 'relative',
142
+ flex: 1,
143
+ display: 'flex',
144
+ flexDirection: 'column'
145
+ }));
146
+ const InteractiveOverlay = /*#__PURE__*/_styledComponents.default.div.withConfig({
147
+ displayName: "Card__InteractiveOverlay",
148
+ componentId: "components-web__sc-1elbtwd-2"
149
+ })(_ref2 => {
150
+ let {
151
+ overlayOpacity,
152
+ borderRadius
153
+ } = _ref2;
154
+ return {
155
+ position: 'absolute',
156
+ top: 0,
157
+ left: 0,
158
+ right: 0,
159
+ bottom: 0,
160
+ backgroundColor: `rgba(0, 0, 0, ${overlayOpacity || 0})`,
161
+ borderRadius,
162
+ pointerEvents: 'none',
163
+ transition: 'background-color 0.2s ease',
164
+ zIndex: 1
165
+ };
166
+ });
167
+ const FocusBorder = /*#__PURE__*/_styledComponents.default.div.withConfig({
168
+ displayName: "Card__FocusBorder",
169
+ componentId: "components-web__sc-1elbtwd-3"
170
+ })(_ref3 => {
171
+ let {
172
+ borderWidth,
173
+ borderColor,
174
+ borderRadius
175
+ } = _ref3;
176
+ return {
177
+ position: 'absolute',
178
+ top: 0,
179
+ left: 0,
180
+ right: 0,
181
+ bottom: 0,
182
+ borderWidth,
183
+ borderColor,
184
+ borderRadius,
185
+ borderStyle: 'solid',
186
+ pointerEvents: 'none',
187
+ zIndex: 2
188
+ };
189
+ });
80
190
  const Card = /*#__PURE__*/_react.default.forwardRef(function () {
81
191
  let {
82
192
  children,
@@ -130,16 +240,57 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
130
240
  const {
131
241
  borderRadius
132
242
  } = allThemeTokens;
133
- const cardBaseBorderWidth = allThemeTokens.borderWidth;
134
- const pressableBorderWidth = (0, _componentsBase.useThemeTokens)('Card', {}, {
243
+
244
+ // Interactive cards: merge variants for CardBase (outer container)
245
+ // The outer variant takes priority over interactiveCard.variant for the style property
246
+ // This ensures the gradient is only applied to CardBase, not PressableCardBase and avoid duplication
247
+ const interactiveStyle = interactiveCard?.variant?.style;
248
+ const outerStyle = variant?.style;
249
+ const mergedVariant = {
250
+ ...variant,
251
+ style: outerStyle || interactiveStyle
252
+ };
253
+
254
+ // Interactive cards: build configuration for PressableCardBase
255
+ // This determines which style to use for interactive states (hover, pressed, etc.)
256
+ // without causing gradient duplication
257
+ let interactiveCardConfig = {};
258
+ if (interactiveCard?.body) {
259
+ const styleToUse = interactiveCard?.variant?.style || variant?.style;
260
+ const {
261
+ style,
262
+ ...otherVariantProps
263
+ } = interactiveCard?.variant || {};
264
+ interactiveCardConfig = {
265
+ interactive: true,
266
+ ...(styleToUse && {
267
+ style: styleToUse
268
+ }),
269
+ ...otherVariantProps
270
+ };
271
+ }
272
+ const getThemeTokensBase = (0, _componentsBase.useThemeTokensCallback)('Card', interactiveCard?.tokens, interactiveCardConfig);
273
+
274
+ // Wrap getThemeTokens to remove gradient from resolved tokens
275
+ // PressableCardBase calls this function with pressableState (hover, pressed, etc.)
276
+ // We intercept the resolved tokens and remove gradient properties to prevent duplication
277
+ // since the gradient should only appear on CardBase (outer container)
278
+ const getThemeTokens = _react.default.useCallback(pressableState => {
279
+ const resolvedTokens = getThemeTokensBase(pressableState);
280
+ const {
281
+ gradient,
282
+ backgroundGradient,
283
+ ...tokensWithoutGradient
284
+ } = resolvedTokens;
285
+ return tokensWithoutGradient;
286
+ }, [getThemeTokensBase]);
287
+ const getFocusBorderTokens = (0, _componentsBase.useThemeTokensCallback)('Card', {}, {
135
288
  ...variant,
136
289
  interactive: true
137
- }).borderWidth;
138
- const marginOffset = `${-(cardBaseBorderWidth + pressableBorderWidth) / 2}px`;
139
- const getThemeTokens = (0, _componentsBase.useThemeTokensCallback)('Card', interactiveCard?.tokens, {
140
- interactive: true,
141
- ...(interactiveCard?.variant || {})
142
290
  });
291
+
292
+ // Remove backgroundColor from tokens for full bleed interactive content
293
+ // to prevent background from covering the full bleed image
143
294
  const {
144
295
  backgroundColor: _,
145
296
  ...tokensWithoutBg
@@ -148,17 +299,19 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
148
299
  ...variant,
149
300
  interactive: true
150
301
  });
151
- const getFullBleedInteractiveCardTokens = cardState => ({
152
- ...getFullBleedInteractiveTokens(cardState),
153
- paddingTop: 0,
154
- paddingBottom: 0,
155
- paddingLeft: 0,
156
- paddingRight: 0,
157
- // Suppress gradient if interactiveCard.body exists to avoid border duplication
158
- ...(interactiveCard?.body ? {
159
- gradient: undefined
160
- } : {})
161
- });
302
+ const getFullBleedInteractiveCardTokens = cardState => {
303
+ return {
304
+ ...getFullBleedInteractiveTokens(cardState),
305
+ paddingTop: 0,
306
+ paddingBottom: 0,
307
+ paddingLeft: 0,
308
+ paddingRight: 0,
309
+ borderWidth: 0,
310
+ ...(interactiveCard?.body ? {
311
+ gradient: undefined
312
+ } : {})
313
+ };
314
+ };
162
315
  const hasFooter = Boolean(footer);
163
316
  const fullBleedBorderRadius = (0, _FullBleedContent.getFullBleedBorderRadius)(borderRadius, fullBleedContentPosition, hasFooter);
164
317
 
@@ -167,12 +320,15 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
167
320
  // pass as props to ConditionalWrapper
168
321
  const imgColCurrentViewport = (0, _componentsBase.useResponsiveProp)(imgCol);
169
322
  const maxCol = GRID_COLUMNS;
170
- const fullBleedImageWidth = `${imgColCurrentViewport / maxCol * 100}%`;
171
- const adaptiveContentWidth = `${(maxCol - imgColCurrentViewport) / maxCol * 100}%`;
172
- const isImageWidthAdjustable = imgCol && (fullBleedContentPosition === 'left' || fullBleedContentPosition === 'right');
323
+ const hasValidImgCol = imgCol && imgColCurrentViewport !== undefined && !Number.isNaN(imgColCurrentViewport);
324
+ const fullBleedImageWidth = hasValidImgCol ? `${imgColCurrentViewport / maxCol * 100}%` : undefined;
325
+ const adaptiveContentWidth = hasValidImgCol ? `${(maxCol - imgColCurrentViewport) / maxCol * 100}%` : undefined;
326
+ const isImageWidthAdjustable = hasValidImgCol && (fullBleedContentPosition === POSITION.LEFT || fullBleedContentPosition === POSITION.RIGHT);
173
327
  const contentWrapperStyleProps = {
174
- width: adaptiveContentWidth,
175
- ...(imgColCurrentViewport >= maxCol && {
328
+ ...(hasValidImgCol && {
329
+ width: adaptiveContentWidth
330
+ }),
331
+ ...(hasValidImgCol && imgColCurrentViewport >= maxCol && {
176
332
  display: 'none'
177
333
  }),
178
334
  ...(fullBleedContentChildrenAlign && {
@@ -184,28 +340,32 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
184
340
  flexShrink: 1,
185
341
  justifyContent: 'space-between'
186
342
  };
187
- const cardBaseTokens = Object.fromEntries(Object.entries(tokens).filter(_ref2 => {
188
- let [key] = _ref2;
189
- return !['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', ...(backgroundImage ? ['backgroundColor'] : [])].includes(key);
343
+ const cardBaseTokens = Object.fromEntries(Object.entries(tokens).filter(_ref4 => {
344
+ let [key] = _ref4;
345
+ return !['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', ...(backgroundImage && interactiveCard?.body ? ['backgroundColor'] : [])].includes(key);
190
346
  }));
347
+ const isHorizontalFullBleed = fullBleedContentPosition === POSITION.LEFT || fullBleedContentPosition === POSITION.RIGHT;
348
+ const isVerticalFullBleed = fullBleedContentPosition === POSITION.TOP || fullBleedContentPosition === POSITION.BOTTOM;
191
349
  const imageWrapperStyleProps = {
192
- width: fullBleedImageWidth,
193
- ...(imgColCurrentViewport >= maxCol && {
350
+ ...(isImageWidthAdjustable && {
351
+ width: fullBleedImageWidth
352
+ }),
353
+ ...(isImageWidthAdjustable && imgColCurrentViewport >= maxCol && {
194
354
  borderRadius,
195
355
  overflow: 'hidden'
196
356
  }),
197
- ...(imgColCurrentViewport === 0 && {
357
+ ...(isImageWidthAdjustable && imgColCurrentViewport === 0 && {
198
358
  display: 'none'
199
359
  })
200
360
  };
201
361
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.Card, {
202
362
  ref: ref,
203
363
  variant: {
204
- ...variant,
364
+ ...(interactiveCard?.body ? mergedVariant : variant),
205
365
  padding: 'custom'
206
366
  },
207
367
  tokens: cardBaseTokens,
208
- backgroundImage: backgroundImage,
368
+ backgroundImage: !interactiveCard?.body && backgroundImage,
209
369
  onPress: fullBleedInteractive ? undefined : onPress,
210
370
  ...(interactiveCard?.selectionType && {
211
371
  interactiveCard,
@@ -222,6 +382,7 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
222
382
  ref: ref,
223
383
  tokens: getThemeTokens,
224
384
  dataSet: dataSet,
385
+ backgroundImage: backgroundImage,
225
386
  onPress: onPress,
226
387
  href: interactiveCard?.href,
227
388
  hrefAttrs: interactiveCard?.hrefAttrs,
@@ -229,96 +390,95 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
229
390
  children: cardState => /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
230
391
  children: typeof interactiveCard?.body === 'function' ? interactiveCard.body(cardState) : interactiveCard.body
231
392
  })
232
- }), children && fullBleedContentPosition === 'none' && !fullBleedInteractive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
393
+ }), children && fullBleedContentPosition === POSITION.NONE && !fullBleedInteractive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
233
394
  tokens: tokens,
234
395
  variant: variant,
235
396
  withFooter: hasFooter,
236
397
  children: children
237
398
  }) : null]
238
- }) : null, fullBleedInteractive ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
239
- style: {
240
- marginTop: marginOffset,
241
- marginBottom: marginOffset,
242
- marginLeft: marginOffset,
243
- marginRight: marginOffset
244
- },
245
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.PressableCardBase, {
246
- ref: ref,
247
- tokens: getFullBleedInteractiveCardTokens,
248
- dataSet: dataSet,
249
- onPress: effectiveFullBleedOnPress,
250
- href: effectiveFullBleedHref,
251
- hrefAttrs: effectiveFullBleedHrefAttrs,
252
- ...selectProps(restProps),
253
- children: cardState => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
254
- direction: contentStackDirection,
255
- tokens: {
256
- ...columnFlex,
257
- alignItems: contentStackAlign
258
- },
259
- space: 0,
260
- children: [children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
261
- WrapperComponent: DynamicWidthContainer,
262
- wrapperProps: contentWrapperStyleProps,
263
- condition: isImageWidthAdjustable,
264
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
265
- tokens: {
266
- ...tokensWithoutBg,
267
- ...(backgroundImage ? {} : {
268
- backgroundColor: 'transparent'
269
- }),
270
- ...(!isImageWidthAdjustable && fullBleedContentChildrenAlign && {
271
- alignSelf: fullBleedContentChildrenAlign
272
- })
273
- },
274
- variant: variant,
275
- withFooter: hasFooter,
276
- children: children
277
- })
278
- }) : null, fullBleedContentPosition !== 'none' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
279
- WrapperComponent: DynamicWidthContainer,
280
- wrapperProps: imageWrapperStyleProps,
281
- condition: isImageWidthAdjustable,
282
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FullBleedContent.default, {
283
- borderRadius: fullBleedBorderRadius,
284
- ...fullBleedContentPropsClean,
285
- position: fullBleedContentPosition,
286
- cardState: cardState
287
- })
399
+ }) : null, fullBleedInteractive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.PressableCardBase, {
400
+ ref: ref,
401
+ tokens: getFullBleedInteractiveCardTokens,
402
+ dataSet: dataSet,
403
+ onPress: effectiveFullBleedOnPress,
404
+ href: effectiveFullBleedHref,
405
+ hrefAttrs: effectiveFullBleedHrefAttrs,
406
+ ...selectProps(restProps),
407
+ children: cardState => {
408
+ let overlayOpacity = 0;
409
+ if (cardState.pressed) {
410
+ overlayOpacity = 0.2;
411
+ } else if (cardState.hover) {
412
+ overlayOpacity = 0.1;
413
+ }
414
+ const focusTokens = getFocusBorderTokens(cardState);
415
+ const showFocusBorder = cardState.focus && focusTokens.borderWidth > 0;
416
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(InteractiveCardWrapper, {
417
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
418
+ direction: contentStackDirection,
419
+ tokens: getStackViewTokens(columnFlex, contentStackAlign),
420
+ space: 0,
421
+ children: [children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
422
+ WrapperComponent: DynamicWidthContainer,
423
+ wrapperProps: contentWrapperStyleProps,
424
+ condition: isImageWidthAdjustable,
425
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
426
+ tokens: {
427
+ ...getCardContentTokens(tokensWithoutBg, {
428
+ backgroundImage,
429
+ fullBleedContentChildrenAlign,
430
+ useTransparentBackground: true
431
+ }),
432
+ paddingTop: tokens.paddingTop !== undefined ? tokens.paddingTop : allThemeTokens.paddingTop,
433
+ paddingBottom: tokens.paddingBottom !== undefined ? tokens.paddingBottom : allThemeTokens.paddingBottom,
434
+ paddingLeft: tokens.paddingLeft !== undefined ? tokens.paddingLeft : allThemeTokens.paddingLeft,
435
+ paddingRight: tokens.paddingRight !== undefined ? tokens.paddingRight : allThemeTokens.paddingRight
436
+ },
437
+ variant: variant,
438
+ withFooter: hasFooter,
439
+ children: children
440
+ })
441
+ }) : null, fullBleedContentPosition !== POSITION.NONE && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
442
+ WrapperComponent: DynamicWidthContainer,
443
+ wrapperProps: imageWrapperStyleProps,
444
+ condition: isImageWidthAdjustable || isHorizontalFullBleed || isVerticalFullBleed,
445
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FullBleedContent.default, {
446
+ borderRadius: fullBleedBorderRadius,
447
+ ...fullBleedContentPropsClean,
448
+ position: fullBleedContentPosition,
449
+ cardState: undefined
450
+ })
451
+ })]
452
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(InteractiveOverlay, {
453
+ overlayOpacity: overlayOpacity,
454
+ borderRadius: borderRadius
455
+ }), showFocusBorder && /*#__PURE__*/(0, _jsxRuntime.jsx)(FocusBorder, {
456
+ borderWidth: `${focusTokens.borderWidth}px`,
457
+ borderColor: focusTokens.borderColor,
458
+ borderRadius: borderRadius
288
459
  })]
289
- })
290
- })
291
- }) : null, !fullBleedInteractive && !interactiveCard?.body && fullBleedContentPosition === 'none' && children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
292
- tokens: {
293
- ...tokens,
294
- ...(backgroundImage ? {
295
- backgroundColor: 'transparent'
296
- } : {}),
297
- ...(fullBleedContentChildrenAlign && {
298
- alignSelf: fullBleedContentChildrenAlign
299
- })
300
- },
460
+ });
461
+ }
462
+ }) : null, !fullBleedInteractive && !interactiveCard?.body && fullBleedContentPosition === POSITION.NONE && children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
463
+ tokens: getCardContentTokens(tokens, {
464
+ backgroundImage,
465
+ fullBleedContentChildrenAlign
466
+ }),
301
467
  variant: variant,
302
468
  withFooter: hasFooter,
303
469
  children: children
304
- }) : null, !fullBleedInteractive && fullBleedContentPosition !== 'none' ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
470
+ }) : null, !fullBleedInteractive && fullBleedContentPosition !== POSITION.NONE ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
305
471
  direction: contentStackDirection,
306
- tokens: {
307
- ...columnFlex,
308
- alignItems: contentStackAlign
309
- },
472
+ tokens: getStackViewTokens(columnFlex, contentStackAlign),
310
473
  space: 0,
311
474
  children: [children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
312
475
  WrapperComponent: DynamicWidthContainer,
313
476
  wrapperProps: contentWrapperStyleProps,
314
477
  condition: isImageWidthAdjustable,
315
478
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardContent.default, {
316
- tokens: {
317
- ...tokens,
318
- ...(!isImageWidthAdjustable && fullBleedContentChildrenAlign && {
319
- alignSelf: fullBleedContentChildrenAlign
320
- })
321
- },
479
+ tokens: getCardContentTokens(tokens, {
480
+ fullBleedContentChildrenAlign
481
+ }),
322
482
  variant: variant,
323
483
  withFooter: hasFooter,
324
484
  children: children
@@ -326,7 +486,7 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
326
486
  }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConditionalWrapper.default, {
327
487
  WrapperComponent: DynamicWidthContainer,
328
488
  wrapperProps: imageWrapperStyleProps,
329
- condition: isImageWidthAdjustable,
489
+ condition: isImageWidthAdjustable || isHorizontalFullBleed || isVerticalFullBleed,
330
490
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_FullBleedContent.default, {
331
491
  borderRadius: fullBleedBorderRadius,
332
492
  ...fullBleedContentPropsClean,
@@ -342,7 +502,7 @@ const Card = /*#__PURE__*/_react.default.forwardRef(function () {
342
502
  })]
343
503
  });
344
504
  });
345
- const positionValues = ['none', 'bottom', 'left', 'right', 'top'];
505
+ const positionValues = Object.values(POSITION);
346
506
  const alignValues = ['start', 'end', 'center', 'stretch'];
347
507
  const PositionedFullBleedContentPropType = _propTypes.default.shape({
348
508
  position: _componentsBase.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(positionValues)).isRequired,
@@ -28,12 +28,28 @@ const Heading = /*#__PURE__*/_styledComponents.default.div.withConfig({
28
28
  letterSpacing: 0
29
29
  }
30
30
  });
31
+ const ContentWrapper = /*#__PURE__*/_styledComponents.default.div.withConfig({
32
+ displayName: "NavigationBar__ContentWrapper",
33
+ componentId: "components-web__sc-1vis1gt-1"
34
+ })(_ref => {
35
+ let {
36
+ maxWidth
37
+ } = _ref;
38
+ return {
39
+ width: '100%',
40
+ ...(maxWidth && {
41
+ maxWidth,
42
+ marginLeft: 'auto',
43
+ marginRight: 'auto'
44
+ })
45
+ };
46
+ });
31
47
 
32
48
  /**
33
49
  * NavigationBar can be used to allow customers to consistently navigate across
34
50
  * key pages within a specific product line
35
51
  */
36
- const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
52
+ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
37
53
  let {
38
54
  accessibilityRole = 'navigation',
39
55
  heading,
@@ -46,8 +62,9 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
46
62
  linkRouterProps,
47
63
  tokens,
48
64
  variant,
65
+ contentMaxWidth,
49
66
  ...rest
50
- } = _ref;
67
+ } = _ref2;
51
68
  const {
52
69
  currentValue,
53
70
  setValue
@@ -56,29 +73,35 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
56
73
  initialValue: selectedId,
57
74
  onChange
58
75
  });
76
+ const {
77
+ themeOptions
78
+ } = (0, _componentsBase.useTheme)();
79
+ const contentWidthValue = (0, _componentsBase.useResponsiveProp)(contentMaxWidth);
80
+ const responsiveWidth = (0, _componentsBase.useResponsiveProp)(themeOptions?.contentMaxWidth);
81
+ const maxWidth = (0, _componentsBase.resolveContentMaxWidth)(contentWidthValue, responsiveWidth);
59
82
  (0, _componentsBase.useHash)((hash, event) => {
60
- let hashItem = hash && items.find(_ref2 => {
83
+ let hashItem = hash && items.find(_ref3 => {
61
84
  let {
62
85
  href
63
- } = _ref2;
86
+ } = _ref3;
64
87
  return hash === href;
65
88
  });
66
89
  if (!hashItem) {
67
- const parentItem = items.find(_ref3 => {
90
+ const parentItem = items.find(_ref4 => {
68
91
  let {
69
92
  items: parentItems
70
- } = _ref3;
71
- return parentItems?.some(_ref4 => {
93
+ } = _ref4;
94
+ return parentItems?.some(_ref5 => {
72
95
  let {
73
96
  href
74
- } = _ref4;
97
+ } = _ref5;
75
98
  return hash === href;
76
99
  });
77
100
  });
78
- hashItem = parentItem?.items.find(_ref5 => {
101
+ hashItem = parentItem?.items.find(_ref6 => {
79
102
  let {
80
103
  href
81
- } = _ref5;
104
+ } = _ref6;
82
105
  return hash === href;
83
106
  });
84
107
  }
@@ -145,7 +168,7 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
145
168
  }
146
169
  };
147
170
  }, [openSubMenuId, handleMouseDown]);
148
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
171
+ const stackView = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
149
172
  accessibilityRole: accessibilityRole,
150
173
  direction: direction,
151
174
  ref: navRef,
@@ -163,7 +186,7 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
163
186
  heading: headingLevel,
164
187
  children: heading
165
188
  })
166
- }), itemsForViewport?.map((_ref6, index) => {
189
+ }), itemsForViewport?.map((_ref7, index) => {
167
190
  let {
168
191
  href,
169
192
  label,
@@ -174,7 +197,7 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
174
197
  linkRouterProps: itemLinkRouterProps,
175
198
  items: nestedItems,
176
199
  ...itemRest
177
- } = _ref6;
200
+ } = _ref7;
178
201
  const itemId = id ?? label;
179
202
  const handleClick = event => {
180
203
  if (nestedItems) {
@@ -200,9 +223,7 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
200
223
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(ItemComponent, {
201
224
  ref: itemRef,
202
225
  href: href,
203
- onClick: handleClick
204
- // TODO: refactor to pass selected ID via context
205
- ,
226
+ onClick: handleClick,
206
227
  selectedId: currentValue,
207
228
  index: index,
208
229
  LinkRouter: ItemLinkRouter,
@@ -226,6 +247,10 @@ const NavigationBar = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
226
247
  }, itemId);
227
248
  })]
228
249
  });
250
+ return maxWidth ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ContentWrapper, {
251
+ maxWidth: maxWidth,
252
+ children: stackView
253
+ }) : stackView;
229
254
  });
230
255
  NavigationBar.displayName = 'NavigationBar';
231
256
  NavigationBar.propTypes = {
@@ -285,6 +310,23 @@ NavigationBar.propTypes = {
285
310
  /**
286
311
  * Variant configuration
287
312
  */
288
- variant: _componentsBase.variantProp.propType
313
+ variant: _componentsBase.variantProp.propType,
314
+ /**
315
+ * The maximum width of the content in the NavigationBar.
316
+ * This prop accepts responsive values for different viewports. If a number is provided,
317
+ * it will be the max content width for the desired viewport.
318
+ * - `xs`: 'max' | 'full' | <number>
319
+ * - `sm`: 'max' | 'full' | <number>
320
+ * - `md`: 'max' | 'full' | <number>
321
+ * - `lg`: 'max' | 'full' | <number>
322
+ * - `xl`: 'max' | 'full' | <number>
323
+ */
324
+ contentMaxWidth: _propTypes.default.shape({
325
+ xl: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
326
+ lg: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
327
+ md: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
328
+ sm: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number]),
329
+ xs: _propTypes.default.oneOfType([_propTypes.default.oneOf(['max', 'full']), _propTypes.default.number])
330
+ })
289
331
  };
290
332
  var _default = exports.default = NavigationBar;