@telus-uds/components-base 3.22.0 → 3.24.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 (84) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/lib/cjs/Button/Button.js +2 -0
  3. package/lib/cjs/Button/ButtonBase.js +10 -5
  4. package/lib/cjs/Button/ButtonDropdown.js +2 -0
  5. package/lib/cjs/Button/ButtonGroup.js +45 -38
  6. package/lib/cjs/Button/propTypes.js +6 -0
  7. package/lib/cjs/Card/CardBase.js +97 -17
  8. package/lib/cjs/Card/PressableCardBase.js +12 -8
  9. package/lib/cjs/Carousel/Carousel.js +52 -19
  10. package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +23 -3
  11. package/lib/cjs/HorizontalScroll/HorizontalScroll.js +5 -2
  12. package/lib/cjs/Icon/Icon.js +11 -11
  13. package/lib/cjs/Icon/IconText.js +0 -1
  14. package/lib/cjs/Listbox/GroupControl.js +44 -44
  15. package/lib/cjs/Listbox/Listbox.js +63 -20
  16. package/lib/cjs/Listbox/ListboxGroup.js +141 -9
  17. package/lib/cjs/Listbox/ListboxOverlay.js +13 -5
  18. package/lib/cjs/Listbox/PressableItem.js +8 -4
  19. package/lib/cjs/Listbox/SecondLevelHeader.js +201 -0
  20. package/lib/cjs/Listbox/dictionary.js +14 -0
  21. package/lib/cjs/Shortcuts/Shortcuts.js +169 -0
  22. package/lib/cjs/Shortcuts/ShortcutsItem.js +280 -0
  23. package/lib/cjs/Shortcuts/index.js +16 -0
  24. package/lib/cjs/TextInput/TextInputBase.js +5 -1
  25. package/lib/cjs/Tooltip/Tooltip.native.js +2 -0
  26. package/lib/cjs/Validator/Validator.js +171 -135
  27. package/lib/cjs/index.js +15 -0
  28. package/lib/esm/Button/Button.js +2 -0
  29. package/lib/esm/Button/ButtonBase.js +10 -5
  30. package/lib/esm/Button/ButtonDropdown.js +2 -0
  31. package/lib/esm/Button/ButtonGroup.js +44 -39
  32. package/lib/esm/Button/propTypes.js +6 -0
  33. package/lib/esm/Card/CardBase.js +97 -17
  34. package/lib/esm/Card/PressableCardBase.js +10 -8
  35. package/lib/esm/Carousel/Carousel.js +52 -19
  36. package/lib/esm/Carousel/CarouselItem/CarouselItem.js +23 -3
  37. package/lib/esm/HorizontalScroll/HorizontalScroll.js +6 -3
  38. package/lib/esm/Icon/Icon.js +11 -11
  39. package/lib/esm/Icon/IconText.js +0 -1
  40. package/lib/esm/Listbox/GroupControl.js +44 -44
  41. package/lib/esm/Listbox/Listbox.js +64 -21
  42. package/lib/esm/Listbox/ListboxGroup.js +143 -11
  43. package/lib/esm/Listbox/ListboxOverlay.js +13 -5
  44. package/lib/esm/Listbox/PressableItem.js +8 -4
  45. package/lib/esm/Listbox/SecondLevelHeader.js +194 -0
  46. package/lib/esm/Listbox/dictionary.js +8 -0
  47. package/lib/esm/Shortcuts/Shortcuts.js +160 -0
  48. package/lib/esm/Shortcuts/ShortcutsItem.js +273 -0
  49. package/lib/esm/Shortcuts/index.js +3 -0
  50. package/lib/esm/TextInput/TextInputBase.js +5 -1
  51. package/lib/esm/Tooltip/Tooltip.native.js +2 -0
  52. package/lib/esm/Validator/Validator.js +171 -135
  53. package/lib/esm/index.js +1 -0
  54. package/lib/package.json +2 -2
  55. package/package.json +2 -2
  56. package/src/Button/Button.jsx +2 -1
  57. package/src/Button/ButtonBase.jsx +18 -12
  58. package/src/Button/ButtonDropdown.jsx +2 -0
  59. package/src/Button/ButtonGroup.jsx +62 -45
  60. package/src/Button/propTypes.js +6 -0
  61. package/src/Card/CardBase.jsx +113 -14
  62. package/src/Card/PressableCardBase.jsx +17 -5
  63. package/src/Carousel/Carousel.jsx +58 -5
  64. package/src/Carousel/CarouselItem/CarouselItem.jsx +31 -3
  65. package/src/HorizontalScroll/HorizontalScroll.jsx +6 -3
  66. package/src/Icon/Icon.jsx +14 -14
  67. package/src/Icon/IconText.jsx +0 -1
  68. package/src/Listbox/GroupControl.jsx +72 -70
  69. package/src/Listbox/Listbox.jsx +67 -11
  70. package/src/Listbox/ListboxGroup.jsx +160 -27
  71. package/src/Listbox/ListboxOverlay.jsx +23 -5
  72. package/src/Listbox/PressableItem.jsx +8 -4
  73. package/src/Listbox/SecondLevelHeader.jsx +182 -0
  74. package/src/Listbox/dictionary.js +8 -0
  75. package/src/Shortcuts/Shortcuts.jsx +174 -0
  76. package/src/Shortcuts/ShortcutsItem.jsx +297 -0
  77. package/src/Shortcuts/index.js +4 -0
  78. package/src/TextInput/TextInputBase.jsx +5 -1
  79. package/src/Tooltip/Tooltip.native.jsx +2 -1
  80. package/src/Validator/Validator.jsx +180 -159
  81. package/src/index.js +1 -0
  82. package/types/Listbox.d.ts +24 -0
  83. package/types/Shortcuts.d.ts +136 -0
  84. package/types/index.d.ts +12 -0
