@telus-uds/components-base 3.13.0 → 3.14.1

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 (36) hide show
  1. package/CHANGELOG.md +10 -2
  2. package/lib/cjs/BaseProvider/index.js +4 -1
  3. package/lib/cjs/Card/Card.js +23 -4
  4. package/lib/cjs/Card/CardBase.js +170 -19
  5. package/lib/cjs/Card/PressableCardBase.js +19 -5
  6. package/lib/cjs/Card/backgroundImageStylesMap.js +197 -0
  7. package/lib/cjs/FlexGrid/FlexGrid.js +28 -12
  8. package/lib/cjs/Tabs/Tabs.js +34 -2
  9. package/lib/cjs/Tabs/TabsDropdown.js +252 -0
  10. package/lib/cjs/Tabs/TabsItem.js +4 -2
  11. package/lib/cjs/Tabs/dictionary.js +14 -0
  12. package/lib/cjs/ViewportProvider/ViewportProvider.js +9 -3
  13. package/lib/esm/BaseProvider/index.js +4 -1
  14. package/lib/esm/Card/Card.js +21 -4
  15. package/lib/esm/Card/CardBase.js +169 -19
  16. package/lib/esm/Card/PressableCardBase.js +19 -5
  17. package/lib/esm/Card/backgroundImageStylesMap.js +190 -0
  18. package/lib/esm/FlexGrid/FlexGrid.js +28 -12
  19. package/lib/esm/Tabs/Tabs.js +35 -3
  20. package/lib/esm/Tabs/TabsDropdown.js +245 -0
  21. package/lib/esm/Tabs/TabsItem.js +4 -2
  22. package/lib/esm/Tabs/dictionary.js +8 -0
  23. package/lib/esm/ViewportProvider/ViewportProvider.js +9 -3
  24. package/lib/package.json +2 -2
  25. package/package.json +2 -2
  26. package/src/BaseProvider/index.jsx +4 -2
  27. package/src/Card/Card.jsx +27 -3
  28. package/src/Card/CardBase.jsx +165 -19
  29. package/src/Card/PressableCardBase.jsx +31 -4
  30. package/src/Card/backgroundImageStylesMap.js +41 -0
  31. package/src/FlexGrid/FlexGrid.jsx +30 -13
  32. package/src/Tabs/Tabs.jsx +36 -2
  33. package/src/Tabs/TabsDropdown.jsx +265 -0
  34. package/src/Tabs/TabsItem.jsx +4 -2
  35. package/src/Tabs/dictionary.js +8 -0
  36. package/src/ViewportProvider/ViewportProvider.jsx +8 -3
@@ -24,17 +24,14 @@ const CONTENT_FULL_WIDTH = 'full';
24
24
  * Resolves the maximum width for content based on the provided value and responsive width.
25
25
  *
26
26
  * @param {number|string|null|undefined} contentMinWidthValue - The minimum width value for the content.
27
- * Can be a number (pixels), a string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
28
- * @param {number|string} responsiveWidth - The responsive width to use when contentMinWidthValue is CONTENT_MAX_WIDTH.
29
- * @returns {number|string|null} The resolved maximum width value, which can be a number, a string (e.g., '100%'), or null.
27
+ * Can be a number, a special string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
28
+ * @param {number} responsiveWidth - The responsive width to use when contentMinWidthValue is CONTENT_MAX_WIDTH.
29
+ * @returns {number|string|null} The resolved maximum width value, or null if full width is desired.
30
30
  */
