@telus-uds/components-base 3.12.2 → 3.14.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 (63) hide show
  1. package/CHANGELOG.md +37 -2
  2. package/lib/cjs/BaseProvider/index.js +4 -1
  3. package/lib/cjs/Button/ButtonDropdown.js +105 -12
  4. package/lib/cjs/Card/Card.js +23 -4
  5. package/lib/cjs/Card/CardBase.js +170 -19
  6. package/lib/cjs/Card/PressableCardBase.js +19 -5
  7. package/lib/cjs/Card/backgroundImageStylesMap.js +197 -0
  8. package/lib/cjs/ExpandCollapse/ExpandCollapse.js +3 -1
  9. package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +1 -1
  10. package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +30 -6
  11. package/lib/cjs/FlexGrid/FlexGrid.js +71 -6
  12. package/lib/cjs/Icon/Icon.js +3 -1
  13. package/lib/cjs/InputLabel/InputLabel.js +1 -1
  14. package/lib/cjs/InputSupports/InputSupports.js +1 -1
  15. package/lib/cjs/Notification/Notification.js +27 -8
  16. package/lib/cjs/Tabs/Tabs.js +34 -2
  17. package/lib/cjs/Tabs/TabsDropdown.js +252 -0
  18. package/lib/cjs/Tabs/TabsItem.js +4 -2
  19. package/lib/cjs/Tabs/dictionary.js +14 -0
  20. package/lib/cjs/ViewportProvider/ViewportProvider.js +9 -3
  21. package/lib/cjs/utils/props/inputSupportsProps.js +1 -1
  22. package/lib/esm/BaseProvider/index.js +4 -1
  23. package/lib/esm/Button/ButtonDropdown.js +107 -14
  24. package/lib/esm/Card/Card.js +21 -4
  25. package/lib/esm/Card/CardBase.js +169 -19
  26. package/lib/esm/Card/PressableCardBase.js +19 -5
  27. package/lib/esm/Card/backgroundImageStylesMap.js +190 -0
  28. package/lib/esm/ExpandCollapse/ExpandCollapse.js +4 -2
  29. package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +2 -2
  30. package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +30 -6
  31. package/lib/esm/FlexGrid/FlexGrid.js +72 -7
  32. package/lib/esm/Icon/Icon.js +3 -1
  33. package/lib/esm/InputLabel/InputLabel.js +1 -1
  34. package/lib/esm/InputSupports/InputSupports.js +1 -1
  35. package/lib/esm/Notification/Notification.js +27 -8
  36. package/lib/esm/Tabs/Tabs.js +35 -3
  37. package/lib/esm/Tabs/TabsDropdown.js +245 -0
  38. package/lib/esm/Tabs/TabsItem.js +4 -2
  39. package/lib/esm/Tabs/dictionary.js +8 -0
  40. package/lib/esm/ViewportProvider/ViewportProvider.js +9 -3
  41. package/lib/esm/utils/props/inputSupportsProps.js +1 -1
  42. package/lib/package.json +2 -2
  43. package/package.json +2 -2
  44. package/src/BaseProvider/index.jsx +4 -2
  45. package/src/Button/ButtonDropdown.jsx +109 -16
  46. package/src/Card/Card.jsx +27 -3
  47. package/src/Card/CardBase.jsx +165 -19
  48. package/src/Card/PressableCardBase.jsx +31 -4
  49. package/src/Card/backgroundImageStylesMap.js +41 -0
  50. package/src/ExpandCollapse/ExpandCollapse.jsx +5 -2
  51. package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +2 -2
  52. package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +39 -9
  53. package/src/FlexGrid/FlexGrid.jsx +80 -7
  54. package/src/Icon/Icon.jsx +3 -1
  55. package/src/InputLabel/InputLabel.jsx +1 -1
  56. package/src/InputSupports/InputSupports.jsx +1 -1
  57. package/src/Notification/Notification.jsx +58 -9
  58. package/src/Tabs/Tabs.jsx +36 -2
  59. package/src/Tabs/TabsDropdown.jsx +265 -0
  60. package/src/Tabs/TabsItem.jsx +4 -2
  61. package/src/Tabs/dictionary.js +8 -0
  62. package/src/ViewportProvider/ViewportProvider.jsx +8 -3
  63. package/src/utils/props/inputSupportsProps.js +1 -1
