@telus-uds/components-base 3.3.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -2
- package/lib/cjs/ActivityIndicator/Dots.js +165 -0
- package/lib/cjs/ActivityIndicator/Dots.native.js +221 -0
- package/lib/cjs/ActivityIndicator/Spinner.js +57 -50
- package/lib/cjs/ActivityIndicator/Spinner.native.js +90 -108
- package/lib/cjs/ActivityIndicator/index.js +12 -1
- package/lib/cjs/ActivityIndicator/shared.js +53 -6
- package/lib/cjs/Button/ButtonBase.js +1 -1
- package/lib/cjs/Button/ButtonLink.js +1 -0
- package/lib/cjs/Carousel/Carousel.js +18 -7
- package/lib/cjs/ExpandCollapse/ExpandCollapse.js +3 -1
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +10 -1
- package/lib/cjs/FileUpload/FileUpload.js +31 -2
- package/lib/cjs/Link/Link.js +8 -1
- package/lib/cjs/Link/LinkBase.js +2 -0
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +3 -2
- package/lib/cjs/utils/containUniqueFields.js +5 -5
- package/lib/cjs/utils/useUniqueId.js +2 -6
- package/lib/esm/ActivityIndicator/Dots.js +158 -0
- package/lib/esm/ActivityIndicator/Dots.native.js +212 -0
- package/lib/esm/ActivityIndicator/Spinner.js +58 -51
- package/lib/esm/ActivityIndicator/Spinner.native.js +90 -110
- package/lib/esm/ActivityIndicator/index.js +12 -1
- package/lib/esm/ActivityIndicator/shared.js +52 -5
- package/lib/esm/Button/ButtonBase.js +2 -2
- package/lib/esm/Button/ButtonLink.js +2 -1
- package/lib/esm/Carousel/Carousel.js +18 -7
- package/lib/esm/ExpandCollapse/ExpandCollapse.js +4 -2
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +11 -2
- package/lib/esm/FileUpload/FileUpload.js +31 -2
- package/lib/esm/Link/Link.js +8 -1
- package/lib/esm/Link/LinkBase.js +2 -0
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +3 -2
- package/lib/esm/utils/containUniqueFields.js +5 -5
- package/lib/esm/utils/useUniqueId.js +3 -7
- package/lib/package.json +4 -3
- package/package.json +4 -3
- package/src/ActivityIndicator/Dots.jsx +200 -0
- package/src/ActivityIndicator/Dots.native.jsx +213 -0
- package/src/ActivityIndicator/Spinner.jsx +95 -59
- package/src/ActivityIndicator/Spinner.native.jsx +125 -132
- package/src/ActivityIndicator/index.jsx +17 -2
- package/src/ActivityIndicator/shared.js +52 -5
- package/src/Button/ButtonBase.jsx +4 -2
- package/src/Button/ButtonLink.jsx +3 -1
- package/src/Carousel/Carousel.jsx +28 -7
- package/src/ExpandCollapse/ExpandCollapse.jsx +9 -4
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +15 -3
- package/src/FileUpload/FileUpload.jsx +32 -2
- package/src/Link/Link.jsx +8 -1
- package/src/Link/LinkBase.jsx +2 -0
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -2
- package/src/utils/containUniqueFields.js +5 -5
- package/src/utils/useUniqueId.js +3 -8
|
@@ -1,144 +1,124 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import View from "react-native-web/dist/exports/View";
|
|
2
3
|
import Animated from "react-native-web/dist/exports/Animated";
|
|
3
4
|
import Easing from "react-native-web/dist/exports/Easing";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared';
|
|
5
|
+
import Svg, { Circle } from 'react-native-svg';
|
|
6
|
+
import { DURATION, SVG_CIRCUMFERENCE, SVG_SIZE, SVG_CENTER, SPINNER_RADIUS, SPINNER_DASHARRAY_HALF, SPINNER_DASHARRAY_MIN, SPINNER_DASHOFFSET_FACTOR, propTypes } from './shared';
|
|
7
7
|
import { useA11yInfo } from '../A11yInfoProvider';
|
|
8
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const ea = MIN_EMPTY_ANGLE / 2;
|
|
10
|
-
const sa = MIN_STROKE_ANGLE / 2;
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
9
|
const Spinner = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
12
10
|
let {
|
|
13
11
|
size,
|
|
14
12
|
color,
|
|
13
|
+
indicatorBackgroundColor,
|
|
15
14
|
thickness,
|
|
16
15
|
label,
|
|
17
16
|
isStatic = false
|
|
18
17
|
} = _ref;
|
|
19
|
-
const {
|
|
20
|
-
current: timer
|
|
21
|
-
} = React.useRef(new Animated.Value(0));
|
|
22
18
|
const {
|
|
23
19
|
reduceMotionEnabled
|
|
24
20
|
} = useA11yInfo();
|
|
25
21
|
const reduceMotion = reduceMotionEnabled || isStatic;
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
|
|
23
|
+
// Animated value between 0..1 that will loop
|
|
24
|
+
const progress = React.useRef(new Animated.Value(0)).current;
|
|
25
|
+
|
|
26
|
+
// Local state to force re-render on each frame
|
|
27
|
+
const [progressVal, setProgressVal] = React.useState(0);
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
if (reduceMotion) {
|
|
30
|
+
progress.stopAnimation(() => {
|
|
31
|
+
progress.setValue(0);
|
|
32
|
+
setProgressVal(0);
|
|
33
|
+
});
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const id = progress.addListener(_ref2 => {
|
|
37
|
+
let {
|
|
38
|
+
value
|
|
39
|
+
} = _ref2;
|
|
40
|
+
setProgressVal(value);
|
|
41
|
+
});
|
|
42
|
+
Animated.loop(Animated.timing(progress, {
|
|
43
|
+
toValue: 1,
|
|
28
44
|
duration: DURATION,
|
|
29
45
|
easing: Easing.linear,
|
|
30
|
-
|
|
31
|
-
useNativeDriver: true,
|
|
32
|
-
toValue: 1,
|
|
46
|
+
useNativeDriver: false,
|
|
33
47
|
isInteraction: false
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
width: size,
|
|
41
|
-
height: size / (reduceMotion ? 1.5 : 2),
|
|
42
|
-
overflow: 'hidden'
|
|
43
|
-
};
|
|
44
|
-
const animationFrequency = reduceMotion ? [0] : [0, 1];
|
|
48
|
+
})).start();
|
|
49
|
+
return () => {
|
|
50
|
+
progress.removeListener(id);
|
|
51
|
+
progress.stopAnimation();
|
|
52
|
+
};
|
|
53
|
+
}, [progress, reduceMotion]);
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
/* The same logic used in Wweb keyframes:
|
|
56
|
+
- rotation from -90° base plus 0..183° => -90..93
|
|
57
|
+
- dasharray from 1% -> 50% -> 1%
|
|
58
|
+
- dashoffset from 0 -> 0 -> -49%
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
// 1) rotation (0->183) plus base offset -90
|
|
62
|
+
const rotationDeg = -90 + 183 * progressVal; // -90..+93
|
|
63
|
+
|
|
64
|
+
// strokeDasharray
|
|
65
|
+
let dashArrayVisible;
|
|
66
|
+
if (progressVal < SPINNER_DASHARRAY_HALF) {
|
|
67
|
+
const segmentProgress = progressVal / SPINNER_DASHARRAY_HALF;
|
|
68
|
+
dashArrayVisible = SPINNER_DASHARRAY_MIN + (SPINNER_DASHARRAY_HALF - SPINNER_DASHARRAY_MIN) * segmentProgress;
|
|
69
|
+
} else {
|
|
70
|
+
const segmentProgress = (progressVal - SPINNER_DASHARRAY_HALF) / SPINNER_DASHARRAY_HALF;
|
|
71
|
+
dashArrayVisible = SPINNER_DASHARRAY_HALF + (SPINNER_DASHARRAY_MIN - SPINNER_DASHARRAY_HALF) * segmentProgress;
|
|
72
|
+
}
|
|
73
|
+
const visibleLength = dashArrayVisible * SVG_CIRCUMFERENCE;
|
|
74
|
+
const invisibleLength = SVG_CIRCUMFERENCE - visibleLength;
|
|
75
|
+
const strokeDasharray = `${visibleLength},${invisibleLength}`;
|
|
76
|
+
|
|
77
|
+
// strokeDashoffset
|
|
78
|
+
let strokeDashoffset = 0;
|
|
79
|
+
if (progressVal > SPINNER_DASHARRAY_HALF) {
|
|
80
|
+
const segmentProgress = (progressVal - SPINNER_DASHARRAY_HALF) / SPINNER_DASHARRAY_HALF;
|
|
81
|
+
strokeDashoffset = -SPINNER_DASHOFFSET_FACTOR * SVG_CIRCUMFERENCE * segmentProgress;
|
|
82
|
+
}
|
|
83
|
+
const strokeWidth = thickness * SVG_SIZE / size;
|
|
47
84
|
return /*#__PURE__*/_jsx(View, {
|
|
48
85
|
ref: ref,
|
|
49
|
-
style:
|
|
86
|
+
style: {
|
|
87
|
+
width: size,
|
|
88
|
+
height: size
|
|
89
|
+
},
|
|
50
90
|
accessible: true,
|
|
51
91
|
accessibilityLabel: label,
|
|
52
92
|
accessibilityRole: "progressbar",
|
|
53
93
|
accessibilityState: {
|
|
54
94
|
busy: true
|
|
55
95
|
},
|
|
56
|
-
children: /*#__PURE__*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
height: size
|
|
80
|
-
};
|
|
81
|
-
if (!reduceMotion) {
|
|
82
|
-
layerStyle.transform = [{
|
|
83
|
-
rotate: timer.interpolate({
|
|
84
|
-
inputRange: [0, 1],
|
|
85
|
-
outputRange: [`${0 + ea + sa}deg`, `${2 * 360 + ea + sa}deg`]
|
|
86
|
-
})
|
|
87
|
-
}];
|
|
88
|
-
viewportStyle.transform = [{
|
|
89
|
-
translateY: index ? -size / 2 : 0
|
|
90
|
-
}, {
|
|
91
|
-
rotate: timer.interpolate({
|
|
92
|
-
inputRange,
|
|
93
|
-
outputRange
|
|
94
|
-
})
|
|
95
|
-
}];
|
|
96
|
-
}
|
|
97
|
-
const offsetStyle = index ? {
|
|
98
|
-
top: size / 2
|
|
99
|
-
} : null;
|
|
100
|
-
const lineStyle = {
|
|
101
|
-
width: size,
|
|
102
|
-
height: size,
|
|
103
|
-
borderColor: color,
|
|
104
|
-
borderWidth: thickness,
|
|
105
|
-
borderRadius: size / 2
|
|
106
|
-
};
|
|
107
|
-
return /*#__PURE__*/_jsx(Animated.View, {
|
|
108
|
-
style: [styles.layer],
|
|
109
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
110
|
-
style: layerStyle,
|
|
111
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
112
|
-
style: [containerStyle, offsetStyle],
|
|
113
|
-
collapsable: false,
|
|
114
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
115
|
-
style: viewportStyle,
|
|
116
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
117
|
-
style: containerStyle,
|
|
118
|
-
collapsable: false,
|
|
119
|
-
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
120
|
-
style: lineStyle
|
|
121
|
-
})
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
})
|
|
125
|
-
})
|
|
126
|
-
}, index);
|
|
127
|
-
})
|
|
96
|
+
children: /*#__PURE__*/_jsxs(Svg, {
|
|
97
|
+
width: size,
|
|
98
|
+
height: size,
|
|
99
|
+
viewBox: `0 0 ${SVG_SIZE} ${SVG_SIZE}`,
|
|
100
|
+
children: [/*#__PURE__*/_jsx(Circle, {
|
|
101
|
+
cx: SVG_CENTER,
|
|
102
|
+
cy: SVG_CENTER,
|
|
103
|
+
r: SPINNER_RADIUS,
|
|
104
|
+
fill: "none",
|
|
105
|
+
stroke: indicatorBackgroundColor,
|
|
106
|
+
strokeWidth: strokeWidth
|
|
107
|
+
}), /*#__PURE__*/_jsx(Circle, {
|
|
108
|
+
cx: SVG_CENTER,
|
|
109
|
+
cy: SVG_CENTER,
|
|
110
|
+
r: SPINNER_RADIUS,
|
|
111
|
+
fill: "none",
|
|
112
|
+
stroke: color,
|
|
113
|
+
strokeWidth: strokeWidth,
|
|
114
|
+
strokeLinecap: "round",
|
|
115
|
+
transform: `rotate(${rotationDeg}, 24, 24)`,
|
|
116
|
+
strokeDasharray: strokeDasharray,
|
|
117
|
+
strokeDashoffset: strokeDashoffset
|
|
118
|
+
})]
|
|
128
119
|
})
|
|
129
120
|
});
|
|
130
121
|
});
|
|
131
122
|
Spinner.displayName = 'Spinner';
|
|
132
123
|
Spinner.propTypes = propTypes;
|
|
133
|
-
const styles = StyleSheet.create({
|
|
134
|
-
container: {
|
|
135
|
-
flexGrow: 0,
|
|
136
|
-
flexShrink: 0
|
|
137
|
-
},
|
|
138
|
-
layer: {
|
|
139
|
-
...StyleSheet.absoluteFillObject,
|
|
140
|
-
justifyContent: 'center',
|
|
141
|
-
alignItems: 'center'
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
124
|
export default Spinner;
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { useThemeTokens } from '../ThemeProvider';
|
|
4
4
|
import { getTokensPropType, variantProp } from '../utils/props';
|
|
5
5
|
import Spinner from './Spinner';
|
|
6
|
+
import Dots from './Dots';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* `ActivityIndicator` renders a visual loading state.
|
|
@@ -18,13 +19,23 @@ const ActivityIndicator = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
18
19
|
} = _ref;
|
|
19
20
|
const {
|
|
20
21
|
size,
|
|
22
|
+
dotSize,
|
|
21
23
|
color,
|
|
24
|
+
indicatorBackgroundColor,
|
|
22
25
|
thickness
|
|
23
26
|
} = useThemeTokens('ActivityIndicator', tokens, variant);
|
|
24
|
-
return /*#__PURE__*/_jsx(
|
|
27
|
+
return variant?.dots ? /*#__PURE__*/_jsx(Dots, {
|
|
28
|
+
ref: ref,
|
|
29
|
+
size: dotSize,
|
|
30
|
+
color: color,
|
|
31
|
+
indicatorBackgroundColor: indicatorBackgroundColor,
|
|
32
|
+
label: label,
|
|
33
|
+
isStatic: isStatic
|
|
34
|
+
}) : /*#__PURE__*/_jsx(Spinner, {
|
|
25
35
|
ref: ref,
|
|
26
36
|
size: size,
|
|
27
37
|
color: color,
|
|
38
|
+
indicatorBackgroundColor: indicatorBackgroundColor,
|
|
28
39
|
thickness: thickness,
|
|
29
40
|
label: label,
|
|
30
41
|
isStatic: isStatic
|
|
@@ -1,14 +1,61 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
export const DURATION =
|
|
5
|
-
export const
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
3
|
+
// Spinner
|
|
4
|
+
export const DURATION = 1200;
|
|
5
|
+
export const SVG_RADIUS = 20;
|
|
6
|
+
export const SVG_CIRCUMFERENCE = SVG_RADIUS * 2 * Math.PI;
|
|
7
|
+
export const SVG_SIZE = 48;
|
|
8
|
+
export const ROTATION_TRANSFORM = 'rotate(-90 24 24)';
|
|
9
|
+
export const SVG_CENTER = 24;
|
|
10
|
+
export const SPINNER_RADIUS = 20;
|
|
11
|
+
export const SPINNER_ROTATION_DEGREES = 183;
|
|
12
|
+
export const SPINNER_DASHARRAY_MIN = 0.01;
|
|
13
|
+
export const SPINNER_DASHARRAY_MAX = 0.99;
|
|
14
|
+
|
|
15
|
+
// Spinner animation
|
|
16
|
+
export const SPINNER_KEYTIMES = '0; 0.5; 1';
|
|
17
|
+
export const SPINNER_DASHARRAY_HALF = 0.5;
|
|
18
|
+
export const SPINNER_DASHOFFSET_FACTOR = 0.49;
|
|
19
|
+
|
|
20
|
+
// Dots
|
|
21
|
+
export const DOTS_ANIMATION_DURATION = 300;
|
|
22
|
+
export const DOTS_TOTAL_ANIMATION_DURATION = DOTS_ANIMATION_DURATION * 10;
|
|
23
|
+
export const OVERSHOOT_FACTOR = 1.3;
|
|
24
|
+
export const UNDERSHOOT_FACTOR = 0.2;
|
|
25
|
+
export const BOUNCY_CURVE = '0.2 1 0.8 1';
|
|
26
|
+
export const DOTS_SPACING_X = 3;
|
|
27
|
+
export const DOTS_BASE_Y_FACTOR = 3;
|
|
28
|
+
export const DOTS_JUMP_HEIGHT_FACTOR = 1;
|
|
29
|
+
export const DOTS_PADDING_FACTOR = 0.5;
|
|
30
|
+
|
|
31
|
+
// Dots fadeout
|
|
32
|
+
export const DOTS_FADEOUT_KEYTIMES = '0; 0.7; 0.8; 1';
|
|
33
|
+
export const DOTS_FADEOUT_VALUES = '1; 1; 0; 0';
|
|
34
|
+
|
|
35
|
+
// Dots animation
|
|
36
|
+
export const DOT1_ANIMATION_KEYTIMES = '0; 0.1; 0.2; 1';
|
|
37
|
+
export const DOT2_ANIMATION_KEYTIMES = '0; 0.3; 0.4; 0.5; 1';
|
|
38
|
+
export const DOT3_ANIMATION_KEYTIMES = '0; 0.6; 0.7; 0.8; 1';
|
|
39
|
+
|
|
40
|
+
// Dots color keytimes
|
|
41
|
+
export const DOT1_COLOR_KEYTIMES = '0; 0.3; 0.4; 1';
|
|
42
|
+
export const DOT2_COLOR_KEYTIMES = '0; 0.3; 0.4; 0.6; 0.7; 1';
|
|
43
|
+
export const DOT3_COLOR_KEYTIMES = '0; 0.5; 0.6; 0.8; 1';
|
|
44
|
+
|
|
45
|
+
// Dots native fadeout
|
|
46
|
+
export const DOT_FADEOUT_INPUT_RANGE = [0, 0.7, 0.8, 1];
|
|
47
|
+
export const DOT_FADEOUT_OUTPUT_RANGE = [1, 1, 0, 0];
|
|
48
|
+
|
|
49
|
+
// Dots native animation
|
|
50
|
+
export const DOT1_ANIMATION_INPUT_RANGE = [0, 0.1, 0.2, 1];
|
|
51
|
+
export const DOT2_ANIMATION_INPUT_RANGE = [0, 0.3, 0.4, 0.5, 1];
|
|
52
|
+
export const DOT3_ANIMATION_INPUT_RANGE = [0, 0.6, 0.7, 0.8, 1];
|
|
8
53
|
export const propTypes = {
|
|
9
54
|
color: PropTypes.string.isRequired,
|
|
55
|
+
baseColor: PropTypes.string,
|
|
10
56
|
label: PropTypes.string.isRequired,
|
|
11
57
|
size: PropTypes.number.isRequired,
|
|
58
|
+
dotsize: PropTypes.number,
|
|
12
59
|
thickness: PropTypes.number.isRequired,
|
|
13
60
|
isStatic: PropTypes.bool
|
|
14
61
|
};
|
|
@@ -6,10 +6,10 @@ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
|
6
6
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
7
7
|
import { applyTextStyles, applyShadowToken, applyOuterBorder, useTheme } from '../ThemeProvider';
|
|
8
8
|
import buttonPropTypes from './propTypes';
|
|
9
|
-
import { a11yProps, clickProps, focusHandlerProps, getCursorStyle, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, viewProps, wrapStringsInText, withLinkRouter } from '../utils';
|
|
9
|
+
import { a11yProps, clickProps, focusHandlerProps, getCursorStyle, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, viewProps, wrapStringsInText, withLinkRouter, contentfulProps } from '../utils';
|
|
10
10
|
import { IconText } from '../Icon';
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, linkProps, viewProps]);
|
|
12
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, linkProps, viewProps, contentfulProps]);
|
|
13
13
|
const getOuterBorderOffset = _ref => {
|
|
14
14
|
let {
|
|
15
15
|
outerBorderGap = 0,
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import ButtonBase from './ButtonBase';
|
|
4
4
|
import buttonPropTypes, { textAndA11yText } from './propTypes';
|
|
5
|
-
import { a11yProps, hrefAttrsProp, linkProps } from '../utils/props';
|
|
5
|
+
import { a11yProps, hrefAttrsProp, linkProps, contentfulProps } from '../utils/props';
|
|
6
6
|
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
7
7
|
import { useViewport } from '../ViewportProvider';
|
|
8
8
|
|
|
@@ -43,6 +43,7 @@ ButtonLink.propTypes = {
|
|
|
43
43
|
...a11yProps.types,
|
|
44
44
|
...buttonPropTypes,
|
|
45
45
|
...linkProps.types,
|
|
46
|
+
...contentfulProps.types,
|
|
46
47
|
children: textAndA11yText,
|
|
47
48
|
dataSet: PropTypes.object,
|
|
48
49
|
accessibilityRole: PropTypes.string
|
|
@@ -84,7 +84,9 @@ const selectControlButtonPositionStyles = _ref => {
|
|
|
84
84
|
positionProperty = getDynamicPositionProperty(),
|
|
85
85
|
spaceBetweenSlideAndButton,
|
|
86
86
|
enablePeeking,
|
|
87
|
-
enableDisplayMultipleItemsPerSlide
|
|
87
|
+
enableDisplayMultipleItemsPerSlide,
|
|
88
|
+
isAutoPlayEnabled,
|
|
89
|
+
viewport
|
|
88
90
|
} = _ref;
|
|
89
91
|
const styles = {};
|
|
90
92
|
if (positionVariant === 'edge') {
|
|
@@ -92,7 +94,7 @@ const selectControlButtonPositionStyles = _ref => {
|
|
|
92
94
|
} else if (positionVariant === 'inside') {
|
|
93
95
|
styles[positionProperty] = DEFAULT_POSITION_OFFSET;
|
|
94
96
|
} else if (positionVariant === 'outside') {
|
|
95
|
-
if (enablePeeking || enableDisplayMultipleItemsPerSlide) {
|
|
97
|
+
if (enablePeeking || enableDisplayMultipleItemsPerSlide || isAutoPlayEnabled && viewport === 'xs') {
|
|
96
98
|
styles[positionProperty] = 0;
|
|
97
99
|
} else {
|
|
98
100
|
styles[positionProperty] = -1 * (spaceBetweenSlideAndButton + buttonWidth);
|
|
@@ -100,7 +102,7 @@ const selectControlButtonPositionStyles = _ref => {
|
|
|
100
102
|
}
|
|
101
103
|
return styles;
|
|
102
104
|
};
|
|
103
|
-
const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton, enablePeeking, enableDisplayMultipleItemsPerSlide) => {
|
|
105
|
+
const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport) => {
|
|
104
106
|
const styles = {
|
|
105
107
|
zIndex: 1,
|
|
106
108
|
position: 'absolute'
|
|
@@ -120,7 +122,9 @@ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWi
|
|
|
120
122
|
positionProperty: getDynamicPositionProperty(areStylesAppliedOnPreviousButton),
|
|
121
123
|
spaceBetweenSlideAndButton: spaceBetweenSlideAndPreviousNextNavigation,
|
|
122
124
|
enablePeeking,
|
|
123
|
-
enableDisplayMultipleItemsPerSlide
|
|
125
|
+
enableDisplayMultipleItemsPerSlide,
|
|
126
|
+
isAutoPlayEnabled,
|
|
127
|
+
viewport
|
|
124
128
|
})
|
|
125
129
|
};
|
|
126
130
|
};
|
|
@@ -167,6 +171,11 @@ const selectRootContainerStyles = (enableHero, viewport) => {
|
|
|
167
171
|
alignItems: 'center'
|
|
168
172
|
};
|
|
169
173
|
}
|
|
174
|
+
if (enableHero) {
|
|
175
|
+
return {
|
|
176
|
+
paddingHorizontal: 16
|
|
177
|
+
};
|
|
178
|
+
}
|
|
170
179
|
return {};
|
|
171
180
|
};
|
|
172
181
|
const selectMainContainerStyles = (enableHero, viewport) => {
|
|
@@ -881,7 +890,9 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
881
890
|
positionProperty: getDynamicPositionProperty(),
|
|
882
891
|
spaceBetweenSlideAndButton: spaceBetweenSlideAndPreviousNextNavigation,
|
|
883
892
|
enablePeeking,
|
|
884
|
-
enableDisplayMultipleItemsPerSlide
|
|
893
|
+
enableDisplayMultipleItemsPerSlide,
|
|
894
|
+
isAutoPlayEnabled,
|
|
895
|
+
viewport
|
|
885
896
|
})],
|
|
886
897
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
887
898
|
icon: isCarouselPlaying ? pauseIcon : playIcon,
|
|
@@ -890,7 +901,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
890
901
|
onPress: onAnimationControlButtonPress
|
|
891
902
|
})
|
|
892
903
|
}) : null, showPreviousNextNavigation && totalItems > 1 ? /*#__PURE__*/_jsx(View, {
|
|
893
|
-
style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true, enablePeeking, enableDisplayMultipleItemsPerSlide),
|
|
904
|
+
style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport),
|
|
894
905
|
testID: "previous-button-container",
|
|
895
906
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
896
907
|
onLayout: onPreviousNextNavigationButtonLayout,
|
|
@@ -942,7 +953,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
942
953
|
})
|
|
943
954
|
})
|
|
944
955
|
}), showPreviousNextNavigation && totalItems > 1 ? /*#__PURE__*/_jsx(View, {
|
|
945
|
-
style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, false, enablePeeking, enableDisplayMultipleItemsPerSlide),
|
|
956
|
+
style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, false, enablePeeking, enableDisplayMultipleItemsPerSlide, isAutoPlayEnabled, viewport),
|
|
946
957
|
testID: "next-button-container",
|
|
947
958
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
948
959
|
onLayout: onPreviousNextNavigationButtonLayout,
|
|
@@ -3,9 +3,9 @@ import View from "react-native-web/dist/exports/View";
|
|
|
3
3
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { useThemeTokens } from '../ThemeProvider';
|
|
6
|
-
import { a11yProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps } from '../utils';
|
|
6
|
+
import { a11yProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps, contentfulProps } from '../utils';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps, contentfulProps]);
|
|
9
9
|
function selectBorderStyles(tokens) {
|
|
10
10
|
return {
|
|
11
11
|
borderBottomWidth: tokens.borderWidth,
|
|
@@ -30,6 +30,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
30
30
|
open,
|
|
31
31
|
initialOpen,
|
|
32
32
|
onChange,
|
|
33
|
+
dataSet,
|
|
33
34
|
...rest
|
|
34
35
|
} = _ref;
|
|
35
36
|
const {
|
|
@@ -49,6 +50,7 @@ const ExpandCollapse = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
49
50
|
style: staticStyles.container,
|
|
50
51
|
ref: ref,
|
|
51
52
|
...selectProps(rest),
|
|
53
|
+
dataSet: dataSet,
|
|
52
54
|
children: /*#__PURE__*/_jsx(View, {
|
|
53
55
|
style: selectBorderStyles(themeTokens),
|
|
54
56
|
children: typeof children === 'function' ? children({
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import ExpandCollapse from '../ExpandCollapse';
|
|
4
|
-
import { getTokensPropType } from '../utils';
|
|
4
|
+
import { getTokensPropType, selectSystemProps, contentfulProps } from '../utils';
|
|
5
5
|
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl';
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps]);
|
|
7
8
|
const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
8
9
|
let {
|
|
9
10
|
children,
|
|
@@ -11,6 +12,7 @@ const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
11
12
|
tokens = {},
|
|
12
13
|
nativeID,
|
|
13
14
|
initialOpen = false,
|
|
15
|
+
dataSet,
|
|
14
16
|
...rest
|
|
15
17
|
} = _ref;
|
|
16
18
|
const expandCollapeMiniPanelId = 'ExpandCollapseMiniPanel';
|
|
@@ -24,6 +26,8 @@ const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
24
26
|
onChange: handleChange,
|
|
25
27
|
tokens: tokens,
|
|
26
28
|
initialOpen: initialOpen ? [expandCollapeMiniPanelId] : [],
|
|
29
|
+
...selectContainerProps(rest),
|
|
30
|
+
dataSet: dataSet,
|
|
27
31
|
children: expandProps => /*#__PURE__*/_jsx(ExpandCollapse.Panel, {
|
|
28
32
|
...expandProps,
|
|
29
33
|
panelId: expandCollapeMiniPanelId,
|
|
@@ -53,6 +57,7 @@ const ExpandCollapseMini = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
53
57
|
ExpandCollapseMini.displayName = 'ExpandCollapseMini';
|
|
54
58
|
ExpandCollapseMini.propTypes = {
|
|
55
59
|
...ExpandCollapseMiniControl.propTypes,
|
|
60
|
+
...selectedContainerPropTypes,
|
|
56
61
|
/**
|
|
57
62
|
* Function to call on pressing the panel's control, which should open or close the panel.
|
|
58
63
|
*/
|
|
@@ -72,6 +77,10 @@ ExpandCollapseMini.propTypes = {
|
|
|
72
77
|
/**
|
|
73
78
|
* Optional variant object to override the default theme tokens
|
|
74
79
|
*/
|
|
75
|
-
tokens: getTokensPropType('ExpandCollapseMini')
|
|
80
|
+
tokens: getTokensPropType('ExpandCollapseMini'),
|
|
81
|
+
/**
|
|
82
|
+
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
83
|
+
*/
|
|
84
|
+
dataSet: PropTypes.object
|
|
76
85
|
};
|
|
77
86
|
export default ExpandCollapseMini;
|
|
@@ -10,7 +10,7 @@ import Notification from '../Notification';
|
|
|
10
10
|
import Spacer from '../Spacer';
|
|
11
11
|
import StackView from '../StackView';
|
|
12
12
|
import NotificationContent from './NotificationContent';
|
|
13
|
-
import
|
|
13
|
+
import defaultDictionary from './dictionary';
|
|
14
14
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
15
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
16
16
|
const getHintFromFileTypes = fileTypes => {
|
|
@@ -95,6 +95,7 @@ const FileUpload = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
95
95
|
onUpload,
|
|
96
96
|
onDelete,
|
|
97
97
|
documentPicker,
|
|
98
|
+
dictionary = defaultDictionary,
|
|
98
99
|
...rest
|
|
99
100
|
} = _ref2;
|
|
100
101
|
if (minFilesCount <= 0) {
|
|
@@ -315,6 +316,27 @@ const FileUpload = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
315
316
|
});
|
|
316
317
|
});
|
|
317
318
|
FileUpload.displayName = 'FileUpload';
|
|
319
|
+
const dictionaryEntryShape = PropTypes.shape({
|
|
320
|
+
label: PropTypes.string.isRequired,
|
|
321
|
+
buttonLabel: PropTypes.string.isRequired,
|
|
322
|
+
dismissButtonLabel: PropTypes.string.isRequired,
|
|
323
|
+
wrongFileType: PropTypes.string.isRequired,
|
|
324
|
+
allowedFileTypes: PropTypes.string.isRequired,
|
|
325
|
+
fileTooBig: PropTypes.string.isRequired,
|
|
326
|
+
fileIsEmpty: PropTypes.string.isRequired,
|
|
327
|
+
problemUploading: PropTypes.string.isRequired,
|
|
328
|
+
problemDeleting: PropTypes.string.isRequired,
|
|
329
|
+
problemUploadingMultipleFiles: PropTypes.string.isRequired,
|
|
330
|
+
only: PropTypes.string.isRequired,
|
|
331
|
+
and: PropTypes.string.isRequired,
|
|
332
|
+
or: PropTypes.string.isRequired,
|
|
333
|
+
uploadSuccess: PropTypes.string.isRequired,
|
|
334
|
+
uploadError: PropTypes.string.isRequired,
|
|
335
|
+
deleteProblem: PropTypes.string.isRequired,
|
|
336
|
+
tooManyFiles: PropTypes.string.isRequired,
|
|
337
|
+
fileTooSmall: PropTypes.string.isRequired,
|
|
338
|
+
fewFiles: PropTypes.string.isRequired
|
|
339
|
+
});
|
|
318
340
|
FileUpload.propTypes = {
|
|
319
341
|
...selectedSystemPropTypes,
|
|
320
342
|
tokens: getTokensPropType('FileUpload'),
|
|
@@ -358,6 +380,13 @@ FileUpload.propTypes = {
|
|
|
358
380
|
/**
|
|
359
381
|
* The minimum file size allowed for upload in MB.
|
|
360
382
|
*/
|
|
361
|
-
minFileSize: PropTypes.number
|
|
383
|
+
minFileSize: PropTypes.number,
|
|
384
|
+
/**
|
|
385
|
+
* Custom dictionary containing the labels to use for the steps
|
|
386
|
+
*/
|
|
387
|
+
dictionary: PropTypes.shape({
|
|
388
|
+
en: dictionaryEntryShape,
|
|
389
|
+
fr: dictionaryEntryShape
|
|
390
|
+
})
|
|
362
391
|
};
|
|
363
392
|
export default FileUpload;
|
package/lib/esm/Link/Link.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
2
3
|
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
3
4
|
import LinkBase from './LinkBase';
|
|
4
5
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -24,5 +25,11 @@ const Link = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
24
25
|
});
|
|
25
26
|
});
|
|
26
27
|
Link.displayName = 'Link';
|
|
27
|
-
Link.propTypes =
|
|
28
|
+
Link.propTypes = {
|
|
29
|
+
...LinkBase.propTypes,
|
|
30
|
+
/**
|
|
31
|
+
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
32
|
+
*/
|
|
33
|
+
dataSet: PropTypes.object
|
|
34
|
+
};
|
|
28
35
|
export default Link;
|
package/lib/esm/Link/LinkBase.js
CHANGED
|
@@ -136,6 +136,7 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
136
136
|
variant,
|
|
137
137
|
tokens = {},
|
|
138
138
|
children,
|
|
139
|
+
dataSet,
|
|
139
140
|
accessibilityRole = 'link',
|
|
140
141
|
...rawRest
|
|
141
142
|
} = _ref6;
|
|
@@ -170,6 +171,7 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
170
171
|
} = useTheme();
|
|
171
172
|
return /*#__PURE__*/_jsx(InlinePressable, {
|
|
172
173
|
...selectedProps,
|
|
174
|
+
dataSet: dataSet,
|
|
173
175
|
inlineFlex: hasIcon
|
|
174
176
|
// assuming links without icons should be inline (even if they are long)
|
|
175
177
|
,
|
|
@@ -101,6 +101,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
101
101
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
102
102
|
const [checkedIds, setCheckedIds] = React.useState(currentValues ?? []);
|
|
103
103
|
const [maxWidth, setMaxWidth] = React.useState(false);
|
|
104
|
+
const isSelected = currentValues.length > 0;
|
|
104
105
|
const {
|
|
105
106
|
headerFontColor,
|
|
106
107
|
headerFontSize,
|
|
@@ -133,7 +134,8 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
133
134
|
} = useThemeTokens('MultiSelectFilter', tokens, {
|
|
134
135
|
...variant,
|
|
135
136
|
maxHeight,
|
|
136
|
-
maxWidth
|
|
137
|
+
maxWidth,
|
|
138
|
+
selected: isSelected
|
|
137
139
|
}, {
|
|
138
140
|
viewport
|
|
139
141
|
});
|
|
@@ -161,7 +163,6 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
161
163
|
const colSizeNotMobile = items.length > rowLimit ? 2 : 1;
|
|
162
164
|
const colSize = viewport !== 'xs' ? colSizeNotMobile : 1;
|
|
163
165
|
const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit;
|
|
164
|
-
const isSelected = currentValues.length > 0;
|
|
165
166
|
const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length;
|
|
166
167
|
React.useEffect(() => {
|
|
167
168
|
if (colSize === 1) return setMaxWidth(false);
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
// Note that if a value of a field in an item is not set, it will be
|
|
5
5
|
// excluded from comparison.
|
|
6
6
|
const containUniqueFields = (items, fields) => {
|
|
7
|
-
const map =
|
|
7
|
+
const map = new Map();
|
|
8
8
|
const itemsHaveDuplicateFields = items.some(item => fields.some(field => {
|
|
9
|
-
if (!map
|
|
10
|
-
map
|
|
9
|
+
if (!map.has(field)) {
|
|
10
|
+
map.set(field, new Map());
|
|
11
11
|
}
|
|
12
12
|
if (!item[field]) {
|
|
13
13
|
// We exclude empty values from comparison
|
|
@@ -15,8 +15,8 @@ const containUniqueFields = (items, fields) => {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// Duplicate found!
|
|
18
|
-
if (map
|
|
19
|
-
map
|
|
18
|
+
if (map.get(field).has(item[field])) return true;
|
|
19
|
+
map.get(field).set(item[field], true);
|
|
20
20
|
return false;
|
|
21
21
|
}));
|
|
22
22
|
return !itemsHaveDuplicateFields;
|