31
31
  const resolveContentMaxWidth = (contentMinWidthValue, responsiveWidth) => {
32
- if (!contentMinWidthValue) {
32
+ if (!contentMinWidthValue || contentMinWidthValue === CONTENT_FULL_WIDTH) {
33
33
  return null;
34
34
  }
35
- if (contentMinWidthValue === CONTENT_FULL_WIDTH) {
36
- return '100%';
37
- }
38
35
  if (Number.isFinite(contentMinWidthValue)) {
39
36
  return contentMinWidthValue;
40
37
  }
@@ -44,6 +41,25 @@ const resolveContentMaxWidth = (contentMinWidthValue, responsiveWidth) => {
44
41
  return contentMinWidthValue;
45
42
  };
46
43
 
44
+ /**
45
+ * Calculates the maximum width for a given viewport based on limitWidth and contentMinWidth settings.
46
+ *
47
+ * @param {string} viewportKey - The viewport key ('xs', 'sm', 'md', 'lg', 'xl')
48
+ * @param {boolean} limitWidth - Whether to limit the width to viewport breakpoints
49
+ * @param {any} contentMinWidth - The contentMinWidth prop value
50
+ * @param {number|string|null} maxWidth - The resolved max width value
51
+ * @returns {number|string|null} The calculated maximum width for the viewport
52
+ */
53
+ const getMaxWidthForViewport = (viewportKey, limitWidth, contentMinWidth, maxWidth) => {
54
+ if (limitWidth) {
55
+ return _systemConstants.viewports.map.get(viewportKey === 'xs' ? 'sm' : viewportKey);
56
+ }
57
+ if (contentMinWidth) {
58
+ return maxWidth;
59
+ }
60
+ return viewportKey === 'xl' ? _systemConstants.viewports.map.get('xl') : null;
61
+ };
62
+
47
63
  /**
48
64
  * A mobile-first flexbox grid.
49
65
  */
@@ -80,23 +96,23 @@ const FlexGrid = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
80
96
  const maxWidth = resolveContentMaxWidth(contentMinWidthValue, responsiveWidth);
81
97
  const stylesByViewport = {
82
98
  xs: {
83
- maxWidth: limitWidth ? _systemConstants.viewports.map.get('sm') : maxWidth,
99
+ maxWidth: getMaxWidthForViewport('xs', limitWidth, contentMinWidth, maxWidth),
84
100
  flexDirection: reverseLevel[0] ? 'column-reverse' : 'column'
85
101
  },
86
102
  sm: {
87
- maxWidth: limitWidth ? _systemConstants.viewports.map.get('sm') : maxWidth,
103
+ maxWidth: getMaxWidthForViewport('sm', limitWidth, contentMinWidth, maxWidth),
88
104
  flexDirection: reverseLevel[1] ? 'column-reverse' : 'column'
89
105
  },
90
106
  md: {
91
- maxWidth: limitWidth ? _systemConstants.viewports.map.get('md') : maxWidth,
107
+ maxWidth: getMaxWidthForViewport('md', limitWidth, contentMinWidth, maxWidth),
92
108
  flexDirection: reverseLevel[2] ? 'column-reverse' : 'column'
93
109
  },
94
110
  lg: {
95
- maxWidth: limitWidth ? _systemConstants.viewports.map.get('lg') : maxWidth,
111
+ maxWidth: getMaxWidthForViewport('lg', limitWidth, contentMinWidth, maxWidth),
96
112
  flexDirection: reverseLevel[3] ? 'column-reverse' : 'column'
97
113
  },
98
114
  xl: {
99
- maxWidth: limitWidth ? _systemConstants.viewports.map.get('xl') : maxWidth,
115
+ maxWidth: getMaxWidthForViewport('xl', limitWidth, contentMinWidth, maxWidth),
100
116
  flexDirection: reverseLevel[4] ? 'column-reverse' : 'column'
101
117
  }
102
118
  };
@@ -13,6 +13,7 @@ var _StackView = _interopRequireDefault(require("../StackView"));
13
13
  var _utils = require("../utils");
14
14
  var _HorizontalScroll = _interopRequireWildcard(require("../HorizontalScroll"));
15
15
  var _TabsItem = _interopRequireDefault(require("./TabsItem"));
16
+ var _TabsDropdown = _interopRequireDefault(require("./TabsDropdown"));
16
17
  var _jsxRuntime = require("react/jsx-runtime");
17
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); }
18
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; }
@@ -48,6 +49,12 @@ const getStackViewTokens = variant => {
48
49
  * Tabs renders a horizontally-scrolling menu of selectable buttons which may link
49
50
  * to a page or control what content is displayed on this page.
50
51
  *
52
+ * By default, Tabs always renders as horizontal scrolling tabs regardless of viewport.
53
+ * To enable dropdown mode, you must explicitly pass `variant={{ dropdown: true }}`.
54
+ * When dropdown is enabled, it will only render as a dropdown on mobile and tablet
55
+ * viewports (XS and SM). On larger viewports (MD, LG, XL), it will still render as
56
+ * horizontal tabs even with dropdown enabled.
57
+ *
51
58
  * If you are using Tabs to navigate to a new page (web-only) you should pass
52
59
  * `navigation`as the `accessibilityRole` to te Tabs component, this will cause
53
60
  * TabItems to default to a role of link and obtain aria-current behaviour.
@@ -93,6 +100,31 @@ const Tabs = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
93
100
  const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist';
94
101
  const defaultTabItemAccessibiltyRole = getDefaultTabItemAccessibilityRole(parentAccessibilityRole);
95
102
  const stackViewTokens = getStackViewTokens(variant);
103
+
104
+ // Render dropdown only if explicitly requested via variant AND viewport is xs or sm
105
+ const isSmallViewport = (0, _utils.useResponsiveProp)({
106
+ xs: true,
107
+ sm: true,
108
+ md: false,
109
+ lg: false,
110
+ xl: false
111
+ }, false);
112
+ const shouldRenderDropdown = variant?.dropdown === true && isSmallViewport;
113
+ if (shouldRenderDropdown) {
114
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabsDropdown.default, {
115
+ ref: ref,
116
+ tokens: tokens,
117
+ itemTokens: itemTokens,
118
+ variant: variant,
119
+ value: currentValue,
120
+ onChange: setValue,
121
+ items: items,
122
+ LinkRouter: LinkRouter,
123
+ linkRouterProps: linkRouterProps,
124
+ accessibilityRole: parentAccessibilityRole === 'tablist' ? 'button' : parentAccessibilityRole,
125
+ ...restProps
126
+ });
127
+ }
96
128
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_HorizontalScroll.default, {
97
129
  ref: ref,
98
130
  ScrollButton: _HorizontalScroll.HorizontalScrollButton,
@@ -152,13 +184,13 @@ const Tabs = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
152
184
  Tabs.displayName = 'Tabs';
153
185
  Tabs.propTypes = {
154
186
  ...selectedSystemPropTypes,
155
- ..._utils.withLinkRouter.PropTypes,
187
+ ..._utils.withLinkRouter.propTypes,
156
188
  /**
157
189
  * Array of `TabsItem`s
158
190
  */
159
191
  items: _propTypes.default.arrayOf(_propTypes.default.shape({
160
192
  ...selectedItemPropTypes,
161
- ..._utils.withLinkRouter.PropTypes,
193
+ ..._utils.withLinkRouter.propTypes,
162
194
  href: _propTypes.default.string,
163
195
  label: _propTypes.default.string,
164
196
  id: _propTypes.default.string,
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _Pressable = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Pressable"));
10
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
11
+ var _Text = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Text"));
12
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
13
+ var _ThemeProvider = require("../ThemeProvider");
14
+ var _utils = require("../utils");
15
+ var _ViewportProvider = require("../ViewportProvider");
16
+ var _Icon = _interopRequireDefault(require("../Icon"));
17
+ var _Listbox = _interopRequireDefault(require("../Listbox"));
18
+ var _dictionary = _interopRequireDefault(require("./dictionary"));
19
+ var _jsxRuntime = require("react/jsx-runtime");
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
22
+ const selectButtonContentStyles = _ref => {
23
+ let {
24
+ backgroundColor,
25
+ borderColor,
26
+ borderWidth,
27
+ borderRadius,
28
+ paddingHorizontal,
29
+ paddingVertical,
30
+ marginHorizontal,
31
+ marginVertical
32
+ } = _ref;
33
+ return {
34
+ backgroundColor,
35
+ borderColor,
36
+ borderWidth,
37
+ borderRadius,
38
+ paddingHorizontal,
39
+ paddingVertical,
40
+ marginLeft: marginHorizontal,
41
+ marginRight: marginHorizontal,
42
+ marginTop: marginVertical,
43
+ marginBottom: marginVertical
44
+ };
45
+ };
46
+
47
+ /**
48
+ * TabsDropdown renders a dropdown version of tabs for mobile/tablet viewports.
49
+ * It shows the currently selected tab as a button that opens a dropdown menu
50
+ * containing all available tabs.
51
+ *
52
+ * This is rendered automatically by `Tabs` on mobile viewports and when variant
53
+ * is dropdown and isn't intended to be used directly.
54
+ */
55
+ const TabsDropdown = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
56
+ let {
57
+ itemTokens,
58
+ variant,
59
+ value,
60
+ onChange,
61
+ items = [],
62
+ LinkRouter,
63
+ linkRouterProps,
64
+ accessibilityRole = 'button',
65
+ copy = 'en',
66
+ dictionary: customDictionary = _dictionary.default,
67
+ ...rest
68
+ } = _ref2;
69
+ const {
70
+ themeOptions
71
+ } = (0, _ThemeProvider.useTheme)();
72
+ const viewport = (0, _ViewportProvider.useViewport)();
73
+ const [isOpen, setIsOpen] = _react.default.useState(false);
74
+ const getTokens = (0, _ThemeProvider.useThemeTokensCallback)('TabsItem', itemTokens, {
75
+ viewport,
76
+ ...variant
77
+ });
78
+ const selectedItem = items.find(item => {
79
+ const itemId = item.id ?? item.label;
80
+ return value === itemId;
81
+ }) || items[0];
82
+ const {
83
+ overlaidPosition,
84
+ sourceRef,
85
+ targetRef,
86
+ onTargetLayout,
87
+ isReady
88
+ } = (0, _utils.useOverlaidPosition)({
89
+ isShown: isOpen,
90
+ offsets: {
91
+ vertical: 4
92
+ },
93
+ align: {
94
+ top: 'bottom',
95
+ left: 'left'
96
+ }
97
+ });
98
+ const handleToggle = () => setIsOpen(prev => !prev);
99
+ const handleClose = () => setIsOpen(false);
100
+ const handleItemSelect = (item, event) => {
101
+ const itemId = item.id ?? item.label;
102
+ setIsOpen(false);
103
+ if (onChange) onChange(itemId, event);
104
+ if (item.onPress) item.onPress(event);
105
+ };
106
+ const listboxItems = items.map(item => ({
107
+ ...item,
108
+ onPress: event => handleItemSelect(item, event)
109
+ }));
110
+ const isSelected = Boolean(selectedItem && value);
111
+ const getCopy = (0, _utils.useCopy)({
112
+ dictionary: customDictionary,
113
+ copy
114
+ });
115
+ const selectedProps = selectProps({
116
+ accessibilityRole,
117
+ ...rest
118
+ });
119
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
120
+ ref: ref,
121
+ style: styles.container,
122
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Pressable.default, {
123
+ ref: sourceRef,
124
+ onPress: handleToggle,
125
+ ...selectedProps,
126
+ style: styles.pressable,
127
+ children: pressableState => {
128
+ // Use resolvePressableTokens like TabBarItem does for proper state handling
129
+ const resolvedTokens = (0, _utils.resolvePressableTokens)(getTokens, pressableState, {
130
+ viewport,
131
+ expanded: isOpen,
132
+ selected: isSelected
133
+ });
134
+ const textStyles = (0, _ThemeProvider.applyTextStyles)({
135
+ ...(0, _utils.selectTokens)('Typography', resolvedTokens),
136
+ themeOptions
137
+ });
138
+
139
+ // Get dropdown icons from resolved tokens
140
+ const dropdownIcon = isOpen ? resolvedTokens.dropdownIconExpanded : resolvedTokens.dropdownIcon;
141
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
142
+ style: [styles.buttonContent, selectButtonContentStyles(resolvedTokens)],
143
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
144
+ style: textStyles,
145
+ children: selectedItem?.label || getCopy('selectTab')
146
+ }), dropdownIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
147
+ icon: dropdownIcon,
148
+ variant: {
149
+ size: 'micro'
150
+ },
151
+ tokens: {
152
+ color: textStyles.color
153
+ }
154
+ })]
155
+ });
156
+ }
157
+ }), isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Listbox.default.Overlay, {
158
+ overlaidPosition: overlaidPosition,
159
+ maxWidth: 400,
160
+ minWidth: 200,
161
+ isReady: isReady,
162
+ onLayout: onTargetLayout,
163
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Listbox.default, {
164
+ items: listboxItems,
165
+ firstItemRef: targetRef,
166
+ parentRef: sourceRef,
167
+ selectedId: value,
168
+ onClose: handleClose,
169
+ LinkRouter: LinkRouter,
170
+ linkRouterProps: linkRouterProps
171
+ })
172
+ })]
173
+ });
174
+ });
175
+ TabsDropdown.displayName = 'TabsDropdown';
176
+ const dictionaryContentShape = _propTypes.default.shape({
177
+ selectTab: _propTypes.default.string.isRequired
178
+ });
179
+ TabsDropdown.propTypes = {
180
+ ...selectedSystemPropTypes,
181
+ ..._utils.withLinkRouter.propTypes,
182
+ /**
183
+ * Array of tab items
184
+ */
185
+ items: _propTypes.default.arrayOf(_propTypes.default.shape({
186
+ ..._utils.withLinkRouter.propTypes,
187
+ /** URL to navigate to when the tab is pressed */
188
+ href: _propTypes.default.string,
189
+ /** Display text for the tab */
190
+ label: _propTypes.default.string,
191
+ /** Unique identifier for the tab */
192
+ id: _propTypes.default.string,
193
+ /** Reference to the tab element */
194
+ ref: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object]),
195
+ /** Custom render function for the tab content */
196
+ render: _propTypes.default.func
197
+ })),
198
+ /**
199
+ * Current selected tab id
200
+ */
201
+ value: _propTypes.default.string,
202
+ /**
203
+ * Callback for when the selected tab changes
204
+ */
205
+ onChange: _propTypes.default.func,
206
+ /**
207
+ * Custom tokens for the main Tabs container
208
+ */
209
+ tokens: (0, _utils.getTokensPropType)('Tabs'),
210
+ /**
211
+ * Custom tokens for `TabsItem`
212
+ */
213
+ itemTokens: (0, _utils.getTokensPropType)('TabsItem'),
214
+ /**
215
+ * Visual and behavioral variants for the tabs dropdown
216
+ */
217
+ variant: _utils.variantProp.propType,
218
+ /**
219
+ * Select English or French copy for the accessible labels.
220
+ * You may also pass in a custom dictionary object.
221
+ */
222
+ copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), dictionaryContentShape]),
223
+ /**
224
+ * Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
225
+ */
226
+ dictionary: _propTypes.default.shape({
227
+ en: dictionaryContentShape,
228
+ fr: dictionaryContentShape
229
+ })
230
+ };
231
+ const styles = _StyleSheet.default.create({
232
+ container: {
233
+ position: 'relative',
234
+ width: '100%'
235
+ },
236
+ pressable: {
237
+ outlineWidth: 0,
238
+ outlineStyle: 'none',
239
+ outlineColor: 'transparent'
240
+ },
241
+ buttonContent: {
242
+ display: 'flex',
243
+ flexDirection: 'row',
244
+ alignItems: 'center',
245
+ justifyContent: 'space-between',
246
+ width: '100%',
247
+ minHeight: 44,
248
+ outline: 'none',
249
+ boxSizing: 'border-box'
250
+ }
251
+ });
252
+ var _default = exports.default = TabsDropdown;
@@ -79,8 +79,10 @@ const selectContainerStyles = _ref3 => {
79
79
  borderRadius,
80
80
  paddingHorizontal: paddingHorizontal - borderWidth,
81
81
  paddingVertical: paddingVertical - borderWidth,
82
- marginHorizontal,
83
- marginVertical
82
+ marginLeft: marginHorizontal,
83
+ marginRight: marginHorizontal,
84
+ marginTop: marginVertical,
85
+ marginBottom: marginVertical
84
86
  };