package/CHANGELOG.md CHANGED
@@ -1,12 +1,47 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Fri, 25 Jul 2025 04:09:38 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 04 Sep 2025 06:46:41 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.14.0
8
+
9
+ Thu, 04 Sep 2025 06:46:41 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `ViewportProvider`: add default-viewport prop (guillermo.peitzner@telus.com)
14
+ - `Card`: position and align props added (35577399+JoshHC@users.noreply.github.com)
15
+ - `Tabs`: new dropdown feature added for xs and sm viewports (35577399+JoshHC@users.noreply.github.com)
16
+ - Bump @telus-uds/system-theme-tokens to v4.13.0
17
+
18
+ ### Patches
19
+
20
+ - `Card`: fix media queries styles (guillermo.peitzner@telus.com)
21
+ - `FlexGrid`: change limitWidth default prop value from true to false (guillermo.peitzner@telus.com)
22
+ - `Icon - backgroundColor`: update icon documentation with new section (sergio.ramirez@telus.com)
23
+
24
+ ## 3.13.0
25
+
26
+ Fri, 15 Aug 2025 00:52:15 GMT
27
+
28
+ ### Minor changes
29
+
30
+ - `Carousel`: add new stories & documentation (sergio.ramirez@telus.com)
31
+ - `Notification`: Add `contentMinWidth` prop for system variant (guillermo.peitzner@telus.com)
32
+ - `FlexGrid`: add min-content-width prop (guillermo.peitzner@telus.com)
33
+ - `Checkbox`: Update storybook to add description to the component (sergio.ramirez@telus.com)
34
+ - `ButtonDropdown`: add lead icon props and new variants (guillermo.peitzner@telus.com)
35
+ - Bump @telus-uds/system-theme-tokens to v4.12.0
36
+
37
+ ### Patches
38
+
39
+ - `ExpandCollapseMini` fix design & animations (sergio.ramirez@telus.com)
40
+ - Invalid argument supplied to oneOfType issue fixed (35577399+JoshHC@users.noreply.github.com)
41
+
7
42
  ## 3.12.2
8
43
 
9
- Fri, 25 Jul 2025 04:09:38 GMT
44
+ Fri, 25 Jul 2025 04:13:56 GMT
10
45
 
11
46
  ### Patches
12
47
 
@@ -7,6 +7,7 @@ exports.default = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _portal = require("@gorhom/portal");
10
+ var _systemConstants = require("@telus-uds/system-constants");
10
11
  var _A11yInfoProvider = _interopRequireDefault(require("../A11yInfoProvider"));
11
12
  var _ViewportProvider = _interopRequireDefault(require("../ViewportProvider"));
12
13
  var _ThemeProvider = _interopRequireDefault(require("../ThemeProvider"));