package/CHANGELOG.md CHANGED
@@ -1,9 +1,37 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Wed, 29 Oct 2025 07:40:46 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 12 Dec 2025 05:37:22 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.24.0
8
+
9
+ Fri, 12 Dec 2025 05:37:22 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Card`: interactive mode added for FullBleedContent (35577399+JoshHC@users.noreply.github.com)
14
+ - `Shortcuts`: add component (guillermo.peitzner@telus.com)
15
+ - `Listbox & NavigationBar`: add `secondLevel` variant (sergio.ramirez@telus.com)
16
+ - Bump @telus-uds/system-theme-tokens to v4.17.0
17
+
18
+ ## 3.23.0
19
+
20
+ Wed, 19 Nov 2025 05:51:39 GMT
21
+
22
+ ### Minor changes
23
+
24
+ - `Listbox`: Added test and snapshot for Listbox (david.melara1@telus.com)
25
+ - `Listbox`: Updated style for koodo, allium and public mobile; added new style variant (david.melara1@telus.com)
26
+ - `ButtonGroup`: enhacements for iOS and android implemented and fix for the mobile version (35577399+JoshHC@users.noreply.github.com)
27
+ - `Button`: Implement heightFull prop (oscar.palencia@telus.com)
28
+ - Bump @telus-uds/system-theme-tokens to v4.16.0
29
+
30
+ ### Patches
31
+
32
+ - `Validator`: code refactored to resolve several bugs (35577399+JoshHC@users.noreply.github.com)
33
+ - `Carousel`: fix tab navigation (guillermo.peitzner@telus.com)
34
+
7
35
  ## 3.22.0
8
36
 
9
37
  Wed, 29 Oct 2025 07:40:46 GMT
@@ -19,6 +19,7 @@ const Button = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
19
19
  accessibilityRole = 'button',
20
20
  tokens,
21
21
  variant,
22
+ heightFull = true,
22
23
  ...props
23
24
  } = _ref;
24
25
  const viewport = (0, _ViewportProvider.useViewport)();
@@ -36,6 +37,7 @@ const Button = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
36
37
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ButtonBase.default, {
37
38
  ...props,
38
39
  tokens: getTokens,
40
+ heightFull: heightFull,
39
41
  accessibilityRole: accessibilityRole,
40
42
  ref: ref,
41
43
  viewport: viewport
@@ -40,23 +40,27 @@ const selectFlexAndWidthStyles = _ref2 => {
40
40
  }
41
41
  return styles;
42
42
  };
43
- const selectOuterContainerStyles = _ref3 => {
43
+ const selectOuterContainerStyles = (_ref3, heightFull) => {
44
44
  let {
45
45
  opacity,
46
46
  outerBorderColor,
47
47
  outerBorderWidth,
48
48
  outerBorderGap,
49
49
  borderRadius,
50
- outerBackgroundColor
50
+ outerBackgroundColor,
51
+ alignSelf
51
52
  } = _ref3;
52
53
  return {
54
+ backgroundColor: outerBackgroundColor,
55
+ opacity,
53
56
  ..._Platform.default.select({
54
57
  native: {
58
+ alignSelf: alignSelf !== undefined ? alignSelf : 'flex-start'
59
+ },
60
+ web: heightFull ? {} : {
55
61
  alignSelf: 'flex-start'
56
62
  }
57
63
  }),
58
- backgroundColor: outerBackgroundColor,
59
- opacity,
60
64
  ...(0, _ThemeProvider.applyOuterBorder)({
61
65
  outerBorderGap,
62
66
  outerBorderWidth,
@@ -255,6 +259,7 @@ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref12, ref) => {
255
259
  icon,
256
260
  iconPosition = icon ? 'left' : undefined,
257
261
  iconProps,
262
+ heightFull = true,
258
263
  ...rawRest
259
264
  } = _ref12;
260
265
  const {
@@ -314,7 +319,7 @@ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref12, ref) => {
314
319
  }
315
320
  const themeTokens = resolveButtonTokens(pressableState);
316
321
  const flexAndWidthStyles = themeTokens.width === '100%' && themeTokens.flex === 1 ? selectFlexAndWidthStyles(themeTokens) : {};
317
- return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens), ...(Object.keys(flexAndWidthStyles).length > 0 ? [flexAndWidthStyles] : []), selectOuterSizeStyles(themeTokens)];
322
+ return [staticStyles.row, selectWebOnlyStyles(inactive, themeTokens, systemProps), selectOuterContainerStyles(themeTokens, heightFull), ...(Object.keys(flexAndWidthStyles).length > 0 ? [flexAndWidthStyles] : []), selectOuterSizeStyles(themeTokens)];
318
323
  };
319
324
  const dataSetProp = flexAndWidthStylesIds || rawRest.dataSet ? {
320
325
  dataSet: {
@@ -112,6 +112,7 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
112
112
  accessibilityRole = 'radio',
113
113
  description,
114
114
  singleOption,
115
+ heightFull = true,
115
116
  ...props
116
117
  } = _ref2;
117
118
  const isFullWidth = variant?.width === FULL_WIDTH_STYLE;
@@ -154,6 +155,7 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
154
155
  ...pressHandlers,
155
156
  onPress: handlePress,
156
157
  tokens: getButtonTokens,
158
+ heightFull: heightFull,
157
159
  inactive: singleOption || inactive,
158
160
  icon: () => null,
159
161
  accessibilityRole: accessibilityRole,
@@ -4,12 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _react = _interopRequireDefault(require("react"));
7
+ var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _airbnbPropTypes = _interopRequireDefault(require("airbnb-prop-types"));
10
10
  var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
12
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
11
13
  var _ButtonBase = _interopRequireDefault(require("./ButtonBase"));
12
- var _StackView = require("../StackView");
13
14
  var _Fieldset = _interopRequireDefault(require("../Fieldset"));
14
15
  var _ViewportProvider = require("../ViewportProvider");
15
16
  var _ThemeProvider = require("../ThemeProvider");
@@ -17,17 +18,10 @@ var _utils = require("../utils");
17
18
  var _pressability = require("../utils/pressability");
18
19
  var _jsxRuntime = require("react/jsx-runtime");
19
20
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ 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); }
22
+ 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; }
20
23
  const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
21
24
  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
- };
31
25
  const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
32
26
  let {
33
27
  variant,
@@ -60,12 +54,6 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
60
54
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('ButtonGroup', tokens, variant, {
61
55
  viewport
62
56
  });
63
- const themeStackTokens = (0, _utils.selectTokens)('StackView', themeTokens);
64
- const variantStackTokens = getStackWrapTokens(variant);
65
- const stackTokens = {
66
- ...themeStackTokens,
67
- ...variantStackTokens
68
- };
69
57
  const {
70
58
  direction,
71
59
  space,
@@ -75,15 +63,34 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
75
63
  padding,
76
64
  gap
77
65
  } = themeTokens;
66
+ const isMobileNonContained = _Platform.default.OS !== 'web' && (!variant || variant?.style !== 'contained');
78
67
  const themeButtonTokensCallback = (0, _ThemeProvider.useThemeTokensCallback)('ButtonGroupItem', tokens, variant);
79
- const getButtonTokens = state => {
68
+ const gapValue = (0, _utils.useSpacingScale)(gap || space);
69
+ const getButtonTokens = (0, _react.useCallback)(state => {
80
70
  const themeButtonTokens = themeButtonTokensCallback(state);
71
+ const shouldUseTransparentBackground = isMobileNonContained && !state.selected && !state.pressed && !state.hover && !state.focus;
81
72
  return {
82
73
  ...themeButtonTokens,
83
- width: variant?.width === 'equal' ? '100%' : 'auto',
84
- flex: variant?.width === 'equal' ? 1 : undefined
74
+ ...(variant?.width === 'equal' && staticStyles.equalWidth),
75
+ ...(shouldUseTransparentBackground && {
76
+ backgroundColor: 'transparent'
77
+ }),
78
+ alignSelf: themeButtonTokens.width ? 'flex-start' : 'center'
85
79
  };
86
- };
80
+ }, [themeButtonTokensCallback, isMobileNonContained, variant?.width]);
81
+ const fieldsetStyles = (0, _react.useMemo)(() => ({
82
+ ...staticStyles.fieldsetBase,
83
+ borderRadius,
84
+ backgroundColor: isMobileNonContained ? 'transparent' : backgroundColor || 'transparent',
85
+ padding,
86
+ width: variant?.width === 'equal' ? '100%' : 'auto'
87
+ }), [borderRadius, backgroundColor, padding, variant?.width, isMobileNonContained]);
88
+ const viewStyles = (0, _react.useMemo)(() => ({
89
+ ...staticStyles.viewBase,
90
+ flexDirection: direction === 'column' ? 'column' : 'row',
91
+ gap: gapValue || 0,
92
+ justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start'
93
+ }), [direction, gapValue, variant?.width]);
87
94
  const {
88
95
  currentValues,
89
96
  toggleOneValue
@@ -120,25 +127,11 @@ const ButtonGroup = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
120
127
  inactive: inactive,
121
128
  validation: validation,
122
129
  accessibilityRole: accessibilityRole,
123
- style: {
124
- borderRadius,
125
- backgroundColor,
126
- padding,
127
- ...(_Platform.default.OS === 'web' ? {
128
- gap,
129
- width: variant?.width === 'equal' ? '100%' : 'auto'
130
- } : {
131
- alignSelf: 'flex-start'
132
- })
133
- },
130
+ style: fieldsetStyles,
134
131
  ...selectProps(rest),
135
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.StackWrap, {
132
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
136
133
  accessibilityRole: innerRole,
137
- space: space,
138
- direction: direction,
139
- tokens: stackTokens,
140
- gap: gap,
141
- ref: ref,
134
+ style: viewStyles,
142
135
  children: items.map((_ref2, index) => {
143
136
  let {
144
137
  label,
@@ -298,4 +291,18 @@ ButtonGroup.propTypes = {
298
291
  */
299
292
  copy: _propTypes.default.oneOf(['en', 'fr'])
300
293
  };
294
+ const staticStyles = _StyleSheet.default.create({
295
+ fieldsetBase: {
296
+ alignSelf: 'flex-start',
297
+ display: 'inline'
298
+ },
299
+ viewBase: {
300
+ flexWrap: 'wrap',
301
+ alignItems: 'center'
302
+ },
303
+ equalWidth: {
304
+ width: '100%',
305
+ flex: 1
306
+ }
307
+ });
301
308
  var _default = exports.default = ButtonGroup;
@@ -13,6 +13,12 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
13
13
  const textAndA11yText = exports.textAndA11yText = _airbnbPropTypes.default.childrenOf(_propTypes.default.oneOfType([_airbnbPropTypes.default.elementType(_A11yText.default), _propTypes.default.string]));
14
14
  const buttonPropTypes = {
15
15
  tokens: (0, _props.getTokensPropType)('Button'),
16
+ /**
17
+ * If true, the button will honor the align-items value from its parent flex container.
18
+ * If false, the button will always align to 'flex-start' in a flex container.
19
+ * Currently, `heightFull`'s default behaviour will expand to the full height of its parent's flex container. In an upcoming major release, the default behaviour will be changed to expand based on the content. To maintain the expected behaviour, you must explicitly set `heightFull: true`
20
+ */
21
+ heightFull: _propTypes.default.bool,
16
22
  /**
17
23
  * If true, prevents the button from being pressed, changes the cursor (on web) and accessibility
18
24
  * attributes to communicate this to the user, and applies `inactive: true` appearances from the theme
@@ -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);