85
87
  };
86
88
 
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = exports.default = {
8
+ en: {
9
+ selectTab: 'Select tab'
10
+ },
11
+ fr: {
12
+ selectTab: 'Sélectionner un onglet'
13
+ }
14
+ };
@@ -13,13 +13,18 @@ var _jsxRuntime = require("react/jsx-runtime");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  /**
15
15
  * Provides an up-to-date viewport value from system-constants, available via the `useViewport` hook
16
+ *
17
+ * @param {React.ReactNode} children - Child components that will have access to viewport context
18
+ * @param {string} [defaultViewport] - Default viewport to use during server-side rendering.
19
+ * Must be one of the viewport keys from system-constants. If not provided, defaults to the smallest viewport.
16
20
  */const ViewportProvider = _ref => {
17
21
  let {
18
- children
22
+ children,
23
+ defaultViewport
19
24
  } = _ref;
20
25
  // Default to the smallest viewport for mobile-first SSR. On client side, this is updated
21
26
  // by useViewportListener in a layout effect before anything is shown to the user.
22
- const [viewport, setViewport] = _react.default.useState(_systemConstants.viewports.keys[0]);
27
+ const [viewport, setViewport] = _react.default.useState(defaultViewport || _systemConstants.viewports.keys[0]);
23
28
  (0, _useViewportListener.default)(setViewport);
24
29
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_useViewport.ViewportContext.Provider, {
25
30
  value: viewport,
@@ -27,6 +32,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
27
32
  });