@@ -23,6 +24,7 @@ const BaseProvider = /*#__PURE__*/_react.default.forwardRef((_ref, _) => {
23
24
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_HydrationContext.HydrationProvider, {
24
25
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_A11yInfoProvider.default, {
25
26
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ViewportProvider.default, {
27
+ defaultViewport: themeOptions?.defaultViewport,
26
28
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ThemeProvider.default, {
27
29
  defaultTheme: defaultTheme,
28
30
  themeOptions: themeOptions,
@@ -40,7 +42,8 @@ BaseProvider.propTypes = {
40
42
  defaultTheme: _ThemeProvider.default.propTypes?.defaultTheme,
41
43
  themeOptions: _propTypes.default.shape({
42
44
  forceAbsoluteFontSizing: _propTypes.default.bool,
43
- forceZIndex: _propTypes.default.bool
45
+ forceZIndex: _propTypes.default.bool,
46
+ defaultViewport: _propTypes.default.oneOf(_systemConstants.viewports.keys)
44
47
  })
45
48
  };
46
49
  var _default = exports.default = BaseProvider;
@@ -7,6 +7,7 @@ exports.default = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
10
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
10
11
  var _Text = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Text"));
11
12
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
12
13
  var _propTypes2 = _interopRequireWildcard(require("./propTypes"));
@@ -14,12 +15,12 @@ var _ButtonBase = _interopRequireDefault(require("./ButtonBase"));
14
15
  var _ThemeProvider = require("../ThemeProvider");
15
16
  var _utils = require("../utils");
16
17
  var _Icon = _interopRequireDefault(require("../Icon"));
17
- var _StackView = require("../StackView");
18
18
  var _pressability = require("../utils/pressability");
19
19
  var _jsxRuntime = require("react/jsx-runtime");
20
20
  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); }
21
21
  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; }
22
22
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
+ const FULL_WIDTH_STYLE = 'full';
23
24
  const selectIconTokens = _ref => {
24
25
  let {
25
26
  icon,
@@ -58,6 +59,44 @@ const selectIconTokens = _ref => {
58
59
  }
59
60
  };
60
61
  };
62
+ const selectDescriptionTextStyles = tokens => ({
63
+ ...(0, _ThemeProvider.applyTextStyles)({
64
+ fontName: tokens?.descriptionFontName,
65
+ fontSize: tokens?.descriptionFontSize,
66
+ fontWeight: tokens?.descriptionFontWeight,
67
+ fontColor: tokens?.color
68
+ }),
69
+ paddingBottom: tokens?.descriptionTextPaddingBottom
70
+ });
71
+ const selectLeadIconTokens = tokens => ({
72
+ color: tokens?.leadIconColor,
73
+ backgroundColor: tokens?.leadIconBackgroundColor,
74
+ size: tokens?.leadIconSize,
75
+ borderRadius: tokens?.leadIconBorderRadius,
76
+ padding: tokens?.leadIconPadding
77
+ });
78
+ const selectLeadIconContainerStyles = tokens => ({
79
+ paddingTop: tokens?.leadIconContainerPaddingTop,
80
+ paddingBottom: tokens?.leadIconContainerPaddingBottom,
81
+ paddingLeft: tokens?.leadIconContainerPaddingLeft,
82
+ paddingRight: tokens?.leadIconContainerPaddingRight
83
+ });
84
+ const selectTextContainerStyles = tokens => ({
85
+ paddingLeft: tokens?.textPaddingLeft,
86
+ paddingRight: tokens?.textPaddingRight
87
+ });
88
+ const selectStackedContentStyles = (tokens, iconPosition, isFullWidth) => ({
89
+ ...staticStyles.stackedContent,
90
+ gap: tokens?.iconSpace,
91
+ flexDirection: iconPosition === 'left' ? 'row' : 'row-reverse',
92
+ ...(_Platform.default.OS === 'web' && {
93
+ flex: 1
94
+ }),
95
+ ...(isFullWidth && {
96
+ justifyContent: 'space-between',
97
+ flex: 1
98
+ })
99
+ });
61
100
  const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
62
101
  let {
63
102
  value,
@@ -70,8 +109,11 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
70
109
  readOnly = false,
71
110
  children = null,
72
111
  accessibilityRole = 'radio',
112
+ description,
113
+ singleOption,
73
114
  ...props
74
115
  } = _ref2;
116
+ const isFullWidth = variant?.width === FULL_WIDTH_STYLE;
75
117
  const {
76
118
  currentValue: isOpen,
77
119
  setValue: setIsOpen
@@ -87,7 +129,13 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
87
129
  ...variant
88
130
  };
89
131
  const getTokens = (0, _ThemeProvider.useThemeTokensCallback)('ButtonDropdown', tokens, extraState);
90
- const getButtonTokens = buttonState => (0, _utils.selectTokens)('Button', getTokens(buttonState));
132
+ const getButtonTokens = buttonState => ({
133
+ ...(0, _utils.selectTokens)('Button', getTokens(buttonState)),
134
+ iconSpace: props?.icon ? getTokens(buttonState)?.iconSpace : 0,
135
+ ...(isFullWidth && {
136
+ width: 'full'
137
+ })
138
+ });
91
139
 
92
140
  // Pass an object of relevant component state as first argument for any passed-in press handlers
93
141
  const pressHandlers = (0, _pressability.getPressHandlersWithArgs)(props, [{
@@ -105,7 +153,7 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
105
153
  ...pressHandlers,
106
154
  onPress: handlePress,
107
155
  tokens: getButtonTokens,
108
- inactive: inactive,
156
+ inactive: singleOption || inactive,
109
157
  icon: () => null,
110
158
  accessibilityRole: accessibilityRole,
111
159
  ...props,
@@ -121,14 +169,14 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
121
169
  // - Token sets: https://github.com/telus/universal-design-system/issues/782
122
170
 
123
171
  const itemTokens = getTokens(buttonState);
172
+ const leadIcon = itemTokens?.leadIcon;
124
173
  const {
125
174
  iconTokens,
126
175
  iconPosition,
127
- iconSpace,
128
176
  iconWrapperStyle,
129
177
  icon: IconComponent
130
178
  } = selectIconTokens(itemTokens);
131
- const iconContent = IconComponent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
179
+ const iconContent = IconComponent && !singleOption ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
132
180
  style: iconWrapperStyle,
133
181
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
134
182
  icon: IconComponent,
@@ -139,13 +187,28 @@ const ButtonDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
139
187
  ...(0, _utils.resolvePressableState)(buttonState, extraState),
140
188
  textStyles
141
189
  }) : children;
142
- const content = children ? childrenContent() : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
143
- style: textStyles,
144
- children: label
190
+ const content = children ? childrenContent() : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
191
+ style: staticStyles.contentContainer,
192
+ children: [leadIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
193
+ style: selectLeadIconContainerStyles(itemTokens),
194
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
195
+ icon: leadIcon,
196
+ tokens: selectLeadIconTokens(itemTokens)
197
+ })
198
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
199
+ style: [staticStyles.textContainer, selectTextContainerStyles(itemTokens)],
200
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
201
+ style: textStyles,
202
+ children: label
203
+ }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
204
+ style: selectDescriptionTextStyles(itemTokens),
205
+ children: description
206
+ })]
207
+ })]
145
208
  });
