@fluentui-react-native/experimental-shimmer 0.8.11 → 0.8.13

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 (80) hide show
  1. package/CHANGELOG.json +51 -1
  2. package/CHANGELOG.md +20 -2
  3. package/jest.config.js +2 -0
  4. package/lib/Shimmer.d.ts.map +1 -1
  5. package/lib/Shimmer.js +27 -30
  6. package/lib/Shimmer.js.map +1 -1
  7. package/lib/Shimmer.styling.d.ts.map +1 -1
  8. package/lib/Shimmer.styling.js +5 -16
  9. package/lib/Shimmer.styling.js.map +1 -1
  10. package/lib/Shimmer.styling.win32.d.ts +1 -2
  11. package/lib/Shimmer.styling.win32.d.ts.map +1 -1
  12. package/lib/Shimmer.styling.win32.js +1 -13
  13. package/lib/Shimmer.styling.win32.js.map +1 -1
  14. package/lib/Shimmer.test.d.ts +2 -0
  15. package/lib/Shimmer.test.d.ts.map +1 -0
  16. package/lib/Shimmer.test.js +48 -0
  17. package/lib/Shimmer.test.js.map +1 -0
  18. package/lib/Shimmer.types.d.ts +2 -2
  19. package/lib/Shimmer.types.d.ts.map +1 -1
  20. package/lib/Shimmer.types.win32.d.ts +1 -1
  21. package/lib/Shimmer.types.win32.d.ts.map +1 -1
  22. package/lib/Shimmer.win32.js +1 -1
  23. package/lib/Shimmer.win32.js.map +1 -1
  24. package/lib/ShimmerTokens.android.d.ts +5 -0
  25. package/lib/ShimmerTokens.android.d.ts.map +1 -0
  26. package/lib/ShimmerTokens.android.js +12 -0
  27. package/lib/ShimmerTokens.android.js.map +1 -0
  28. package/lib/ShimmerTokens.d.ts +5 -0
  29. package/lib/ShimmerTokens.d.ts.map +1 -0
  30. package/lib/ShimmerTokens.js +13 -0
  31. package/lib/ShimmerTokens.js.map +1 -0
  32. package/lib/ShimmerTokens.win32.d.ts +5 -0
  33. package/lib/ShimmerTokens.win32.d.ts.map +1 -0
  34. package/lib/ShimmerTokens.win32.js +14 -0
  35. package/lib/ShimmerTokens.win32.js.map +1 -0
  36. package/lib-commonjs/Shimmer.d.ts.map +1 -1
  37. package/lib-commonjs/Shimmer.js +27 -30
  38. package/lib-commonjs/Shimmer.js.map +1 -1
  39. package/lib-commonjs/Shimmer.styling.d.ts.map +1 -1
  40. package/lib-commonjs/Shimmer.styling.js +5 -16
  41. package/lib-commonjs/Shimmer.styling.js.map +1 -1
  42. package/lib-commonjs/Shimmer.styling.win32.d.ts +1 -2
  43. package/lib-commonjs/Shimmer.styling.win32.d.ts.map +1 -1
  44. package/lib-commonjs/Shimmer.styling.win32.js +3 -16
  45. package/lib-commonjs/Shimmer.styling.win32.js.map +1 -1
  46. package/lib-commonjs/Shimmer.test.d.ts +2 -0
  47. package/lib-commonjs/Shimmer.test.d.ts.map +1 -0
  48. package/lib-commonjs/Shimmer.test.js +69 -0
  49. package/lib-commonjs/Shimmer.test.js.map +1 -0
  50. package/lib-commonjs/Shimmer.types.d.ts +2 -2
  51. package/lib-commonjs/Shimmer.types.d.ts.map +1 -1
  52. package/lib-commonjs/Shimmer.types.win32.d.ts +1 -1
  53. package/lib-commonjs/Shimmer.types.win32.d.ts.map +1 -1
  54. package/lib-commonjs/Shimmer.win32.js +1 -1
  55. package/lib-commonjs/Shimmer.win32.js.map +1 -1
  56. package/lib-commonjs/ShimmerTokens.android.d.ts +5 -0
  57. package/lib-commonjs/ShimmerTokens.android.d.ts.map +1 -0
  58. package/lib-commonjs/ShimmerTokens.android.js +16 -0
  59. package/lib-commonjs/ShimmerTokens.android.js.map +1 -0
  60. package/lib-commonjs/ShimmerTokens.d.ts +5 -0
  61. package/lib-commonjs/ShimmerTokens.d.ts.map +1 -0
  62. package/lib-commonjs/ShimmerTokens.js +17 -0
  63. package/lib-commonjs/ShimmerTokens.js.map +1 -0
  64. package/lib-commonjs/ShimmerTokens.win32.d.ts +5 -0
  65. package/lib-commonjs/ShimmerTokens.win32.d.ts.map +1 -0
  66. package/lib-commonjs/ShimmerTokens.win32.js +18 -0
  67. package/lib-commonjs/ShimmerTokens.win32.js.map +1 -0
  68. package/package.json +9 -3
  69. package/src/Shimmer.styling.ts +6 -17
  70. package/src/Shimmer.styling.win32.ts +2 -14
  71. package/src/Shimmer.test.tsx +53 -0
  72. package/src/Shimmer.tsx +12 -17
  73. package/src/Shimmer.types.ts +2 -2
  74. package/src/Shimmer.types.win32.ts +1 -1
  75. package/src/Shimmer.win32.tsx +2 -2
  76. package/src/ShimmerTokens.android.ts +14 -0
  77. package/src/ShimmerTokens.ts +15 -0
  78. package/src/ShimmerTokens.win32.ts +16 -0
  79. package/src/__snapshots__/Shimmer.test.tsx.snap +249 -0
  80. package/tsconfig.json +2 -1
