@telus-uds/components-base 3.22.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 +18 -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/Carousel/Carousel.js +52 -19
- 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/Validator/Validator.js +171 -135
- 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/Carousel/Carousel.js +52 -19
- 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/Validator/Validator.js +171 -135
- 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/Carousel/Carousel.jsx +58 -5
- 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/TextInput/TextInputBase.jsx +5 -1
- package/src/Validator/Validator.jsx +180 -159
|
@@ -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
|
|
@@ -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,
|
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, {
|
|
@@ -30,12 +30,14 @@ const DropdownOverlay = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
30
30
|
maxWidth,
|
|
31
31
|
minWidth,
|
|
32
32
|
onLayout,
|
|
33
|
-
tokens
|
|
33
|
+
tokens,
|
|
34
|
+
testID
|
|
34
35
|
} = _ref;
|
|
35
36
|
const systemTokens = useThemeTokens('Listbox', {}, {});
|
|
36
37
|
return /*#__PURE__*/_jsx(View, {
|
|
37
38
|
ref: ref,
|
|
38
39
|
onLayout: onLayout,
|
|
40
|
+
testID: testID,
|
|
39
41
|
style: [overlaidPosition, {
|
|
40
42
|
maxWidth,
|
|
41
43
|
minWidth
|
|
@@ -74,6 +76,7 @@ DropdownOverlay.propTypes = {
|
|
|
74
76
|
maxWidth: PropTypes.number,
|
|
75
77
|
minWidth: PropTypes.number,
|
|
76
78
|
onLayout: PropTypes.func,
|
|
77
|
-
tokens: PropTypes.object
|
|
79
|
+
tokens: PropTypes.object,
|
|
80
|
+
testID: PropTypes.string
|
|
78
81
|
};
|
|
79
82
|
export default Platform.OS === 'web' ? withPortal(DropdownOverlay) : DropdownOverlay;
|
|
@@ -41,10 +41,14 @@ const getItemStyles = _ref => {
|
|
|
41
41
|
color: itemColor,
|
|
42
42
|
outline: itemOutline,
|
|
43
43
|
textDecoration: itemTextDecoration,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
borderLeftWidth: itemBorderLeftWidth,
|
|
45
|
+
borderLeftColor: itemBorderLeftColor,
|
|
46
|
+
borderRightWidth: itemBorderRightWidth,
|
|
47
|
+
borderRightColor: itemBorderRightColor,
|
|
48
|
+
borderTopWidth: itemBorderTopWidth,
|
|
49
|
+
borderTopColor: itemBorderTopColor,
|
|
50
|
+
borderBottomWidth: itemBorderBottomWidth,
|
|
51
|
+
borderBottomColor: itemBorderBottomColor,
|
|
48
52
|
borderRadius: itemBorderRadius,
|
|
49
53
|
justifyContent: 'center'
|
|
50
54
|
};
|
|
@@ -279,6 +279,10 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
279
279
|
// Add a space every 4 digits starting from the 5th position
|
|
280
280
|
filteredText = formattedValue.replace(regex, '$1 ').trim();
|
|
281
281
|
}
|
|
282
|
+
// Apply maxLength if provided
|
|
283
|
+
if (rest.maxLength && filteredText && filteredText.length > rest.maxLength) {
|
|
284
|
+
filteredText = filteredText.substring(0, rest.maxLength);
|
|
285
|
+
}
|
|
282
286
|
setValue(filteredText, event);
|
|
283
287
|
if (typeof onChangeText === 'function') onChangeText(filteredText, event);
|
|
284
288
|
};
|
|
@@ -351,7 +355,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
351
355
|
onMouseOut: handleMouseOut,
|
|
352
356
|
onChange: handleChangeText,
|
|
353
357
|
defaultValue: initialValue,
|
|
354
|
-
maxLength: type === 'card' ? 19 :
|
|
358
|
+
maxLength: type === 'card' ? 19 : rest.maxLength,
|
|
355
359
|
value: isControlled ? currentValue : undefined,
|
|
356
360
|
onKeyPress
|
|
357
361
|
};
|