146
- return (0, _StackView.getStackedContent)(iconPosition === 'left' ? [iconContent, content] : [content, iconContent], {
147
- space: iconSpace,
148
- direction: 'row'
209
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
210
+ style: selectStackedContentStyles(itemTokens, iconPosition, isFullWidth),
211
+ children: [iconContent, content]
149
212
  });
150
213
  }
151
214
  });
@@ -177,6 +240,36 @@ ButtonDropdown.propTypes = {
177
240
  /**
178
241
  * By default, `ButtonDropdown` is treated by accessibility tools as a radio button.
179
242
  */
180
- accessibilityRole: _propTypes.default.string
243
+ accessibilityRole: _propTypes.default.string,
244
+ /**
245
+ * The description of ButtonDropdown.
246
+ */
247
+ description: _propTypes.default.string,
248
+ /**
249
+ * Use this prop to render the ButtonDropdown as display only without any interaction when there is only one option.
250
+ */
251
+ singleOption: _propTypes.default.bool
181
252
  };
253
+ const staticStyles = _StyleSheet.default.create({
254
+ textContainer: {
255
+ alignItems: 'flex-start',
256
+ flexShrink: 1,
257
+ ...(_Platform.default.OS === 'web' && {
258
+ flex: 1
259
+ })
260
+ },
261
+ contentContainer: {
262
+ flexDirection: 'row',
263
+ alignContent: 'center',
264
+ alignItems: 'center',
265
+ ...(_Platform.default.OS === 'web' && {
266
+ flex: 1
267
+ }),
268
+ flexShrink: 1
269
+ },
270
+ stackedContent: {
271
+ flexDirection: 'row',
272
+ alignItems: 'center'
273
+ }
274
+ });
182
275
  var _default = exports.default = ButtonDropdown;