28
33
  };
29
34
  ViewportProvider.propTypes = {
30
- children: _propTypes.default.node.isRequired
35
+ children: _propTypes.default.node.isRequired,
36
+ defaultViewport: _propTypes.default.oneOf(_systemConstants.viewports.keys)
31
37
  };
32
38
  var _default = exports.default = ViewportProvider;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { PortalProvider } from '@gorhom/portal';
4
+ import { viewports } from '@telus-uds/system-constants';
4
5
  import A11yInfoProvider from '../A11yInfoProvider';
5
6
  import ViewportProvider from '../ViewportProvider';
6
7
  import ThemeProvider from '../ThemeProvider';
@@ -17,6 +18,7 @@ const BaseProvider = /*#__PURE__*/React.forwardRef((_ref, _) => {
17
18
  return /*#__PURE__*/_jsx(HydrationProvider, {
18
19
  children: /*#__PURE__*/_jsx(A11yInfoProvider, {
19
20
  children: /*#__PURE__*/_jsx(ViewportProvider, {
21
+ defaultViewport: themeOptions?.defaultViewport,
20
22
  children: /*#__PURE__*/_jsx(ThemeProvider, {
21
23
  defaultTheme: defaultTheme,
22
24
  themeOptions: themeOptions,
@@ -34,7 +36,8 @@ BaseProvider.propTypes = {
34
36
  defaultTheme: ThemeProvider.propTypes?.defaultTheme,
35
37
  themeOptions: PropTypes.shape({
36
38
  forceAbsoluteFontSizing: PropTypes.bool,
37
- forceZIndex: PropTypes.bool
39
+ forceZIndex: PropTypes.bool,
40
+ defaultViewport: PropTypes.oneOf(viewports.keys)
38
41
  })
39
42
  };
40
43
  export default BaseProvider;
@@ -5,7 +5,7 @@ import { useThemeTokens, useThemeTokensCallback, useResponsiveThemeTokens, useTh
5
5
  import { getTokensPropType, variantProp, StyleSheet, createMediaQueryStyles } from '../utils';
6
6
  import { useViewport } from '../ViewportProvider';
7
7
  import { a11yProps, linkProps, selectSystemProps, viewProps, responsiveProps, hrefAttrsProp } from '../utils/props';
8
- import CardBase from './CardBase';
8
+ import CardBase, { selectStyles } from './CardBase';
9
9
  import PressableCardBase from './PressableCardBase';
10
10
  import CheckboxButton from '../Checkbox/CheckboxButton';
11
11
  import RadioButton from '../Radio/RadioButton';
@@ -182,12 +182,27 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
182
182
  let cardStyles;
183
183
  let mediaIds;
184
184
  if (enableMediaQueryStyleSheet) {
185
- const mediaQueryStyleSheet = createMediaQueryStyles(themeTokens);
185
+ const transformedThemeTokens = Object.entries(themeTokens).reduce((acc, _ref4) => {
186
+ let [vp, viewportTokens] = _ref4;
187
+ const tokensToTransform = selectionType ? selectStyles({
188
+ ...viewportTokens,
189
+ paddingTop: 0,
190
+ paddingBottom: 0,
191
+ paddingLeft: 0,
192
+ paddingRight: 0
193
+ }) : selectStyles(viewportTokens);
194
+ acc[vp] = tokensToTransform;
195
+ return acc;
196
+ }, {});
197
+ const mediaQueryStyleSheet = createMediaQueryStyles(transformedThemeTokens);
186
198
  const {
187
199
  ids,
188
200
  styles
189
201
  } = StyleSheet.create({
190
- card: mediaQueryStyleSheet
202
+ card: {
203
+ ...themeTokens[viewport],
204
+ ...mediaQueryStyleSheet
205
+ }
191
206
  });
192
207
  cardStyles = styles.card;
193
208
  mediaIds = ids.card;
@@ -321,7 +336,9 @@ Card.propTypes = {
321
336
  // src is an object when used responsively to provide different image sources for different screen sizes
322
337
  src: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]).isRequired,
323
338
  alt: PropTypes.string,
324
- resizeMode: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']))
339
+ resizeMode: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])),
340
+ position: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['bottom', 'left', 'right', 'top'])),
341
+ align: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['start', 'end', 'center', 'stretch']))
325
342
  }),
326
343
  /**
327
344
  * Data set for the card.