@telus-uds/components-base 3.4.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +19 -2
  2. package/lib/cjs/ActivityIndicator/Dots.js +165 -0
  3. package/lib/cjs/ActivityIndicator/Dots.native.js +221 -0
  4. package/lib/cjs/ActivityIndicator/Spinner.js +57 -50
  5. package/lib/cjs/ActivityIndicator/Spinner.native.js +90 -108
  6. package/lib/cjs/ActivityIndicator/index.js +12 -1
  7. package/lib/cjs/ActivityIndicator/shared.js +53 -6
  8. package/lib/cjs/Carousel/Carousel.js +18 -7
  9. package/lib/cjs/FileUpload/FileUpload.js +31 -2
  10. package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +3 -2
  11. package/lib/cjs/utils/containUniqueFields.js +5 -5
  12. package/lib/esm/ActivityIndicator/Dots.js +158 -0
  13. package/lib/esm/ActivityIndicator/Dots.native.js +212 -0
  14. package/lib/esm/ActivityIndicator/Spinner.js +58 -51
  15. package/lib/esm/ActivityIndicator/Spinner.native.js +90 -110
  16. package/lib/esm/ActivityIndicator/index.js +12 -1
  17. package/lib/esm/ActivityIndicator/shared.js +52 -5
  18. package/lib/esm/Carousel/Carousel.js +18 -7
  19. package/lib/esm/FileUpload/FileUpload.js +31 -2
  20. package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +3 -2
  21. package/lib/esm/utils/containUniqueFields.js +5 -5
  22. package/lib/package.json +4 -3
  23. package/package.json +4 -3
  24. package/src/ActivityIndicator/Dots.jsx +200 -0
  25. package/src/ActivityIndicator/Dots.native.jsx +213 -0
  26. package/src/ActivityIndicator/Spinner.jsx +95 -59
  27. package/src/ActivityIndicator/Spinner.native.jsx +125 -132
  28. package/src/ActivityIndicator/index.jsx +17 -2
  29. package/src/ActivityIndicator/shared.js +52 -5
  30. package/src/Carousel/Carousel.jsx +28 -7
  31. package/src/FileUpload/FileUpload.jsx +32 -2
  32. package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -2
  33. package/src/utils/containUniqueFields.js +5 -5