@@ -11,11 +11,13 @@ var _ThemeProvider = require("../ThemeProvider");
11
11
  var _utils = require("../utils");
12
12
  var _ViewportProvider = require("../ViewportProvider");
13
13
  var _props = require("../utils/props");
14
- var _CardBase = _interopRequireDefault(require("./CardBase"));
14
+ var _CardBase = _interopRequireWildcard(require("./CardBase"));
15
15
  var _PressableCardBase = _interopRequireDefault(require("./PressableCardBase"));
16
16
  var _CheckboxButton = _interopRequireDefault(require("../Checkbox/CheckboxButton"));
17
17
  var _RadioButton = _interopRequireDefault(require("../Radio/RadioButton"));
18
18
  var _jsxRuntime = require("react/jsx-runtime");
19
+ 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); }
20
+ 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; }
19
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
20
22
  const [selectProps, selectedSystemPropTypes] = (0, _props.selectSystemProps)([_props.a11yProps, _props.viewProps, _props.linkProps]);
21
23
  const SelectionType = {
@@ -189,12 +191,27 @@ const Card = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
189
191
  let cardStyles;
190
192
  let mediaIds;
191
193
  if (enableMediaQueryStyleSheet) {
192
- const mediaQueryStyleSheet = (0, _utils.createMediaQueryStyles)(themeTokens);
194
+ const transformedThemeTokens = Object.entries(themeTokens).reduce((acc, _ref4) => {
195
+ let [vp, viewportTokens] = _ref4;
196
+ const tokensToTransform = selectionType ? (0, _CardBase.selectStyles)({
197
+ ...viewportTokens,
198
+ paddingTop: 0,
199
+ paddingBottom: 0,
200
+ paddingLeft: 0,
201
+ paddingRight: 0
202
+ }) : (0, _CardBase.selectStyles)(viewportTokens);
203
+ acc[vp] = tokensToTransform;
204
+ return acc;
205
+ }, {});
206
+ const mediaQueryStyleSheet = (0, _utils.createMediaQueryStyles)(transformedThemeTokens);
193
207
  const {
194
208
  ids,
195
209
  styles
196
210
  } = _utils.StyleSheet.create({
197
- card: mediaQueryStyleSheet
211
+ card: {
212
+ ...themeTokens[viewport],
213
+ ...mediaQueryStyleSheet
214
+ }
198
215
  });
199
216
  cardStyles = styles.card;
200
217
  mediaIds = ids.card;
@@ -328,7 +345,9 @@ Card.propTypes = {
328
345
  // src is an object when used responsively to provide different image sources for different screen sizes
329
346
  src: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object]).isRequired,
330
347
  alt: _propTypes.default.string,
331
- resizeMode: _props.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']))
348
+ resizeMode: _props.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])),
349
+ position: _props.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['bottom', 'left', 'right', 'top'])),
350
+ align: _props.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['start', 'end', 'center', 'stretch']))
332
351
  }),
