react-native-smart-skeleton 0.0.1
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/README.md +255 -0
- package/lib/commonjs/animations/breathing.js +53 -0
- package/lib/commonjs/animations/breathing.js.map +1 -0
- package/lib/commonjs/animations/pulse.js +50 -0
- package/lib/commonjs/animations/pulse.js.map +1 -0
- package/lib/commonjs/animations/shimmer.js +68 -0
- package/lib/commonjs/animations/shimmer.js.map +1 -0
- package/lib/commonjs/animations/wave.js +54 -0
- package/lib/commonjs/animations/wave.js.map +1 -0
- package/lib/commonjs/clone/SkeletonClone.js +91 -0
- package/lib/commonjs/clone/SkeletonClone.js.map +1 -0
- package/lib/commonjs/components/Circle.js +27 -0
- package/lib/commonjs/components/Circle.js.map +1 -0
- package/lib/commonjs/components/Group.js +57 -0
- package/lib/commonjs/components/Group.js.map +1 -0
- package/lib/commonjs/components/Pill.js +32 -0
- package/lib/commonjs/components/Pill.js.map +1 -0
- package/lib/commonjs/components/Rect.js +21 -0
- package/lib/commonjs/components/Rect.js.map +1 -0
- package/lib/commonjs/components/Skeleton.js +196 -0
- package/lib/commonjs/components/Skeleton.js.map +1 -0
- package/lib/commonjs/components/Square.js +28 -0
- package/lib/commonjs/components/Square.js.map +1 -0
- package/lib/commonjs/demo/demo.gif +0 -0
- package/lib/commonjs/hooks/useReducedMotion.js +42 -0
- package/lib/commonjs/hooks/useReducedMotion.js.map +1 -0
- package/lib/commonjs/hooks/useSkeletonTheme.js +46 -0
- package/lib/commonjs/hooks/useSkeletonTheme.js.map +1 -0
- package/lib/commonjs/index.js +149 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/presets/Card.js +83 -0
- package/lib/commonjs/presets/Card.js.map +1 -0
- package/lib/commonjs/presets/Chat.js +54 -0
- package/lib/commonjs/presets/Chat.js.map +1 -0
- package/lib/commonjs/presets/Product.js +70 -0
- package/lib/commonjs/presets/Product.js.map +1 -0
- package/lib/commonjs/presets/Profile.js +67 -0
- package/lib/commonjs/presets/Profile.js.map +1 -0
- package/lib/commonjs/presets/Video.js +76 -0
- package/lib/commonjs/presets/Video.js.map +1 -0
- package/lib/commonjs/providers/SkeletonProvider.js +70 -0
- package/lib/commonjs/providers/SkeletonProvider.js.map +1 -0
- package/lib/commonjs/types/index.js +6 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/colors.js +144 -0
- package/lib/commonjs/utils/colors.js.map +1 -0
- package/lib/commonjs/utils/responsive.js +84 -0
- package/lib/commonjs/utils/responsive.js.map +1 -0
- package/lib/commonjs/utils/theme.js +39 -0
- package/lib/commonjs/utils/theme.js.map +1 -0
- package/lib/module/animations/breathing.js +47 -0
- package/lib/module/animations/breathing.js.map +1 -0
- package/lib/module/animations/pulse.js +44 -0
- package/lib/module/animations/pulse.js.map +1 -0
- package/lib/module/animations/shimmer.js +61 -0
- package/lib/module/animations/shimmer.js.map +1 -0
- package/lib/module/animations/wave.js +48 -0
- package/lib/module/animations/wave.js.map +1 -0
- package/lib/module/clone/SkeletonClone.js +84 -0
- package/lib/module/clone/SkeletonClone.js.map +1 -0
- package/lib/module/components/Circle.js +20 -0
- package/lib/module/components/Circle.js.map +1 -0
- package/lib/module/components/Group.js +50 -0
- package/lib/module/components/Group.js.map +1 -0
- package/lib/module/components/Pill.js +25 -0
- package/lib/module/components/Pill.js.map +1 -0
- package/lib/module/components/Rect.js +14 -0
- package/lib/module/components/Rect.js.map +1 -0
- package/lib/module/components/Skeleton.js +188 -0
- package/lib/module/components/Skeleton.js.map +1 -0
- package/lib/module/components/Square.js +21 -0
- package/lib/module/components/Square.js.map +1 -0
- package/lib/module/demo/demo.gif +0 -0
- package/lib/module/hooks/useReducedMotion.js +37 -0
- package/lib/module/hooks/useReducedMotion.js.map +1 -0
- package/lib/module/hooks/useSkeletonTheme.js +40 -0
- package/lib/module/hooks/useSkeletonTheme.js.map +1 -0
- package/lib/module/index.js +50 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/presets/Card.js +76 -0
- package/lib/module/presets/Card.js.map +1 -0
- package/lib/module/presets/Chat.js +47 -0
- package/lib/module/presets/Chat.js.map +1 -0
- package/lib/module/presets/Product.js +63 -0
- package/lib/module/presets/Product.js.map +1 -0
- package/lib/module/presets/Profile.js +60 -0
- package/lib/module/presets/Profile.js.map +1 -0
- package/lib/module/presets/Video.js +69 -0
- package/lib/module/presets/Video.js.map +1 -0
- package/lib/module/providers/SkeletonProvider.js +61 -0
- package/lib/module/providers/SkeletonProvider.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/colors.js +132 -0
- package/lib/module/utils/colors.js.map +1 -0
- package/lib/module/utils/responsive.js +74 -0
- package/lib/module/utils/responsive.js.map +1 -0
- package/lib/module/utils/theme.js +32 -0
- package/lib/module/utils/theme.js.map +1 -0
- package/lib/typescript/animations/breathing.d.ts +26 -0
- package/lib/typescript/animations/breathing.d.ts.map +1 -0
- package/lib/typescript/animations/pulse.d.ts +22 -0
- package/lib/typescript/animations/pulse.d.ts.map +1 -0
- package/lib/typescript/animations/shimmer.d.ts +34 -0
- package/lib/typescript/animations/shimmer.d.ts.map +1 -0
- package/lib/typescript/animations/wave.d.ts +23 -0
- package/lib/typescript/animations/wave.d.ts.map +1 -0
- package/lib/typescript/clone/SkeletonClone.d.ts +30 -0
- package/lib/typescript/clone/SkeletonClone.d.ts.map +1 -0
- package/lib/typescript/components/Circle.d.ts +10 -0
- package/lib/typescript/components/Circle.d.ts.map +1 -0
- package/lib/typescript/components/Group.d.ts +21 -0
- package/lib/typescript/components/Group.d.ts.map +1 -0
- package/lib/typescript/components/Pill.d.ts +12 -0
- package/lib/typescript/components/Pill.d.ts.map +1 -0
- package/lib/typescript/components/Rect.d.ts +12 -0
- package/lib/typescript/components/Rect.d.ts.map +1 -0
- package/lib/typescript/components/Skeleton.d.ts +16 -0
- package/lib/typescript/components/Skeleton.d.ts.map +1 -0
- package/lib/typescript/components/Square.d.ts +10 -0
- package/lib/typescript/components/Square.d.ts.map +1 -0
- package/lib/typescript/hooks/useReducedMotion.d.ts +11 -0
- package/lib/typescript/hooks/useReducedMotion.d.ts.map +1 -0
- package/lib/typescript/hooks/useSkeletonTheme.d.ts +12 -0
- package/lib/typescript/hooks/useSkeletonTheme.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +51 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/presets/Card.d.ts +11 -0
- package/lib/typescript/presets/Card.d.ts.map +1 -0
- package/lib/typescript/presets/Chat.d.ts +12 -0
- package/lib/typescript/presets/Chat.d.ts.map +1 -0
- package/lib/typescript/presets/Product.d.ts +12 -0
- package/lib/typescript/presets/Product.d.ts.map +1 -0
- package/lib/typescript/presets/Profile.d.ts +11 -0
- package/lib/typescript/presets/Profile.d.ts.map +1 -0
- package/lib/typescript/presets/Video.d.ts +12 -0
- package/lib/typescript/presets/Video.d.ts.map +1 -0
- package/lib/typescript/providers/SkeletonProvider.d.ts +18 -0
- package/lib/typescript/providers/SkeletonProvider.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +149 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/utils/colors.d.ts +51 -0
- package/lib/typescript/utils/colors.d.ts.map +1 -0
- package/lib/typescript/utils/responsive.d.ts +27 -0
- package/lib/typescript/utils/responsive.d.ts.map +1 -0
- package/lib/typescript/utils/theme.d.ts +16 -0
- package/lib/typescript/utils/theme.d.ts.map +1 -0
- package/package.json +74 -0
- package/src/animations/breathing.tsx +81 -0
- package/src/animations/pulse.tsx +75 -0
- package/src/animations/shimmer.tsx +88 -0
- package/src/animations/wave.tsx +74 -0
- package/src/clone/SkeletonClone.tsx +82 -0
- package/src/components/Circle.tsx +13 -0
- package/src/components/Group.tsx +55 -0
- package/src/components/Pill.tsx +23 -0
- package/src/components/Rect.tsx +15 -0
- package/src/components/Skeleton.tsx +218 -0
- package/src/components/Square.tsx +13 -0
- package/src/demo/demo.gif +0 -0
- package/src/hooks/useReducedMotion.ts +46 -0
- package/src/hooks/useSkeletonTheme.ts +45 -0
- package/src/index.ts +94 -0
- package/src/presets/Card.tsx +56 -0
- package/src/presets/Chat.tsx +52 -0
- package/src/presets/Product.tsx +45 -0
- package/src/presets/Profile.tsx +54 -0
- package/src/presets/Video.tsx +53 -0
- package/src/providers/SkeletonProvider.tsx +67 -0
- package/src/types/index.ts +246 -0
- package/src/utils/colors.ts +132 -0
- package/src/utils/responsive.ts +73 -0
- package/src/utils/theme.ts +35 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getRecommendedColumns = getRecommendedColumns;
|
|
7
|
+
exports.getScreenSizeClass = getScreenSizeClass;
|
|
8
|
+
exports.getScreenWidth = getScreenWidth;
|
|
9
|
+
exports.pixelSnap = pixelSnap;
|
|
10
|
+
exports.scaleBySize = scaleBySize;
|
|
11
|
+
var _reactNative = require("react-native");
|
|
12
|
+
/**
|
|
13
|
+
* Breakpoints (in dp) used to classify the current screen width.
|
|
14
|
+
* Roughly: phones -> "compact", small tablets / large phones landscape -> "regular",
|
|
15
|
+
* tablets / desktop-like windows -> "wide".
|
|
16
|
+
*/
|
|
17
|
+
const BREAKPOINTS = {
|
|
18
|
+
regular: 480,
|
|
19
|
+
wide: 768
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the current window width, with a safe fallback for environments
|
|
24
|
+
* where Dimensions may not be ready (e.g. very early app boot, tests).
|
|
25
|
+
*/
|
|
26
|
+
function getScreenWidth() {
|
|
27
|
+
try {
|
|
28
|
+
const {
|
|
29
|
+
width
|
|
30
|
+
} = _reactNative.Dimensions.get("window");
|
|
31
|
+
return width || 0;
|
|
32
|
+
} catch {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Classify the current screen width into a coarse size bucket, useful for
|
|
39
|
+
* preset components that want to adapt column counts or avatar sizes.
|
|
40
|
+
*/
|
|
41
|
+
function getScreenSizeClass(width = getScreenWidth()) {
|
|
42
|
+
if (width >= BREAKPOINTS.wide) return "wide";
|
|
43
|
+
if (width >= BREAKPOINTS.regular) return "regular";
|
|
44
|
+
return "compact";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Scale a base dp value by the size class, useful for nudging preset
|
|
49
|
+
* dimensions (avatar size, line height) up slightly on larger screens.
|
|
50
|
+
*/
|
|
51
|
+
function scaleBySize(base, sizeClass) {
|
|
52
|
+
switch (sizeClass) {
|
|
53
|
+
case "wide":
|
|
54
|
+
return Math.round(base * 1.25);
|
|
55
|
+
case "regular":
|
|
56
|
+
return Math.round(base * 1.1);
|
|
57
|
+
default:
|
|
58
|
+
return base;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a recommended column count for grid-style presets (e.g. Product),
|
|
64
|
+
* based on the current screen size class.
|
|
65
|
+
*/
|
|
66
|
+
function getRecommendedColumns(sizeClass = getScreenSizeClass()) {
|
|
67
|
+
switch (sizeClass) {
|
|
68
|
+
case "wide":
|
|
69
|
+
return 4;
|
|
70
|
+
case "regular":
|
|
71
|
+
return 3;
|
|
72
|
+
default:
|
|
73
|
+
return 2;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Snap a dp value to the nearest physical pixel, reducing anti-aliased/blurry
|
|
79
|
+
* edges on skeleton borders, similar to React Native's own hairline handling.
|
|
80
|
+
*/
|
|
81
|
+
function pixelSnap(value) {
|
|
82
|
+
return _reactNative.PixelRatio.roundToNearestPixel(value);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=responsive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","BREAKPOINTS","regular","wide","getScreenWidth","width","Dimensions","get","getScreenSizeClass","scaleBySize","base","sizeClass","Math","round","getRecommendedColumns","pixelSnap","value","PixelRatio","roundToNearestPixel"],"sourceRoot":"../../../src","sources":["utils/responsive.ts"],"mappings":";;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAGA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAW,GAAG;EAChBC,OAAO,EAAE,GAAG;EACZC,IAAI,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACO,SAASC,cAAcA,CAAA,EAAW;EACrC,IAAI;IACA,MAAM;MAAEC;IAAM,CAAC,GAAGC,uBAAU,CAACC,GAAG,CAAC,QAAQ,CAAC;IAC1C,OAAOF,KAAK,IAAI,CAAC;EACrB,CAAC,CAAC,MAAM;IACJ,OAAO,CAAC;EACZ;AACJ;;AAEA;AACA;AACA;AACA;AACO,SAASG,kBAAkBA,CAACH,KAAa,GAAGD,cAAc,CAAC,CAAC,EAAmB;EAClF,IAAIC,KAAK,IAAIJ,WAAW,CAACE,IAAI,EAAE,OAAO,MAAM;EAC5C,IAAIE,KAAK,IAAIJ,WAAW,CAACC,OAAO,EAAE,OAAO,SAAS;EAClD,OAAO,SAAS;AACpB;;AAEA;AACA;AACA;AACA;AACO,SAASO,WAAWA,CAACC,IAAY,EAAEC,SAA0B,EAAU;EAC1E,QAAQA,SAAS;IACb,KAAK,MAAM;MACP,OAAOC,IAAI,CAACC,KAAK,CAACH,IAAI,GAAG,IAAI,CAAC;IAClC,KAAK,SAAS;MACV,OAAOE,IAAI,CAACC,KAAK,CAACH,IAAI,GAAG,GAAG,CAAC;IACjC;MACI,OAAOA,IAAI;EACnB;AACJ;;AAEA;AACA;AACA;AACA;AACO,SAASI,qBAAqBA,CAACH,SAA0B,GAAGH,kBAAkB,CAAC,CAAC,EAAU;EAC7F,QAAQG,SAAS;IACb,KAAK,MAAM;MACP,OAAO,CAAC;IACZ,KAAK,SAAS;MACV,OAAO,CAAC;IACZ;MACI,OAAO,CAAC;EAChB;AACJ;;AAEA;AACA;AACA;AACA;AACO,SAASI,SAASA,CAACC,KAAa,EAAU;EAC7C,OAAOC,uBAAU,CAACC,mBAAmB,CAACF,KAAK,CAAC;AAChD","ignoreList":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getDefaultThemeColors = getDefaultThemeColors;
|
|
7
|
+
exports.getSystemColorScheme = getSystemColorScheme;
|
|
8
|
+
exports.resolveIsDark = resolveIsDark;
|
|
9
|
+
var _reactNative = require("react-native");
|
|
10
|
+
var _colors = require("./colors");
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a SkeletonThemeMode ("light" | "dark" | "system") plus the current
|
|
13
|
+
* OS color scheme into a concrete isDark boolean.
|
|
14
|
+
*/
|
|
15
|
+
function resolveIsDark(mode, systemScheme) {
|
|
16
|
+
if (mode === "light") return false;
|
|
17
|
+
if (mode === "dark") return true;
|
|
18
|
+
return systemScheme === "dark";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Synchronous read of the current system color scheme, for use outside
|
|
23
|
+
* of component render (e.g. computing an initial value).
|
|
24
|
+
*/
|
|
25
|
+
function getSystemColorScheme() {
|
|
26
|
+
try {
|
|
27
|
+
return _reactNative.Appearance.getColorScheme() ?? null;
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Default theme colors for a resolved dark/light state.
|
|
35
|
+
*/
|
|
36
|
+
function getDefaultThemeColors(isDark) {
|
|
37
|
+
return isDark ? _colors.DEFAULT_DARK_COLORS : _colors.DEFAULT_LIGHT_COLORS;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_colors","resolveIsDark","mode","systemScheme","getSystemColorScheme","Appearance","getColorScheme","getDefaultThemeColors","isDark","DEFAULT_DARK_COLORS","DEFAULT_LIGHT_COLORS"],"sourceRoot":"../../../src","sources":["utils/theme.ts"],"mappings":";;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,IAAAC,OAAA,GAAAD,OAAA;AAEA;AACA;AACA;AACA;AACO,SAASE,aAAaA,CAACC,IAAuB,EAAEC,YAAiD,EAAW;EAC/G,IAAID,IAAI,KAAK,OAAO,EAAE,OAAO,KAAK;EAClC,IAAIA,IAAI,KAAK,MAAM,EAAE,OAAO,IAAI;EAChC,OAAOC,YAAY,KAAK,MAAM;AAClC;;AAEA;AACA;AACA;AACA;AACO,SAASC,oBAAoBA,CAAA,EAGzB;EACP,IAAI;IACA,OAAOC,uBAAU,CAACC,cAAc,CAAC,CAAC,IAAI,IAAI;EAC9C,CAAC,CAAC,MAAM;IACJ,OAAO,IAAI;EACf;AACJ;;AAEA;AACA;AACA;AACO,SAASC,qBAAqBA,CAACC,MAAe,EAAE;EACnD,OAAOA,MAAM,GAAGC,2BAAmB,GAAGC,4BAAoB;AAC9D","ignoreList":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Easing, cancelAnimation, useAnimatedStyle, useSharedValue, withDelay, withRepeat, withTiming } from "react-native-reanimated";
|
|
3
|
+
/**
|
|
4
|
+
* A slow, very gentle scale + opacity oscillation — softer and slower than
|
|
5
|
+
* "pulse" — intended as the most reduced-motion-friendly animation. This is
|
|
6
|
+
* the animation `Skeleton` falls back to (at a slowed rate) when the OS
|
|
7
|
+
* reduce-motion setting is on and the consumer hasn't explicitly chosen "none".
|
|
8
|
+
*/
|
|
9
|
+
export function useBreathingStyle({
|
|
10
|
+
duration = 2200,
|
|
11
|
+
delay = 0,
|
|
12
|
+
disabled = false,
|
|
13
|
+
performanceMode = "balanced",
|
|
14
|
+
minScale = 0.97,
|
|
15
|
+
maxScale = 1,
|
|
16
|
+
minOpacity = 0.85
|
|
17
|
+
}) {
|
|
18
|
+
const progress = useSharedValue(0);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (disabled) {
|
|
21
|
+
progress.value = 0;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.2 : duration;
|
|
25
|
+
progress.value = 0;
|
|
26
|
+
progress.value = withDelay(delay, withRepeat(withTiming(1, {
|
|
27
|
+
duration: effectiveDuration / 2,
|
|
28
|
+
easing: Easing.inOut(Easing.ease)
|
|
29
|
+
}), -1, true));
|
|
30
|
+
return () => {
|
|
31
|
+
cancelAnimation(progress);
|
|
32
|
+
};
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
35
|
+
const style = useAnimatedStyle(() => {
|
|
36
|
+
const scale = minScale + progress.value * (maxScale - minScale);
|
|
37
|
+
const opacity = minOpacity + progress.value * (1 - minOpacity);
|
|
38
|
+
return {
|
|
39
|
+
opacity,
|
|
40
|
+
transform: [{
|
|
41
|
+
scale
|
|
42
|
+
}]
|
|
43
|
+
};
|
|
44
|
+
}, [minScale, maxScale, minOpacity]);
|
|
45
|
+
return style;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=breathing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","Easing","cancelAnimation","useAnimatedStyle","useSharedValue","withDelay","withRepeat","withTiming","useBreathingStyle","duration","delay","disabled","performanceMode","minScale","maxScale","minOpacity","progress","value","effectiveDuration","easing","inOut","ease","style","scale","opacity","transform"],"sourceRoot":"../../../src","sources":["animations/breathing.tsx"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SACIC,MAAM,EACNC,eAAe,EACfC,gBAAgB,EAChBC,cAAc,EACdC,SAAS,EACTC,UAAU,EACVC,UAAU,QACP,yBAAyB;AAgBhC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAC;EAC9BC,QAAQ,GAAG,IAAI;EACfC,KAAK,GAAG,CAAC;EACTC,QAAQ,GAAG,KAAK;EAChBC,eAAe,GAAG,UAAU;EAC5BC,QAAQ,GAAG,IAAI;EACfC,QAAQ,GAAG,CAAC;EACZC,UAAU,GAAG;AACC,CAAC,EAAE;EACjB,MAAMC,QAAQ,GAAGZ,cAAc,CAAC,CAAC,CAAC;EAElCJ,SAAS,CAAC,MAAM;IACZ,IAAIW,QAAQ,EAAE;MACVK,QAAQ,CAACC,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBN,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEO,QAAQ,CAACC,KAAK,GAAG,CAAC;IAClBD,QAAQ,CAACC,KAAK,GAAGZ,SAAS,CACtBK,KAAK,EACLJ,UAAU,CACNC,UAAU,CAAC,CAAC,EAAE;MACVE,QAAQ,EAAES,iBAAiB,GAAG,CAAC;MAC/BC,MAAM,EAAElB,MAAM,CAACmB,KAAK,CAACnB,MAAM,CAACoB,IAAI;IACpC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,IACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACTnB,eAAe,CAACc,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACP,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMU,KAAK,GAAGnB,gBAAgB,CAAC,MAAM;IACjC,MAAMoB,KAAK,GAAGV,QAAQ,GAAGG,QAAQ,CAACC,KAAK,IAAIH,QAAQ,GAAGD,QAAQ,CAAC;IAC/D,MAAMW,OAAO,GAAGT,UAAU,GAAGC,QAAQ,CAACC,KAAK,IAAI,CAAC,GAAGF,UAAU,CAAC;IAC9D,OAAO;MACHS,OAAO;MACPC,SAAS,EAAE,CAAC;QAAEF;MAAM,CAAC;IACzB,CAAC;EACL,CAAC,EAAE,CAACV,QAAQ,EAAEC,QAAQ,EAAEC,UAAU,CAAC,CAAC;EAEpC,OAAOO,KAAK;AAChB","ignoreList":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Easing, cancelAnimation, useAnimatedStyle, useSharedValue, withDelay, withRepeat, withTiming } from "react-native-reanimated";
|
|
3
|
+
/**
|
|
4
|
+
* Classic fade in/out pulse: opacity oscillates between minOpacity and
|
|
5
|
+
* maxOpacity using an ease-in-out curve, looping indefinitely.
|
|
6
|
+
*
|
|
7
|
+
* Returns an animated style with just `opacity`, ready to spread onto the
|
|
8
|
+
* skeleton's base View.
|
|
9
|
+
*/
|
|
10
|
+
export function usePulseStyle({
|
|
11
|
+
duration = 1000,
|
|
12
|
+
delay = 0,
|
|
13
|
+
disabled = false,
|
|
14
|
+
performanceMode = "balanced",
|
|
15
|
+
minOpacity = 0.4,
|
|
16
|
+
maxOpacity = 1
|
|
17
|
+
}) {
|
|
18
|
+
const progress = useSharedValue(0);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (disabled) {
|
|
21
|
+
progress.value = 0;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.3 : duration;
|
|
25
|
+
progress.value = 0;
|
|
26
|
+
progress.value = withDelay(delay, withRepeat(withTiming(1, {
|
|
27
|
+
duration: effectiveDuration / 2,
|
|
28
|
+
easing: Easing.inOut(Easing.ease)
|
|
29
|
+
}), -1, true // reverse, giving the fade-in/fade-out loop
|
|
30
|
+
));
|
|
31
|
+
return () => {
|
|
32
|
+
cancelAnimation(progress);
|
|
33
|
+
};
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
36
|
+
const style = useAnimatedStyle(() => {
|
|
37
|
+
const opacity = minOpacity + progress.value * (maxOpacity - minOpacity);
|
|
38
|
+
return {
|
|
39
|
+
opacity
|
|
40
|
+
};
|
|
41
|
+
}, [minOpacity, maxOpacity]);
|
|
42
|
+
return style;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=pulse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","Easing","cancelAnimation","useAnimatedStyle","useSharedValue","withDelay","withRepeat","withTiming","usePulseStyle","duration","delay","disabled","performanceMode","minOpacity","maxOpacity","progress","value","effectiveDuration","easing","inOut","ease","style","opacity"],"sourceRoot":"../../../src","sources":["animations/pulse.tsx"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SACIC,MAAM,EACNC,eAAe,EACfC,gBAAgB,EAChBC,cAAc,EACdC,SAAS,EACTC,UAAU,EACVC,UAAU,QACP,yBAAyB;AAchC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAAC;EAC1BC,QAAQ,GAAG,IAAI;EACfC,KAAK,GAAG,CAAC;EACTC,QAAQ,GAAG,KAAK;EAChBC,eAAe,GAAG,UAAU;EAC5BC,UAAU,GAAG,GAAG;EAChBC,UAAU,GAAG;AACH,CAAC,EAAE;EACb,MAAMC,QAAQ,GAAGX,cAAc,CAAC,CAAC,CAAC;EAElCJ,SAAS,CAAC,MAAM;IACZ,IAAIW,QAAQ,EAAE;MACVI,QAAQ,CAACC,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBL,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEM,QAAQ,CAACC,KAAK,GAAG,CAAC;IAClBD,QAAQ,CAACC,KAAK,GAAGX,SAAS,CACtBK,KAAK,EACLJ,UAAU,CACNC,UAAU,CAAC,CAAC,EAAE;MACVE,QAAQ,EAAEQ,iBAAiB,GAAG,CAAC;MAC/BC,MAAM,EAAEjB,MAAM,CAACkB,KAAK,CAAClB,MAAM,CAACmB,IAAI;IACpC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,IAAI,CAAC;IACT,CACJ,CAAC;IAED,OAAO,MAAM;MACTlB,eAAe,CAACa,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACN,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMS,KAAK,GAAGlB,gBAAgB,CAAC,MAAM;IACjC,MAAMmB,OAAO,GAAGT,UAAU,GAAGE,QAAQ,CAACC,KAAK,IAAIF,UAAU,GAAGD,UAAU,CAAC;IACvE,OAAO;MAAES;IAAQ,CAAC;EACtB,CAAC,EAAE,CAACT,UAAU,EAAEC,UAAU,CAAC,CAAC;EAE5B,OAAOO,KAAK;AAChB","ignoreList":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Easing, cancelAnimation, useAnimatedStyle, useSharedValue, withDelay, withRepeat, withTiming } from "react-native-reanimated";
|
|
3
|
+
/**
|
|
4
|
+
* Drives a 0 -> 1 -> 0 progress value looping indefinitely, intended to be
|
|
5
|
+
* mapped (by the consuming component) onto a translateX of a gradient
|
|
6
|
+
* overlay to create the classic "shimmer sweep" effect.
|
|
7
|
+
*
|
|
8
|
+
* Returns both the raw shared value-derived animated style (opacity passthrough,
|
|
9
|
+
* so it can be spread directly) and the progress itself isn't exposed —
|
|
10
|
+
* components should use `useShimmerTransform` below to get a transform style
|
|
11
|
+
* sized to their own width.
|
|
12
|
+
*/
|
|
13
|
+
export function useShimmerProgress({
|
|
14
|
+
duration = 1200,
|
|
15
|
+
delay = 0,
|
|
16
|
+
disabled = false,
|
|
17
|
+
performanceMode = "balanced"
|
|
18
|
+
}) {
|
|
19
|
+
const progress = useSharedValue(0);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (disabled) {
|
|
22
|
+
progress.value = 0;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.4 : duration;
|
|
26
|
+
progress.value = 0;
|
|
27
|
+
progress.value = withDelay(delay, withRepeat(withTiming(1, {
|
|
28
|
+
duration: effectiveDuration,
|
|
29
|
+
easing: Easing.linear
|
|
30
|
+
}), -1, false));
|
|
31
|
+
return () => {
|
|
32
|
+
cancelAnimation(progress);
|
|
33
|
+
};
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
36
|
+
return progress;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Convenience hook: given a measured width, returns an animated style that
|
|
41
|
+
* translates a highlight overlay (assumed ~60% of `width` wide) from off-screen
|
|
42
|
+
* left to off-screen right, looping. Use on an absolutely-positioned overlay
|
|
43
|
+
* View/LinearGradient layered on top of the base skeleton rect.
|
|
44
|
+
*/
|
|
45
|
+
export function useShimmerTransform(width, options) {
|
|
46
|
+
const progress = useShimmerProgress(options);
|
|
47
|
+
const sweepWidth = Math.max(width, 1) * 0.6;
|
|
48
|
+
const style = useAnimatedStyle(() => {
|
|
49
|
+
const translateX = -sweepWidth + progress.value * (width + sweepWidth);
|
|
50
|
+
return {
|
|
51
|
+
transform: [{
|
|
52
|
+
translateX
|
|
53
|
+
}]
|
|
54
|
+
};
|
|
55
|
+
}, [width, sweepWidth]);
|
|
56
|
+
return {
|
|
57
|
+
style,
|
|
58
|
+
sweepWidth
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=shimmer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","Easing","cancelAnimation","useAnimatedStyle","useSharedValue","withDelay","withRepeat","withTiming","useShimmerProgress","duration","delay","disabled","performanceMode","progress","value","effectiveDuration","easing","linear","useShimmerTransform","width","options","sweepWidth","Math","max","style","translateX","transform"],"sourceRoot":"../../../src","sources":["animations/shimmer.tsx"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SACIC,MAAM,EACNC,eAAe,EACfC,gBAAgB,EAChBC,cAAc,EACdC,SAAS,EACTC,UAAU,EACVC,UAAU,QACP,yBAAyB;AAWhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAAC;EAC/BC,QAAQ,GAAG,IAAI;EACfC,KAAK,GAAG,CAAC;EACTC,QAAQ,GAAG,KAAK;EAChBC,eAAe,GAAG;AACN,CAAC,EAAE;EACf,MAAMC,QAAQ,GAAGT,cAAc,CAAC,CAAC,CAAC;EAElCJ,SAAS,CAAC,MAAM;IACZ,IAAIW,QAAQ,EAAE;MACVE,QAAQ,CAACC,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBH,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEI,QAAQ,CAACC,KAAK,GAAG,CAAC;IAClBD,QAAQ,CAACC,KAAK,GAAGT,SAAS,CACtBK,KAAK,EACLJ,UAAU,CACNC,UAAU,CAAC,CAAC,EAAE;MACVE,QAAQ,EAAEM,iBAAiB;MAC3BC,MAAM,EAAEf,MAAM,CAACgB;IACnB,CAAC,CAAC,EACF,CAAC,CAAC,EACF,KACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACTf,eAAe,CAACW,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACJ,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,OAAOC,QAAQ;AACnB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,mBAAmBA,CAACC,KAAa,EAAEC,OAAuB,EAAE;EACxE,MAAMP,QAAQ,GAAGL,kBAAkB,CAACY,OAAO,CAAC;EAC5C,MAAMC,UAAU,GAAGC,IAAI,CAACC,GAAG,CAACJ,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG;EAE3C,MAAMK,KAAK,GAAGrB,gBAAgB,CAAC,MAAM;IACjC,MAAMsB,UAAU,GAAG,CAACJ,UAAU,GAAGR,QAAQ,CAACC,KAAK,IAAIK,KAAK,GAAGE,UAAU,CAAC;IACtE,OAAO;MACHK,SAAS,EAAE,CAAC;QAAED;MAAW,CAAC;IAC9B,CAAC;EACL,CAAC,EAAE,CAACN,KAAK,EAAEE,UAAU,CAAC,CAAC;EAEvB,OAAO;IAAEG,KAAK;IAAEH;EAAW,CAAC;AAChC","ignoreList":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { Easing, cancelAnimation, interpolate, useAnimatedStyle, useSharedValue, withDelay, withRepeat, withTiming } from "react-native-reanimated";
|
|
3
|
+
/**
|
|
4
|
+
* Similar to shimmer, but drives a smoother sine-like sweep (ease-in-out
|
|
5
|
+
* instead of linear) intended for a softer "ripple" look, typically paired
|
|
6
|
+
* with a wider, lower-contrast gradient than shimmer uses.
|
|
7
|
+
*
|
|
8
|
+
* Returns a translateX-based animated style for a given measured width.
|
|
9
|
+
*/
|
|
10
|
+
export function useWaveTransform(width, options) {
|
|
11
|
+
const {
|
|
12
|
+
duration = 1500,
|
|
13
|
+
delay = 0,
|
|
14
|
+
disabled = false,
|
|
15
|
+
performanceMode = "balanced"
|
|
16
|
+
} = options;
|
|
17
|
+
const progress = useSharedValue(0);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (disabled) {
|
|
20
|
+
progress.value = 0;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.4 : duration;
|
|
24
|
+
progress.value = 0;
|
|
25
|
+
progress.value = withDelay(delay, withRepeat(withTiming(1, {
|
|
26
|
+
duration: effectiveDuration,
|
|
27
|
+
easing: Easing.inOut(Easing.sin)
|
|
28
|
+
}), -1, false));
|
|
29
|
+
return () => {
|
|
30
|
+
cancelAnimation(progress);
|
|
31
|
+
};
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
34
|
+
const sweepWidth = Math.max(width, 1) * 0.8;
|
|
35
|
+
const style = useAnimatedStyle(() => {
|
|
36
|
+
const translateX = interpolate(progress.value, [0, 1], [-sweepWidth, width + sweepWidth]);
|
|
37
|
+
return {
|
|
38
|
+
transform: [{
|
|
39
|
+
translateX
|
|
40
|
+
}]
|
|
41
|
+
};
|
|
42
|
+
}, [width, sweepWidth]);
|
|
43
|
+
return {
|
|
44
|
+
style,
|
|
45
|
+
sweepWidth
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=wave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","Easing","cancelAnimation","interpolate","useAnimatedStyle","useSharedValue","withDelay","withRepeat","withTiming","useWaveTransform","width","options","duration","delay","disabled","performanceMode","progress","value","effectiveDuration","easing","inOut","sin","sweepWidth","Math","max","style","translateX","transform"],"sourceRoot":"../../../src","sources":["animations/wave.tsx"],"mappings":"AAAA,SAASA,SAAS,QAAQ,OAAO;AACjC,SACIC,MAAM,EACNC,eAAe,EACfC,WAAW,EACXC,gBAAgB,EAChBC,cAAc,EACdC,SAAS,EACTC,UAAU,EACVC,UAAU,QACP,yBAAyB;AAUhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAACC,KAAa,EAAEC,OAAoB,EAAE;EAClE,MAAM;IAAEC,QAAQ,GAAG,IAAI;IAAEC,KAAK,GAAG,CAAC;IAAEC,QAAQ,GAAG,KAAK;IAAEC,eAAe,GAAG;EAAW,CAAC,GAAGJ,OAAO;EAC9F,MAAMK,QAAQ,GAAGX,cAAc,CAAC,CAAC,CAAC;EAElCL,SAAS,CAAC,MAAM;IACZ,IAAIc,QAAQ,EAAE;MACVE,QAAQ,CAACC,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBH,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEI,QAAQ,CAACC,KAAK,GAAG,CAAC;IAClBD,QAAQ,CAACC,KAAK,GAAGX,SAAS,CACtBO,KAAK,EACLN,UAAU,CACNC,UAAU,CAAC,CAAC,EAAE;MACVI,QAAQ,EAAEM,iBAAiB;MAC3BC,MAAM,EAAElB,MAAM,CAACmB,KAAK,CAACnB,MAAM,CAACoB,GAAG;IACnC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,KACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACTnB,eAAe,CAACc,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACJ,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMO,UAAU,GAAGC,IAAI,CAACC,GAAG,CAACd,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG;EAE3C,MAAMe,KAAK,GAAGrB,gBAAgB,CAAC,MAAM;IACjC,MAAMsB,UAAU,GAAGvB,WAAW,CAC1Ba,QAAQ,CAACC,KAAK,EACd,CAAC,CAAC,EAAE,CAAC,CAAC,EACN,CAAC,CAACK,UAAU,EAAEZ,KAAK,GAAGY,UAAU,CACpC,CAAC;IACD,OAAO;MACHK,SAAS,EAAE,CAAC;QAAED;MAAW,CAAC;IAC9B,CAAC;EACL,CAAC,EAAE,CAAChB,KAAK,EAAEY,UAAU,CAAC,CAAC;EAEvB,OAAO;IAAEG,KAAK;IAAEH;EAAW,CAAC;AAChC","ignoreList":[]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import Skeleton from "../components/Skeleton";
|
|
4
|
+
function renderNode(node, animation, keyPrefix) {
|
|
5
|
+
const {
|
|
6
|
+
shape = "rect",
|
|
7
|
+
width,
|
|
8
|
+
height,
|
|
9
|
+
borderRadius,
|
|
10
|
+
style,
|
|
11
|
+
children,
|
|
12
|
+
direction = "column",
|
|
13
|
+
gap = 8
|
|
14
|
+
} = node;
|
|
15
|
+
let resolvedBorderRadius = borderRadius;
|
|
16
|
+
if (shape === "circle") {
|
|
17
|
+
const numericSize = typeof width === "number" ? width : typeof height === "number" ? height : 50;
|
|
18
|
+
resolvedBorderRadius = numericSize / 2;
|
|
19
|
+
} else if (shape === "pill") {
|
|
20
|
+
const numericHeight = typeof height === "number" ? height : 24;
|
|
21
|
+
resolvedBorderRadius = resolvedBorderRadius ?? numericHeight / 2;
|
|
22
|
+
}
|
|
23
|
+
if (children && children.length > 0) {
|
|
24
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
25
|
+
key: keyPrefix,
|
|
26
|
+
style: [{
|
|
27
|
+
flexDirection: direction === "row" ? "row" : "column"
|
|
28
|
+
}, style]
|
|
29
|
+
}, children.map((child, i) => /*#__PURE__*/React.createElement(View, {
|
|
30
|
+
key: `${keyPrefix}-${i}`,
|
|
31
|
+
style: direction === "row" ? {
|
|
32
|
+
marginLeft: i === 0 ? 0 : gap
|
|
33
|
+
} : {
|
|
34
|
+
marginTop: i === 0 ? 0 : gap
|
|
35
|
+
}
|
|
36
|
+
}, renderNode(child, animation, `${keyPrefix}-${i}`))));
|
|
37
|
+
}
|
|
38
|
+
return /*#__PURE__*/React.createElement(Skeleton, {
|
|
39
|
+
width: width ?? "100%",
|
|
40
|
+
height: height ?? 16,
|
|
41
|
+
borderRadius: resolvedBorderRadius ?? 4,
|
|
42
|
+
animation: animation,
|
|
43
|
+
style: style
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Clones an arbitrary layout tree as skeleton placeholders. Useful when you
|
|
49
|
+
* have a complex, bespoke screen layout and don't want to hand-place a
|
|
50
|
+
* Skeleton for every element — instead describe the rough shape once as a
|
|
51
|
+
* `SkeletonCloneNode` tree (mirroring your real layout's structure) and let
|
|
52
|
+
* SkeletonClone render matching placeholders.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* <SkeletonClone
|
|
56
|
+
* layout={{
|
|
57
|
+
* direction: "row",
|
|
58
|
+
* gap: 12,
|
|
59
|
+
* children: [
|
|
60
|
+
* { shape: "circle", width: 48, height: 48 },
|
|
61
|
+
* {
|
|
62
|
+
* direction: "column",
|
|
63
|
+
* gap: 6,
|
|
64
|
+
* children: [
|
|
65
|
+
* { width: 120, height: 14 },
|
|
66
|
+
* { width: 80, height: 12 },
|
|
67
|
+
* ],
|
|
68
|
+
* },
|
|
69
|
+
* ],
|
|
70
|
+
* }}
|
|
71
|
+
* />
|
|
72
|
+
*/
|
|
73
|
+
export default function SkeletonClone({
|
|
74
|
+
layout,
|
|
75
|
+
animation,
|
|
76
|
+
style,
|
|
77
|
+
testID
|
|
78
|
+
}) {
|
|
79
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
80
|
+
style: style,
|
|
81
|
+
testID: testID
|
|
82
|
+
}, renderNode(layout, animation, "clone-root"));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=SkeletonClone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","View","Skeleton","renderNode","node","animation","keyPrefix","shape","width","height","borderRadius","style","children","direction","gap","resolvedBorderRadius","numericSize","numericHeight","length","createElement","key","flexDirection","map","child","i","marginLeft","marginTop","SkeletonClone","layout","testID"],"sourceRoot":"../../../src","sources":["clone/SkeletonClone.tsx"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;AACnC,OAAOC,QAAQ,MAAM,wBAAwB;AAG7C,SAASC,UAAUA,CAACC,IAAuB,EAAEC,SAA0C,EAAEC,SAAiB,EAAE;EACxG,MAAM;IAAEC,KAAK,GAAG,MAAM;IAAEC,KAAK;IAAEC,MAAM;IAAEC,YAAY;IAAEC,KAAK;IAAEC,QAAQ;IAAEC,SAAS,GAAG,QAAQ;IAAEC,GAAG,GAAG;EAAE,CAAC,GAAGV,IAAI;EAE5G,IAAIW,oBAAoB,GAAGL,YAAY;EACvC,IAAIH,KAAK,KAAK,QAAQ,EAAE;IACpB,MAAMS,WAAW,GAAG,OAAOR,KAAK,KAAK,QAAQ,GAAGA,KAAK,GAAG,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,EAAE;IAChGM,oBAAoB,GAAGC,WAAW,GAAG,CAAC;EAC1C,CAAC,MAAM,IAAIT,KAAK,KAAK,MAAM,EAAE;IACzB,MAAMU,aAAa,GAAG,OAAOR,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,EAAE;IAC9DM,oBAAoB,GAAGA,oBAAoB,IAAIE,aAAa,GAAG,CAAC;EACpE;EAEA,IAAIL,QAAQ,IAAIA,QAAQ,CAACM,MAAM,GAAG,CAAC,EAAE;IACjC,oBACIlB,KAAA,CAAAmB,aAAA,CAAClB,IAAI;MACDmB,GAAG,EAAEd,SAAU;MACfK,KAAK,EAAE,CACH;QAAEU,aAAa,EAAER,SAAS,KAAK,KAAK,GAAG,KAAK,GAAG;MAAS,CAAC,EACzDF,KAAK;IACP,GAEDC,QAAQ,CAACU,GAAG,CAAC,CAACC,KAAK,EAAEC,CAAC,kBACnBxB,KAAA,CAAAmB,aAAA,CAAClB,IAAI;MACDmB,GAAG,EAAE,GAAGd,SAAS,IAAIkB,CAAC,EAAG;MACzBb,KAAK,EACDE,SAAS,KAAK,KAAK,GACb;QAAEY,UAAU,EAAED,CAAC,KAAK,CAAC,GAAG,CAAC,GAAGV;MAAI,CAAC,GACjC;QAAEY,SAAS,EAAEF,CAAC,KAAK,CAAC,GAAG,CAAC,GAAGV;MAAI;IACxC,GAEAX,UAAU,CAACoB,KAAK,EAAElB,SAAS,EAAE,GAAGC,SAAS,IAAIkB,CAAC,EAAE,CAC/C,CACT,CACC,CAAC;EAEf;EAEA,oBACIxB,KAAA,CAAAmB,aAAA,CAACjB,QAAQ;IACLM,KAAK,EAAEA,KAAK,IAAI,MAAO;IACvBC,MAAM,EAAEA,MAAM,IAAI,EAAG;IACrBC,YAAY,EAAEK,oBAAoB,IAAI,CAAE;IACxCV,SAAS,EAAEA,SAAU;IACrBM,KAAK,EAAEA;EAAM,CAChB,CAAC;AAEV;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASgB,aAAaA,CAAC;EAAEC,MAAM;EAAEvB,SAAS;EAAEM,KAAK;EAAEkB;AAA2B,CAAC,EAAE;EAC5F,oBAAO7B,KAAA,CAAAmB,aAAA,CAAClB,IAAI;IAACU,KAAK,EAAEA,KAAM;IAACkB,MAAM,EAAEA;EAAO,GAAE1B,UAAU,CAACyB,MAAM,EAAEvB,SAAS,EAAE,YAAY,CAAQ,CAAC;AACnG","ignoreList":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from "react";
|
|
3
|
+
import Skeleton from "./Skeleton";
|
|
4
|
+
/**
|
|
5
|
+
* A circular skeleton placeholder, commonly used for avatars.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <Skeleton.Circle size={48} />
|
|
9
|
+
*/
|
|
10
|
+
export default function Circle({
|
|
11
|
+
size = 50,
|
|
12
|
+
...props
|
|
13
|
+
}) {
|
|
14
|
+
return /*#__PURE__*/React.createElement(Skeleton, _extends({
|
|
15
|
+
width: size,
|
|
16
|
+
height: size,
|
|
17
|
+
borderRadius: size / 2
|
|
18
|
+
}, props));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=Circle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Skeleton","Circle","size","props","createElement","_extends","width","height","borderRadius"],"sourceRoot":"../../../src","sources":["components/Circle.tsx"],"mappings":";AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,OAAOC,QAAQ,MAAM,YAAY;AAGjC;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,MAAMA,CAAC;EAAEC,IAAI,GAAG,EAAE;EAAE,GAAGC;AAA2B,CAAC,EAAE;EACzE,oBAAOJ,KAAA,CAAAK,aAAA,CAACJ,QAAQ,EAAAK,QAAA;IAACC,KAAK,EAAEJ,IAAK;IAACK,MAAM,EAAEL,IAAK;IAACM,YAAY,EAAEN,IAAI,GAAG;EAAE,GAAKC,KAAK,CAAG,CAAC;AACrF","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React, { Children, isValidElement, cloneElement } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
/**
|
|
4
|
+
* Groups multiple skeleton children together and automatically staggers
|
|
5
|
+
* their animation start so they don't all pulse/shimmer perfectly in sync —
|
|
6
|
+
* a subtle touch that reads as more natural for lists of skeleton rows.
|
|
7
|
+
*
|
|
8
|
+
* Any direct child that accepts a `delay` prop (i.e. any Skeleton.* shape,
|
|
9
|
+
* or a custom component that forwards `delay` to one) will have an
|
|
10
|
+
* incremental delay injected automatically. Children that already specify
|
|
11
|
+
* their own `delay` are left untouched.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <Skeleton.Group staggerDelay={80}>
|
|
15
|
+
* <Skeleton.Rect width="100%" height={16} />
|
|
16
|
+
* <Skeleton.Rect width="80%" height={16} />
|
|
17
|
+
* <Skeleton.Rect width="60%" height={16} />
|
|
18
|
+
* </Skeleton.Group>
|
|
19
|
+
*/
|
|
20
|
+
export default function Group({
|
|
21
|
+
children,
|
|
22
|
+
staggerDelay = 80,
|
|
23
|
+
animation,
|
|
24
|
+
direction = "column",
|
|
25
|
+
style,
|
|
26
|
+
testID
|
|
27
|
+
}) {
|
|
28
|
+
const items = Children.toArray(children);
|
|
29
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
30
|
+
style: [{
|
|
31
|
+
flexDirection: direction === "row" ? "row" : "column"
|
|
32
|
+
}, style],
|
|
33
|
+
testID: testID
|
|
34
|
+
}, items.map((child, index) => {
|
|
35
|
+
if (! /*#__PURE__*/isValidElement(child)) return child;
|
|
36
|
+
const existingProps = child.props;
|
|
37
|
+
const injectedProps = {};
|
|
38
|
+
if (existingProps.delay === undefined) {
|
|
39
|
+
injectedProps.delay = index * staggerDelay;
|
|
40
|
+
}
|
|
41
|
+
if (animation && existingProps.animation === undefined) {
|
|
42
|
+
injectedProps.animation = animation;
|
|
43
|
+
}
|
|
44
|
+
return /*#__PURE__*/cloneElement(child, {
|
|
45
|
+
key: child.key ?? index,
|
|
46
|
+
...injectedProps
|
|
47
|
+
});
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=Group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Children","isValidElement","cloneElement","View","Group","children","staggerDelay","animation","direction","style","testID","items","toArray","createElement","flexDirection","map","child","index","existingProps","props","injectedProps","delay","undefined","key"],"sourceRoot":"../../../src","sources":["components/Group.tsx"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,QAAQ,EAAEC,cAAc,EAAEC,YAAY,QAAQ,OAAO;AACrE,SAASC,IAAI,QAAQ,cAAc;AAGnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,KAAKA,CAAC;EAC1BC,QAAQ;EACRC,YAAY,GAAG,EAAE;EACjBC,SAAS;EACTC,SAAS,GAAG,QAAQ;EACpBC,KAAK;EACLC;AACgB,CAAC,EAAE;EACnB,MAAMC,KAAK,GAAGX,QAAQ,CAACY,OAAO,CAACP,QAAQ,CAAC;EAExC,oBACIN,KAAA,CAAAc,aAAA,CAACV,IAAI;IACDM,KAAK,EAAE,CAAC;MAAEK,aAAa,EAAEN,SAAS,KAAK,KAAK,GAAG,KAAK,GAAG;IAAS,CAAC,EAAEC,KAAK,CAAE;IAC1EC,MAAM,EAAEA;EAAO,GAEdC,KAAK,CAACI,GAAG,CAAC,CAACC,KAAK,EAAEC,KAAK,KAAK;IACzB,IAAI,eAAChB,cAAc,CAACe,KAAK,CAAC,EAAE,OAAOA,KAAK;IAExC,MAAME,aAAa,GAAGF,KAAK,CAACG,KAAgC;IAC5D,MAAMC,aAAsC,GAAG,CAAC,CAAC;IAEjD,IAAIF,aAAa,CAACG,KAAK,KAAKC,SAAS,EAAE;MACnCF,aAAa,CAACC,KAAK,GAAGJ,KAAK,GAAGX,YAAY;IAC9C;IAEA,IAAIC,SAAS,IAAIW,aAAa,CAACX,SAAS,KAAKe,SAAS,EAAE;MACpDF,aAAa,CAACb,SAAS,GAAGA,SAAS;IACvC;IAEA,oBAAOL,YAAY,CAACc,KAAK,EAAE;MAAEO,GAAG,EAAEP,KAAK,CAACO,GAAG,IAAIN,KAAK;MAAE,GAAGG;IAAc,CAAC,CAAC;EAC7E,CAAC,CACC,CAAC;AAEf","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from "react";
|
|
3
|
+
import Skeleton from "./Skeleton";
|
|
4
|
+
/**
|
|
5
|
+
* A fully-rounded "pill" skeleton placeholder, commonly used for buttons,
|
|
6
|
+
* tags/chips, or badges. Border radius is automatically derived from height
|
|
7
|
+
* unless overridden.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* <Skeleton.Pill width={80} height={28} />
|
|
11
|
+
*/
|
|
12
|
+
export default function Pill({
|
|
13
|
+
width = 80,
|
|
14
|
+
height = 24,
|
|
15
|
+
borderRadius,
|
|
16
|
+
...props
|
|
17
|
+
}) {
|
|
18
|
+
const numericHeight = typeof height === "number" ? height : 24;
|
|
19
|
+
return /*#__PURE__*/React.createElement(Skeleton, _extends({
|
|
20
|
+
width: width,
|
|
21
|
+
height: height,
|
|
22
|
+
borderRadius: borderRadius ?? numericHeight / 2
|
|
23
|
+
}, props));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=Pill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Skeleton","Pill","width","height","borderRadius","props","numericHeight","createElement","_extends"],"sourceRoot":"../../../src","sources":["components/Pill.tsx"],"mappings":";AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,OAAOC,QAAQ,MAAM,YAAY;AAGjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,IAAIA,CAAC;EAAEC,KAAK,GAAG,EAAE;EAAEC,MAAM,GAAG,EAAE;EAAEC,YAAY;EAAE,GAAGC;AAAyB,CAAC,EAAE;EACjG,MAAMC,aAAa,GAAG,OAAOH,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,EAAE;EAC9D,oBACIJ,KAAA,CAAAQ,aAAA,CAACP,QAAQ,EAAAQ,QAAA;IACLN,KAAK,EAAEA,KAAM;IACbC,MAAM,EAAEA,MAAO;IACfC,YAAY,EAAEA,YAAY,IAAIE,aAAa,GAAG;EAAE,GAC5CD,KAAK,CACZ,CAAC;AAEV","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Skeleton from "./Skeleton";
|
|
3
|
+
/**
|
|
4
|
+
* A rectangular skeleton placeholder. Equivalent to `<Skeleton />` directly,
|
|
5
|
+
* provided for a consistent, explicit naming convention alongside
|
|
6
|
+
* `Skeleton.Circle`, `Skeleton.Square`, and `Skeleton.Pill`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* <Skeleton.Rect width={200} height={20} />
|
|
10
|
+
*/
|
|
11
|
+
export default function Rect(props) {
|
|
12
|
+
return /*#__PURE__*/React.createElement(Skeleton, props);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=Rect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Skeleton","Rect","props","createElement"],"sourceRoot":"../../../src","sources":["components/Rect.tsx"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,OAAOC,QAAQ,MAAM,YAAY;AAGjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASC,IAAIA,CAACC,KAAoB,EAAE;EAC/C,oBAAOH,KAAA,CAAAI,aAAA,CAACH,QAAQ,EAAKE,KAAQ,CAAC;AAClC","ignoreList":[]}
|