@@ -0,0 +1,158 @@
1
+ import React from 'react';
2
+ import { DOTS_TOTAL_ANIMATION_DURATION, OVERSHOOT_FACTOR, UNDERSHOOT_FACTOR, BOUNCY_CURVE, DOTS_SPACING_X, DOTS_BASE_Y_FACTOR, DOTS_JUMP_HEIGHT_FACTOR, DOTS_PADDING_FACTOR, DOTS_FADEOUT_KEYTIMES, DOTS_FADEOUT_VALUES, DOT1_COLOR_KEYTIMES, DOT2_COLOR_KEYTIMES, DOT3_COLOR_KEYTIMES, DOT1_ANIMATION_KEYTIMES, DOT2_ANIMATION_KEYTIMES, DOT3_ANIMATION_KEYTIMES, propTypes } from './shared';
3
+ import { useA11yInfo } from '../A11yInfoProvider';
4
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
5
+ const CY_PROPS = {
6
+ attributeName: 'cy',
7
+ calcMode: 'spline',
8
+ dur: `${DOTS_TOTAL_ANIMATION_DURATION}ms`,
9
+ repeatCount: 'indefinite'
10
+ };
11
+ const FILL_PROPS = {
12
+ attributeName: 'fill',
13
+ calcMode: 'linear',
14
+ dur: `${DOTS_TOTAL_ANIMATION_DURATION}ms`,
15
+ repeatCount: 'indefinite'
16
+ };
17
+ const OPACITY_PROPS = {
18
+ attributeName: 'opacity',
19
+ calcMode: 'linear',
20
+ dur: `${DOTS_TOTAL_ANIMATION_DURATION}ms`,
21
+ repeatCount: 'indefinite'
22
+ };
23
+ const Dots = /*#__PURE__*/React.forwardRef((_ref, ref) => {
24
+ let {
25
+ size,
26
+ color,
27
+ indicatorBackgroundColor,
28
+ label,
29
+ isStatic = false
30
+ } = _ref;
31
+ const {
32
+ reduceMotionEnabled
33
+ } = useA11yInfo();
34
+ const reduceMotion = reduceMotionEnabled || isStatic;
35
+ const spacingX = size + DOTS_SPACING_X;
36
+ const baseY = size * DOTS_BASE_Y_FACTOR;
37
+ const jumpHeight = size * DOTS_JUMP_HEIGHT_FACTOR;
38
+ const padding = size * DOTS_PADDING_FACTOR;
39
+ return /*#__PURE__*/_jsx("svg", {
40
+ ref: ref,
41
+ "aria-valuetext": label,
42
+ role: "progressbar",
43
+ "aria-busy": "true",
44
+ width: size * 3 + spacingX * 2 + padding * 2,
45
+ height: size * 6,
46
+ viewBox: `0 0 ${size * 3 + spacingX * 2 + padding * 2} ${size * 6}`,
47
+ children: /*#__PURE__*/_jsxs("g", {
48
+ children: [/*#__PURE__*/_jsx("circle", {
49
+ cx: padding + size / 2,
50
+ cy: baseY,
51
+ r: size / 2,
52
+ fill: color,
53
+ children: !reduceMotion && /*#__PURE__*/_jsxs(_Fragment, {
54
+ children: [/*#__PURE__*/_jsx("animate", {
55
+ ...CY_PROPS,
56
+ keyTimes: DOT1_ANIMATION_KEYTIMES,
57
+ keySplines: `${BOUNCY_CURVE};${BOUNCY_CURVE};${BOUNCY_CURVE}`,
58
+ values: `
59
+ ${baseY};
60
+ ${baseY - jumpHeight * OVERSHOOT_FACTOR};
61
+ ${baseY + jumpHeight * UNDERSHOOT_FACTOR};
62
+ ${baseY}
63
+ `
64
+ }), /*#__PURE__*/_jsx("animate", {
65
+ ...FILL_PROPS,
66
+ keyTimes: DOT1_COLOR_KEYTIMES,
67
+ values: `
68
+ ${color};
69
+ ${color};
70
+ ${indicatorBackgroundColor};
71
+ ${indicatorBackgroundColor}
72
+ `
73
+ }), /*#__PURE__*/_jsx("animate", {
74
+ ...OPACITY_PROPS,
75
+ keyTimes: DOTS_FADEOUT_KEYTIMES,
76
+ values: DOTS_FADEOUT_VALUES
77
+ })]
78
+ })
79
+ }), /*#__PURE__*/_jsx("circle", {
80
+ cx: padding + size + spacingX + size / 2,
81
+ cy: baseY,
82
+ r: size / 2,
83
+ fill: indicatorBackgroundColor,
84
+ children: reduceMotion ? null : /*#__PURE__*/_jsxs(_Fragment, {
85
+ children: [/*#__PURE__*/_jsx("animate", {
86
+ ...CY_PROPS,
87
+ keyTimes: DOT2_ANIMATION_KEYTIMES,
88
+ keySplines: `
89
+ ${BOUNCY_CURVE};
90
+ ${BOUNCY_CURVE};
91
+ ${BOUNCY_CURVE};
92
+ ${BOUNCY_CURVE}
93
+ `,
94
+ values: `
95
+ ${baseY};
96
+ ${baseY};
97
+ ${baseY - jumpHeight * OVERSHOOT_FACTOR};
98
+ ${baseY + jumpHeight * UNDERSHOOT_FACTOR};
99
+ ${baseY}
100
+ `
101
+ }), /*#__PURE__*/_jsx("animate", {
102
+ ...FILL_PROPS,
103
+ keyTimes: DOT2_COLOR_KEYTIMES,
104
+ values: `
105
+ ${indicatorBackgroundColor};
106
+ ${indicatorBackgroundColor};
107
+ ${color};
108
+ ${color};
109
+ ${indicatorBackgroundColor};
110
+ ${indicatorBackgroundColor}
111
+ `
112
+ }), /*#__PURE__*/_jsx("animate", {
113
+ ...OPACITY_PROPS,
114
+ keyTimes: DOTS_FADEOUT_KEYTIMES,
115
+ values: DOTS_FADEOUT_VALUES
116
+ })]
117
+ })
118
+ }), /*#__PURE__*/_jsx("circle", {
119
+ cx: padding + (size + spacingX) * 2 + size / 2,
120
+ cy: baseY,
121
+ r: size / 2,
122
+ fill: indicatorBackgroundColor,
123
+ children: reduceMotion ? null : /*#__PURE__*/_jsxs(_Fragment, {
124
+ children: [/*#__PURE__*/_jsx("animate", {
125
+ ...CY_PROPS,
126
+ keyTimes: DOT3_ANIMATION_KEYTIMES,
127
+ keySplines: `
128
+ ${BOUNCY_CURVE};
129
+ ${BOUNCY_CURVE};
130
+ ${BOUNCY_CURVE};
131
+ ${BOUNCY_CURVE}
132
+ `,
133
+ values: `
134
+ ${baseY};
135
+ ${baseY};
136
+ ${baseY - jumpHeight * OVERSHOOT_FACTOR};
137
+ ${baseY + jumpHeight * UNDERSHOOT_FACTOR};
138
+ ${baseY}
139
+ `
140
+ }), /*#__PURE__*/_jsx("animate", {
141
+ ...FILL_PROPS,
142
+ keyTimes: DOT3_COLOR_KEYTIMES,
143
+ values: `
144
+ ${indicatorBackgroundColor};
145
+ ${indicatorBackgroundColor};
146
+ ${color};
147
+ ${color};
148
+ ${color}
149
+ `
150
+ })]
151
+ })
152
+ })]
153
+ })
154
+ });
155
+ });
156
+ Dots.displayName = 'Dots';
157
+ Dots.propTypes = propTypes;
158
+ export default Dots;
@@ -0,0 +1,212 @@
1
+ import React from 'react';
2
+ import View from "react-native-web/dist/exports/View";
3
+ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
+ import Animated from "react-native-web/dist/exports/Animated";
5
+ import Easing from "react-native-web/dist/exports/Easing";
6
+ import Svg, { Circle } from 'react-native-svg';
7
+ import { DOTS_TOTAL_ANIMATION_DURATION, OVERSHOOT_FACTOR, UNDERSHOOT_FACTOR, DOTS_SPACING_X, DOTS_BASE_Y_FACTOR, DOTS_JUMP_HEIGHT_FACTOR, DOTS_PADDING_FACTOR, DOT_FADEOUT_INPUT_RANGE, DOT_FADEOUT_OUTPUT_RANGE, DOT1_ANIMATION_INPUT_RANGE, DOT2_ANIMATION_INPUT_RANGE, DOT3_ANIMATION_INPUT_RANGE, propTypes } from './shared';
8
+ import { useA11yInfo } from '../A11yInfoProvider';
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ const AnimatedCircle = Animated.createAnimatedComponent(Circle);
11
+ const Dots = /*#__PURE__*/React.forwardRef((_ref, ref) => {
12
+ let {
13
+ size,
14
+ color,
15
+ indicatorBackgroundColor,
16
+ label,
17
+ isStatic = false
18
+ } = _ref;
19
+ const {
20
+ reduceMotionEnabled
21
+ } = useA11yInfo();
22
+ const reduceMotion = reduceMotionEnabled || isStatic;
23
+ const spacingX = size + DOTS_SPACING_X;
24
+ const baseY = size * DOTS_BASE_Y_FACTOR;
25
+ const jumpHeight = size * DOTS_JUMP_HEIGHT_FACTOR;
26
+ const padding = size * DOTS_PADDING_FACTOR;
27
+ const width = (size + 1) * 6;
28
+ const height = size * 6;
29
+ const animationValue = React.useRef(new Animated.Value(0)).current;
30
+ React.useEffect(() => {
31
+ if (reduceMotion) {
32
+ animationValue.stopAnimation();
33
+ animationValue.setValue(0);
34
+ return () => {};
35
+ }
36
+ const loopAnimation = Animated.loop(Animated.timing(animationValue, {
37
+ toValue: 1,
38
+ duration: DOTS_TOTAL_ANIMATION_DURATION,
39
+ easing: Easing.linear,
40
+ useNativeDriver: false
41
+ }));
42
+ loopAnimation.start();
43
+ return () => loopAnimation.stop();
44
+ }, [reduceMotion, animationValue]);
45
+ const makeStepInterpolation = steps => {
46
+ const inputRange = [];
47
+ const outputRange = [];
48
+ steps.forEach(_ref2 => {
49
+ let {
50
+ time,
51
+ value
52
+ } = _ref2;
53
+ inputRange.push(time);
54
+ outputRange.push(value);
55
+ });
56
+ return {
57
+ inputRange,
58
+ outputRange
59
+ };
60
+ };
61
+
62
+ // ---- DOT 1 ----
63
+ const dot1Cy = animationValue.interpolate({
64
+ inputRange: DOT1_ANIMATION_INPUT_RANGE,
65
+ outputRange: [baseY, baseY - jumpHeight * OVERSHOOT_FACTOR, baseY + jumpHeight * UNDERSHOOT_FACTOR, baseY],
66
+ extrapolate: 'clamp'
67
+ });
68
+ const {
69
+ inputRange: dot1FillInputRange,
70
+ outputRange: dot1FillOutputRange
71
+ } = makeStepInterpolation([{
72
+ time: 0,
73
+ value: color
74
+ }, {
75
+ time: 0.3,
76
+ value: color
77
+ }, {
78
+ time: 0.4,
79
+ value: indicatorBackgroundColor
80
+ }, {
81
+ time: 1,
82
+ value: indicatorBackgroundColor
83
+ }]);
84
+ const dot1Fill = animationValue.interpolate({
85
+ inputRange: dot1FillInputRange,
86
+ outputRange: dot1FillOutputRange,
87
+ extrapolate: 'clamp'
88
+ });
89
+
90
+ // Fade-out Dot 1
91
+ const dot1Opacity = animationValue.interpolate({
92
+ inputRange: DOT_FADEOUT_INPUT_RANGE,
93
+ outputRange: DOT_FADEOUT_OUTPUT_RANGE,
94
+ extrapolate: 'clamp'
95
+ });
96
+
97
+ // ---- DOT 2 ----
98
+ const dot2Cy = animationValue.interpolate({
99
+ inputRange: DOT2_ANIMATION_INPUT_RANGE,
100
+ outputRange: [baseY, baseY, baseY - jumpHeight * OVERSHOOT_FACTOR, baseY + jumpHeight * UNDERSHOOT_FACTOR, baseY],
101
+ extrapolate: 'clamp'
102
+ });
103
+ const {
104
+ inputRange: dot2FillInputRange,
105
+ outputRange: dot2FillOutputRange
106
+ } = makeStepInterpolation([{
107
+ time: 0,
108
+ value: indicatorBackgroundColor
109
+ }, {
110
+ time: 0.3,
111
+ value: indicatorBackgroundColor
112
+ }, {
113
+ time: 0.4,
114
+ value: color
115
+ }, {
116
+ time: 0.6,
117
+ value: color
118
+ }, {
119
+ time: 0.7,
120
+ value: indicatorBackgroundColor
121
+ }, {
122
+ time: 1,
123
+ value: indicatorBackgroundColor
124
+ }]);
125
+ const dot2Fill = animationValue.interpolate({
126
+ inputRange: dot2FillInputRange,
127
+ outputRange: dot2FillOutputRange,
128
+ extrapolate: 'clamp'
129
+ });
130
+
131
+ // Fade-out Dot 2
132
+ const dot2Opacity = animationValue.interpolate({
133
+ inputRange: DOT_FADEOUT_INPUT_RANGE,
134
+ outputRange: DOT_FADEOUT_OUTPUT_RANGE,
135
+ extrapolate: 'clamp'
136
+ });
137
+
138
+ // ---- DOT 3 ----
139
+ const dot3Cy = animationValue.interpolate({
140
+ inputRange: DOT3_ANIMATION_INPUT_RANGE,
141
+ outputRange: [baseY, baseY, baseY - jumpHeight * OVERSHOOT_FACTOR, baseY + jumpHeight * UNDERSHOOT_FACTOR, baseY],
142
+ extrapolate: 'clamp'
143
+ });
144
+ const {
145
+ inputRange: dot3FillInputRange,
146
+ outputRange: dot3FillOutputRange
147
+ } = makeStepInterpolation([{
148
+ time: 0,
149
+ value: indicatorBackgroundColor
150
+ }, {
151
+ time: 0.5,
152
+ value: indicatorBackgroundColor
153
+ }, {
154
+ time: 0.6,
155
+ value: color
156
+ }, {
157
+ time: 0.8,
158
+ value: color
159
+ }, {
160
+ time: 1,
161
+ value: color
162
+ }]);
163
+ const dot3Fill = animationValue.interpolate({
164
+ inputRange: dot3FillInputRange,
165
+ outputRange: dot3FillOutputRange,
166
+ extrapolate: 'clamp'
167
+ });
168
+ const dot3Opacity = new Animated.Value(1);
169
+ return /*#__PURE__*/_jsx(View, {
170
+ ref: ref,
171
+ style: styles.container,
172
+ accessible: true,
173
+ accessibilityLabel: label,
174
+ accessibilityRole: "progressbar",
175
+ accessibilityState: {
176
+ busy: true
177
+ },
178
+ children: /*#__PURE__*/_jsxs(Svg, {
179
+ width: width,
180
+ height: height,
181
+ viewBox: `0 0 ${width} ${height}`,
182
+ children: [/*#__PURE__*/_jsx(AnimatedCircle, {
183
+ cx: size,
184
+ cy: reduceMotion ? baseY : dot1Cy,
185
+ r: padding,
186
+ fill: reduceMotion ? color : dot1Fill,
187
+ opacity: reduceMotion ? 1 : dot1Opacity
188
+ }), /*#__PURE__*/_jsx(AnimatedCircle, {
189
+ cx: 2 * size + spacingX,
190
+ cy: reduceMotion ? baseY : dot2Cy,
191
+ r: padding,
192
+ fill: reduceMotion ? indicatorBackgroundColor : dot2Fill,
193
+ opacity: reduceMotion ? 1 : dot2Opacity
194
+ }), /*#__PURE__*/_jsx(AnimatedCircle, {
195
+ cx: 3 * size + 2 * spacingX,
196
+ cy: reduceMotion ? baseY : dot3Cy,
197
+ r: padding,
198
+ fill: reduceMotion ? indicatorBackgroundColor : dot3Fill,
199
+ opacity: reduceMotion ? 1 : dot3Opacity
200
+ })]
201
+ })
202
+ });
203
+ });
204
+ Dots.displayName = 'Dots';
205
+ Dots.propTypes = propTypes;
206
+ const styles = StyleSheet.create({
207
+ container: {
208
+ alignItems: 'center',
209
+ justifyContent: 'center'
210
+ }
211
+ });
212
+ export default Dots;
@@ -1,28 +1,16 @@
1
1
  import React from 'react';