333
352
  /**
334
353
  * Data set for the card.
@@ -3,22 +3,119 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.selectStyles = 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"));
10
10
  var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
11
  var _ImageBackground = _interopRequireDefault(require("react-native-web/dist/cjs/exports/ImageBackground"));
12
+ var _Image = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Image"));
12
13
  var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
13
14
  var _ThemeProvider = require("../ThemeProvider");
14
15
  var _utils = require("../utils");
15
16
  var _props = require("../utils/props");
17
+ var _backgroundImageStylesMap = _interopRequireDefault(require("./backgroundImageStylesMap"));
16
18
  var _jsxRuntime = require("react/jsx-runtime");
17
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
20
  const [selectProps, selectedSystemPropTypes] = (0, _props.selectSystemProps)([_props.a11yProps, _props.viewProps]);
21
+ const setBackgroundImage = _ref => {
22
+ let {
23
+ src,
24
+ alt,
25
+ backgroundImageResizeMode,
26
+ backgroundImagePosition,
27
+ backgroundImageAlign,
28
+ content,
29
+ cardStyle
30
+ } = _ref;
31
+ const borderRadius = cardStyle?.borderRadius || 0;
32
+ const borderWidth = cardStyle?.borderWidth || 0;
33
+ const adjustedBorderRadius = Math.max(0, borderRadius - borderWidth);
34
+
35
+ // For contain mode with position and align, use CSS background properties for web
36
+ if (backgroundImageResizeMode === 'contain' && backgroundImagePosition && backgroundImageAlign) {
37
+ const positionKey = `${backgroundImagePosition}-${backgroundImageAlign}`;
38
+ if (_Platform.default.OS === 'web') {
39
+ // Create background position based on position and align
40
+ let backgroundPosition;
41
+ switch (positionKey) {
42
+ case 'top-start':
43
+ backgroundPosition = 'left top';
44
+ break;
45
+ case 'top-center':
46
+ backgroundPosition = 'center top';
47
+ break;
48
+ case 'top-end':
49
+ backgroundPosition = 'right top';
50
+ break;
51
+ case 'bottom-start':
52
+ backgroundPosition = 'left bottom';
53
+ break;
54
+ case 'bottom-center':
55
+ backgroundPosition = 'center bottom';
56
+ break;
57
+ case 'bottom-end':
58
+ backgroundPosition = 'right bottom';
59
+ break;
60
+ case 'left-center':
61
+ backgroundPosition = 'left center';
62
+ break;
63
+ case 'right-center':
64
+ backgroundPosition = 'right center';
65
+ break;
66
+ default:
67
+ backgroundPosition = 'center center';
68
+ }
69
+ const backgroundImageStyle = {
70
+ backgroundImage: `url(${src})`,
71
+ backgroundSize: 'contain',
72
+ backgroundRepeat: 'no-repeat',
73
+ backgroundPosition,
74
+ borderRadius: adjustedBorderRadius
75
+ };
76
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
77
+ style: [staticStyles.imageBackground, backgroundImageStyle],
78
+ role: "img",
79
+ "aria-label": alt,
80
+ children: content
81
+ });
82
+ }
83
+ // For React Native, apply positioning styles with full dimensions
84
+ const positionStyles = _backgroundImageStylesMap.default[positionKey] || {};
85
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
86
+ style: [staticStyles.containContainer, {
87
+ borderRadius: adjustedBorderRadius
88
+ }],
89
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Image.default, {
90
+ source: src,
91
+ resizeMode: backgroundImageResizeMode,
92
+ style: [staticStyles.containImage, positionStyles],
93
+ accessible: true,
94
+ accessibilityLabel: alt,
95
+ accessibilityIgnoresInvertColors: true
96
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
97
+ style: staticStyles.contentOverlay,
98
+ children: content
99
+ })]
100
+ });
101
+ }
102
+
103
+ // Use ImageBackground for all other resize modes and React Native
104
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImageBackground.default, {
105
+ source: src,
106
+ imageStyle: {
107
+ borderRadius: adjustedBorderRadius
108
+ },
109
+ resizeMode: backgroundImageResizeMode,
110
+ style: staticStyles.imageBackground,
111
+ accessible: true,
112
+ accessibilityLabel: alt,
113
+ children: content
114
+ });
115
+ };
19
116
 
20
117
  // Ensure explicit selection of tokens
21
- const selectStyles = _ref => {
118
+ const selectStyles = _ref2 => {
22
119
  let {
23
120
  flex,
24
121
  backgroundColor,
@@ -35,7 +132,7 @@ const selectStyles = _ref => {
35
132
  gradient,
36
133
  maxHeight,
37
134
  overflowY
38
- } = _ref;
135
+ } = _ref2;
39
136
  return {
40
137
  flex,
41
138
  backgroundColor,
@@ -68,46 +165,98 @@ const selectStyles = _ref => {
68
165
  * A themeless base component for Card which components can apply theme tokens to. Not
69
166
  * intended to be used in apps or sites directly: build themed components on top of this.
70
167
  */
