@telus-uds/components-base 3.21.0 → 3.23.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 +31 -1
- package/lib/cjs/Button/Button.js +12 -3
- package/lib/cjs/Button/ButtonBase.js +63 -10
- 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/PressableCardBase.js +3 -1
- package/lib/cjs/Carousel/Carousel.js +63 -22
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +23 -3
- package/lib/cjs/Icon/Icon.js +8 -11
- package/lib/cjs/Icon/IconText.js +0 -1
- package/lib/cjs/Listbox/GroupControl.js +33 -39
- package/lib/cjs/Listbox/Listbox.js +22 -13
- package/lib/cjs/Listbox/ListboxGroup.js +2 -1
- package/lib/cjs/Listbox/ListboxOverlay.js +5 -2
- package/lib/cjs/Listbox/PressableItem.js +8 -4
- package/lib/cjs/TextInput/TextInputBase.js +5 -1
- package/lib/cjs/ThemeProvider/index.js +9 -1
- package/lib/cjs/ThemeProvider/useResponsiveThemeTokensCallback.js +124 -0
- package/lib/cjs/Validator/Validator.js +171 -135
- package/lib/cjs/index.js +7 -0
- package/lib/esm/Button/Button.js +13 -4
- package/lib/esm/Button/ButtonBase.js +64 -11
- 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/PressableCardBase.js +3 -1
- package/lib/esm/Carousel/Carousel.js +63 -22
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +23 -3
- package/lib/esm/Icon/Icon.js +8 -11
- package/lib/esm/Icon/IconText.js +0 -1
- package/lib/esm/Listbox/GroupControl.js +33 -39
- package/lib/esm/Listbox/Listbox.js +23 -14
- package/lib/esm/Listbox/ListboxGroup.js +2 -1
- package/lib/esm/Listbox/ListboxOverlay.js +5 -2
- package/lib/esm/Listbox/PressableItem.js +8 -4
- package/lib/esm/TextInput/TextInputBase.js +5 -1
- package/lib/esm/ThemeProvider/index.js +1 -0
- package/lib/esm/ThemeProvider/useResponsiveThemeTokensCallback.js +117 -0
- package/lib/esm/Validator/Validator.js +171 -135
- package/lib/esm/index.js +1 -1
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Button/Button.jsx +26 -5
- package/src/Button/ButtonBase.jsx +79 -16
- package/src/Button/ButtonDropdown.jsx +2 -0
- package/src/Button/ButtonGroup.jsx +62 -45
- package/src/Button/propTypes.js +6 -0
- package/src/Card/PressableCardBase.jsx +3 -1
- package/src/Carousel/Carousel.jsx +71 -7
- package/src/Carousel/CarouselItem/CarouselItem.jsx +31 -3
- package/src/Icon/Icon.jsx +11 -14
- package/src/Icon/IconText.jsx +0 -1
- package/src/Listbox/GroupControl.jsx +41 -47
- package/src/Listbox/Listbox.jsx +26 -9
- package/src/Listbox/ListboxGroup.jsx +2 -1
- package/src/Listbox/ListboxOverlay.jsx +7 -2
- package/src/Listbox/PressableItem.jsx +8 -4
- package/src/PriceLockup/utils/renderPrice.jsx +15 -17
- package/src/TextInput/TextInputBase.jsx +5 -1
- package/src/ThemeProvider/index.js +1 -0
- package/src/ThemeProvider/useResponsiveThemeTokensCallback.js +129 -0
- package/src/Validator/Validator.jsx +180 -159
- package/src/index.js +2 -1
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import ABBPropTypes from 'airbnb-prop-types';
|
|
4
4
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
5
|
+
import View from "react-native-web/dist/exports/View";
|
|
6
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
7
|
import ButtonBase from './ButtonBase';
|
|
6
|
-
import { StackWrap } from '../StackView';
|
|
7
8
|
import Fieldset from '../Fieldset';
|
|
8
9
|
import { useViewport } from '../ViewportProvider';
|
|
9
10
|
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
|
|
10
|
-
import { a11yProps, containUniqueFields, focusHandlerProps, pressProps, getTokensPropType, selectSystemProps,
|
|
11
|
+
import { useSpacingScale, a11yProps, containUniqueFields, focusHandlerProps, pressProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps } from '../utils';
|
|
11
12
|
import { getPressHandlersWithArgs } from '../utils/pressability';
|
|
12
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
14
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
14
15
|
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, pressProps, viewProps]);
|
|
15
|
-
const getStackWrapTokens = variant => {
|
|
16
|
-
return Platform.select({
|
|
17
|
-
web: {
|
|
18
|
-
justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start',
|
|
19
|
-
width: variant?.width === 'equal' ? '100%' : 'auto'
|
|
20
|
-
},
|
|
21
|
-
default: {}
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
16
|
const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
25
17
|
let {
|
|
26
18
|
variant,
|
|
@@ -53,12 +45,6 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
53
45
|
const themeTokens = useThemeTokens('ButtonGroup', tokens, variant, {
|
|
54
46
|
viewport
|
|
55
47
|
});
|
|
56
|
-
const themeStackTokens = selectTokens('StackView', themeTokens);
|
|
57
|
-
const variantStackTokens = getStackWrapTokens(variant);
|
|
58
|
-
const stackTokens = {
|
|
59
|
-
...themeStackTokens,
|
|
60
|
-
...variantStackTokens
|
|
61
|
-
};
|
|
62
48
|
const {
|
|
63
49
|
direction,
|
|
64
50
|
space,
|
|
@@ -68,15 +54,34 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
68
54
|
padding,
|
|
69
55
|
gap
|
|
70
56
|
} = themeTokens;
|
|
57
|
+
const isMobileNonContained = Platform.OS !== 'web' && (!variant || variant?.style !== 'contained');
|
|
71
58
|
const themeButtonTokensCallback = useThemeTokensCallback('ButtonGroupItem', tokens, variant);
|
|
72
|
-
const
|
|
59
|
+
const gapValue = useSpacingScale(gap || space);
|
|
60
|
+
const getButtonTokens = useCallback(state => {
|
|
73
61
|
const themeButtonTokens = themeButtonTokensCallback(state);
|
|
62
|
+
const shouldUseTransparentBackground = isMobileNonContained && !state.selected && !state.pressed && !state.hover && !state.focus;
|
|
74
63
|
return {
|
|
75
64
|
...themeButtonTokens,
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
...(variant?.width === 'equal' && staticStyles.equalWidth),
|
|
66
|
+
...(shouldUseTransparentBackground && {
|
|
67
|
+
backgroundColor: 'transparent'
|
|
68
|
+
}),
|
|
69
|
+
alignSelf: themeButtonTokens.width ? 'flex-start' : 'center'
|
|
78
70
|
};
|
|
79
|
-
};
|
|
71
|
+
}, [themeButtonTokensCallback, isMobileNonContained, variant?.width]);
|
|
72
|
+
const fieldsetStyles = useMemo(() => ({
|
|
73
|
+
...staticStyles.fieldsetBase,
|
|
74
|
+
borderRadius,
|
|
75
|
+
backgroundColor: isMobileNonContained ? 'transparent' : backgroundColor || 'transparent',
|
|
76
|
+
padding,
|
|
77
|
+
width: variant?.width === 'equal' ? '100%' : 'auto'
|
|
78
|
+
}), [borderRadius, backgroundColor, padding, variant?.width, isMobileNonContained]);
|
|
79
|
+
const viewStyles = useMemo(() => ({
|
|
80
|
+
...staticStyles.viewBase,
|
|
81
|
+
flexDirection: direction === 'column' ? 'column' : 'row',
|
|
82
|
+
gap: gapValue || 0,
|
|
83
|
+
justifyContent: variant?.width === 'equal' ? 'space-evenly' : 'flex-start'
|
|
84
|
+
}), [direction, gapValue, variant?.width]);
|
|
80
85
|
const {
|
|
81
86
|
currentValues,
|
|
82
87
|
toggleOneValue
|
|
@@ -113,25 +118,11 @@ const ButtonGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
113
118
|
inactive: inactive,
|
|
114
119
|
validation: validation,
|
|
115
120
|
accessibilityRole: accessibilityRole,
|
|
116
|
-
style:
|
|
117
|
-
borderRadius,
|
|
118
|
-
backgroundColor,
|
|
119
|
-
padding,
|
|
120
|
-
...(Platform.OS === 'web' ? {
|
|
121
|
-
gap,
|
|
122
|
-
width: variant?.width === 'equal' ? '100%' : 'auto'
|
|
123
|
-
} : {
|
|
124
|
-
alignSelf: 'flex-start'
|
|
125
|
-
})
|
|
126
|
-
},
|
|
121
|
+
style: fieldsetStyles,
|
|
127
122
|
...selectProps(rest),
|
|
128
|
-
children: /*#__PURE__*/_jsx(
|
|
123
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
129
124
|
accessibilityRole: innerRole,
|
|
130
|
-
|
|
131
|
-
direction: direction,
|
|
132
|
-
tokens: stackTokens,
|
|
133
|
-
gap: gap,
|
|
134
|
-
ref: ref,
|
|
125
|
+
style: viewStyles,
|
|
135
126
|
children: items.map((_ref2, index) => {
|
|
136
127
|
let {
|
|
137
128
|
label,
|
|
@@ -291,4 +282,18 @@ ButtonGroup.propTypes = {
|
|
|
291
282
|
*/
|
|
292
283
|
copy: PropTypes.oneOf(['en', 'fr'])
|
|
293
284
|
};
|
|
285
|
+
const staticStyles = StyleSheet.create({
|
|
286
|
+
fieldsetBase: {
|
|
287
|
+
alignSelf: 'flex-start',
|
|
288
|
+
display: 'inline'
|
|
289
|
+
},
|
|
290
|
+
viewBase: {
|
|
291
|
+
flexWrap: 'wrap',
|
|
292
|
+
alignItems: 'center'
|
|
293
|
+
},
|
|
294
|
+
equalWidth: {
|
|
295
|
+
width: '100%',
|
|
296
|
+
flex: 1
|
|
297
|
+
}
|
|
298
|
+
});
|
|
294
299
|
export default ButtonGroup;
|
|
@@ -6,6 +6,12 @@ import { iconComponentPropTypes } from '../Icon';
|
|
|
6
6
|
export const textAndA11yText = ABBPropTypes.childrenOf(PropTypes.oneOfType([ABBPropTypes.elementType(A11yText), PropTypes.string]));
|
|
7
7
|
const buttonPropTypes = {
|
|
8
8
|
tokens: getTokensPropType('Button'),
|
|
9
|
+
/**
|
|
10
|
+
* If true, the button will honor the align-items value from its parent flex container.
|
|
11
|
+
* If false, the button will always align to 'flex-start' in a flex container.
|
|
12
|
+
* Currently, `heightFull`'s default behaviour will expand to the full height of its parent's flex container. In an upcoming major release, the default behaviour will be changed to expand based on the content. To maintain the expected behaviour, you must explicitly set `heightFull: true`
|
|
13
|
+
*/
|
|
14
|
+
heightFull: PropTypes.bool,
|
|
9
15
|
/**
|
|
10
16
|
* If true, prevents the button from being pressed, changes the cursor (on web) and accessibility
|
|
11
17
|
* attributes to communicate this to the user, and applies `inactive: true` appearances from the theme
|
|
@@ -173,7 +173,9 @@ const staticStyles = StyleSheet.create({
|
|
|
173
173
|
},
|
|
174
174
|
linkContainer: {
|
|
175
175
|
flex: 1,
|
|
176
|
-
display: 'flex'
|
|
176
|
+
display: 'flex',
|
|
177
|
+
alignItems: 'stretch',
|
|
178
|
+
justifyContent: 'flex-start'
|
|
177
179
|
}
|
|
178
180
|
});
|
|
179
181
|
PressableCardBase.displayName = 'PressableCardBase';
|
|
@@ -351,11 +351,13 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
351
351
|
copy,
|
|
352
352
|
slideDuration = 0,
|
|
353
353
|
transitionDuration = 0,
|
|
354
|
+
loopDuration = transitionDuration,
|
|
354
355
|
autoPlay = false,
|
|
355
356
|
enablePeeking = false,
|
|
356
357
|
...rest
|
|
357
358
|
} = _ref3;
|
|
358
359
|
let childrenArray = unpackFragment(children);
|
|
360
|
+
const isTransitioningRef = React.useRef(false);
|
|
359
361
|
const viewport = useViewport();
|
|
360
362
|
const totalItems = getTotalItems(enableDisplayMultipleItemsPerSlide, childrenArray, viewport);
|
|
361
363
|
const autoPlayFeatureEnabled = autoPlay && slideDuration > 0 && transitionDuration > 0 && totalItems > 1;
|
|
@@ -426,9 +428,14 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
426
428
|
setIsAnimating(true);
|
|
427
429
|
}, [onAnimationStart]);
|
|
428
430
|
const handleAnimationEnd = React.useCallback(function () {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
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]);
|
|
432
439
|
const updateOffset = React.useCallback(() => {
|
|
433
440
|
if (enablePeeking) {
|
|
434
441
|
const {
|
|
@@ -470,6 +477,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
470
477
|
}
|
|
471
478
|
}, [pan, animatedX, heroPan, heroAnimatedX, enableHero, viewport, enablePeeking]);
|
|
472
479
|
const animate = React.useCallback((panToAnimate, toValue, toIndex) => {
|
|
480
|
+
const applicableTransitionDuration = isLastSlide && toIndex === 0 ? loopDuration : transitionDuration;
|
|
473
481
|
const handleAnimationEndToIndex = function () {
|
|
474
482
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
475
483
|
args[_key] = arguments[_key];
|
|
@@ -487,14 +495,14 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
487
495
|
...springConfig,
|
|
488
496
|
toValue,
|
|
489
497
|
useNativeDriver: false,
|
|
490
|
-
duration:
|
|
498
|
+
duration: applicableTransitionDuration * 1000
|
|
491
499
|
}).start(handleAnimationEndToIndex);
|
|
492
500
|
} else if (enablePeeking || enableDisplayMultipleItemsPerSlide) {
|
|
493
501
|
Animated.timing(panToAnimate, {
|
|
494
502
|
...springConfig,
|
|
495
503
|
toValue,
|
|
496
504
|
useNativeDriver: false,
|
|
497
|
-
duration:
|
|
505
|
+
duration: applicableTransitionDuration ? applicableTransitionDuration * 1000 : 1000
|
|
498
506
|
}).start(handleAnimationEndToIndex);
|
|
499
507
|
} else {
|
|
500
508
|
Animated.spring(panToAnimate, {
|
|
@@ -503,7 +511,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
503
511
|
useNativeDriver: false
|
|
504
512
|
}).start(handleAnimationEndToIndex);
|
|
505
513
|
}
|
|
506
|
-
}, [springConfig, handleAnimationEnd, transitionDuration, isAutoPlayEnabled, enablePeeking, enableDisplayMultipleItemsPerSlide]);
|
|
514
|
+
}, [springConfig, handleAnimationEnd, transitionDuration, loopDuration, isLastSlide, isAutoPlayEnabled, enablePeeking, enableDisplayMultipleItemsPerSlide]);
|
|
507
515
|
const stopAutoplay = React.useCallback(() => {
|
|
508
516
|
if (autoPlayRef?.current) {
|
|
509
517
|
clearTimeout(autoPlayRef?.current);
|
|
@@ -535,6 +543,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
535
543
|
}
|
|
536
544
|
const index = activeIndexRef.current + calcDelta;
|
|
537
545
|
if (skipChanges) {
|
|
546
|
+
isTransitioningRef.current = true;
|
|
538
547
|
animate(pan, toValue, index);
|
|
539
548
|
if (enableHero) {
|
|
540
549
|
animate(heroPan, toValue, index);
|
|
@@ -550,6 +559,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
550
559
|
y: 0
|
|
551
560
|
};
|
|
552
561
|
heroToValue.x = heroContainerLayoutRef.current.width * -1 * calcDelta;
|
|
562
|
+
isTransitioningRef.current = true;
|
|
553
563
|
animate(pan, toValue, index);
|
|
554
564
|
if (enableHero) {
|
|
555
565
|
animate(heroPan, heroToValue, index);
|
|
@@ -605,29 +615,29 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
605
615
|
heroContainerLayoutRef.current = heroContainerLayout;
|
|
606
616
|
}, [heroContainerLayout]);
|
|
607
617
|
React.useEffect(() => {
|
|
608
|
-
pan.x.addListener(
|
|
618
|
+
pan.x.addListener(_ref5 => {
|
|
609
619
|
let {
|
|
610
620
|
value
|
|
611
|
-
} =
|
|
621
|
+
} = _ref5;
|
|
612
622
|
animatedX.current = value;
|
|
613
623
|
});
|
|
614
|
-
pan.y.addListener(
|
|
624
|
+
pan.y.addListener(_ref6 => {
|
|
615
625
|
let {
|
|
616
626
|
value
|
|
617
|
-
} =
|
|
627
|
+
} = _ref6;
|
|
618
628
|
animatedY.current = value;
|
|
619
629
|
});
|
|
620
630
|
if (enableHero) {
|
|
621
|
-
heroPan.x.addListener(
|
|
631
|
+
heroPan.x.addListener(_ref7 => {
|
|
622
632
|
let {
|
|
623
633
|
value
|
|
624
|
-
} =
|
|
634
|
+
} = _ref7;
|
|
625
635
|
heroAnimatedX.current = value;
|
|
626
636
|
});
|
|
627
|
-
heroPan.y.addListener(
|
|
637
|
+
heroPan.y.addListener(_ref8 => {
|
|
628
638
|
let {
|
|
629
639
|
value
|
|
630
|
-
} =
|
|
640
|
+
} = _ref8;
|
|
631
641
|
heroAnimatedY.current = value;
|
|
632
642
|
});
|
|
633
643
|
}
|
|
@@ -664,7 +674,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
664
674
|
stopAutoplay();
|
|
665
675
|
};
|
|
666
676
|
}, [stopAutoplay]);
|
|
667
|
-
const onContainerLayout =
|
|
677
|
+
const onContainerLayout = _ref9 => {
|
|
668
678
|
let {
|
|
669
679
|
nativeEvent: {
|
|
670
680
|
layout: {
|
|
@@ -674,7 +684,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
674
684
|
height
|
|
675
685
|
}
|
|
676
686
|
}
|
|
677
|
-
} =
|
|
687
|
+
} = _ref9;
|
|
678
688
|
return setContainerLayout(prevState => ({
|
|
679
689
|
...prevState,
|
|
680
690
|
x,
|
|
@@ -683,7 +693,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
683
693
|
height
|
|
684
694
|
}));
|
|
685
695
|
};
|
|
686
|
-
const onHeroContainerLayout =
|
|
696
|
+
const onHeroContainerLayout = _ref10 => {
|
|
687
697
|
let {
|
|
688
698
|
nativeEvent: {
|
|
689
699
|
layout: {
|
|
@@ -693,7 +703,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
693
703
|
height
|
|
694
704
|
}
|
|
695
705
|
}
|
|
696
|
-
} =
|
|
706
|
+
} = _ref10;
|
|
697
707
|
return setHeroContainerLayout(prevState => ({
|
|
698
708
|
...prevState,
|
|
699
709
|
x,
|
|
@@ -702,14 +712,14 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
702
712
|
height
|
|
703
713
|
}));
|
|
704
714
|
};
|
|
705
|
-
const onPreviousNextNavigationButtonLayout =
|
|
715
|
+
const onPreviousNextNavigationButtonLayout = _ref11 => {
|
|
706
716
|
let {
|
|
707
717
|
nativeEvent: {
|
|
708
718
|
layout: {
|
|
709
719
|
width
|
|
710
720
|
}
|
|
711
721
|
}
|
|
712
|
-
} =
|
|
722
|
+
} = _ref11;
|
|
713
723
|
return setPreviousNextNavigationButtonWidth(width);
|
|
714
724
|
};
|
|
715
725
|
const isSwipeAllowed = React.useCallback(() => {
|
|
@@ -871,6 +881,11 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
871
881
|
}
|
|
872
882
|
setisCarouselPlaying(prevState => !prevState);
|
|
873
883
|
}, [isCarouselPlaying, stopAutoplay, startAutoplay]);
|
|
884
|
+
const handleKeyDown = React.useCallback(event => {
|
|
885
|
+
if (isTransitioningRef.current && event.key === 'Tab') {
|
|
886
|
+
event.preventDefault();
|
|
887
|
+
}
|
|
888
|
+
}, [isTransitioningRef]);
|
|
874
889
|
return /*#__PURE__*/_jsxs(View, {
|
|
875
890
|
style: selectRootContainerStyles(enableHero, viewport),
|
|
876
891
|
children: [/*#__PURE__*/_jsx(View, {
|
|
@@ -896,6 +911,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
896
911
|
ref: ref,
|
|
897
912
|
...systemProps,
|
|
898
913
|
...containerProps,
|
|
914
|
+
...(Platform.OS === 'web' ? {
|
|
915
|
+
onKeyDown: handleKeyDown
|
|
916
|
+
} : {}),
|
|
899
917
|
children: [isAutoPlayEnabled ? /*#__PURE__*/_jsx(View, {
|
|
900
918
|
style: [staticStyles.animationControlButton, selectControlButtonPositionStyles({
|
|
901
919
|
positionVariant: previousNextNavigationPosition,
|
|
@@ -950,10 +968,27 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
950
968
|
// This is a known Voiceover bug: https://github.com/phetsims/a11y-research/issues/132
|
|
951
969
|
accessibilityLiveRegion: accessibilityLiveRegion,
|
|
952
970
|
children: childrenArray.map((element, index) => {
|
|
953
|
-
|
|
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
|
+
}
|
|
954
989
|
const clonedElement = /*#__PURE__*/React.cloneElement(element, {
|
|
955
990
|
elementIndex: index,
|
|
956
|
-
hidden
|
|
991
|
+
hidden,
|
|
957
992
|
enablePeeking,
|
|
958
993
|
peekingProps: getPeekingProps(viewport),
|
|
959
994
|
enableDisplayMultipleItemsPerSlide,
|
|
@@ -1197,6 +1232,12 @@ Carousel.propTypes = {
|
|
|
1197
1232
|
* - `autoPlay` and `slideDuration` are required to be set for this to work
|
|
1198
1233
|
*/
|
|
1199
1234
|
transitionDuration: PropTypes.number,
|
|
1235
|
+
/**
|
|
1236
|
+
* Time it takes in seconds to transition from last slide to first slide
|
|
1237
|
+
* - Default value equals `transitionDuration`'s value
|
|
1238
|
+
* - `autoPlay` and `transitionDuration` are required to be set for this to work
|
|
1239
|
+
*/
|
|
1240
|
+
loopDuration: PropTypes.number,
|
|
1200
1241
|
/**
|
|
1201
1242
|
* If set to `true`, the Carousel will show the previous and next slides
|
|
1202
1243
|
* - Default value is `false`
|
|
@@ -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,
|
package/lib/esm/Icon/Icon.js
CHANGED
|
@@ -36,17 +36,14 @@ const Icon = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
36
36
|
padding: themeTokens.padding
|
|
37
37
|
};
|
|
38
38
|
const getIconContentForMobile = () => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return iconContent;
|
|
39
|
+
return /*#__PURE__*/_jsx(View, {
|
|
40
|
+
style: {
|
|
41
|
+
backgroundColor: themeTokens.backgroundColor,
|
|
42
|
+
borderRadius: themeTokens.borderRadius,
|
|
43
|
+
...paddingStyles
|
|
44
|
+
},
|
|
45
|
+
children: iconContent
|
|
46
|
+
});
|
|
50
47
|
};
|
|
51
48
|
return Platform.OS === 'web' ? /*#__PURE__*/_jsx(View, {
|
|
52
49
|
ref: ref
|
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: {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
|
-
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
4
|
import Text from "react-native-web/dist/exports/Text";
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider';
|
|
7
7
|
import Icon from '../Icon';
|
|
8
8
|
import Spacer from '../Spacer';
|
|
9
9
|
import { useListboxContext } from './ListboxContext';
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
11
|
const styles = StyleSheet.create({
|
|
12
|
-
|
|
12
|
+
container: {
|
|
13
13
|
width: '100%',
|
|
14
14
|
flex: 1,
|
|
15
15
|
alignItems: 'center',
|
|
@@ -18,6 +18,34 @@ const styles = StyleSheet.create({
|
|
|
18
18
|
boxSizing: 'border-box'
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
+
const selectTextStyles = tokens => ({
|
|
22
|
+
color: tokens.groupColor,
|
|
23
|
+
fontFamily: `${tokens.groupFontName}${tokens.groupFontWeight}normal`,
|
|
24
|
+
fontSize: tokens.groupFontSize,
|
|
25
|
+
fontWeight: tokens.groupFontWeight
|
|
26
|
+
});
|
|
27
|
+
const selectContainerStyles = tokens => ({
|
|
28
|
+
fontFamily: `${tokens.groupFontName}${tokens.groupFontWeight}normal`,
|
|
29
|
+
fontSize: tokens.groupFontSize,
|
|
30
|
+
color: tokens.groupColor,
|
|
31
|
+
textDecoration: tokens.itemTextDecoration,
|
|
32
|
+
backgroundColor: tokens.groupBackgroundColor,
|
|
33
|
+
outline: tokens.itemOutline,
|
|
34
|
+
minHeight: tokens.groupHeight,
|
|
35
|
+
borderRadius: tokens.groupBorderRadius,
|
|
36
|
+
paddingLeft: tokens.groupPaddingLeft - tokens.groupBorderLeftWidth,
|
|
37
|
+
paddingRight: tokens.groupPaddingRight - tokens.groupBorderRightWidth,
|
|
38
|
+
paddingTop: tokens.groupPaddingTop - tokens.groupBorderTopWidth,
|
|
39
|
+
paddingBottom: tokens.groupPaddingBottom - tokens.groupBorderBottomWidth,
|
|
40
|
+
borderLeftWidth: tokens.groupBorderLeftWidth,
|
|
41
|
+
borderLeftColor: tokens.groupBorderLeftColor,
|
|
42
|
+
borderRightWidth: tokens.groupBorderRightWidth,
|
|
43
|
+
borderRightColor: tokens.groupBorderRightColor,
|
|
44
|
+
borderTopWidth: tokens.groupBorderTopWidth,
|
|
45
|
+
borderTopColor: tokens.groupBorderTopColor,
|
|
46
|
+
borderBottomWidth: tokens.groupBorderBottomWidth,
|
|
47
|
+
borderBottomColor: tokens.groupBorderBottomColor
|
|
48
|
+
});
|
|
21
49
|
const GroupControl = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
22
50
|
let {
|
|
23
51
|
expanded,
|
|
@@ -38,51 +66,17 @@ const GroupControl = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
38
66
|
current: selectedId === id && id !== undefined,
|
|
39
67
|
focus
|
|
40
68
|
});
|
|
41
|
-
const {
|
|
42
|
-
groupFontName,
|
|
43
|
-
groupFontWeight,
|
|
44
|
-
groupFontSize,
|
|
45
|
-
groupColor,
|
|
46
|
-
groupBackgroundColor,
|
|
47
|
-
groupBorderColor,
|
|
48
|
-
groupBorderWidth,
|
|
49
|
-
groupBorderRadius,
|
|
50
|
-
groupPaddingLeft,
|
|
51
|
-
groupPaddingRight,
|
|
52
|
-
groupPaddingTop,
|
|
53
|
-
groupPaddingBottom,
|
|
54
|
-
itemTextDecoration,
|
|
55
|
-
itemOutline,
|
|
56
|
-
groupHeight
|
|
57
|
-
} = tokens;
|
|
58
|
-
const getTextStyles = () => ({
|
|
59
|
-
color: groupColor
|
|
60
|
-
});
|
|
61
69
|
return /*#__PURE__*/_jsxs(View, {
|
|
62
70
|
onPress: () => setSelectedId(id),
|
|
63
|
-
style: [styles.
|
|
64
|
-
fontFamily: `${groupFontName}${groupFontWeight}normal`,
|
|
65
|
-
fontSize: groupFontSize,
|
|
66
|
-
color: groupColor,
|
|
67
|
-
textDecoration: itemTextDecoration,
|
|
68
|
-
backgroundColor: groupBackgroundColor,
|
|
69
|
-
outline: itemOutline,
|
|
70
|
-
height: groupHeight,
|
|
71
|
-
border: `${groupBorderWidth}px solid ${groupBorderColor}`,
|
|
72
|
-
borderRadius: groupBorderRadius,
|
|
73
|
-
paddingLeft: groupPaddingLeft - groupBorderWidth,
|
|
74
|
-
paddingRight: groupPaddingRight - groupBorderWidth,
|
|
75
|
-
paddingTop: groupPaddingTop - groupBorderWidth,
|
|
76
|
-
paddingBottom: groupPaddingBottom - groupBorderWidth
|
|
77
|
-
}],
|
|
71
|
+
style: [styles.container, selectContainerStyles(tokens)],
|
|
78
72
|
ref: ref,
|
|
79
73
|
children: [/*#__PURE__*/_jsx(Text, {
|
|
80
|
-
style:
|
|
74
|
+
style: selectTextStyles(tokens),
|
|
81
75
|
children: label
|
|
82
76
|
}), /*#__PURE__*/_jsx(Spacer, {
|
|
83
77
|
space: 1,
|
|
84
78
|
direction: "row"
|
|
85
|
-
}), /*#__PURE__*/_jsx(Icon, {
|
|
79
|
+
}), tokens.groupIcon && /*#__PURE__*/_jsx(Icon, {
|
|
86
80
|
icon: tokens.groupIcon,
|
|
87
81
|
tokens: {
|
|
88
82
|
color: tokens.groupColor
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { createElement as _createElement } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
|
-
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
4
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
5
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider';
|
|
7
|
-
import { withLinkRouter, getTokensPropType } from '../utils';
|
|
7
|
+
import { withLinkRouter, getTokensPropType, variantProp } from '../utils';
|
|
8
8
|
import ExpandCollapse from '../ExpandCollapse';
|
|
9
9
|
import ListboxGroup from './ListboxGroup';
|
|
10
10
|
import ListboxItem from './ListboxItem';
|
|
@@ -12,11 +12,16 @@ import { ListboxContext } from './ListboxContext';
|
|
|
12
12
|
import DropdownOverlay from './ListboxOverlay';
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
const styles = StyleSheet.create({
|
|
15
|
-
|
|
15
|
+
container: {
|
|
16
16
|
padding: 0,
|
|
17
17
|
margin: 0
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
|
+
const selectContainerStyles = tokens => ({
|
|
21
|
+
minHeight: tokens.minHeight,
|
|
22
|
+
minWidth: tokens.minWidth,
|
|
23
|
+
backgroundColor: tokens.containerBackgroundColor
|
|
24
|
+
});
|
|
20
25
|
const getInitialOpen = (items, selectedId) => items.filter(item => item.items && item.items.some(nestedItem => (nestedItem.id ?? nestedItem.label) === selectedId)).map(item => item.id ?? item.label);
|
|
21
26
|
const Listbox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
22
27
|
let {
|
|
@@ -30,14 +35,12 @@ const Listbox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
30
35
|
itemRouterProps,
|
|
31
36
|
onClose,
|
|
32
37
|
variant,
|
|
33
|
-
tokens
|
|
38
|
+
tokens,
|
|
39
|
+
testID
|
|
34
40
|
} = _ref;
|
|
35
41
|
const initialOpen = getInitialOpen(items, defaultSelectedId);
|
|
36
42
|
const [selectedId, setSelectedId] = React.useState(defaultSelectedId);
|
|
37
|
-
const
|
|
38
|
-
minHeight,
|
|
39
|
-
minWidth
|
|
40
|
-
} = useThemeTokens('Listbox', variant, tokens);
|
|
43
|
+
const listboxTokens = useThemeTokens('Listbox', tokens, variant);
|
|
41
44
|
|
|
42
45
|
// We need to keep track of each item's ref in order to be able to
|
|
43
46
|
// focus on a specific item via keyboard navigation
|
|
@@ -96,11 +99,9 @@ const Listbox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
96
99
|
maxOpen: 1,
|
|
97
100
|
ref: ref,
|
|
98
101
|
children: expandProps => /*#__PURE__*/_jsx(View, {
|
|
99
|
-
style: [styles.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}],
|
|
103
|
-
role: "listbox",
|
|
102
|
+
style: [styles.container, selectContainerStyles(listboxTokens)],
|
|
103
|
+
accessibilityRole: "combobox",
|
|
104
|
+
testID: testID,
|
|
104
105
|
children: items.map((item, index) => {
|
|
105
106
|
const {
|
|
106
107
|
id,
|
|
@@ -162,7 +163,15 @@ Listbox.propTypes = {
|
|
|
162
163
|
/**
|
|
163
164
|
* onClose event
|
|
164
165
|
*/
|
|
165
|
-
onClose: PropTypes.func
|
|
166
|
+
onClose: PropTypes.func,
|
|
167
|
+
/**
|
|
168
|
+
* Test ID for testing
|
|
169
|
+
*/
|
|
170
|
+
testID: PropTypes.string,
|
|
171
|
+
/**
|
|
172
|
+
* Listbox variant
|
|
173
|
+
*/
|
|
174
|
+
variant: variantProp.propType
|
|
166
175
|
};
|
|
167
176
|
Listbox.Overlay = DropdownOverlay;
|
|
168
177
|
export default Listbox;
|
|
@@ -77,7 +77,8 @@ const ListboxGroup = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
77
77
|
borderColor: 'transparent',
|
|
78
78
|
borderRadius: 0,
|
|
79
79
|
borderWidth: 0,
|
|
80
|
-
marginBottom: 0
|
|
80
|
+
marginBottom: 0,
|
|
81
|
+
contentPanelBackgroundColor: 'transparent'
|
|
81
82
|
},
|
|
82
83
|
controlRef: ref,
|
|
83
84
|
children: /*#__PURE__*/_jsx(View, {
|