@telus-uds/components-base 3.22.0 → 3.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -1
- package/lib/cjs/Button/Button.js +2 -0
- package/lib/cjs/Button/ButtonBase.js +10 -5
- package/lib/cjs/Button/ButtonDropdown.js +2 -0
- package/lib/cjs/Button/ButtonGroup.js +45 -38
- package/lib/cjs/Button/propTypes.js +6 -0
- package/lib/cjs/Card/CardBase.js +97 -17
- package/lib/cjs/Card/PressableCardBase.js +12 -8
- package/lib/cjs/Carousel/Carousel.js +52 -19
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +23 -3
- package/lib/cjs/HorizontalScroll/HorizontalScroll.js +5 -2
- package/lib/cjs/Icon/Icon.js +11 -11
- package/lib/cjs/Icon/IconText.js +0 -1
- package/lib/cjs/Listbox/GroupControl.js +44 -44
- package/lib/cjs/Listbox/Listbox.js +63 -20
- package/lib/cjs/Listbox/ListboxGroup.js +141 -9
- package/lib/cjs/Listbox/ListboxOverlay.js +13 -5
- package/lib/cjs/Listbox/PressableItem.js +8 -4
- package/lib/cjs/Listbox/SecondLevelHeader.js +201 -0
- package/lib/cjs/Listbox/dictionary.js +14 -0
- package/lib/cjs/Shortcuts/Shortcuts.js +169 -0
- package/lib/cjs/Shortcuts/ShortcutsItem.js +280 -0
- package/lib/cjs/Shortcuts/index.js +16 -0
- package/lib/cjs/TextInput/TextInputBase.js +5 -1
- package/lib/cjs/Tooltip/Tooltip.native.js +2 -0
- package/lib/cjs/Validator/Validator.js +171 -135
- package/lib/cjs/index.js +15 -0
- package/lib/esm/Button/Button.js +2 -0
- package/lib/esm/Button/ButtonBase.js +10 -5
- package/lib/esm/Button/ButtonDropdown.js +2 -0
- package/lib/esm/Button/ButtonGroup.js +44 -39
- package/lib/esm/Button/propTypes.js +6 -0
- package/lib/esm/Card/CardBase.js +97 -17
- package/lib/esm/Card/PressableCardBase.js +10 -8
- package/lib/esm/Carousel/Carousel.js +52 -19
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +23 -3
- package/lib/esm/HorizontalScroll/HorizontalScroll.js +6 -3
- package/lib/esm/Icon/Icon.js +11 -11
- package/lib/esm/Icon/IconText.js +0 -1
- package/lib/esm/Listbox/GroupControl.js +44 -44
- package/lib/esm/Listbox/Listbox.js +64 -21
- package/lib/esm/Listbox/ListboxGroup.js +143 -11
- package/lib/esm/Listbox/ListboxOverlay.js +13 -5
- package/lib/esm/Listbox/PressableItem.js +8 -4
- package/lib/esm/Listbox/SecondLevelHeader.js +194 -0
- package/lib/esm/Listbox/dictionary.js +8 -0
- package/lib/esm/Shortcuts/Shortcuts.js +160 -0
- package/lib/esm/Shortcuts/ShortcutsItem.js +273 -0
- package/lib/esm/Shortcuts/index.js +3 -0
- package/lib/esm/TextInput/TextInputBase.js +5 -1
- package/lib/esm/Tooltip/Tooltip.native.js +2 -0
- package/lib/esm/Validator/Validator.js +171 -135
- package/lib/esm/index.js +1 -0
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Button/Button.jsx +2 -1
- package/src/Button/ButtonBase.jsx +18 -12
- package/src/Button/ButtonDropdown.jsx +2 -0
- package/src/Button/ButtonGroup.jsx +62 -45
- package/src/Button/propTypes.js +6 -0
- package/src/Card/CardBase.jsx +113 -14
- package/src/Card/PressableCardBase.jsx +17 -5
- package/src/Carousel/Carousel.jsx +58 -5
- package/src/Carousel/CarouselItem/CarouselItem.jsx +31 -3
- package/src/HorizontalScroll/HorizontalScroll.jsx +6 -3
- package/src/Icon/Icon.jsx +14 -14
- package/src/Icon/IconText.jsx +0 -1
- package/src/Listbox/GroupControl.jsx +72 -70
- package/src/Listbox/Listbox.jsx +67 -11
- package/src/Listbox/ListboxGroup.jsx +160 -27
- package/src/Listbox/ListboxOverlay.jsx +23 -5
- package/src/Listbox/PressableItem.jsx +8 -4
- package/src/Listbox/SecondLevelHeader.jsx +182 -0
- package/src/Listbox/dictionary.js +8 -0
- package/src/Shortcuts/Shortcuts.jsx +174 -0
- package/src/Shortcuts/ShortcutsItem.jsx +297 -0
- package/src/Shortcuts/index.js +4 -0
- package/src/TextInput/TextInputBase.jsx +5 -1
- package/src/Tooltip/Tooltip.native.jsx +2 -1
- package/src/Validator/Validator.jsx +180 -159
- package/src/index.js +1 -0
- package/types/Listbox.d.ts +24 -0
- package/types/Shortcuts.d.ts +136 -0
- package/types/index.d.ts +12 -0
package/lib/esm/Card/CardBase.js
CHANGED
|
@@ -9,8 +9,15 @@ import { applyShadowToken } from '../ThemeProvider';
|
|
|
9
9
|
import { getTokensPropType, responsiveProps, useResponsiveProp, formatImageSource } from '../utils';
|
|
10
10
|
import { a11yProps, viewProps, selectSystemProps } from '../utils/props';
|
|
11
11
|
import backgroundImageStylesMap from './backgroundImageStylesMap';
|
|
12
|
-
import
|
|
12
|
+
import FlexGrid from '../FlexGrid/FlexGrid';
|
|
13
|
+
import FlexGridRow from '../FlexGrid/Row';
|
|
14
|
+
import FlexGridCol from '../FlexGrid/Col';
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
16
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
17
|
+
const GRID_COLUMNS = 12;
|
|
18
|
+
const isOverlayColor = color => {
|
|
19
|
+
return color && typeof color === 'string' && color.startsWith('rgba(');
|
|
20
|
+
};
|
|
14
21
|
const setBackgroundImage = _ref => {
|
|
15
22
|
let {
|
|
16
23
|
src,
|
|
@@ -24,12 +31,9 @@ const setBackgroundImage = _ref => {
|
|
|
24
31
|
const borderRadius = cardStyle?.borderRadius || 0;
|
|
25
32
|
const borderWidth = cardStyle?.borderWidth || 0;
|
|
26
33
|
const adjustedBorderRadius = Math.max(0, borderRadius - borderWidth);
|
|
27
|
-
|
|
28
|
-
// For contain mode with position and align, use CSS background properties for web
|
|
29
34
|
if (backgroundImageResizeMode === 'contain' && backgroundImagePosition && backgroundImageAlign) {
|
|
30
35
|
const positionKey = `${backgroundImagePosition}-${backgroundImageAlign}`;
|
|
31
36
|
if (Platform.OS === 'web') {
|
|
32
|
-
// Create background position based on position and align
|
|
33
37
|
let backgroundPosition;
|
|
34
38
|
switch (positionKey) {
|
|
35
39
|
case 'top-start':
|
|
@@ -73,7 +77,6 @@ const setBackgroundImage = _ref => {
|
|
|
73
77
|
children: content
|
|
74
78
|
});
|
|
75
79
|
}
|
|
76
|
-
// For React Native, apply positioning styles with full dimensions
|
|
77
80
|
const positionStyles = backgroundImageStylesMap[positionKey] || {};
|
|
78
81
|
return /*#__PURE__*/_jsxs(View, {
|
|
79
82
|
style: [staticStyles.containContainer, {
|
|
@@ -92,8 +95,6 @@ const setBackgroundImage = _ref => {
|
|
|
92
95
|
})]
|
|
93
96
|
});
|
|
94
97
|
}
|
|
95
|
-
|
|
96
|
-
// Use ImageBackground for all other resize modes and React Native
|
|
97
98
|
return /*#__PURE__*/_jsx(ImageBackground, {
|
|
98
99
|
source: src,
|
|
99
100
|
imageStyle: {
|
|
@@ -119,6 +120,10 @@ export const selectStyles = _ref2 => {
|
|
|
119
120
|
paddingLeft,
|
|
120
121
|
paddingRight,
|
|
121
122
|
paddingTop,
|
|
123
|
+
marginTop,
|
|
124
|
+
marginBottom,
|
|
125
|
+
marginLeft,
|
|
126
|
+
marginRight,
|
|
122
127
|
minWidth,
|
|
123
128
|
shadow,
|
|
124
129
|
backgroundGradient,
|
|
@@ -126,9 +131,18 @@ export const selectStyles = _ref2 => {
|
|
|
126
131
|
maxHeight,
|
|
127
132
|
overflowY
|
|
128
133
|
} = _ref2;
|
|
134
|
+
const hasGradient = (gradient || backgroundGradient) && Platform.OS === 'web';
|
|
135
|
+
let backgroundImageValue = null;
|
|
136
|
+
if (hasGradient) {
|
|
137
|
+
const gradientObj = gradient || backgroundGradient;
|
|
138
|
+
const gradientString = `linear-gradient(${gradientObj.angle}deg, ${gradientObj.stops[0].color}, ${gradientObj.stops[1].color})`;
|
|
139
|
+
const shouldApplyOverlay = (gradient || backgroundGradient && backgroundColor && backgroundColor !== 'transparent') && isOverlayColor(backgroundColor);
|
|
140
|
+
backgroundImageValue = shouldApplyOverlay ? `linear-gradient(${backgroundColor}, ${backgroundColor}), ${gradientString}` : gradientString;
|
|
141
|
+
}
|
|
142
|
+
const boxShadowColor = isOverlayColor(backgroundColor) ? backgroundColor : 'white';
|
|
129
143
|
return {
|
|
130
144
|
flex,
|
|
131
|
-
backgroundColor,
|
|
145
|
+
backgroundColor: hasGradient ? 'transparent' : backgroundColor,
|
|
132
146
|
borderColor,
|
|
133
147
|
borderRadius,
|
|
134
148
|
borderWidth,
|
|
@@ -136,16 +150,20 @@ export const selectStyles = _ref2 => {
|
|
|
136
150
|
paddingLeft,
|
|
137
151
|
paddingRight,
|
|
138
152
|
paddingTop,
|
|
153
|
+
marginTop,
|
|
154
|
+
marginBottom,
|
|
155
|
+
marginLeft,
|
|
156
|
+
marginRight,
|
|
139
157
|
minWidth,
|
|
140
158
|
...applyShadowToken(shadow),
|
|
141
159
|
...(gradient && Platform.OS === 'web' ? {
|
|
142
|
-
backgroundImage:
|
|
160
|
+
backgroundImage: backgroundImageValue,
|
|
143
161
|
backgroundOrigin: `border-box`,
|
|
144
|
-
boxShadow: `inset 0 1000px
|
|
162
|
+
boxShadow: `inset 0 1000px ${boxShadowColor}`,
|
|
145
163
|
border: `${borderWidth}px solid transparent`
|
|
146
164
|
} : {}),
|
|
147
165
|
...(backgroundGradient && Platform.OS === 'web' ? {
|
|
148
|
-
backgroundImage:
|
|
166
|
+
backgroundImage: backgroundImageValue
|
|
149
167
|
} : {}),
|
|
150
168
|
...(Platform.OS === 'web' ? {
|
|
151
169
|
maxHeight,
|
|
@@ -164,9 +182,11 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
164
182
|
tokens,
|
|
165
183
|
dataSet,
|
|
166
184
|
backgroundImage,
|
|
185
|
+
fullBleedContent,
|
|
186
|
+
cardState,
|
|
167
187
|
...rest
|
|
168
188
|
} = _ref3;
|
|
169
|
-
const cardStyle = selectStyles(typeof tokens === 'function' ? tokens() : tokens);
|
|
189
|
+
const cardStyle = selectStyles(typeof tokens === 'function' ? tokens(cardState) : tokens);
|
|
170
190
|
const props = selectProps(rest);
|
|
171
191
|
let content = children;
|
|
172
192
|
const {
|
|
@@ -180,9 +200,13 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
180
200
|
const backgroundImagePosition = useResponsiveProp(position);
|
|
181
201
|
const backgroundImageAlign = useResponsiveProp(align);
|
|
182
202
|
const imageSourceViewport = formatImageSource(useResponsiveProp(src));
|
|
203
|
+
const {
|
|
204
|
+
content: fullBleedImageContent,
|
|
205
|
+
position: fullBleedContentPosition,
|
|
206
|
+
imgCol
|
|
207
|
+
} = fullBleedContent || {};
|
|
208
|
+
const fullBleedPosition = useResponsiveProp(fullBleedContentPosition, 'bottom');
|
|
183
209
|
if (backgroundImage && src) {
|
|
184
|
-
// When there's a background image, separate the padding from the container style
|
|
185
|
-
// so the image can fill the entire container without padding interference
|
|
186
210
|
const {
|
|
187
211
|
paddingTop,
|
|
188
212
|
paddingBottom,
|
|
@@ -190,8 +214,6 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
190
214
|
paddingRight,
|
|
191
215
|
...containerStyle
|
|
192
216
|
} = cardStyle;
|
|
193
|
-
|
|
194
|
-
// Only create padding wrapper if there's actually padding defined
|
|
195
217
|
const hasPadding = paddingTop || paddingBottom || paddingLeft || paddingRight;
|
|
196
218
|
const paddedContent = hasPadding ? /*#__PURE__*/_jsx(View, {
|
|
197
219
|
style: {
|
|
@@ -219,6 +241,53 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
219
241
|
children: content
|
|
220
242
|
});
|
|
221
243
|
}
|
|
244
|
+
if (fullBleedContent && fullBleedImageContent) {
|
|
245
|
+
const {
|
|
246
|
+
paddingTop,
|
|
247
|
+
paddingBottom,
|
|
248
|
+
paddingLeft,
|
|
249
|
+
paddingRight,
|
|
250
|
+
...containerStyle
|
|
251
|
+
} = cardStyle;
|
|
252
|
+
const imageColumns = imgCol || {
|
|
253
|
+
xs: GRID_COLUMNS
|
|
254
|
+
};
|
|
255
|
+
const textColumns = {};
|
|
256
|
+
Object.keys(imageColumns).forEach(breakpoint => {
|
|
257
|
+
textColumns[breakpoint] = GRID_COLUMNS - (imageColumns[breakpoint] || GRID_COLUMNS);
|
|
258
|
+
});
|
|
259
|
+
const imageFirst = fullBleedPosition === 'top' || fullBleedPosition === 'left';
|
|
260
|
+
const imageColContent = /*#__PURE__*/_jsx(FlexGridCol, {
|
|
261
|
+
...imageColumns,
|
|
262
|
+
style: staticStyles.fullBleedImageCol,
|
|
263
|
+
children: fullBleedImageContent
|
|
264
|
+
});
|
|
265
|
+
const textColContent = /*#__PURE__*/_jsx(FlexGridCol, {
|
|
266
|
+
...textColumns,
|
|
267
|
+
style: {
|
|
268
|
+
paddingTop,
|
|
269
|
+
paddingBottom,
|
|
270
|
+
paddingLeft,
|
|
271
|
+
paddingRight
|
|
272
|
+
},
|
|
273
|
+
children: children
|
|
274
|
+
});
|
|
275
|
+
return /*#__PURE__*/_jsx(View, {
|
|
276
|
+
style: containerStyle,
|
|
277
|
+
dataSet: dataSet,
|
|
278
|
+
ref: ref,
|
|
279
|
+
...props,
|
|
280
|
+
children: /*#__PURE__*/_jsx(FlexGrid, {
|
|
281
|
+
children: /*#__PURE__*/_jsx(FlexGridRow, {
|
|
282
|
+
children: imageFirst ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
283
|
+
children: [imageColContent, textColContent]
|
|
284
|
+
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
285
|
+
children: [textColContent, imageColContent]
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
});
|
|
290
|
+
}
|
|
222
291
|
return /*#__PURE__*/_jsx(View, {
|
|
223
292
|
style: cardStyle,
|
|
224
293
|
dataSet: dataSet,
|
|
@@ -228,6 +297,13 @@ const CardBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
228
297
|
});
|
|
229
298
|
});
|
|
230
299
|
CardBase.displayName = 'CardBase';
|
|
300
|
+
export const fullBleedContentPropTypes = PropTypes.shape({
|
|
301
|
+
content: PropTypes.node.isRequired,
|
|
302
|
+
alt: PropTypes.string,
|
|
303
|
+
position: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['bottom', 'left', 'right', 'top'])),
|
|
304
|
+
align: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['start', 'end', 'center', 'stretch'])),
|
|
305
|
+
imgCol: PropTypes.object
|
|
306
|
+
});
|
|
231
307
|
const staticStyles = StyleSheet.create({
|
|
232
308
|
imageBackground: {
|
|
233
309
|
width: '100%',
|
|
@@ -249,6 +325,9 @@ const staticStyles = StyleSheet.create({
|
|
|
249
325
|
position: 'absolute',
|
|
250
326
|
width: '100%',
|
|
251
327
|
height: '100%'
|
|
328
|
+
},
|
|
329
|
+
fullBleedImageCol: {
|
|
330
|
+
padding: 0
|
|
252
331
|
}
|
|
253
332
|
});
|
|
254
333
|
CardBase.propTypes = {
|
|
@@ -266,6 +345,7 @@ CardBase.propTypes = {
|
|
|
266
345
|
resizeMode: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])),
|
|
267
346
|
position: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['bottom', 'left', 'right', 'top'])),
|
|
268
347
|
align: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['start', 'end', 'center', 'stretch']))
|
|
269
|
-
})
|
|
348
|
+
}),
|
|
349
|
+
fullBleedContent: fullBleedContentPropTypes
|
|
270
350
|
};
|
|
271
351
|
export default CardBase;
|
|
@@ -7,10 +7,10 @@ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
|
7
7
|
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
|
-
import CardBase from './CardBase';
|
|
10
|
+
import CardBase, { fullBleedContentPropTypes } from './CardBase';
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
13
|
-
const tokenKeys = ['flex', 'backgroundColor', 'borderColor', 'gradient', 'borderRadius', 'borderWidth', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'minWidth', 'shadow', 'contentAlignItems', 'contentJustifyContent', 'contentFlexGrow', 'contentFlexShrink',
|
|
13
|
+
const tokenKeys = ['flex', 'backgroundColor', 'borderColor', 'gradient', 'borderRadius', 'borderWidth', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', 'minWidth', 'shadow', 'contentAlignItems', 'contentJustifyContent', 'contentFlexGrow', 'contentFlexShrink',
|
|
14
14
|
// Outer border tokens. TODO: centralise common token sets like these as part of
|
|
15
15
|
// https://github.com/telus/universal-design-system/issues/782
|
|
16
16
|
'outerBorderColor', 'outerBorderWidth', 'outerBorderGap', 'icon', 'iconBackgroundColor', 'iconColor', 'iconSize', 'inputBackgroundColor', 'inputBorderColor', 'inputBorderRadius', 'inputBorderWidth', 'inputHeight', 'inputShadow', 'inputWidth'];
|
|
@@ -32,6 +32,7 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
32
32
|
hrefAttrs,
|
|
33
33
|
dataSet,
|
|
34
34
|
backgroundImage,
|
|
35
|
+
fullBleedContent,
|
|
35
36
|
accessibilityRole = href ? 'link' : undefined,
|
|
36
37
|
...rawRest
|
|
37
38
|
} = _ref;
|
|
@@ -125,10 +126,7 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
125
126
|
setFocused(false);
|
|
126
127
|
setPressed(false);
|
|
127
128
|
},
|
|
128
|
-
style:
|
|
129
|
-
...staticStyles.linkContainer,
|
|
130
|
-
textDecoration: 'none'
|
|
131
|
-
},
|
|
129
|
+
style: staticStyles.linkContainer,
|
|
132
130
|
...(hrefAttrs || {}),
|
|
133
131
|
role: accessibilityRole,
|
|
134
132
|
children: /*#__PURE__*/_jsx(CardBase, {
|
|
@@ -138,6 +136,7 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
138
136
|
hovered
|
|
139
137
|
}),
|
|
140
138
|
backgroundImage: backgroundImage,
|
|
139
|
+
fullBleedContent: fullBleedContent,
|
|
141
140
|
children: typeof children === 'function' ? children(getCardState({
|
|
142
141
|
pressed,
|
|
143
142
|
focused,
|
|
@@ -162,6 +161,7 @@ const PressableCardBase = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
162
161
|
children: pressableState => /*#__PURE__*/_jsx(CardBase, {
|
|
163
162
|
tokens: getCardTokens(pressableState),
|
|
164
163
|
backgroundImage: backgroundImage,
|
|
164
|
+
fullBleedContent: fullBleedContent,
|
|
165
165
|
children: typeof children === 'function' ? children(getCardState(pressableState)) : children
|
|
166
166
|
})
|
|
167
167
|
});
|
|
@@ -175,7 +175,8 @@ const staticStyles = StyleSheet.create({
|
|
|
175
175
|
flex: 1,
|
|
176
176
|
display: 'flex',
|
|
177
177
|
alignItems: 'stretch',
|
|
178
|
-
justifyContent: 'flex-start'
|
|
178
|
+
justifyContent: 'flex-start',
|
|
179
|
+
textDecorationLine: 'none'
|
|
179
180
|
}
|
|
180
181
|
});
|
|
181
182
|
PressableCardBase.displayName = 'PressableCardBase';
|
|
@@ -195,6 +196,7 @@ PressableCardBase.propTypes = {
|
|
|
195
196
|
resizeMode: PropTypes.oneOfType([PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center']), PropTypes.object]),
|
|
196
197
|
position: PropTypes.oneOfType([PropTypes.oneOf(['bottom', 'left', 'right', 'top']), PropTypes.object]),
|
|
197
198
|
align: PropTypes.oneOfType([PropTypes.oneOf(['start', 'end', 'center', 'stretch']), PropTypes.object])
|
|
198
|
-
})
|
|
199
|
+
}),
|
|
200
|
+
fullBleedContent: fullBleedContentPropTypes
|
|
199
201
|
};
|
|
200
202
|
export default withLinkRouter(PressableCardBase);
|
|
@@ -357,6 +357,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
357
357
|
...rest
|
|
358
358
|
} = _ref3;
|
|
359
359
|
let childrenArray = unpackFragment(children);
|
|
360
|
+
const isTransitioningRef = React.useRef(false);
|
|
360
361
|
const viewport = useViewport();
|
|
361
362
|
const totalItems = getTotalItems(enableDisplayMultipleItemsPerSlide, childrenArray, viewport);
|
|
362
363
|
const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && totalItems > 1;
|
|
@@ -427,9 +428,14 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
427
428
|
setIsAnimating(true);
|
|
428
429
|
}, [onAnimationStart]);
|
|
429
430
|
const handleAnimationEnd = React.useCallback(function () {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
431
|
+
var _ref4;
|
|
432
|
+
const result = (_ref4 = arguments.length - 1, _ref4 < 0 || arguments.length <= _ref4 ? undefined : arguments[_ref4]);
|
|
433
|
+
if (result?.finished) {
|
|
434
|
+
if (typeof onAnimationEnd === 'function') onAnimationEnd(...arguments);
|
|
435
|
+
setIsAnimating(false);
|
|
436
|
+
isTransitioningRef.current = false;
|
|
437
|
+
}
|
|
438
|
+
}, [onAnimationEnd, isTransitioningRef]);
|
|
433
439
|
const updateOffset = React.useCallback(() => {
|
|
434
440
|
if (enablePeeking) {
|
|
435
441
|
const {
|
|
@@ -537,6 +543,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
537
543
|
}
|
|
538
544
|
const index = activeIndexRef.current + calcDelta;
|
|
539
545
|
if (skipChanges) {
|
|
546
|
+
isTransitioningRef.current = true;
|
|
540
547
|
animate(pan, toValue, index);
|
|
541
548
|
if (enableHero) {
|
|
542
549
|
animate(heroPan, toValue, index);
|
|
@@ -552,6 +559,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
552
559
|
y: 0
|
|
553
560
|
};
|
|
554
561
|
heroToValue.x = heroContainerLayoutRef.current.width * -1 * calcDelta;
|
|
562
|
+
isTransitioningRef.current = true;
|
|
555
563
|
animate(pan, toValue, index);
|
|
556
564
|
if (enableHero) {
|
|
557
565
|
animate(heroPan, heroToValue, index);
|
|
@@ -607,29 +615,29 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
607
615
|
heroContainerLayoutRef.current = heroContainerLayout;
|
|
608
616
|
}, [heroContainerLayout]);
|
|
609
617
|
React.useEffect(() => {
|
|
610
|
-
pan.x.addListener(
|
|
618
|
+
pan.x.addListener(_ref5 => {
|
|
611
619
|
let {
|
|
612
620
|
value
|
|
613
|
-
} =
|
|
621
|
+
} = _ref5;
|
|
614
622
|
animatedX.current = value;
|
|
615
623
|
});
|
|
616
|
-
pan.y.addListener(
|
|
624
|
+
pan.y.addListener(_ref6 => {
|
|
617
625
|
let {
|
|
618
626
|
value
|
|
619
|
-
} =
|
|
627
|
+
} = _ref6;
|
|
620
628
|
animatedY.current = value;
|
|
621
629
|
});
|
|
622
630
|
if (enableHero) {
|
|
623
|
-
heroPan.x.addListener(
|
|
631
|
+
heroPan.x.addListener(_ref7 => {
|
|
624
632
|
let {
|
|
625
633
|
value
|
|
626
|
-
} =
|
|
634
|
+
} = _ref7;
|
|
627
635
|
heroAnimatedX.current = value;
|
|
628
636
|
});
|
|
629
|
-
heroPan.y.addListener(
|
|
637
|
+
heroPan.y.addListener(_ref8 => {
|
|
630
638
|
let {
|
|
631
639
|
value
|
|
632
|
-
} =
|
|
640
|
+
} = _ref8;
|
|
633
641
|
heroAnimatedY.current = value;
|
|
634
642
|
});
|
|
635
643
|
}
|
|
@@ -666,7 +674,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
666
674
|
stopAutoplay();
|
|
667
675
|
};
|
|
668
676
|
}, [stopAutoplay]);
|
|
669
|
-
const onContainerLayout =
|
|
677
|
+
const onContainerLayout = _ref9 => {
|
|
670
678
|
let {
|
|
671
679
|
nativeEvent: {
|
|
672
680
|
layout: {
|
|
@@ -676,7 +684,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
676
684
|
height
|
|
677
685
|
}
|
|
678
686
|
}
|
|
679
|
-
} =
|
|
687
|
+
} = _ref9;
|
|
680
688
|
return setContainerLayout(prevState => ({
|
|
681
689
|
...prevState,
|
|
682
690
|
x,
|
|
@@ -685,7 +693,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
685
693
|
height
|
|
686
694
|
}));
|
|
687
695
|
};
|
|
688
|
-
const onHeroContainerLayout =
|
|
696
|
+
const onHeroContainerLayout = _ref10 => {
|
|
689
697
|
let {
|
|
690
698
|
nativeEvent: {
|
|
691
699
|
layout: {
|
|
@@ -695,7 +703,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
695
703
|
height
|
|
696
704
|
}
|
|
697
705
|
}
|
|
698
|
-
} =
|
|
706
|
+
} = _ref10;
|
|
699
707
|
return setHeroContainerLayout(prevState => ({
|
|
700
708
|
...prevState,
|
|
701
709
|
x,
|
|
@@ -704,14 +712,14 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
704
712
|
height
|
|
705
713
|
}));
|
|
706
714
|
};
|
|
707
|
-
const onPreviousNextNavigationButtonLayout =
|
|
715
|
+
const onPreviousNextNavigationButtonLayout = _ref11 => {
|
|
708
716
|
let {
|
|
709
717
|
nativeEvent: {
|
|
710
718
|
layout: {
|
|
711
719
|
width
|
|
712
720
|
}
|
|
713
721
|
}
|
|
714
|
-
} =
|
|
722
|
+
} = _ref11;
|
|
715
723
|
return setPreviousNextNavigationButtonWidth(width);
|
|
716
724
|
};
|
|
717
725
|
const isSwipeAllowed = React.useCallback(() => {
|
|
@@ -873,6 +881,11 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
873
881
|
}
|
|
874
882
|
setisCarouselPlaying(prevState => !prevState);
|
|
875
883
|
}, [isCarouselPlaying, stopAutoplay, startAutoplay]);
|
|
884
|
+
const handleKeyDown = React.useCallback(event => {
|
|
885
|
+
if (isTransitioningRef.current && event.key === 'Tab') {
|
|
886
|
+
event.preventDefault();
|
|
887
|
+
}
|
|
888
|
+
}, [isTransitioningRef]);
|
|
876
889
|
return /*#__PURE__*/_jsxs(View, {
|
|
877
890
|
style: selectRootContainerStyles(enableHero, viewport),
|
|
878
891
|
children: [/*#__PURE__*/_jsx(View, {
|
|
@@ -898,6 +911,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
898
911
|
ref: ref,
|
|
899
912
|
...systemProps,
|
|
900
913
|
...containerProps,
|
|
914
|
+
...(Platform.OS === 'web' ? {
|
|
915
|
+
onKeyDown: handleKeyDown
|
|
916
|
+
} : {}),
|
|
901
917
|
children: [isAutoPlayEnabled ? /*#__PURE__*/_jsx(View, {
|
|
902
918
|
style: [staticStyles.animationControlButton, selectControlButtonPositionStyles({
|
|
903
919
|
positionVariant: previousNextNavigationPosition,
|
|
@@ -952,10 +968,27 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
952
968
|
// This is a known Voiceover bug: https://github.com/phetsims/a11y-research/issues/132
|
|
953
969
|
accessibilityLiveRegion: accessibilityLiveRegion,
|
|
954
970
|
children: childrenArray.map((element, index) => {
|
|
955
|
-
|
|
971
|
+
let hidden = !isAnimating && index !== activeIndex;
|
|
972
|
+
if (enablePeeking && !isAnimating) {
|
|
973
|
+
if (enableDisplayMultipleItemsPerSlide) {
|
|
974
|
+
const maxItemsForSlide = getMaximumItemsForSlide(enableDisplayMultipleItemsPerSlide, viewport);
|
|
975
|
+
if (index >= activeIndex * maxItemsForSlide - 1 && index < activeIndex * maxItemsForSlide + maxItemsForSlide + 1) {
|
|
976
|
+
hidden = false;
|
|
977
|
+
} else {
|
|
978
|
+
hidden = true;
|
|
979
|
+
}
|
|
980
|
+
} else if (index >= activeIndex - 1 && index <= activeIndex + 1) {
|
|
981
|
+
hidden = false;
|
|
982
|
+
}
|
|
983
|
+
} else if (!enablePeeking && enableDisplayMultipleItemsPerSlide && !isAnimating) {
|
|
984
|
+
const maxItemsForSlide = getMaximumItemsForSlide(enableDisplayMultipleItemsPerSlide, viewport);
|
|
985
|
+
if (index >= activeIndex * maxItemsForSlide && index < activeIndex * maxItemsForSlide + maxItemsForSlide) {
|
|
986
|
+
hidden = false;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
956
989
|
const clonedElement = /*#__PURE__*/React.cloneElement(element, {
|
|
957
990
|
elementIndex: index,
|
|
958
|
-
hidden
|
|
991
|
+
hidden,
|
|
959
992
|
enablePeeking,
|
|
960
993
|
peekingProps: getPeekingProps(viewport),
|
|
961
994
|
enableDisplayMultipleItemsPerSlide,
|
|
@@ -97,13 +97,33 @@ const CarouselItem = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
97
97
|
});
|
|
98
98
|
const focusabilityProps = activeIndex === elementIndex || enablePeeking ? {} : a11yProps.nonFocusableProps;
|
|
99
99
|
const handleFocus = React.useCallback(event => {
|
|
100
|
-
if (Platform.OS === 'web'
|
|
101
|
-
|
|
100
|
+
if (Platform.OS === 'web') {
|
|
101
|
+
if (enablePeeking) {
|
|
102
|
+
if (enableDisplayMultipleItemsPerSlide) {
|
|
103
|
+
const startIndex = maximumItemsForSlide * activeIndex;
|
|
104
|
+
const endIndex = startIndex + maximumItemsForSlide - 1;
|
|
105
|
+
if (elementIndex < startIndex) {
|
|
106
|
+
if (activeIndex - 1 < 0) {
|
|
107
|
+
goTo(0);
|
|
108
|
+
} else {
|
|
109
|
+
goTo(activeIndex - 1);
|
|
110
|
+
}
|
|
111
|
+
} else if (elementIndex > endIndex) {
|
|
112
|
+
goTo(activeIndex + 1);
|
|
113
|
+
}
|
|
114
|
+
} else if (elementIndex !== activeIndex) {
|
|
115
|
+
if (elementIndex > activeIndex) {
|
|
116
|
+
goTo(activeIndex + 1);
|
|
117
|
+
} else if (elementIndex < activeIndex) {
|
|
118
|
+
goTo(activeIndex - 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
102
122
|
}
|
|
103
123
|
if (rest.onFocus) {
|
|
104
124
|
rest.onFocus(event);
|
|
105
125
|
}
|
|
106
|
-
}, [elementIndex, activeIndex, goTo, maximumItemsForSlide, rest]);
|
|
126
|
+
}, [elementIndex, activeIndex, goTo, maximumItemsForSlide, rest, enablePeeking, enableDisplayMultipleItemsPerSlide]);
|
|
107
127
|
return /*#__PURE__*/_jsx(View, {
|
|
108
128
|
style: selectContainerStyle({
|
|
109
129
|
width,
|
|
@@ -4,7 +4,7 @@ import Platform from "react-native-web/dist/exports/Platform";
|
|
|
4
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
5
|
import View from "react-native-web/dist/exports/View";
|
|
6
6
|
import { validateThemeTokens, resolveThemeTokens } from '../ThemeProvider';
|
|
7
|
-
import { a11yProps, getTokensSetPropType, selectSystemProps, selectTokens, viewProps } from '../utils';
|
|
7
|
+
import { a11yProps, getTokensSetPropType, selectSystemProps, selectTokens, variantProp, viewProps } from '../utils';
|
|
8
8
|
import ScrollViewEnd from './ScrollViewEnd';
|
|
9
9
|
import { getItemPositionScrollTarget, itemPositionsPropType } from './itemPositions';
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -27,6 +27,7 @@ const HorizontalScroll = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
27
27
|
ScrollButton,
|
|
28
28
|
tokens,
|
|
29
29
|
itemPositions,
|
|
30
|
+
variant,
|
|
30
31
|
children,
|
|
31
32
|
...rest
|
|
32
33
|
} = _ref;
|
|
@@ -70,8 +71,9 @@ const HorizontalScroll = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
70
71
|
setScrollOffset(x);
|
|
71
72
|
};
|
|
72
73
|
const scrollMax = Math.max(0, contentWidth - containerWidth);
|
|
73
|
-
const
|
|
74
|
-
const
|
|
74
|
+
const hideNavigationButtons = variant?.hideNavigationButtons || false;
|
|
75
|
+
const showNextButton = scrollOffset < scrollMax && !hideNavigationButtons;
|
|
76
|
+
const showPreviousButton = scrollOffset > 0 && !hideNavigationButtons;
|
|
75
77
|
const scrollRef = React.useRef(null);
|
|
76
78
|
const scrollTo = targetX => {
|
|
77
79
|
if (typeof scrollRef.current?.scrollTo === 'function') {
|
|
@@ -162,6 +164,7 @@ HorizontalScroll.propTypes = {
|
|
|
162
164
|
tokens: getTokensSetPropType(tokenKeys, {
|
|
163
165
|
allowFunction: true
|
|
164
166
|
}),
|
|
167
|
+
variant: variantProp.propType,
|
|
165
168
|
children: PropTypes.node
|
|
166
169
|
};
|
|
167
170
|
export default HorizontalScroll;
|
package/lib/esm/Icon/Icon.js
CHANGED
|
@@ -14,6 +14,7 @@ const Icon = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
14
14
|
tokens,
|
|
15
15
|
scalesWithText = false,
|
|
16
16
|
style = {},
|
|
17
|
+
testID,
|
|
17
18
|
dataSet
|
|
18
19
|
} = _ref;
|
|
19
20
|
const themeTokens = useThemeTokens('Icon', tokens, variant);
|
|
@@ -36,19 +37,18 @@ const Icon = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
36
37
|
padding: themeTokens.padding
|
|
37
38
|
};
|
|
38
39
|
const getIconContentForMobile = () => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
return iconContent;
|
|
40
|
+
return /*#__PURE__*/_jsx(View, {
|
|
41
|
+
testID: testID,
|
|
42
|
+
style: {
|
|
43
|
+
backgroundColor: themeTokens.backgroundColor,
|
|
44
|
+
borderRadius: themeTokens.borderRadius,
|
|
45
|
+
...paddingStyles
|
|
46
|
+
},
|
|
47
|
+
children: iconContent
|
|
48
|
+
});
|
|
50
49
|
};
|
|
51
50
|
return Platform.OS === 'web' ? /*#__PURE__*/_jsx(View, {
|
|
51
|
+
testID: testID,
|
|
52
52
|
ref: ref
|
|
53
53
|
// eslint-disable-next-line react-native/no-inline-styles
|
|
54
54
|
,
|
package/lib/esm/Icon/IconText.js
CHANGED
|
@@ -100,7 +100,6 @@ IconText.propTypes = {
|
|
|
100
100
|
* `<Typography>` component, or a component that renders `<Text>`.
|
|
101
101
|
*/
|
|
102
102
|
children: PropTypes.node
|
|
103
|
-
/* eslint-enable react/no-unused-prop-types */
|
|
104
103
|
};
|
|
105
104
|
const staticStyles = StyleSheet.create({
|
|
106
105
|
adjustedContainer: {
|