71
- const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
168
+ exports.selectStyles = selectStyles;
169
+ const CardBase = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
72
170
  let {
73
171
  children,
74
172
  tokens,
75
173
  dataSet,
76
174
  backgroundImage,
77
175
  ...rest
78
- } = _ref2;
176
+ } = _ref3;
79
177
  const cardStyle = selectStyles(typeof tokens === 'function' ? tokens() : tokens);
80
178
  const props = selectProps(rest);
179
+ let content = children;
81
180
  const {
82
181
  src = '',
83
182
  alt = '',
84
- resizeMode = ''
183
+ resizeMode = '',
184
+ position = '',
185
+ align = ''
85
186
  } = backgroundImage || {};
86
187
  const backgroundImageResizeMode = (0, _utils.useResponsiveProp)(resizeMode, 'cover');
188
+ const backgroundImagePosition = (0, _utils.useResponsiveProp)(position);
189
+ const backgroundImageAlign = (0, _utils.useResponsiveProp)(align);
87
190
  const imageSourceViewport = (0, _utils.formatImageSource)((0, _utils.useResponsiveProp)(src));
191
+ 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
+ const {
195
+ paddingTop,
196
+ paddingBottom,
197
+ paddingLeft,
198
+ paddingRight,
199
+ ...containerStyle
200
+ } = cardStyle;
201
+
202
+ // Only create padding wrapper if there's actually padding defined
203
+ const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
204
+ const paddedContent = hasPadding ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
205
+ style: {
206
+ paddingTop,
207
+ paddingBottom,
208
+ paddingLeft,
209
+ paddingRight
210
+ },
211
+ children: children
212
+ }) : children;
213
+ content = setBackgroundImage({
214
+ src: imageSourceViewport,
215
+ alt,
216
+ backgroundImageResizeMode,
217
+ backgroundImagePosition,
218
+ backgroundImageAlign,
219
+ content: paddedContent,
220
+ cardStyle: containerStyle
221
+ });
222
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
223
+ style: containerStyle,
224
+ dataSet: dataSet,
225
+ ref: ref,
226
+ ...props,
227
+ children: content
228
+ });
229
+ }
88
230
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
89
231
  style: cardStyle,
90
232
  dataSet: dataSet,
91
233
  ref: ref,
92
234
  ...props,
93
- children: src ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImageBackground.default, {
94
- source: imageSourceViewport,
95
- imageStyle: {
96
- borderRadius: cardStyle?.borderRadius - cardStyle?.borderWidth
97
- },
98
- resizeMode: backgroundImageResizeMode,
99
- style: styles.imageBackground,
100
- accessible: true,
101
- accessibilityLabel: alt,
102
- children: children
103
- }) : children
235
+ children: content
104
236
  });
105
237
  });
106
238
  CardBase.displayName = 'CardBase';
