@telus-uds/components-base 3.26.0 → 3.28.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 +35 -2
- package/lib/cjs/Card/Card.js +34 -13
- package/lib/cjs/Card/CardBase.js +90 -14
- package/lib/cjs/Card/PressableCardBase.js +147 -8
- package/lib/cjs/Carousel/Carousel.js +105 -50
- package/lib/cjs/Carousel/CarouselContext.js +10 -4
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +11 -7
- package/lib/cjs/Carousel/Constants.js +11 -2
- package/lib/cjs/Checkbox/Checkbox.js +43 -13
- package/lib/cjs/ExpandCollapse/Control.js +5 -1
- package/lib/cjs/ExpandCollapse/ExpandCollapse.js +17 -8
- package/lib/cjs/ExpandCollapse/Panel.js +7 -2
- package/lib/cjs/IconButton/IconButton.js +10 -5
- package/lib/cjs/List/List.js +24 -9
- package/lib/cjs/List/ListItem.js +18 -1
- package/lib/cjs/List/ListItemBase.js +27 -8
- package/lib/cjs/List/ListItemMark.js +33 -62
- package/lib/cjs/List/PressableListItemBase.js +1 -0
- package/lib/cjs/Modal/Modal.js +21 -11
- package/lib/cjs/Progress/Progress.js +19 -5
- package/lib/cjs/Progress/ProgressBar.js +22 -4
- package/lib/cjs/Progress/ProgressContext.js +11 -0
- package/lib/cjs/SideNav/Item.js +3 -3
- package/lib/cjs/SideNav/ItemsGroup.js +46 -19
- package/lib/cjs/SideNav/SideNav.js +29 -13
- package/lib/esm/Card/Card.js +34 -13
- package/lib/esm/Card/CardBase.js +90 -14
- package/lib/esm/Card/PressableCardBase.js +148 -9
- package/lib/esm/Carousel/Carousel.js +106 -51
- package/lib/esm/Carousel/CarouselContext.js +10 -4
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +11 -7
- package/lib/esm/Carousel/Constants.js +10 -1
- package/lib/esm/Checkbox/Checkbox.js +43 -13
- package/lib/esm/ExpandCollapse/Control.js +5 -1
- package/lib/esm/ExpandCollapse/ExpandCollapse.js +17 -8
- package/lib/esm/ExpandCollapse/Panel.js +7 -2
- package/lib/esm/IconButton/IconButton.js +10 -5
- package/lib/esm/List/List.js +24 -9
- package/lib/esm/List/ListItem.js +19 -2
- package/lib/esm/List/ListItemBase.js +27 -8
- package/lib/esm/List/ListItemMark.js +33 -62
- package/lib/esm/List/PressableListItemBase.js +1 -0
- package/lib/esm/Modal/Modal.js +21 -11
- package/lib/esm/Progress/Progress.js +19 -5
- package/lib/esm/Progress/ProgressBar.js +22 -4
- package/lib/esm/Progress/ProgressContext.js +5 -0
- package/lib/esm/SideNav/Item.js +3 -3
- package/lib/esm/SideNav/ItemsGroup.js +45 -20
- package/lib/esm/SideNav/SideNav.js +29 -13
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Card/Card.jsx +29 -7
- package/src/Card/CardBase.jsx +97 -11
- package/src/Card/PressableCardBase.jsx +135 -9
- package/src/Carousel/Carousel.jsx +119 -64
- package/src/Carousel/CarouselContext.jsx +12 -4
- package/src/Carousel/CarouselItem/CarouselItem.jsx +10 -6
- package/src/Carousel/Constants.js +10 -0
- package/src/Checkbox/Checkbox.jsx +29 -7
- package/src/ExpandCollapse/Control.jsx +1 -1
- package/src/ExpandCollapse/ExpandCollapse.jsx +9 -8
- package/src/ExpandCollapse/Panel.jsx +10 -2
- package/src/IconButton/IconButton.jsx +40 -28
- package/src/List/List.jsx +33 -9
- package/src/List/ListItem.jsx +33 -11
- package/src/List/ListItemBase.jsx +33 -9
- package/src/List/ListItemMark.jsx +32 -53
- package/src/List/PressableListItemBase.jsx +1 -0
- package/src/Modal/Modal.jsx +23 -11
- package/src/Progress/Progress.jsx +18 -7
- package/src/Progress/ProgressBar.jsx +19 -14
- package/src/Progress/ProgressContext.js +5 -0
- package/src/SideNav/Item.jsx +3 -3
- package/src/SideNav/ItemsGroup.jsx +36 -16
- package/src/SideNav/SideNav.jsx +22 -8
|
@@ -12,6 +12,19 @@ var _utils = require("../utils");
|
|
|
12
12
|
var _ThemeProvider = require("../ThemeProvider");
|
|
13
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
+
const selectPanelTokens = _ref => {
|
|
16
|
+
let {
|
|
17
|
+
borderWidth,
|
|
18
|
+
borderColor,
|
|
19
|
+
backgroundColor
|
|
20
|
+
} = _ref;
|
|
21
|
+
return {
|
|
22
|
+
contentPanelBackgroundColor: backgroundColor,
|
|
23
|
+
borderBottomWidth: borderWidth,
|
|
24
|
+
borderColor
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
29
|
Expandable content areas for use within `SideNav`.
|
|
17
30
|
|
|
@@ -21,7 +34,8 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
21
34
|
|
|
22
35
|
## Usage Criteria
|
|
23
36
|
- Use `SideNav.ItemsGroup` with large pages that have multiple sections
|
|
24
|
-
*/
|
|
37
|
+
*/
|
|
38
|
+
const ItemsGroup = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
|
|
25
39
|
let {
|
|
26
40
|
children,
|
|
27
41
|
label,
|
|
@@ -32,7 +46,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
32
46
|
tokens,
|
|
33
47
|
itemTokens,
|
|
34
48
|
onToggle
|
|
35
|
-
} =
|
|
49
|
+
} = _ref2;
|
|
36
50
|
// A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
|
|
37
51
|
// plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
|
|
38
52
|
const getAppearance = appearance => ({
|
|
@@ -45,28 +59,27 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
45
59
|
type: 'parent'
|
|
46
60
|
});
|
|
47
61
|
const getGroupTokens = (0, _ThemeProvider.useThemeTokensCallback)('SideNavItemsGroup', tokens, variant);
|
|
48
|
-
const getPanelTokens = appearance => {
|
|
49
|
-
const {
|
|
50
|
-
panelBorderColor,
|
|
51
|
-
...itemsGroupTokens
|
|
52
|
-
} = getGroupTokens(getAppearance(appearance));
|
|
53
|
-
const groupTokens = {
|
|
54
|
-
...itemsGroupTokens,
|
|
55
|
-
borderWidth: 0,
|
|
56
|
-
marginBottom: 0
|
|
57
|
-
};
|
|
58
|
-
return (0, _utils.selectTokens)('ExpandCollapsePanel', groupTokens);
|
|
59
|
-
};
|
|
60
62
|
const getItemTokens = (0, _ThemeProvider.useThemeTokensCallback)('SideNavItem', itemTokens, variant);
|
|
61
|
-
const
|
|
62
|
-
...
|
|
63
|
-
|
|
64
|
-
...
|
|
63
|
+
const getPanelTokens = appearance => (0, _utils.selectTokens)('ExpandCollapsePanel', {
|
|
64
|
+
...staticTokens.panel,
|
|
65
|
+
...getGroupTokens(getAppearance(appearance)),
|
|
66
|
+
...selectPanelTokens(getItemTokens(getItemAppearance(appearance)))
|
|
67
|
+
});
|
|
68
|
+
const getControlTokens = appearance => ({
|
|
69
|
+
...(0, _utils.selectTokens)('ExpandCollapseControl', {
|
|
70
|
+
...getItemTokens(getItemAppearance(appearance)),
|
|
71
|
+
// main style from SideNavItem
|
|
72
|
+
...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc,
|
|
73
|
+
}),
|
|
74
|
+
...staticTokens.control
|
|
65
75
|
});
|
|
66
76
|
const controlContent = controlState => {
|
|
67
77
|
const currentItemTokens = getItemTokens(getItemAppearance(controlState));
|
|
68
78
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ItemContent.default, {
|
|
69
|
-
tokens:
|
|
79
|
+
tokens: {
|
|
80
|
+
...currentItemTokens,
|
|
81
|
+
...staticTokens.content
|
|
82
|
+
},
|
|
70
83
|
children: label
|
|
71
84
|
});
|
|
72
85
|
};
|
|
@@ -82,9 +95,23 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
82
95
|
active: isActive
|
|
83
96
|
} // ExpandCollapse.Panel handles expanded state
|
|
84
97
|
,
|
|
98
|
+
disableMobileScrollBuffer: true,
|
|
85
99
|
children: children
|
|
86
100
|
});
|
|
87
101
|
});
|
|
102
|
+
const staticTokens = {
|
|
103
|
+
panel: {
|
|
104
|
+
borderWidth: 0,
|
|
105
|
+
marginBottom: 0
|
|
106
|
+
},
|
|
107
|
+
control: {
|
|
108
|
+
borderWidth: 0,
|
|
109
|
+
textLine: null
|
|
110
|
+
},
|
|
111
|
+
content: {
|
|
112
|
+
accentWidth: 0
|
|
113
|
+
}
|
|
114
|
+
};
|
|
88
115
|
ItemsGroup.displayName = 'ItemsGroup';
|
|
89
116
|
ItemsGroup.propTypes = {
|
|
90
117
|
/**
|
|
@@ -15,13 +15,28 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
15
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
16
|
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); }
|
|
17
17
|
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
|
-
|
|
18
|
+
const selectContainerTokens = _ref => {
|
|
19
|
+
let {
|
|
20
|
+
borderWidth,
|
|
21
|
+
borderStyle,
|
|
22
|
+
borderColor
|
|
23
|
+
} = _ref;
|
|
19
24
|
return {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
borderTopWidth: borderWidth,
|
|
26
|
+
borderStyle,
|
|
27
|
+
borderColor
|
|
23
28
|
};
|
|
24
|
-
}
|
|
29
|
+
};
|
|
30
|
+
const selectItemTokens = function () {
|
|
31
|
+
let tokens = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
32
|
+
let isLastItem = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
33
|
+
return {
|
|
34
|
+
...tokens,
|
|
35
|
+
...(isLastItem ? {
|
|
36
|
+
borderWidth: 0
|
|
37
|
+
} : {})
|
|
38
|
+
};
|
|
39
|
+
};
|
|
25
40
|
const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
|
|
26
41
|
|
|
27
42
|
/**
|
|
@@ -29,7 +44,7 @@ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_u
|
|
|
29
44
|
- Use in conjunction with a large amount of educational / informational content
|
|
30
45
|
- Allow the user to navigate between options frequently and efficiently
|
|
31
46
|
*/
|
|
32
|
-
const SideNav = /*#__PURE__*/_react.default.forwardRef((
|
|
47
|
+
const SideNav = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
|
|
33
48
|
let {
|
|
34
49
|
children,
|
|
35
50
|
variant = {},
|
|
@@ -38,7 +53,7 @@ const SideNav = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
38
53
|
itemTokens,
|
|
39
54
|
groupTokens,
|
|
40
55
|
...rest
|
|
41
|
-
} =
|
|
56
|
+
} = _ref2;
|
|
42
57
|
const themeTokens = (0, _ThemeProvider.useThemeTokens)('SideNav', tokens, variant);
|
|
43
58
|
const [active, setActive] = _react.default.useState({
|
|
44
59
|
groupId: undefined,
|
|
@@ -56,14 +71,15 @@ const SideNav = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
56
71
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandCollapse.default, {
|
|
57
72
|
ref: ref,
|
|
58
73
|
maxOpen: accordion ? 1 : null,
|
|
59
|
-
|
|
74
|
+
tokens: selectContainerTokens(themeTokens),
|
|
60
75
|
...selectProps(rest),
|
|
61
|
-
children:
|
|
76
|
+
children: _ref3 => {
|
|
62
77
|
let {
|
|
63
78
|
openIds,
|
|
64
79
|
onToggle
|
|
65
|
-
} =
|
|
66
|
-
const renderItem = (item, index, groupId)
|
|
80
|
+
} = _ref3;
|
|
81
|
+
const renderItem = function (item, index, groupId) {
|
|
82
|
+
let isLastItem = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
67
83
|
const {
|
|
68
84
|
itemId = `item-${index}`,
|
|
69
85
|
onPress
|
|
@@ -81,7 +97,7 @@ const SideNav = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
81
97
|
...variant,
|
|
82
98
|
type: 'child'
|
|
83
99
|
} : variant,
|
|
84
|
-
tokens: itemTokens,
|
|
100
|
+
tokens: selectItemTokens(itemTokens, isLastItem),
|
|
85
101
|
isActive: isItemActive(itemId, groupId),
|
|
86
102
|
onPress: handlePress
|
|
87
103
|
});
|
|
@@ -105,7 +121,7 @@ const SideNav = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
|
|
|
105
121
|
openGroups: openIds,
|
|
106
122
|
isActive: isGroupActive,
|
|
107
123
|
onToggle: handleToggle
|
|
108
|
-
}, _react.default.Children.map(child.props.children, (item, itemIndex) => renderItem(item, itemIndex, groupId)));
|
|
124
|
+
}, _react.default.Children.map(child.props.children, (item, itemIndex) => renderItem(item, itemIndex, groupId, itemIndex === child.props.children.length - 1)));
|
|
109
125
|
}
|
|
110
126
|
return null;
|
|
111
127
|
});
|
package/lib/esm/Card/Card.js
CHANGED
|
@@ -16,18 +16,26 @@ const SelectionType = {
|
|
|
16
16
|
Radio: 'radiogroup',
|
|
17
17
|
None: undefined
|
|
18
18
|
};
|
|
19
|
-
const selectInputStyle = _ref => {
|
|
19
|
+
const selectInputStyle = (_ref, _ref2) => {
|
|
20
20
|
let {
|
|
21
21
|
paddingTop,
|
|
22
|
-
paddingRight
|
|
22
|
+
paddingRight,
|
|
23
|
+
paddingLeft
|
|
23
24
|
} = _ref;
|
|
25
|
+
let {
|
|
26
|
+
inputPositionProp
|
|
27
|
+
} = _ref2;
|
|
24
28
|
return {
|
|
25
29
|
position: 'absolute',
|
|
26
30
|
top: paddingTop,
|
|
27
|
-
|
|
31
|
+
...(inputPositionProp === 'left' ? {
|
|
32
|
+
left: paddingLeft
|
|
33
|
+
} : {
|
|
34
|
+
right: paddingRight
|
|
35
|
+
})
|
|
28
36
|
};
|
|
29
37
|
};
|
|
30
|
-
const getInputProps =
|
|
38
|
+
const getInputProps = _ref3 => {
|
|
31
39
|
let {
|
|
32
40
|
id,
|
|
33
41
|
checkColor,
|
|
@@ -37,7 +45,7 @@ const getInputProps = _ref2 => {
|
|
|
37
45
|
isChecked,
|
|
38
46
|
isInactive,
|
|
39
47
|
handleChange
|
|
40
|
-
} =
|
|
48
|
+
} = _ref3;
|
|
41
49
|
return {
|
|
42
50
|
inputId: id,
|
|
43
51
|
tokens: {
|
|
@@ -100,7 +108,7 @@ const getInputProps = _ref2 => {
|
|
|
100
108
|
* you automatically make inaccessible its children, which may or may not be appropriate
|
|
101
109
|
* depending on what you are trying to achieve.
|
|
102
110
|
*/
|
|
103
|
-
const Card = /*#__PURE__*/React.forwardRef((
|
|
111
|
+
const Card = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
104
112
|
let {
|
|
105
113
|
children,
|
|
106
114
|
tokens,
|
|
@@ -110,8 +118,9 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
110
118
|
id,
|
|
111
119
|
interactiveCard,
|
|
112
120
|
backgroundImage,
|
|
121
|
+
testID,
|
|
113
122
|
...rest
|
|
114
|
-
} =
|
|
123
|
+
} = _ref4;
|
|
115
124
|
const viewport = useViewport();
|
|
116
125
|
const {
|
|
117
126
|
themeOptions
|
|
@@ -182,8 +191,8 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
182
191
|
let cardStyles;
|
|
183
192
|
let mediaIds;
|
|
184
193
|
if (enableMediaQueryStyleSheet) {
|
|
185
|
-
const transformedThemeTokens = Object.entries(themeTokens).reduce((acc,
|
|
186
|
-
let [vp, viewportTokens] =
|
|
194
|
+
const transformedThemeTokens = Object.entries(themeTokens).reduce((acc, _ref5) => {
|
|
195
|
+
let [vp, viewportTokens] = _ref5;
|
|
187
196
|
const tokensToTransform = selectionType ? selectStyles({
|
|
188
197
|
...viewportTokens,
|
|
189
198
|
paddingTop: 0,
|
|
@@ -210,13 +219,18 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
210
219
|
cardStyles = themeTokens;
|
|
211
220
|
}
|
|
212
221
|
const renderInputPerSelectionType = props => {
|
|
222
|
+
const containerStyle = selectInputStyle(getThemeTokens(), {
|
|
223
|
+
inputPositionProp: interactiveCard?.inputPosition
|
|
224
|
+
});
|
|
225
|
+
const inputTestID = testID && `${testID}-selection-input`;
|
|
213
226
|
if (!isControl) {
|
|
214
227
|
return null;
|
|
215
228
|
}
|
|
216
229
|
switch (selectionType) {
|
|
217
230
|
case SelectionType.Checkbox:
|
|
218
231
|
return /*#__PURE__*/_jsx(View, {
|
|
219
|
-
style:
|
|
232
|
+
style: containerStyle,
|
|
233
|
+
testID: inputTestID,
|
|
220
234
|
children: /*#__PURE__*/_jsx(CheckboxButton, {
|
|
221
235
|
...props,
|
|
222
236
|
tokens: {
|
|
@@ -227,7 +241,8 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
227
241
|
});
|
|
228
242
|
case SelectionType.Radio:
|
|
229
243
|
return /*#__PURE__*/_jsx(View, {
|
|
230
|
-
style:
|
|
244
|
+
style: containerStyle,
|
|
245
|
+
testID: inputTestID,
|
|
231
246
|
children: /*#__PURE__*/_jsx(RadioButton, {
|
|
232
247
|
...props,
|
|
233
248
|
tokens: {
|
|
@@ -248,6 +263,7 @@ const Card = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
248
263
|
dataSet: mediaIds && {
|
|
249
264
|
media: mediaIds
|
|
250
265
|
},
|
|
266
|
+
testID: testID,
|
|
251
267
|
...selectProps(rest),
|
|
252
268
|
children: [interactiveCard?.body && /*#__PURE__*/_jsx(PressableCardBase, {
|
|
253
269
|
ref: ref,
|
|
@@ -326,7 +342,8 @@ Card.propTypes = {
|
|
|
326
342
|
selectionType: PropTypes.oneOf(Object.values(SelectionType)),
|
|
327
343
|
variant: variantProp.propType,
|
|
328
344
|
href: PropTypes.string,
|
|
329
|
-
hrefAttrs: PropTypes.shape(hrefAttrsProp.types)
|
|
345
|
+
hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
|
|
346
|
+
inputPosition: PropTypes.oneOf(['left', 'right'])
|
|
330
347
|
}),
|
|
331
348
|
/**
|
|
332
349
|
* Apply background image to the card.
|
|
@@ -343,6 +360,10 @@ Card.propTypes = {
|
|
|
343
360
|
/**
|
|
344
361
|
* Data set for the card.
|
|
345
362
|
*/
|
|
346
|
-
dataSet: PropTypes.object
|
|
363
|
+
dataSet: PropTypes.object,
|
|
364
|
+
/**
|
|
365
|
+
* Test ID used for e2e testing.
|
|
366
|
+
*/
|
|
367
|
+
testID: PropTypes.string
|
|
347
368
|
};
|
|
348
369
|
export default Card;
|
package/lib/esm/Card/CardBase.js
CHANGED
|
@@ -107,9 +107,51 @@ const setBackgroundImage = _ref => {
|
|
|
107
107
|
children: content
|
|
108
108
|
});
|
|
109
109
|
};
|
|
110
|
+
const selectPaddedContentStyles = _ref2 => {
|
|
111
|
+
let {
|
|
112
|
+
paddingTop,
|
|
113
|
+
paddingBottom,
|
|
114
|
+
paddingLeft,
|
|
115
|
+
paddingRight,
|
|
116
|
+
borderWidth,
|
|
117
|
+
borderColor,
|
|
118
|
+
borderRadius,
|
|
119
|
+
hasInteractiveBorder
|
|
120
|
+
} = _ref2;
|
|
121
|
+
return {
|
|
122
|
+
paddingTop,
|
|
123
|
+
paddingBottom,
|
|
124
|
+
paddingLeft,
|
|
125
|
+
paddingRight,
|
|
126
|
+
...(hasInteractiveBorder ? {
|
|
127
|
+
borderWidth,
|
|
128
|
+
borderColor,
|
|
129
|
+
borderRadius
|
|
130
|
+
} : {})
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const selectInteractiveOverlayStyles = _ref3 => {
|
|
134
|
+
let {
|
|
135
|
+
backgroundColor,
|
|
136
|
+
borderRadius,
|
|
137
|
+
borderWidth
|
|
138
|
+
} = _ref3;
|
|
139
|
+
const adjustedBorderRadius = Math.max(0, borderRadius - borderWidth);
|
|
140
|
+
return {
|
|
141
|
+
position: 'absolute',
|
|
142
|
+
top: 0,
|
|
143
|
+
left: 0,
|
|
144
|
+
right: 0,
|
|
145
|
+
bottom: 0,
|
|
146
|
+
backgroundColor,
|
|
147
|
+
borderRadius: adjustedBorderRadius,
|
|
148
|
+
pointerEvents: 'none',
|
|
149
|
+
zIndex: 1
|
|
150
|
+
};
|
|
151
|
+
};
|
|
110
152
|
|
|
111
153
|
// Ensure explicit selection of tokens
|
|
112
|
-
export const selectStyles =
|
|
154
|
+
export const selectStyles = _ref4 => {
|
|
113
155
|
let {
|
|
114
156
|
flex,
|
|
115
157
|
backgroundColor,
|
|
@@ -130,7 +172,7 @@ export const selectStyles = _ref2 => {
|
|
|
130
172
|
gradient,
|
|
131
173
|
maxHeight,
|
|
132
174
|
overflowY
|
|
133
|
-
} =
|
|
175
|
+
} = _ref4;
|
|
134
176
|
const hasGradient = (gradient || backgroundGradient) && Platform.OS === 'web';
|
|
135
177
|
let backgroundImageValue = null;
|
|
136
178
|
if (hasGradient) {
|
|
@@ -176,7 +218,7 @@ export const selectStyles = _ref2 => {
|
|
|
176
218
|
* A themeless base component for Card which components can apply theme tokens to. Not
|
|
177
219
|
* intended to be used in apps or sites directly: build themed components on top of this.
|
|
178
220
|
*/
|
|
179
|
-
const CardBase = /*#__PURE__*/React.forwardRef((
|
|
221
|
+
const CardBase = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
180
222
|
let {
|
|
181
223
|
children,
|
|
182
224
|
tokens,
|
|
@@ -185,8 +227,14 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
185
227
|
fullBleedContent,
|
|
186
228
|
cardState,
|
|
187
229
|
...rest
|
|
188
|
-
} =
|
|
189
|
-
const
|
|
230
|
+
} = _ref5;
|
|
231
|
+
const resolvedTokens = typeof tokens === 'function' ? tokens(cardState) : tokens;
|
|
232
|
+
const tokensToUse = backgroundImage && backgroundImage.src ? {
|
|
233
|
+
...resolvedTokens,
|
|
234
|
+
gradient: undefined,
|
|
235
|
+
backgroundGradient: undefined
|
|
236
|
+
} : resolvedTokens;
|
|
237
|
+
const cardStyle = selectStyles(tokensToUse);
|
|
190
238
|
const props = selectProps(rest);
|
|
191
239
|
let content = children;
|
|
192
240
|
const {
|
|
@@ -212,29 +260,57 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
212
260
|
paddingBottom,
|
|
213
261
|
paddingLeft,
|
|
214
262
|
paddingRight,
|
|
263
|
+
borderWidth,
|
|
264
|
+
borderColor,
|
|
265
|
+
borderRadius,
|
|
266
|
+
backgroundColor,
|
|
215
267
|
...containerStyle
|
|
216
268
|
} = cardStyle;
|
|
217
269
|
const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
|
|
218
|
-
const
|
|
219
|
-
|
|
270
|
+
const hasInteractiveBorder = borderWidth && borderWidth > 0;
|
|
271
|
+
const hasInteractiveOverlay = isOverlayColor(backgroundColor);
|
|
272
|
+
const paddedContent = hasPadding || hasInteractiveBorder ? /*#__PURE__*/_jsx(View, {
|
|
273
|
+
style: selectPaddedContentStyles({
|
|
220
274
|
paddingTop,
|
|
221
275
|
paddingBottom,
|
|
222
276
|
paddingLeft,
|
|
223
|
-
paddingRight
|
|
224
|
-
|
|
277
|
+
paddingRight,
|
|
278
|
+
borderWidth,
|
|
279
|
+
borderColor,
|
|
280
|
+
borderRadius,
|
|
281
|
+
hasInteractiveBorder
|
|
282
|
+
}),
|
|
225
283
|
children: children
|
|
226
284
|
}) : children;
|
|
285
|
+
const contentWithOverlay = /*#__PURE__*/_jsxs(_Fragment, {
|
|
286
|
+
children: [hasInteractiveOverlay && Platform.OS === 'web' && /*#__PURE__*/_jsx(View, {
|
|
287
|
+
style: selectInteractiveOverlayStyles({
|
|
288
|
+
backgroundColor,
|
|
289
|
+
borderRadius,
|
|
290
|
+
borderWidth
|
|
291
|
+
})
|
|
292
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
293
|
+
style: staticStyles.contentOverlay,
|
|
294
|
+
children: paddedContent
|
|
295
|
+
})]
|
|
296
|
+
});
|
|
227
297
|
content = setBackgroundImage({
|
|
228
298
|
src: imageSourceViewport,
|
|
229
299
|
alt,
|
|
230
300
|
backgroundImageResizeMode,
|
|
231
301
|
backgroundImagePosition,
|
|
232
302
|
backgroundImageAlign,
|
|
233
|
-
content:
|
|
234
|
-
cardStyle:
|
|
303
|
+
content: contentWithOverlay,
|
|
304
|
+
cardStyle: {
|
|
305
|
+
...containerStyle,
|
|
306
|
+
borderRadius
|
|
307
|
+
}
|
|
235
308
|
});
|
|
236
309
|
return /*#__PURE__*/_jsx(View, {
|
|
237
|
-
style:
|
|
310
|
+
style: {
|
|
311
|
+
...containerStyle,
|
|
312
|
+
borderRadius
|
|
313
|
+
},
|
|
238
314
|
dataSet: dataSet,
|
|
239
315
|
ref: ref,
|
|
240
316
|
...props,
|
|
@@ -312,8 +388,8 @@ const staticStyles = StyleSheet.create({
|
|
|
312
388
|
contentOverlay: {
|
|
313
389
|
position: 'relative',
|
|
314
390
|
width: '100%',
|
|
315
|
-
|
|
316
|
-
zIndex:
|
|
391
|
+
minHeight: '100%',
|
|
392
|
+
zIndex: 2
|
|
317
393
|
},
|
|
318
394
|
containContainer: {
|
|
319
395
|
width: '100%',
|
|
@@ -8,8 +8,74 @@ import { useViewport } from '../ViewportProvider';
|
|
|
8
8
|
import { applyOuterBorder, validateThemeTokens } from '../ThemeProvider';
|
|
9
9
|
import { a11yProps, clickProps, focusHandlerProps, getTokensSetPropType, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, selectTokens, variantProp, viewProps, withLinkRouter } from '../utils';
|
|
10
10
|
import CardBase, { fullBleedContentPropTypes } from './CardBase';
|
|
11
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
13
|
+
const selectFocusOverlayContainerStyles = tokens => {
|
|
14
|
+
const {
|
|
15
|
+
flex,
|
|
16
|
+
minWidth,
|
|
17
|
+
marginTop,
|
|
18
|
+
marginBottom,
|
|
19
|
+
marginLeft,
|
|
20
|
+
marginRight
|
|
21
|
+
} = tokens;
|
|
22
|
+
return {
|
|
23
|
+
flex: flex || 1,
|
|
24
|
+
minWidth: minWidth || 0,
|
|
25
|
+
marginTop,
|
|
26
|
+
marginBottom,
|
|
27
|
+
marginLeft,
|
|
28
|
+
marginRight
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const selectFocusBorderStyles = tokens => {
|
|
32
|
+
const {
|
|
33
|
+
borderWidth,
|
|
34
|
+
borderColor,
|
|
35
|
+
borderRadius
|
|
36
|
+
} = tokens;
|
|
37
|
+
return {
|
|
38
|
+
borderWidth,
|
|
39
|
+
borderColor,
|
|
40
|
+
borderRadius: borderRadius || 0
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const FocusBorderOverlay = _ref => {
|
|
44
|
+
let {
|
|
45
|
+
tokens,
|
|
46
|
+
pressableState,
|
|
47
|
+
children
|
|
48
|
+
} = _ref;
|
|
49
|
+
const {
|
|
50
|
+
borderWidth = 0
|
|
51
|
+
} = tokens;
|
|
52
|
+
const showFocusBorder = pressableState.focused && borderWidth > 0;
|
|
53
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
54
|
+
style: [staticStyles.focusOverlayContainer, selectFocusOverlayContainerStyles(tokens), Platform.OS === 'web' && staticStyles.webOutlineNone],
|
|
55
|
+
children: [children, showFocusBorder && /*#__PURE__*/_jsx(View, {
|
|
56
|
+
style: [staticStyles.focusBorder, selectFocusBorderStyles(tokens)],
|
|
57
|
+
accessible: false,
|
|
58
|
+
importantForAccessibility: "no"
|
|
59
|
+
})]
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
FocusBorderOverlay.propTypes = {
|
|
63
|
+
tokens: PropTypes.shape({
|
|
64
|
+
flex: PropTypes.number,
|
|
65
|
+
minWidth: PropTypes.number,
|
|
66
|
+
marginTop: PropTypes.number,
|
|
67
|
+
marginBottom: PropTypes.number,
|
|
68
|
+
marginLeft: PropTypes.number,
|
|
69
|
+
marginRight: PropTypes.number,
|
|
70
|
+
borderColor: PropTypes.string,
|
|
71
|
+
borderWidth: PropTypes.number,
|
|
72
|
+
borderRadius: PropTypes.number
|
|
73
|
+
}).isRequired,
|
|
74
|
+
pressableState: PropTypes.shape({
|
|
75
|
+
focused: PropTypes.bool
|
|
76
|
+
}).isRequired,
|
|
77
|
+
children: PropTypes.node
|
|
78
|
+
};
|
|
13
79
|
const tokenKeys = ['flex', 'backgroundColor', 'borderColor', 'gradient', 'borderRadius', 'borderWidth', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', 'minWidth', 'shadow', 'contentAlignItems', 'contentJustifyContent', 'contentFlexGrow', 'contentFlexShrink',
|
|
14
80
|
// Outer border tokens. TODO: centralise common token sets like these as part of
|
|
15
81
|
// https://github.com/telus/universal-design-system/issues/782
|
|
@@ -21,7 +87,7 @@ export const selectPressableCardTokens = tokens => Object.fromEntries(tokenKeys.
|
|
|
21
87
|
* based on these to an outer border and a base Card component. Not intended to be used in
|
|
22
88
|
* apps or sites directly: build themed components on top of this.
|
|
23
89
|
*/
|
|
24
|
-
const PressableCardBase = /*#__PURE__*/React.forwardRef((
|
|
90
|
+
const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
25
91
|
let {
|
|
26
92
|
children,
|
|
27
93
|
tokens,
|
|
@@ -35,7 +101,7 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
35
101
|
fullBleedContent,
|
|
36
102
|
accessibilityRole = href ? 'link' : undefined,
|
|
37
103
|
...rawRest
|
|
38
|
-
} =
|
|
104
|
+
} = _ref2;
|
|
39
105
|
const {
|
|
40
106
|
onPress,
|
|
41
107
|
...rest
|
|
@@ -52,11 +118,62 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
52
118
|
partial: true,
|
|
53
119
|
allowFunction: true
|
|
54
120
|
}), 'PressableCard');
|
|
55
|
-
const getCardTokens = pressableState =>
|
|
121
|
+
const getCardTokens = pressableState => {
|
|
122
|
+
const allTokens = getTokens(pressableState);
|
|
123
|
+
const cardTokens = selectTokens('Card', allTokens);
|
|
124
|
+
|
|
125
|
+
// Handle focus border transparency to avoid double borders
|
|
126
|
+
if (pressableState.focused && allTokens.borderWidth > 0) {
|
|
127
|
+
const result = {
|
|
128
|
+
...cardTokens,
|
|
129
|
+
borderColor: 'transparent'
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Also handle backgroundImage for interactive states
|
|
133
|
+
if (backgroundImage) {
|
|
134
|
+
const {
|
|
135
|
+
hovered,
|
|
136
|
+
pressed,
|
|
137
|
+
focused
|
|
138
|
+
} = pressableState || {};
|
|
139
|
+
const isInteractiveState = hovered || pressed || focused;
|
|
140
|
+
if (!isInteractiveState) {
|
|
141
|
+
const {
|
|
142
|
+
backgroundColor,
|
|
143
|
+
...restTokens
|
|
144
|
+
} = result;
|
|
145
|
+
return restTokens;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Handle backgroundImage when not in focus state
|
|
152
|
+
if (backgroundImage) {
|
|
153
|
+
const {
|
|
154
|
+
hovered,
|
|
155
|
+
pressed,
|
|
156
|
+
focused
|
|
157
|
+
} = pressableState || {};
|
|
158
|
+
const isInteractiveState = hovered || pressed || focused;
|
|
159
|
+
if (!isInteractiveState) {
|
|
160
|
+
const {
|
|
161
|
+
backgroundColor,
|
|
162
|
+
...restTokens
|
|
163
|
+
} = cardTokens;
|
|
164
|
+
return restTokens;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return cardTokens;
|
|
168
|
+
};
|
|
56
169
|
const getOuterBorderStyle = pressableState => {
|
|
57
170
|
const {
|
|
58
171
|
flex,
|
|
59
172
|
minWidth,
|
|
173
|
+
marginTop,
|
|
174
|
+
marginBottom,
|
|
175
|
+
marginLeft,
|
|
176
|
+
marginRight,
|
|
60
177
|
outerBorderColor,
|
|
61
178
|
outerBorderGap = 0,
|
|
62
179
|
outerBorderWidth = 0,
|
|
@@ -65,6 +182,10 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
65
182
|
return {
|
|
66
183
|
flex,
|
|
67
184
|
minWidth: minWidth + outerBorderGap + outerBorderWidth,
|
|
185
|
+
marginTop,
|
|
186
|
+
marginBottom,
|
|
187
|
+
marginLeft,
|
|
188
|
+
marginRight,
|
|
68
189
|
...applyOuterBorder({
|
|
69
190
|
outerBorderColor,
|
|
70
191
|
outerBorderGap,
|
|
@@ -158,11 +279,15 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
158
279
|
...rest,
|
|
159
280
|
accessibilityRole
|
|
160
281
|
}),
|
|
161
|
-
children: pressableState => /*#__PURE__*/_jsx(
|
|
162
|
-
tokens:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
282
|
+
children: pressableState => /*#__PURE__*/_jsx(FocusBorderOverlay, {
|
|
283
|
+
tokens: getTokens(pressableState),
|
|
284
|
+
pressableState: pressableState,
|
|
285
|
+
children: /*#__PURE__*/_jsx(CardBase, {
|
|
286
|
+
tokens: getCardTokens(pressableState),
|
|
287
|
+
backgroundImage: backgroundImage,
|
|
288
|
+
fullBleedContent: fullBleedContent,
|
|
289
|
+
children: typeof children === 'function' ? children(getCardState(pressableState)) : children
|
|
290
|
+
})
|
|
166
291
|
})
|
|
167
292
|
});
|
|
168
293
|
});
|
|
@@ -177,6 +302,20 @@ const staticStyles = StyleSheet.create({
|
|
|
177
302
|
alignItems: 'stretch',
|
|
178
303
|
justifyContent: 'flex-start',
|
|
179
304
|
textDecorationLine: 'none'
|
|
305
|
+
},
|
|
306
|
+
focusOverlayContainer: {
|
|
307
|
+
position: 'relative'
|
|
308
|
+
},
|
|
309
|
+
webOutlineNone: {
|
|
310
|
+
outline: 'none'
|
|
311
|
+
},
|
|
312
|
+
focusBorder: {
|
|
313
|
+
position: 'absolute',
|
|
314
|
+
top: 0,
|
|
315
|
+
left: 0,
|
|
316
|
+
right: 0,
|
|
317
|
+
bottom: 0,
|
|
318
|
+
pointerEvents: 'none'
|
|
180
319
|
}
|
|
181
320
|
});
|
|
182
321
|
PressableCardBase.displayName = 'PressableCardBase';
|