2
- import { DURATION, MIN_EMPTY_ANGLE, MIN_STROKE_ANGLE, BEZIER, propTypes } from './shared';
2
+ import { DURATION, SVG_CIRCUMFERENCE, SVG_SIZE, ROTATION_TRANSFORM, SVG_CENTER, SPINNER_RADIUS, SPINNER_ROTATION_DEGREES, SPINNER_DASHARRAY_MIN, SPINNER_DASHARRAY_MAX, SPINNER_KEYTIMES, SPINNER_DASHARRAY_HALF, SPINNER_DASHOFFSET_FACTOR, propTypes } from './shared';
3
3
  import { useA11yInfo } from '../A11yInfoProvider';
4
4
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
5
- const SVG_RADIUS = 20;
6
- const SVG_CIRCUMFERENCE = SVG_RADIUS * 2 * Math.PI;
7
- const MIN_SVG_LENGTH = MIN_STROKE_ANGLE / 360 * SVG_CIRCUMFERENCE;
8
- const MAX_SVG_LENGTH = (1 - MIN_EMPTY_ANGLE / 360) * SVG_CIRCUMFERENCE;
9
- const animationProps = {
10
- begin: '0s',
11
- dur: `${DURATION}ms`,
12
- fill: 'freeze',
5
+ const animateProps = {
6
+ keyTimes: SPINNER_KEYTIMES,
13
7
  repeatCount: 'indefinite'
14
8
  };
15
- const bezierProps = {
16
- calcMode: 'spline',
17
- keyTimes: '0; 0.5; 1',
18
- keySplines: `${BEZIER.join(', ')} ; ${BEZIER.join(', ')}`
19
- };
20
- // We're using svg rather than css here to define the animation to avoid needing to introduce css injection mechanism
21
- // It's possible to replicate this functionality with RNW animations, but it snags on chrome at least, see https://github.com/telus/universal-design-system/pull/477 for details.
22
9
  const Spinner = /*#__PURE__*/React.forwardRef((_ref, ref) => {
23
10
  let {
24
11
  size,
25
12
  color,
13
+ indicatorBackgroundColor,
26
14
  thickness,
27
15
  label,
28
16
  isStatic = false
@@ -31,46 +19,65 @@ const Spinner = /*#__PURE__*/React.forwardRef((_ref, ref) => {
31
19
  reduceMotionEnabled
32
20
  } = useA11yInfo();
33
21
  const reduceMotion = reduceMotionEnabled || isStatic;
34
- return /*#__PURE__*/_jsx("svg", {
22
+ const strokeWidth = thickness * SVG_SIZE / size;
23
+ return /*#__PURE__*/_jsxs("svg", {
35
24
  ref: ref,
36
25
  width: `${size}px`,
37
26
  height: `${size}px`,
38
- viewBox: "0 0 48 48",
27
+ viewBox: `0 0 ${SVG_SIZE} ${SVG_SIZE}`,
39
28
  "aria-valuetext": label,
40
29
  role: "progressbar",
41
- "aria-busy": true,
42
- children: /*#__PURE__*/_jsxs("g", {
43
- children: [reduceMotion ? null : /*#__PURE__*/_jsx("animateTransform", {
44
- attributeName: "transform",
45
- type: "rotate",
46
- values: `-180 24 24;${360 + MIN_STROKE_ANGLE - 180} 24 24`,
47
- ...animationProps
48
- }), /*#__PURE__*/_jsx("circle", {
49
- fill: "none",
50
- stroke: color,
51
- strokeWidth: thickness * 48 / size,
52
- strokeLinecap: "round",
53
- cx: "24",
54
- cy: "24",
55
- r: "20",
56
- strokeDasharray: reduceMotion ? MAX_SVG_LENGTH : [MIN_SVG_LENGTH, SVG_CIRCUMFERENCE],
57
- strokeDashoffset: 0,
58
- vectorEffect: "non-scaling-stroke",
59
- children: reduceMotion ? null : /*#__PURE__*/_jsxs(_Fragment, {
60
- children: [/*#__PURE__*/_jsx("animate", {
61
- attributeName: "stroke-dashoffset",
62
- values: `0;-10;${MIN_SVG_LENGTH - SVG_CIRCUMFERENCE}`,
63
- ...animationProps,
64
- ...bezierProps
65
- }), /*#__PURE__*/_jsx("animate", {
66
- attributeName: "stroke-dasharray",
67
- values: `${MIN_SVG_LENGTH}, 200;${MAX_SVG_LENGTH}, 200;${MIN_SVG_LENGTH}, 200`,
68
- ...animationProps,
69
- ...bezierProps
70
- })]
71
- })
72
- })]
73
- })
30
+ "aria-busy": "true",
31
+ children: [/*#__PURE__*/_jsx("circle", {
32
+ fill: "none",
33
+ stroke: indicatorBackgroundColor,
34
+ strokeWidth: strokeWidth,
35
+ cx: SVG_CENTER,
36
+ cy: SVG_CENTER,
37
+ r: SPINNER_RADIUS
38
+ }), /*#__PURE__*/_jsx("circle", {
39
+ fill: "none",
40
+ stroke: color,
41
+ strokeWidth: strokeWidth,
42
+ strokeLinecap: "round",
43
+ cx: SVG_CENTER,
44
+ cy: SVG_CENTER,
45
+ r: SPINNER_RADIUS,
46
+ strokeDasharray: `${SPINNER_DASHARRAY_MIN * SVG_CIRCUMFERENCE}, ${SPINNER_DASHARRAY_MAX * SVG_CIRCUMFERENCE}`,
47
+ strokeDashoffset: "0"
48
+ // Circle rotated -90° so that 0% is at the top (12 o'clock).
49
+ ,
50
+ transform: ROTATION_TRANSFORM,
51
+ children: reduceMotion ? null : /*#__PURE__*/_jsxs(_Fragment, {
52
+ children: [/*#__PURE__*/_jsx("animateTransform", {
53
+ attributeName: "transform",
54
+ type: "rotate",
55
+ from: "0 24 24",
56
+ to: `${SPINNER_ROTATION_DEGREES} ${SVG_CENTER} ${SVG_CENTER}`,
57
+ dur: `${DURATION}ms`,
58
+ repeatCount: "indefinite",
59
+ additive: "sum"
60
+ }), /*#__PURE__*/_jsx("animate", {
61
+ attributeName: "stroke-dasharray",
62
+ dur: `${DURATION}ms`,
63
+ values: `
64
+ ${SPINNER_DASHARRAY_MIN * SVG_CIRCUMFERENCE},${SPINNER_DASHARRAY_MAX * SVG_CIRCUMFERENCE};
65
+ ${SPINNER_DASHARRAY_HALF * SVG_CIRCUMFERENCE},${SPINNER_DASHARRAY_HALF * SVG_CIRCUMFERENCE};
66
+ ${SPINNER_DASHARRAY_MIN * SVG_CIRCUMFERENCE},${SPINNER_DASHARRAY_MAX * SVG_CIRCUMFERENCE}
67
+ `,
68
+ ...animateProps
69
+ }), /*#__PURE__*/_jsx("animate", {
70
+ attributeName: "stroke-dashoffset",
71
+ dur: `${DURATION}ms`,
72
+ values: `
73
+ 0;
74
+ 0;
75
+ -${SPINNER_DASHOFFSET_FACTOR * SVG_CIRCUMFERENCE}
76
+ `,
77
+ ...animateProps
78
+ })]
79
+ })
80
+ })]
74
81
  });
75
82
  });
76
83
  Spinner.displayName = 'Spinner';