107
- const styles = _StyleSheet.default.create({
239
+ const staticStyles = _StyleSheet.default.create({
108
240
  imageBackground: {
109
241
  width: '100%',
110
242
  height: '100%'
243
+ },
244
+ contentOverlay: {
245
+ position: 'relative',
246
+ width: '100%',
247
+ height: '100%',
248
+ zIndex: 1
249
+ },
250
+ containContainer: {
251
+ width: '100%',
252
+ height: '100%',
253
+ overflow: 'hidden',
254
+ position: 'relative'
255
+ },
256
+ containImage: {
257
+ position: 'absolute',
258
+ width: '100%',
259
+ height: '100%'
111
260
  }
112
261
  });
113
262
  CardBase.propTypes = {
@@ -122,7 +271,9 @@ CardBase.propTypes = {
122
271
  // src is an object when used responsively to provide different image sources for different screen sizes
123
272
  src: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object]).isRequired,
124
273
  alt: _propTypes.default.string,
125
- resizeMode: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']))
274
+ resizeMode: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])),
275
+ position: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['bottom', 'left', 'right', 'top'])),
276
+ align: _utils.responsiveProps.getTypeOptionallyByViewport(_propTypes.default.oneOf(['start', 'end', 'center', 'stretch']))
126
277
  })
127
278
  };
128
279
  var _default = exports.default = CardBase;
@@ -39,6 +39,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
39
39
  href,
40
40
  hrefAttrs,
41
41
  dataSet,
42
+ backgroundImage,
42
43
  accessibilityRole = href ? 'link' : undefined,
43
44
  ...rawRest
44
45
  } = _ref;
@@ -133,10 +134,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
133
134
  setFocused(false);
134
135
  setPressed(false);
135
136
  },
136
- style: {
137
- ...staticStyles.container,
138
- textDecoration: 'none'
139
- },
137
+ style: staticStyles.linkContainer,
140
138
  ...(hrefAttrs || {}),
141
139
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardBase.default, {
142
140
  tokens: getCardTokens({
@@ -144,6 +142,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
144
142
  focused,
145
143
  hovered
146
144
  }),
145
+ backgroundImage: backgroundImage,
147
146
  children: typeof children === 'function' ? children(getCardState({
148
147
  pressed,
149
148
  focused,
@@ -167,6 +166,7 @@ const PressableCardBase = /*#__PURE__*/_react.default.forwardRef((_ref, ref) =>
167
166
  }),
168
167
  children: pressableState => /*#__PURE__*/(0, _jsxRuntime.jsx)(_CardBase.default, {
169
168
  tokens: getCardTokens(pressableState),
169
+ backgroundImage: backgroundImage,
170
170
  children: typeof children === 'function' ? children(getCardState(pressableState)) : children
171
171
  })
172
172
  });
@@ -175,6 +175,11 @@ const staticStyles = _StyleSheet.default.create({
175
175
  container: {
176
176
  flex: 1,
177
177
  display: 'flex'
178
+ },
179
+ linkContainer: {
180
+ flex: 1,
181
+ display: 'flex',
182
+ textDecoration: 'none'
178
183
  }
179
184
  });
180
185
  PressableCardBase.displayName = 'PressableCardBase';
@@ -185,6 +190,15 @@ PressableCardBase.propTypes = {
185
190
  partial: true,
186
191
  allowFunction: true
187
192
  }),
188
- variant: _utils.variantProp.propType
193
+ variant: _utils.variantProp.propType,
194
+ backgroundImage: _propTypes.default.shape({
195
+ // The image src is either a URI string or a number (when a local image src is bundled in IOS or Android app)
196
+ // src is an object when used responsively to provide different image sources for different screen sizes
197
+ src: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object]).isRequired,
198
+ alt: _propTypes.default.string,
199
+ resizeMode: _propTypes.default.oneOfType([_propTypes.default.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']), _propTypes.default.object]),
200
+ position: _propTypes.default.oneOfType([_propTypes.default.oneOf(['bottom', 'left', 'right', 'top']), _propTypes.default.object]),
201
+ align: _propTypes.default.oneOfType([_propTypes.default.oneOf(['start', 'end', 'center', 'stretch']), _propTypes.default.object])
202
+ })
189
203
  };
190
204
  var _default = exports.default = (0, _utils.withLinkRouter)(PressableCardBase);