react-native-skelo 0.0.3 → 0.1.0-alpha.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/LICENSE +1 -1
- package/README.md +9 -26
- package/lib/commonjs/animations/PulseAnimation.js +26 -2
- package/lib/commonjs/animations/PulseAnimation.js.map +1 -1
- package/lib/commonjs/animations/ShimmerAnimation.js +55 -25
- package/lib/commonjs/animations/ShimmerAnimation.js.map +1 -1
- package/lib/commonjs/components/Skeleton.js +9 -15
- package/lib/commonjs/components/Skeleton.js.map +1 -1
- package/lib/module/animations/PulseAnimation.js +26 -2
- package/lib/module/animations/PulseAnimation.js.map +1 -1
- package/lib/module/animations/ShimmerAnimation.js +56 -26
- package/lib/module/animations/ShimmerAnimation.js.map +1 -1
- package/lib/module/components/Skeleton.js +9 -15
- package/lib/module/components/Skeleton.js.map +1 -1
- package/lib/typescript/animations/PulseAnimation.d.ts +44 -0
- package/lib/typescript/animations/PulseAnimation.d.ts.map +1 -1
- package/lib/typescript/animations/ShimmerAnimation.d.ts +44 -0
- package/lib/typescript/animations/ShimmerAnimation.d.ts.map +1 -1
- package/lib/typescript/components/Skeleton.d.ts.map +1 -1
- package/package.json +4 -20
- package/src/animations/PulseAnimation.tsx +67 -5
- package/src/animations/ShimmerAnimation.tsx +106 -38
- package/src/components/Skeleton.tsx +9 -17
- package/lib/commonjs/core/deepRegistry.js +0 -18
- package/lib/commonjs/core/deepRegistry.js.map +0 -1
- package/lib/commonjs/deep.js +0 -18
- package/lib/commonjs/deep.js.map +0 -1
- package/lib/module/core/deepRegistry.js +0 -11
- package/lib/module/core/deepRegistry.js.map +0 -1
- package/lib/module/deep.js +0 -11
- package/lib/module/deep.js.map +0 -1
- package/lib/typescript/core/deepRegistry.d.ts +0 -7
- package/lib/typescript/core/deepRegistry.d.ts.map +0 -1
- package/lib/typescript/deep.d.ts +0 -2
- package/lib/typescript/deep.d.ts.map +0 -1
- package/src/core/deepRegistry.ts +0 -16
- package/src/deep.ts +0 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useMemo","Parser","SkeletonRenderer","SkeletonIgnore","StyleSkeleton","
|
|
1
|
+
{"version":3,"names":["React","useMemo","Parser","SkeletonRenderer","SkeletonIgnore","StyleSkeleton","expandToComponentNodes","DEFAULT_CONFIG","Skeleton","loading","children","styles","excludeStyles","deep","animation","duration","baseColor","highlightColor","borderRadius","accessible","accessibilityLabel","debug","skeletonTree","__DEV__","console","log","expanded","createElement","Fragment","length","warn","parsed","parse","summarize","nodes","map","node","type","style","JSON","stringify","error","config","exclude","tree","displayName","Ignore"],"sourceRoot":"../../../src","sources":["components/Skeleton.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,15 +1,59 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { DimensionValue, StyleProp, ViewStyle } from 'react-native';
|
|
3
3
|
interface PulseProps {
|
|
4
|
+
/**
|
|
5
|
+
* Width of the pulse container
|
|
6
|
+
*/
|
|
4
7
|
width?: DimensionValue;
|
|
8
|
+
/**
|
|
9
|
+
* Height of the pulse container
|
|
10
|
+
*/
|
|
5
11
|
height?: DimensionValue;
|
|
12
|
+
/**
|
|
13
|
+
* Base color of the skeleton
|
|
14
|
+
* @default '#E1E9EE'
|
|
15
|
+
*/
|
|
6
16
|
baseColor?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Highlight color for pulse
|
|
19
|
+
* @default '#F2F8FC'
|
|
20
|
+
*/
|
|
7
21
|
highlightColor?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Animation duration in milliseconds
|
|
24
|
+
* @default 1000
|
|
25
|
+
*/
|
|
8
26
|
duration?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Border radius
|
|
29
|
+
*/
|
|
9
30
|
borderRadius?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Additional styles
|
|
33
|
+
*/
|
|
10
34
|
style?: StyleProp<ViewStyle>;
|
|
35
|
+
/**
|
|
36
|
+
* Child content (rendered inside pulse)
|
|
37
|
+
*/
|
|
11
38
|
children?: React.ReactNode;
|
|
12
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Pulse animation component using Reanimated 3
|
|
42
|
+
*
|
|
43
|
+
* Creates a subtle breathing/pulsing effect using:
|
|
44
|
+
* - Shared values for performance
|
|
45
|
+
* - Worklets for 60 FPS on UI thread
|
|
46
|
+
* - Opacity animation for pulse effect
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <PulseAnimation
|
|
51
|
+
* width={200}
|
|
52
|
+
* height={20}
|
|
53
|
+
* borderRadius={4}
|
|
54
|
+
* />
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
13
57
|
export declare function PulseAnimation({ width, height, baseColor, duration, borderRadius, style, children, }: PulseProps): React.JSX.Element;
|
|
14
58
|
export {};
|
|
15
59
|
//# sourceMappingURL=PulseAnimation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PulseAnimation.d.ts","sourceRoot":"","sources":["../../../src/animations/PulseAnimation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAWzE,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"PulseAnimation.d.ts","sourceRoot":"","sources":["../../../src/animations/PulseAnimation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAWzE,UAAU,UAAU;IAClB;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,SAAqB,EACrB,QAAe,EACf,YAAgB,EAChB,KAAK,EACL,QAAQ,GACT,EAAE,UAAU,qBAiDZ"}
|
|
@@ -1,15 +1,59 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { DimensionValue, StyleProp, ViewStyle } from 'react-native';
|
|
3
3
|
interface ShimmerProps {
|
|
4
|
+
/**
|
|
5
|
+
* Width of the shimmer container
|
|
6
|
+
*/
|
|
4
7
|
width?: DimensionValue;
|
|
8
|
+
/**
|
|
9
|
+
* Height of the shimmer container
|
|
10
|
+
*/
|
|
5
11
|
height?: DimensionValue;
|
|
12
|
+
/**
|
|
13
|
+
* Base color of the skeleton
|
|
14
|
+
* @default '#E1E9EE'
|
|
15
|
+
*/
|
|
6
16
|
baseColor?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Highlight color that shimmers across
|
|
19
|
+
* @default '#F2F8FC'
|
|
20
|
+
*/
|
|
7
21
|
highlightColor?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Animation duration in milliseconds
|
|
24
|
+
* @default 1500
|
|
25
|
+
*/
|
|
8
26
|
duration?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Border radius
|
|
29
|
+
*/
|
|
9
30
|
borderRadius?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Additional styles
|
|
33
|
+
*/
|
|
10
34
|
style?: StyleProp<ViewStyle>;
|
|
35
|
+
/**
|
|
36
|
+
* Child content (rendered on top of shimmer)
|
|
37
|
+
*/
|
|
11
38
|
children?: React.ReactNode;
|
|
12
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Shimmer animation component using Reanimated 3
|
|
42
|
+
*
|
|
43
|
+
* Creates a smooth left-to-right shimmer effect using:
|
|
44
|
+
* - Shared values for performance
|
|
45
|
+
* - Worklets for 60 FPS on UI thread
|
|
46
|
+
* - Linear gradient for shimmer effect
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <ShimmerAnimation
|
|
51
|
+
* width={200}
|
|
52
|
+
* height={20}
|
|
53
|
+
* borderRadius={4}
|
|
54
|
+
* />
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
13
57
|
export declare function ShimmerAnimation({ width, height, baseColor, highlightColor, duration, borderRadius, style, children, }: ShimmerProps): React.JSX.Element;
|
|
14
58
|
export {};
|
|
15
59
|
//# sourceMappingURL=ShimmerAnimation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShimmerAnimation.d.ts","sourceRoot":"","sources":["../../../src/animations/ShimmerAnimation.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ShimmerAnimation.d.ts","sourceRoot":"","sources":["../../../src/animations/ShimmerAnimation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAYzE,UAAU,YAAY;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,MAAM,EACN,SAAqB,EACrB,cAA0B,EAC1B,QAAe,EACf,YAAgB,EAChB,KAAK,EACL,QAAQ,GACT,EAAE,YAAY,qBA2Ed"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKlD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,aAAa,EACb,IAAY,EACZ,SAAoC,EACpC,QAAkC,EAClC,SAAoC,EACpC,cAA8C,EAC9C,YAA0C,EAC1C,UAAiB,EACjB,kBAAsC,EACtC,KAAa,GACd,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKlD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,aAAa,EACb,IAAY,EACZ,SAAoC,EACpC,QAAkC,EAClC,SAAoC,EACpC,cAA8C,EAC9C,YAA0C,EAC1C,UAAiB,EACjB,kBAAsC,EACtC,KAAa,GACd,EAAE,aAAa,qBAiFf;yBA/Fe,QAAQ"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-skelo",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
4
|
"description": "Automatic skeleton loading for React Native. Write your UI once, Skelo builds the loading state automatically.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
7
7
|
"types": "lib/typescript/index.d.ts",
|
|
8
8
|
"react-native": "src/index.ts",
|
|
9
9
|
"source": "src/index.ts",
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./lib/typescript/index.d.ts",
|
|
13
|
-
"react-native": "./src/index.ts",
|
|
14
|
-
"import": "./lib/module/index.js",
|
|
15
|
-
"require": "./lib/commonjs/index.js",
|
|
16
|
-
"default": "./lib/commonjs/index.js"
|
|
17
|
-
},
|
|
18
|
-
"./deep": {
|
|
19
|
-
"types": "./lib/typescript/deep.d.ts",
|
|
20
|
-
"react-native": "./src/deep.ts",
|
|
21
|
-
"import": "./lib/module/deep.js",
|
|
22
|
-
"require": "./lib/commonjs/deep.js",
|
|
23
|
-
"default": "./lib/commonjs/deep.js"
|
|
24
|
-
},
|
|
25
|
-
"./package.json": "./package.json"
|
|
26
|
-
},
|
|
27
10
|
"files": [
|
|
28
11
|
"src",
|
|
29
12
|
"lib",
|
|
@@ -35,7 +18,6 @@
|
|
|
35
18
|
"test:watch": "jest --watch",
|
|
36
19
|
"test:coverage": "jest --coverage",
|
|
37
20
|
"typecheck": "tsc --noEmit",
|
|
38
|
-
"build": "bob build",
|
|
39
21
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
40
22
|
"lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
|
41
23
|
"format": "prettier --write \"**/*.{js,ts,tsx,json,md}\"",
|
|
@@ -88,6 +70,7 @@
|
|
|
88
70
|
"peerDependencies": {
|
|
89
71
|
"react": "*",
|
|
90
72
|
"react-native": "*",
|
|
73
|
+
"react-native-linear-gradient": ">=2.8.0",
|
|
91
74
|
"react-native-reanimated": ">=3.0.0",
|
|
92
75
|
"react-reconciler": ">=0.29.0"
|
|
93
76
|
},
|
|
@@ -112,6 +95,7 @@
|
|
|
112
95
|
"react": "18.2.0",
|
|
113
96
|
"react-native": "0.73.1",
|
|
114
97
|
"react-native-builder-bob": "^0.23.2",
|
|
98
|
+
"react-native-linear-gradient": "^2.8.3",
|
|
115
99
|
"react-native-reanimated": "^3.6.1",
|
|
116
100
|
"react-reconciler": "^0.29.2",
|
|
117
101
|
"react-test-renderer": "18.2.0",
|
|
@@ -127,7 +111,7 @@
|
|
|
127
111
|
"<rootDir>/lib/"
|
|
128
112
|
],
|
|
129
113
|
"transformIgnorePatterns": [
|
|
130
|
-
"node_modules/(?!(@react-native|react-native|react-native-reanimated)/)"
|
|
114
|
+
"node_modules/(?!(@react-native|react-native|react-native-reanimated|react-native-linear-gradient)/)"
|
|
131
115
|
],
|
|
132
116
|
"collectCoverageFrom": [
|
|
133
117
|
"src/**/*.{ts,tsx}",
|
|
@@ -11,17 +11,67 @@ import Animated, {
|
|
|
11
11
|
} from 'react-native-reanimated';
|
|
12
12
|
|
|
13
13
|
interface PulseProps {
|
|
14
|
+
/**
|
|
15
|
+
* Width of the pulse container
|
|
16
|
+
*/
|
|
14
17
|
width?: DimensionValue;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Height of the pulse container
|
|
21
|
+
*/
|
|
15
22
|
height?: DimensionValue;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Base color of the skeleton
|
|
26
|
+
* @default '#E1E9EE'
|
|
27
|
+
*/
|
|
16
28
|
baseColor?: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Highlight color for pulse
|
|
32
|
+
* @default '#F2F8FC'
|
|
33
|
+
*/
|
|
17
34
|
highlightColor?: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Animation duration in milliseconds
|
|
38
|
+
* @default 1000
|
|
39
|
+
*/
|
|
18
40
|
duration?: number;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Border radius
|
|
44
|
+
*/
|
|
19
45
|
borderRadius?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Additional styles
|
|
49
|
+
*/
|
|
20
50
|
style?: StyleProp<ViewStyle>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Child content (rendered inside pulse)
|
|
54
|
+
*/
|
|
21
55
|
children?: React.ReactNode;
|
|
22
56
|
}
|
|
23
57
|
|
|
24
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Pulse animation component using Reanimated 3
|
|
60
|
+
*
|
|
61
|
+
* Creates a subtle breathing/pulsing effect using:
|
|
62
|
+
* - Shared values for performance
|
|
63
|
+
* - Worklets for 60 FPS on UI thread
|
|
64
|
+
* - Opacity animation for pulse effect
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```tsx
|
|
68
|
+
* <PulseAnimation
|
|
69
|
+
* width={200}
|
|
70
|
+
* height={20}
|
|
71
|
+
* borderRadius={4}
|
|
72
|
+
* />
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
25
75
|
export function PulseAnimation({
|
|
26
76
|
width,
|
|
27
77
|
height,
|
|
@@ -31,9 +81,12 @@ export function PulseAnimation({
|
|
|
31
81
|
style,
|
|
32
82
|
children,
|
|
33
83
|
}: PulseProps) {
|
|
84
|
+
// Shared value for opacity (0 to 1)
|
|
34
85
|
const opacity = useSharedValue(1);
|
|
35
86
|
|
|
36
87
|
useEffect(() => {
|
|
88
|
+
// Start infinite pulse animation
|
|
89
|
+
// Sequence: fade out -> fade in
|
|
37
90
|
opacity.value = withRepeat(
|
|
38
91
|
withSequence(
|
|
39
92
|
withTiming(0.5, {
|
|
@@ -45,21 +98,30 @@ export function PulseAnimation({
|
|
|
45
98
|
easing: Easing.inOut(Easing.ease),
|
|
46
99
|
})
|
|
47
100
|
),
|
|
48
|
-
-1,
|
|
49
|
-
false
|
|
101
|
+
-1, // Infinite repeat
|
|
102
|
+
false // Don't reverse
|
|
50
103
|
);
|
|
51
104
|
}, [duration, opacity]);
|
|
52
105
|
|
|
106
|
+
// Animated style for pulse effect
|
|
53
107
|
const animatedStyle = useAnimatedStyle(() => {
|
|
54
108
|
'worklet';
|
|
55
|
-
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
opacity: opacity.value,
|
|
112
|
+
};
|
|
56
113
|
}, []);
|
|
57
114
|
|
|
58
115
|
return (
|
|
59
116
|
<Animated.View
|
|
60
117
|
style={[
|
|
61
118
|
styles.container,
|
|
62
|
-
{
|
|
119
|
+
{
|
|
120
|
+
width,
|
|
121
|
+
height,
|
|
122
|
+
borderRadius,
|
|
123
|
+
backgroundColor: baseColor,
|
|
124
|
+
},
|
|
63
125
|
animatedStyle,
|
|
64
126
|
style,
|
|
65
127
|
]}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import React, { useEffect
|
|
2
|
-
import type {
|
|
3
|
-
DimensionValue,
|
|
4
|
-
LayoutChangeEvent,
|
|
5
|
-
StyleProp,
|
|
6
|
-
ViewStyle,
|
|
7
|
-
} from 'react-native';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import type { DimensionValue, StyleProp, ViewStyle } from 'react-native';
|
|
8
3
|
import { StyleSheet, View } from 'react-native';
|
|
9
4
|
import Animated, {
|
|
10
5
|
useSharedValue,
|
|
@@ -14,21 +9,70 @@ import Animated, {
|
|
|
14
9
|
interpolate,
|
|
15
10
|
Easing,
|
|
16
11
|
} from 'react-native-reanimated';
|
|
12
|
+
import { LinearGradient } from 'react-native-linear-gradient';
|
|
17
13
|
|
|
18
14
|
interface ShimmerProps {
|
|
15
|
+
/**
|
|
16
|
+
* Width of the shimmer container
|
|
17
|
+
*/
|
|
19
18
|
width?: DimensionValue;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Height of the shimmer container
|
|
22
|
+
*/
|
|
20
23
|
height?: DimensionValue;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Base color of the skeleton
|
|
27
|
+
* @default '#E1E9EE'
|
|
28
|
+
*/
|
|
21
29
|
baseColor?: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Highlight color that shimmers across
|
|
33
|
+
* @default '#F2F8FC'
|
|
34
|
+
*/
|
|
22
35
|
highlightColor?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Animation duration in milliseconds
|
|
39
|
+
* @default 1500
|
|
40
|
+
*/
|
|
23
41
|
duration?: number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Border radius
|
|
45
|
+
*/
|
|
24
46
|
borderRadius?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Additional styles
|
|
50
|
+
*/
|
|
25
51
|
style?: StyleProp<ViewStyle>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Child content (rendered on top of shimmer)
|
|
55
|
+
*/
|
|
26
56
|
children?: React.ReactNode;
|
|
27
57
|
}
|
|
28
58
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Shimmer animation component using Reanimated 3
|
|
61
|
+
*
|
|
62
|
+
* Creates a smooth left-to-right shimmer effect using:
|
|
63
|
+
* - Shared values for performance
|
|
64
|
+
* - Worklets for 60 FPS on UI thread
|
|
65
|
+
* - Linear gradient for shimmer effect
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* <ShimmerAnimation
|
|
70
|
+
* width={200}
|
|
71
|
+
* height={20}
|
|
72
|
+
* borderRadius={4}
|
|
73
|
+
* />
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
32
76
|
export function ShimmerAnimation({
|
|
33
77
|
width,
|
|
34
78
|
height,
|
|
@@ -39,56 +83,77 @@ export function ShimmerAnimation({
|
|
|
39
83
|
style,
|
|
40
84
|
children,
|
|
41
85
|
}: ShimmerProps) {
|
|
86
|
+
// Shared value for animation progress (0 to 1)
|
|
42
87
|
const progress = useSharedValue(0);
|
|
43
|
-
const [measuredWidth, setMeasuredWidth] = useState(0);
|
|
44
88
|
|
|
45
89
|
useEffect(() => {
|
|
90
|
+
// Start infinite shimmer animation
|
|
46
91
|
progress.value = withRepeat(
|
|
47
|
-
withTiming(1, {
|
|
48
|
-
|
|
49
|
-
|
|
92
|
+
withTiming(1, {
|
|
93
|
+
duration,
|
|
94
|
+
easing: Easing.linear,
|
|
95
|
+
}),
|
|
96
|
+
-1, // Infinite repeat
|
|
97
|
+
false // Don't reverse
|
|
50
98
|
);
|
|
51
99
|
}, [duration, progress]);
|
|
52
100
|
|
|
53
|
-
|
|
54
|
-
const w = event.nativeEvent.layout.width;
|
|
55
|
-
setMeasuredWidth(prev => (prev === w ? prev : w));
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const containerWidth = typeof width === 'number' ? width : measuredWidth;
|
|
59
|
-
|
|
101
|
+
// Animated style for shimmer overlay
|
|
60
102
|
const animatedStyle = useAnimatedStyle(() => {
|
|
61
103
|
'worklet';
|
|
62
|
-
const translateX = interpolate(
|
|
63
|
-
progress.value,
|
|
64
|
-
[0, 1],
|
|
65
|
-
[-containerWidth, containerWidth]
|
|
66
|
-
);
|
|
67
|
-
return { transform: [{ translateX }] };
|
|
68
|
-
}, [containerWidth]);
|
|
69
104
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
// Calculate shimmer position
|
|
106
|
+
// Interpolate from -100% to 100% to create left-to-right sweep
|
|
107
|
+
const translateX = interpolate(progress.value, [0, 1], [-1, 1]);
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
transform: [{ translateX: translateX * (typeof width === 'number' ? width : 200) }],
|
|
111
|
+
};
|
|
112
|
+
}, [width]);
|
|
75
113
|
|
|
76
114
|
return (
|
|
77
115
|
<View
|
|
78
|
-
onLayout={onLayout}
|
|
79
116
|
style={[
|
|
80
117
|
styles.container,
|
|
81
|
-
{
|
|
118
|
+
{
|
|
119
|
+
width,
|
|
120
|
+
height,
|
|
121
|
+
borderRadius,
|
|
122
|
+
backgroundColor: baseColor,
|
|
123
|
+
},
|
|
82
124
|
style,
|
|
83
125
|
]}
|
|
84
126
|
>
|
|
127
|
+
{/* Shimmer gradient overlay */}
|
|
85
128
|
<Animated.View
|
|
86
|
-
|
|
87
|
-
|
|
129
|
+
style={[
|
|
130
|
+
StyleSheet.absoluteFill,
|
|
131
|
+
{
|
|
132
|
+
overflow: 'hidden',
|
|
133
|
+
borderRadius,
|
|
134
|
+
},
|
|
135
|
+
]}
|
|
88
136
|
>
|
|
89
|
-
<View
|
|
137
|
+
<Animated.View
|
|
138
|
+
style={[
|
|
139
|
+
styles.shimmer,
|
|
140
|
+
{
|
|
141
|
+
width: typeof width === 'number' ? width : '100%',
|
|
142
|
+
height: '100%',
|
|
143
|
+
},
|
|
144
|
+
animatedStyle,
|
|
145
|
+
]}
|
|
146
|
+
>
|
|
147
|
+
<LinearGradient
|
|
148
|
+
colors={[baseColor, highlightColor, highlightColor, baseColor]}
|
|
149
|
+
start={{ x: 0, y: 0 }}
|
|
150
|
+
end={{ x: 1, y: 0 }}
|
|
151
|
+
style={StyleSheet.absoluteFill}
|
|
152
|
+
/>
|
|
153
|
+
</Animated.View>
|
|
90
154
|
</Animated.View>
|
|
91
155
|
|
|
156
|
+
{/* Child content */}
|
|
92
157
|
{children}
|
|
93
158
|
</View>
|
|
94
159
|
);
|
|
@@ -98,4 +163,7 @@ const styles = StyleSheet.create({
|
|
|
98
163
|
container: {
|
|
99
164
|
overflow: 'hidden',
|
|
100
165
|
},
|
|
166
|
+
shimmer: {
|
|
167
|
+
position: 'absolute',
|
|
168
|
+
},
|
|
101
169
|
});
|
|
@@ -4,7 +4,7 @@ import { Parser } from '../core/parser';
|
|
|
4
4
|
import { SkeletonRenderer } from './SkeletonRenderer';
|
|
5
5
|
import { SkeletonIgnore } from './SkeletonIgnore';
|
|
6
6
|
import { StyleSkeleton } from '../core/generator/StyleSkeleton';
|
|
7
|
-
import {
|
|
7
|
+
import { expandToComponentNodes } from '../core/parser/expandOffline';
|
|
8
8
|
import { DEFAULT_CONFIG } from '../constants/defaults';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -63,23 +63,15 @@ export function Skeleton({
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
try {
|
|
66
|
-
// Deep mode: expand opaque components into their real host tree
|
|
67
|
-
//
|
|
68
|
-
// Falls back to static parsing if unavailable or it returns nothing.
|
|
66
|
+
// Deep mode: expand opaque components into their real host tree by
|
|
67
|
+
// rendering them offline. Falls back to static parsing on failure.
|
|
69
68
|
if (deep) {
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (__DEV__) {
|
|
77
|
-
console.warn('[Skelo] deep expansion returned nothing; falling back to static parsing.');
|
|
78
|
-
}
|
|
79
|
-
} else if (__DEV__) {
|
|
80
|
-
console.warn(
|
|
81
|
-
"[Skelo] `deep` requires react-reconciler. Install it and add `import 'react-native-skelo/deep';` in your app entry."
|
|
82
|
-
);
|
|
69
|
+
const expanded = expandToComponentNodes(<>{children}</>);
|
|
70
|
+
if (expanded && expanded.length > 0) {
|
|
71
|
+
return expanded;
|
|
72
|
+
}
|
|
73
|
+
if (__DEV__) {
|
|
74
|
+
console.warn('[Skelo] deep expansion returned nothing; falling back to static parsing.');
|
|
83
75
|
}
|
|
84
76
|
}
|
|
85
77
|
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.getDeepExpander = getDeepExpander;
|
|
7
|
-
exports.setDeepExpander = setDeepExpander;
|
|
8
|
-
// Deep expansion is opt-in so the core bundle never depends on react-reconciler.
|
|
9
|
-
// `react-native-skelo/deep` registers the expander; Skeleton reads it here.
|
|
10
|
-
|
|
11
|
-
let expander = null;
|
|
12
|
-
function setDeepExpander(fn) {
|
|
13
|
-
expander = fn;
|
|
14
|
-
}
|
|
15
|
-
function getDeepExpander() {
|
|
16
|
-
return expander;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=deepRegistry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["expander","setDeepExpander","fn","getDeepExpander"],"sourceRoot":"../../../src","sources":["core/deepRegistry.ts"],"mappings":";;;;;;;AAGA;AACA;;AAGA,IAAIA,QAA6B,GAAG,IAAI;AAEjC,SAASC,eAAeA,CAACC,EAAgB,EAAQ;EACtDF,QAAQ,GAAGE,EAAE;AACf;AAEO,SAASC,eAAeA,CAAA,EAAwB;EACrD,OAAOH,QAAQ;AACjB","ignoreList":[]}
|
package/lib/commonjs/deep.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.deepEnabled = void 0;
|
|
7
|
-
var _deepRegistry = require("./core/deepRegistry");
|
|
8
|
-
var _expandOffline = require("./core/parser/expandOffline");
|
|
9
|
-
// Opt-in deep mode. Import once in your app entry to enable `<Skeleton deep>`:
|
|
10
|
-
//
|
|
11
|
-
// import 'react-native-skelo/deep';
|
|
12
|
-
//
|
|
13
|
-
// This is the only module that pulls in react-reconciler, so apps that don't
|
|
14
|
-
// use deep mode never bundle it. Requires `react-reconciler` to be installed.
|
|
15
|
-
|
|
16
|
-
(0, _deepRegistry.setDeepExpander)(_expandOffline.expandToComponentNodes);
|
|
17
|
-
const deepEnabled = exports.deepEnabled = true;
|
|
18
|
-
//# sourceMappingURL=deep.js.map
|
package/lib/commonjs/deep.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_deepRegistry","require","_expandOffline","setDeepExpander","expandToComponentNodes","deepEnabled","exports"],"sourceRoot":"../../src","sources":["deep.ts"],"mappings":";;;;;;AAMA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AAPA;AACA;AACA;AACA;AACA;AACA;;AAIA,IAAAE,6BAAe,EAACC,qCAAsB,CAAC;AAEhC,MAAMC,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,IAAI","ignoreList":[]}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// Deep expansion is opt-in so the core bundle never depends on react-reconciler.
|
|
2
|
-
// `react-native-skelo/deep` registers the expander; Skeleton reads it here.
|
|
3
|
-
|
|
4
|
-
let expander = null;
|
|
5
|
-
export function setDeepExpander(fn) {
|
|
6
|
-
expander = fn;
|
|
7
|
-
}
|
|
8
|
-
export function getDeepExpander() {
|
|
9
|
-
return expander;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=deepRegistry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["expander","setDeepExpander","fn","getDeepExpander"],"sourceRoot":"../../../src","sources":["core/deepRegistry.ts"],"mappings":"AAGA;AACA;;AAGA,IAAIA,QAA6B,GAAG,IAAI;AAExC,OAAO,SAASC,eAAeA,CAACC,EAAgB,EAAQ;EACtDF,QAAQ,GAAGE,EAAE;AACf;AAEA,OAAO,SAASC,eAAeA,CAAA,EAAwB;EACrD,OAAOH,QAAQ;AACjB","ignoreList":[]}
|
package/lib/module/deep.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// Opt-in deep mode. Import once in your app entry to enable `<Skeleton deep>`:
|
|
2
|
-
//
|
|
3
|
-
// import 'react-native-skelo/deep';
|
|
4
|
-
//
|
|
5
|
-
// This is the only module that pulls in react-reconciler, so apps that don't
|
|
6
|
-
// use deep mode never bundle it. Requires `react-reconciler` to be installed.
|
|
7
|
-
import { setDeepExpander } from './core/deepRegistry';
|
|
8
|
-
import { expandToComponentNodes } from './core/parser/expandOffline';
|
|
9
|
-
setDeepExpander(expandToComponentNodes);
|
|
10
|
-
export const deepEnabled = true;
|
|
11
|
-
//# sourceMappingURL=deep.js.map
|
package/lib/module/deep.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["setDeepExpander","expandToComponentNodes","deepEnabled"],"sourceRoot":"../../src","sources":["deep.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,eAAe,QAAQ,qBAAqB;AACrD,SAASC,sBAAsB,QAAQ,6BAA6B;AAEpED,eAAe,CAACC,sBAAsB,CAAC;AAEvC,OAAO,MAAMC,WAAW,GAAG,IAAI","ignoreList":[]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ReactElement } from 'react';
|
|
2
|
-
import type { ComponentNode } from '../types';
|
|
3
|
-
type DeepExpander = (element: ReactElement) => ComponentNode[] | null;
|
|
4
|
-
export declare function setDeepExpander(fn: DeepExpander): void;
|
|
5
|
-
export declare function getDeepExpander(): DeepExpander | null;
|
|
6
|
-
export {};
|
|
7
|
-
//# sourceMappingURL=deepRegistry.d.ts.map
|