@@ -0,0 +1,53 @@
1
+ import * as React from 'react';
2
+ import * as renderer from 'react-test-renderer';
3
+ import { Shimmer } from './Shimmer';
4
+ import { ShimmerCircleElement, ShimmerRectElement } from './Shimmer.types';
5
+
6
+ // mocks out setTimeout and other timer functions with mock functions, test will fail without this as we're using Animated API
7
+ jest.useFakeTimers();
8
+
9
+ function shimmerRects(): Array<ShimmerRectElement | ShimmerCircleElement> {
10
+ return [
11
+ {
12
+ type: 'rect',
13
+ borderRadiusX: 3,
14
+ borderRadiusY: 3,
15
+ width: 100,
16
+ height: 20,
17
+ x: 90,
18
+ y: 70,
19
+ },
20
+ {
21
+ type: 'rect',
22
+ borderRadiusX: 3,
23
+ borderRadiusY: 3,
24
+ width: 150,
25
+ height: 20,
26
+ x: 90,
27
+ y: 42,
28
+ },
29
+ {
30
+ type: 'rect',
31
+ borderRadiusX: 3,
32
+ borderRadiusY: 3,
33
+ width: 200,
34
+ height: 20,
35
+ x: 90,
36
+ y: 15,
37
+ },
38
+ ];
39
+ }
40
+
41
+ const style = { width: 300, height: 100 };
42
+
43
+ describe('Shimmer component tests', () => {
44
+ it('Shimmer default', () => {
45
+ const tree = renderer.create(<Shimmer elements={shimmerRects()} />).toJSON();
46
+ expect(tree).toMatchSnapshot();
47
+ });
48
+
49
+ it('Shimmer with style prop', () => {
50
+ const tree = renderer.create(<Shimmer elements={shimmerRects()} style={style} />).toJSON();
51
+ expect(tree).toMatchSnapshot();
52
+ });
53
+ });
package/src/Shimmer.tsx CHANGED
@@ -21,8 +21,8 @@ export const Shimmer = compose<ShimmerType>({
21
21
  const memoizedShimmerData = useMemo(
22
22
  () => ({
23
23
  angle: props.angle ? props.angle : tokens['angle'],
24
- containerWidth: props?.style['width'] ? props?.style['width'] : '100%',
25
- containerHeight: props?.style['height'] ? props?.style['height'] : '100%',
24
+ containerWidth: props?.style?.['width'] ? props?.style['width'] : '100%',
25
+ containerHeight: props?.style?.['height'] ? props?.style['height'] : '100%',
26
26
  delay: props.delay ? props.delay : tokens['delay'],
27
27
  duration: props.duration ? props.duration : tokens['duration'],
28
28
  shimmerColor: props.shimmerColor ? props.shimmerColor : tokens['shimmerColor'],
@@ -42,27 +42,22 @@ export const Shimmer = compose<ShimmerType>({
42
42
  ],
43
43
  );
44
44
 
45
- const startValue = useRef(new Animated.Value(0)).current;
46
-
47
- /**
48
- * https://github.com/facebook/react-native/pull/29585
49
- * For Animated.loop() to work with the native driver, React Native needs this fix.
50
- * It's only available in React Native 0.66+, and React Native macOS 0.62+
51
- * To workaround this, let's just rerun the loop everytime the animation finishes
45
+ /* The shimmer animation is implemented using a LinearGradient which travels from left to right.
46
+ * Different angles are handled by rotating this gradient.
47
+ * The startValue is used to control the start position of the gradient animation, it is set as -1 to make sure it is starts off the screen for any angle.
48
+ * Similarly the endValue is set to 2 to make sure the gradient animation exits the entire screen for any angle.
52
49
  */
50
+ const startValue = useRef(new Animated.Value(-1)).current;
53
51
  const shimmerAnimation = useCallback(() => {
54
- Animated.sequence([
52
+ Animated.loop(
55
53
  Animated.timing(startValue, {
56
- toValue: 30,
54
+ toValue: 2,
57
55
  duration: memoizedShimmerData.duration,
58
56
  delay: memoizedShimmerData.delay,
59
57
  useNativeDriver: true,
60
58
  }),
61
- ]).start(() => {
62
- startValue.setValue(0);
63
- shimmerAnimation();
64
- });
65
- }, [memoizedShimmerData.duration, memoizedShimmerData.delay]);
59
+ ).start();
60
+ }, [memoizedShimmerData.delay, memoizedShimmerData.duration]);
66
61
 
67
62
  useEffect(() => {
68
63
  shimmerAnimation();
@@ -101,7 +96,7 @@ export const Shimmer = compose<ShimmerType>({
101
96
  return (
102
97
  <Slots.root {...mergedProps}>
103
98
  <Defs>
104
- <AnimatedLinearGradient id="gradient" x1={startValue} y1={memoizedShimmerData.angle} x2="-1" y2="-1">
99
+ <AnimatedLinearGradient id="gradient" x1={startValue} x2="-1" gradientTransform={`rotate(${memoizedShimmerData.angle})`}>
105
100
  <Stop offset="10%" stopColor={memoizedShimmerData.shimmerColor} stopOpacity={memoizedShimmerData.shimmerColorOpacity} />
106
101
  <Stop
107
102
  offset="20%"
@@ -140,7 +140,7 @@ export interface ShimmerTokens extends IBackgroundColorTokens {
140
140
  shimmerWaveWidth?: number | string;
141
141
  }
142
142
 
143
- export interface ShimmerSlotProps extends ShimmerProps {
143
+ export interface ShimmerSlotProps {
144
144
  root: SvgProps;
145
145
  }
146
146
 
@@ -148,7 +148,7 @@ export interface ShimmerProps extends ViewProps, ShimmerTokens {
148
148
  /**
149
149
  * Shimmer shapes that define the masking effect of the Shimmer control.
150
150
  */
151
- elements?: Array<ShimmerElementTypes>;
151
+ elements: Array<ShimmerElementTypes>;
152
152
  }
153
153
 
154
154
  export interface ShimmerType {
@@ -26,7 +26,7 @@ export interface ShimmerWaveProps extends ShimmerTokens {
26
26
  viewBoxWidth: number;
27
27
  }
28
28
 
29
- export interface ShimmerSlotProps extends ShimmerProps {
29
+ export interface ShimmerSlotProps {
30
30
  root: ViewProps;
31
31
  clippingMask: ClippingMaskProps;
32
32
  shimmerWave: ShimmerWaveProps;
@@ -82,10 +82,10 @@ export const Shimmer = compose<ShimmerType>({
82
82
  },
83
83
 
84
84
  useRender: (props: ShimmerProps, useSlots: UseSlots<ShimmerType>) => {
85
+ const Slots = useSlots(props);
86
+
85
87
  return (rest: ShimmerProps) => {
86
88
  const { elements, ...mergedProps } = mergeProps(props, rest);
87
- const Slots = useSlots(mergedProps);
88
-
89
89
  /**
90
90
  * Generate a clip path from the provided element shapes, with their path parameter strings generated from their corresponding properties.
91
91
  * Ideally this would be better possible with functions from the shape elements themselves and not to rely on our own calculations.
@@ -0,0 +1,14 @@
1
+ import { Theme } from '@fluentui-react-native/framework';
2
+ import { ShimmerTokens } from './Shimmer.types';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+
5
+ export const defaultShimmerTokens: TokenSettings<ShimmerTokens, Theme> = (theme: Theme) =>
6
+ ({
7
+ angle: 45,
8
+ delay: 0,
9
+ duration: 1000,
10
+ shimmerColor: theme.colors.neutralStencil1,
11
+ shimmerColorOpacity: 1,
12
+ shimmerWaveColor: theme.colors.neutralStencil2,
13
+ shimmerWaveColorOpacity: 1,
14
+ } as ShimmerTokens);
@@ -0,0 +1,15 @@
1
+ import { Theme } from '@fluentui-react-native/framework';
2
+ import { ShimmerTokens } from './Shimmer.types';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+ import { getCurrentAppearance } from '@fluentui-react-native/theming-utils';
5
+
6
+ export const defaultShimmerTokens: TokenSettings<ShimmerTokens, Theme> = (theme: Theme) =>
7
+ ({
8
+ angle: 0,
9
+ delay: 0,
10
+ duration: 7000,
11
+ shimmerColor: getCurrentAppearance(theme.host.appearance, 'light') === 'light' ? '#E1E1E1' : '#404040',
12
+ shimmerColorOpacity: 1,
13
+ shimmerWaveColor: getCurrentAppearance(theme.host.appearance, 'light') === 'light' ? 'white' : 'black',
14
+ shimmerWaveColorOpacity: 1,
15
+ } as ShimmerTokens);
@@ -0,0 +1,16 @@
1
+ import { Theme } from '@fluentui-react-native/framework';
2
+ import { ShimmerTokens } from './Shimmer.types';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+
5
+ export const defaultShimmerTokens: TokenSettings<ShimmerTokens, Theme> = (theme: Theme) =>
6
+ ({
7
+ angle: 0,
8
+ backgroundColor: theme.colors.background,
9
+ delay: 500,
10
+ duration: 2000,
11
+ shimmerColor: theme.colors.bodyFrameDivider,
12
+ shimmerColorOpacity: 1,
13
+ shimmerWaveColor: '#E1E1E1',
14
+ shimmerWaveColorOpacity: 1,
15
+ shimmerWaveWidth: '100%',
16
+ } as ShimmerTokens);
@@ -0,0 +1,249 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Shimmer component tests Shimmer default 1`] = `
4
+ <RNSVGSvgView
5
+ accessibilityRole="progressbar"
6
+ accessible={true}
7
+ angle={45}
8
+ bbHeight="100%"
9
+ bbWidth="100%"
10
+ delay={0}
11
+ duration={1000}
12
+ focusable={false}
13
+ shimmerColor="#e6e6e6"
14
+ shimmerColorOpacity={1}
15
+ shimmerWaveColor="#fafafa"
16
+ shimmerWaveColorOpacity={1}
17
+ style={
18
+ Array [
19
+ Object {
20
+ "backgroundColor": "transparent",
21
+ "borderWidth": 0,
22
+ },
23
+ Object {
24
+ "flex": 0,
25
+ "height": "100%",
26
+ "width": "100%",
27
+ },
28
+ ]
29
+ }
30
+ >
31
+ <RNSVGGroup>
32
+ <RNSVGDefs>
33
+ <RNSVGLinearGradient
34
+ gradient={
35
+ Array [
36
+ 0.1,
37
+ -1644826,
38
+ 0.2,
39
+ -328966,
40
+ 0.3,
41
+ -1644826,
42
+ ]
43
+ }
44
+ gradientTransform={
45
+ Array [
46
+ 0.7071067811865476,
47
+ 0.7071067811865475,
48
+ -0.7071067811865475,
49
+ 0.7071067811865476,
50
+ 0,
51
+ 0,
52
+ ]
53
+ }
54
+ gradientUnits={0}
55
+ name="gradient"
56
+ x1={-1}
57
+ x2="-1"
58
+ y1="0%"
59
+ y2="0%"
60
+ />
61
+ <RNSVGClipPath
62
+ name="shimmerView"
63
+ >
64
+ <RNSVGRect
65
+ height={20}
66
+ rx={3}
67
+ ry={3}
68
+ width={100}
69
+ x={90}
70
+ y={70}
71
+ />
72
+ <RNSVGRect
73
+ height={20}
74
+ rx={3}
75
+ ry={3}
76
+ width={150}
77
+ x={90}
78
+ y={42}
79
+ />
80
+ <RNSVGRect
81
+ height={20}
82
+ rx={3}
83
+ ry={3}
84
+ width={200}
85
+ x={90}
86
+ y={15}
87
+ />
88
+ </RNSVGClipPath>
89
+ </RNSVGDefs>
90
+ <RNSVGGroup
91
+ matrix={
92
+ Array [
93
+ 1,
94
+ 0,
95
+ 0,
96
+ 1,
97
+ 0,
98
+ 0,
99
+ ]
100
+ }
101
+ >
102
+ <RNSVGRect
103
+ clipPath="shimmerView"
104
+ fill={
105
+ Array [
106
+ 1,
107
+ "gradient",
108
+ ]
109
+ }
110
+ height="100%"
111
+ propList={
112
+ Array [
113
+ "fill",
114
+ ]
115
+ }
116
+ width="100%"
117
+ x="0"
118
+ y="0"
119
+ />
120
+ </RNSVGGroup>
121
+ </RNSVGGroup>
122
+ </RNSVGSvgView>
123
+ `;
124
+
125
+ exports[`Shimmer component tests Shimmer with style prop 1`] = `
126
+ <RNSVGSvgView
127
+ accessibilityRole="progressbar"
128
+ accessible={true}
129
+ angle={45}
130
+ bbHeight={100}
131
+ bbWidth={300}
132
+ delay={0}
133
+ duration={1000}
134
+ focusable={false}
135
+ shimmerColor="#e6e6e6"
136
+ shimmerColorOpacity={1}
137
+ shimmerWaveColor="#fafafa"
138
+ shimmerWaveColorOpacity={1}
139
+ style={
140
+ Array [
141
+ Object {
142
+ "backgroundColor": "transparent",
143
+ "borderWidth": 0,
144
+ },
145
+ Object {
146
+ "height": 100,
147
+ "width": 300,
148
+ },
149
+ Object {
150
+ "flex": 0,
151
+ "height": 100,
152
+ "width": 300,
153
+ },
154
+ ]
155
+ }
156
+ >
157
+ <RNSVGGroup>
158
+ <RNSVGDefs>
159
+ <RNSVGLinearGradient
160
+ gradient={
161
+ Array [
162
+ 0.1,
163
+ -1644826,
164
+ 0.2,
165
+ -328966,
166
+ 0.3,
167
+ -1644826,
168
+ ]
169
+ }
170
+ gradientTransform={
171
+ Array [
172
+ 0.7071067811865476,
173
+ 0.7071067811865475,
174
+ -0.7071067811865475,
175
+ 0.7071067811865476,
176
+ 0,
177
+ 0,
178
+ ]
179
+ }
180
+ gradientUnits={0}
181
+ name="gradient"
182
+ x1={-1}
183
+ x2="-1"
184
+ y1="0%"
185
+ y2="0%"
186
+ />
187
+ <RNSVGClipPath
188
+ name="shimmerView"
189
+ >
190
+ <RNSVGRect
191
+ height={20}
192
+ rx={3}
193
+ ry={3}
194
+ width={100}
195
+ x={90}
196
+ y={70}
197
+ />
198
+ <RNSVGRect
199
+ height={20}
200
+ rx={3}
201
+ ry={3}
202
+ width={150}
203
+ x={90}
204
+ y={42}
205
+ />
206
+ <RNSVGRect
207
+ height={20}
208
+ rx={3}
209
+ ry={3}
210
+ width={200}
211
+ x={90}
212
+ y={15}
213
+ />
214
+ </RNSVGClipPath>
215
+ </RNSVGDefs>
216
+ <RNSVGGroup
217
+ matrix={
218
+ Array [
219
+ 1,
220
+ 0,
221
+ 0,
222
+ 1,
223
+ 0,
224
+ 0,
225
+ ]
226
+ }
227
+ >
228
+ <RNSVGRect
229
+ clipPath="shimmerView"
230
+ fill={
231
+ Array [
232
+ 1,
233
+ "gradient",
234
+ ]
235
+ }
236
+ height={100}
237
+ propList={
238
+ Array [
239
+ "fill",
240
+ ]
241
+ }
242
+ width={300}
243
+ x="0"
244
+ y="0"
245
+ />
246
+ </RNSVGGroup>
247
+ </RNSVGGroup>
248
+ </RNSVGSvgView>
249
+ `;
package/tsconfig.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "@fluentui-react-native/scripts/tsconfig.json",
3
3
  "compilerOptions": {
4
- "outDir": "lib"
4
+ "outDir": "lib",
5
+ "types": ["node", "jest"]
5
6
  },
6
7
  "include": ["src"]
7
8
  }