@telus-uds/components-base 3.25.0 → 3.27.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 +28 -1
- package/lib/cjs/Card/Card.js +34 -13
- package/lib/cjs/Card/CardBase.js +78 -11
- package/lib/cjs/Card/PressableCardBase.js +147 -8
- package/lib/cjs/Carousel/Carousel.js +161 -77
- package/lib/cjs/Carousel/CarouselContext.js +10 -4
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +11 -7
- package/lib/cjs/Carousel/Constants.js +22 -2
- package/lib/cjs/Checkbox/Checkbox.js +43 -13
- package/lib/cjs/InputSupports/InputSupports.js +2 -1
- 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/PriceLockup/PriceLockup.js +1 -1
- package/lib/esm/Card/Card.js +34 -13
- package/lib/esm/Card/CardBase.js +78 -11
- package/lib/esm/Card/PressableCardBase.js +148 -9
- package/lib/esm/Carousel/Carousel.js +153 -69
- package/lib/esm/Carousel/CarouselContext.js +10 -4
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +11 -7
- package/lib/esm/Carousel/Constants.js +21 -1
- package/lib/esm/Checkbox/Checkbox.js +43 -13
- package/lib/esm/InputSupports/InputSupports.js +2 -1
- 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/PriceLockup/PriceLockup.js +1 -1
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Card/Card.jsx +29 -7
- package/src/Card/CardBase.jsx +88 -8
- package/src/Card/PressableCardBase.jsx +135 -9
- package/src/Carousel/Carousel.jsx +185 -88
- package/src/Carousel/CarouselContext.jsx +12 -4
- package/src/Carousel/CarouselItem/CarouselItem.jsx +10 -6
- package/src/Carousel/Constants.js +24 -0
- package/src/Checkbox/Checkbox.jsx +29 -7
- package/src/InputSupports/InputSupports.jsx +6 -1
- 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/PriceLockup/PriceLockup.jsx +1 -1
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,7 +227,7 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
185
227
|
fullBleedContent,
|
|
186
228
|
cardState,
|
|
187
229
|
...rest
|
|
188
|
-
} =
|
|
230
|
+
} = _ref5;
|
|
189
231
|
const cardStyle = selectStyles(typeof tokens === 'function' ? tokens(cardState) : tokens);
|
|
190
232
|
const props = selectProps(rest);
|
|
191
233
|
let content = children;
|
|
@@ -212,26 +254,51 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
212
254
|
paddingBottom,
|
|
213
255
|
paddingLeft,
|
|
214
256
|
paddingRight,
|
|
257
|
+
borderWidth,
|
|
258
|
+
borderColor,
|
|
259
|
+
borderRadius,
|
|
260
|
+
backgroundColor,
|
|
215
261
|
...containerStyle
|
|
216
262
|
} = cardStyle;
|
|
217
263
|
const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
|
|
218
|
-
const
|
|
219
|
-
|
|
264
|
+
const hasInteractiveBorder = borderWidth && borderWidth > 0;
|
|
265
|
+
const hasInteractiveOverlay = isOverlayColor(backgroundColor);
|
|
266
|
+
const paddedContent = hasPadding || hasInteractiveBorder ? /*#__PURE__*/_jsx(View, {
|
|
267
|
+
style: selectPaddedContentStyles({
|
|
220
268
|
paddingTop,
|
|
221
269
|
paddingBottom,
|
|
222
270
|
paddingLeft,
|
|
223
|
-
paddingRight
|
|
224
|
-
|
|
271
|
+
paddingRight,
|
|
272
|
+
borderWidth,
|
|
273
|
+
borderColor,
|
|
274
|
+
borderRadius,
|
|
275
|
+
hasInteractiveBorder
|
|
276
|
+
}),
|
|
225
277
|
children: children
|
|
226
278
|
}) : children;
|
|
279
|
+
const contentWithOverlay = /*#__PURE__*/_jsxs(_Fragment, {
|
|
280
|
+
children: [hasInteractiveOverlay && Platform.OS === 'web' && /*#__PURE__*/_jsx(View, {
|
|
281
|
+
style: selectInteractiveOverlayStyles({
|
|
282
|
+
backgroundColor,
|
|
283
|
+
borderRadius,
|
|
284
|
+
borderWidth
|
|
285
|
+
})
|
|
286
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
287
|
+
style: staticStyles.contentOverlay,
|
|
288
|
+
children: paddedContent
|
|
289
|
+
})]
|
|
290
|
+
});
|
|
227
291
|
content = setBackgroundImage({
|
|
228
292
|
src: imageSourceViewport,
|
|
229
293
|
alt,
|
|
230
294
|
backgroundImageResizeMode,
|
|
231
295
|
backgroundImagePosition,
|
|
232
296
|
backgroundImageAlign,
|
|
233
|
-
content:
|
|
234
|
-
cardStyle:
|
|
297
|
+
content: contentWithOverlay,
|
|
298
|
+
cardStyle: {
|
|
299
|
+
...containerStyle,
|
|
300
|
+
borderRadius
|
|
301
|
+
}
|
|
235
302
|
});
|
|
236
303
|
return /*#__PURE__*/_jsx(View, {
|
|
237
304
|
style: containerStyle,
|
|
@@ -313,7 +380,7 @@ const staticStyles = StyleSheet.create({
|
|
|
313
380
|
position: 'relative',
|
|
314
381
|
width: '100%',
|
|
315
382
|
height: '100%',
|
|
316
|
-
zIndex:
|
|
383
|
+
zIndex: 2
|
|
317
384
|
},
|
|
318
385
|
containContainer: {
|
|
319
386
|
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';
|