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
package/README.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# react-native-smart-skeleton
|
|
2
|
+
|
|
3
|
+
A fully customizable, theme-aware, animated skeleton loader for React Native, powered by `react-native-reanimated`.
|
|
4
|
+
|
|
5
|
+
Created by Neeraj Singh.
|
|
6
|
+
|
|
7
|
+
## Demo
|
|
8
|
+
|
|
9
|
+
<img src="src/demo/demo.gif" alt="React Native Smart Skeleton demo" width="600" />
|
|
10
|
+
|
|
11
|
+
## Why use this package?
|
|
12
|
+
|
|
13
|
+
- Build fast, polished loading placeholders for React Native apps
|
|
14
|
+
- Support light/dark themes out of the box
|
|
15
|
+
- Use shimmer, pulse, wave, breathing, and none animations
|
|
16
|
+
- Customize colors, sizes, spacing, and performance mode
|
|
17
|
+
- Works well for cards, profiles, chats, products, and video screens
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
react-native-smart-skeleton is a lightweight, customizable skeleton loading library for React Native applications. It helps you create beautiful loading states with minimal code while staying accessible and theme-aware.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Auto light/dark theme detection (`useColorScheme`, overridable via `SkeletonProvider`)
|
|
26
|
+
- Global `SkeletonProvider` for app-wide defaults
|
|
27
|
+
- Shimmer, Pulse, Wave, and Breathing animations
|
|
28
|
+
- RTL-aware shimmer/wave sweep direction
|
|
29
|
+
- Accessibility support (`accessibilityRole="image"`, busy state, customizable labels)
|
|
30
|
+
- Automatic reduced-motion fallback (OS setting or explicit override)
|
|
31
|
+
- Dynamic shape builder via `SkeletonClone` (clone an arbitrary layout tree)
|
|
32
|
+
- Smart presets: `Profile`, `Card`, `Chat`, `Product`, `Video`
|
|
33
|
+
- Responsive helpers for grid columns / size scaling
|
|
34
|
+
- Brand color support (named light/dark palettes)
|
|
35
|
+
- Performance modes (`high` / `balanced` / `battery-saver`)
|
|
36
|
+
- `Skeleton.Group` for automatic stagger animations
|
|
37
|
+
- Full TypeScript support
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
### Install from npm
|
|
42
|
+
|
|
43
|
+
React Native CLI:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install react-native-smart-skeleton react-native-reanimated react-native-linear-gradient
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Expo:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx expo install react-native-smart-skeleton react-native-reanimated expo-linear-gradient
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Yarn:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
yarn add react-native-smart-skeleton react-native-reanimated react-native-linear-gradient
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
React Native CLI apps may also need native linking and pods:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cd ios && pod install && cd ..
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Install from a local tarball
|
|
68
|
+
|
|
69
|
+
If you want to test this package locally from a built tarball:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cd /path/to/react-native-smart-skeleton
|
|
73
|
+
npm pack
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Then install it into another app:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm install /path/to/react-native-smart-skeleton/react-native-smart-skeleton-0.1.0.tgz
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If the app is a sibling folder, the relative form is:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install ../react-native-smart-skeleton/react-native-smart-skeleton-0.1.0.tgz
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Import in both environments
|
|
89
|
+
|
|
90
|
+
The import is the same in Expo and React Native CLI:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { SkeletonProvider, Skeleton } from "react-native-smart-skeleton";
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This package automatically uses `expo-linear-gradient` in Expo apps and `react-native-linear-gradient` in React Native CLI apps.
|
|
97
|
+
|
|
98
|
+
Follow the installation instructions for [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) (Babel plugin) and either [`react-native-linear-gradient`](https://github.com/react-native-linear-gradient/react-native-linear-gradient) for React Native CLI or [`expo-linear-gradient`](https://docs.expo.dev/versions/latest/sdk/linear-gradient/) for Expo.
|
|
99
|
+
|
|
100
|
+
## Basic usage
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { SkeletonProvider, Skeleton } from "react-native-smart-skeleton";
|
|
104
|
+
|
|
105
|
+
export default function App() {
|
|
106
|
+
return (
|
|
107
|
+
<SkeletonProvider theme="system" animation="shimmer">
|
|
108
|
+
<Skeleton.Rect width={200} height={20} />
|
|
109
|
+
<Skeleton.Circle size={48} />
|
|
110
|
+
<Skeleton.Pill width={80} height={28} />
|
|
111
|
+
</SkeletonProvider>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`SkeletonProvider` is optional — every shape also works standalone, falling back to the OS color scheme and library defaults.
|
|
117
|
+
|
|
118
|
+
## Shapes
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<Skeleton.Rect width={200} height={20} borderRadius={6} />
|
|
122
|
+
<Skeleton.Circle size={48} />
|
|
123
|
+
<Skeleton.Square size={64} borderRadius={8} />
|
|
124
|
+
<Skeleton.Pill width={100} height={32} />
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
All shapes accept every prop from the base `SkeletonProps`: `animation`, `duration`, `delay`, `backgroundColor`, `highlightColor`, `gradientColors`, `colorVariant`, `rtl`, `style`, `accessibilityLabel`, `accessible`, `testID`.
|
|
128
|
+
|
|
129
|
+
## Animations
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<Skeleton.Rect animation="shimmer" />
|
|
133
|
+
<Skeleton.Rect animation="pulse" />
|
|
134
|
+
<Skeleton.Rect animation="wave" />
|
|
135
|
+
<Skeleton.Rect animation="breathing" />
|
|
136
|
+
<Skeleton.Rect animation="none" />
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
When the OS "Reduce Motion" setting is on, any non-`"none"` animation automatically downgrades to a slow, low-amplitude `breathing` effect. Override via `SkeletonProvider reducedMotion={false}` to force animations regardless of the OS setting (use sparingly).
|
|
140
|
+
|
|
141
|
+
## Stagger groups
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
<Skeleton.Group staggerDelay={80}>
|
|
145
|
+
<Skeleton.Rect width="100%" height={16} />
|
|
146
|
+
<Skeleton.Rect width="80%" height={16} />
|
|
147
|
+
<Skeleton.Rect width="60%" height={16} />
|
|
148
|
+
</Skeleton.Group>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Each child's `delay` is automatically staggered unless it already specifies its own.
|
|
152
|
+
|
|
153
|
+
## Presets
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
<Skeleton.Profile avatarSize={56} lines={2} />
|
|
157
|
+
<Skeleton.Card imageHeight={160} lines={3} showAvatar />
|
|
158
|
+
<Skeleton.Chat messages={5} />
|
|
159
|
+
<Skeleton.Product count={6} columns={2} />
|
|
160
|
+
<Skeleton.Video aspectRatio={16 / 9} showTitle showMeta />
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Every preset accepts `count` (repeat the block N times), `gap`, `animation`, `style`, and `testID`, plus its own shape-specific props.
|
|
164
|
+
|
|
165
|
+
## Layout cloning
|
|
166
|
+
|
|
167
|
+
For bespoke layouts, describe the shape once and let `SkeletonClone` render matching placeholders:
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
<Skeleton.Clone
|
|
171
|
+
layout={{
|
|
172
|
+
direction: "row",
|
|
173
|
+
gap: 12,
|
|
174
|
+
children: [
|
|
175
|
+
{ shape: "circle", width: 48, height: 48 },
|
|
176
|
+
{
|
|
177
|
+
direction: "column",
|
|
178
|
+
gap: 6,
|
|
179
|
+
children: [
|
|
180
|
+
{ width: 120, height: 14 },
|
|
181
|
+
{ width: 80, height: 12 },
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
}}
|
|
186
|
+
/>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Brand colors and custom styling
|
|
190
|
+
|
|
191
|
+
You can define a custom color palette at the provider level and apply it with `colorVariant="brand"`:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<SkeletonProvider
|
|
195
|
+
colors={{
|
|
196
|
+
brand: {
|
|
197
|
+
light: {
|
|
198
|
+
background: "#F3F4F6",
|
|
199
|
+
highlight: "#E5E7EB",
|
|
200
|
+
},
|
|
201
|
+
dark: {
|
|
202
|
+
background: "#1F2937",
|
|
203
|
+
highlight: "#374151",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
<Skeleton.Rect colorVariant="brand" width={220} height={24} />
|
|
209
|
+
</SkeletonProvider>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
You can also override colors for a single shape:
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
<Skeleton.Rect
|
|
216
|
+
width="100%"
|
|
217
|
+
height={120}
|
|
218
|
+
borderRadius={12}
|
|
219
|
+
backgroundColor="#E5E7EB"
|
|
220
|
+
highlightColor="#F3F4F6"
|
|
221
|
+
/>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Performance modes
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
<SkeletonProvider performanceMode="battery-saver">
|
|
228
|
+
<App />
|
|
229
|
+
</SkeletonProvider>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`battery-saver` lengthens animation durations to reduce frame work; `high` and `balanced` keep full fidelity.
|
|
233
|
+
|
|
234
|
+
## API reference
|
|
235
|
+
|
|
236
|
+
| Export | Description |
|
|
237
|
+
| --- | --- |
|
|
238
|
+
| `Skeleton` | Base component + namespace (`Skeleton.Rect`, `.Circle`, `.Square`, `.Pill`, `.Group`, `.Clone`, `.Profile`, `.Card`, `.Chat`, `.Product`, `.Video`) |
|
|
239
|
+
| `SkeletonProvider` | Global config provider (theme, animation, duration, performance mode, rtl, reducedMotion, colors) |
|
|
240
|
+
| `useSkeletonTheme(colorVariant?)` | Hook returning resolved `{ isDark, background, highlight }` |
|
|
241
|
+
| `useReducedMotion()` | Hook returning the current OS reduce-motion boolean |
|
|
242
|
+
|
|
243
|
+
See `src/types/index.ts` for the full prop type definitions.
|
|
244
|
+
|
|
245
|
+
## Contribution
|
|
246
|
+
|
|
247
|
+
Feel free to contribute, report issues, or suggest improvements.
|
|
248
|
+
|
|
249
|
+
## Author
|
|
250
|
+
|
|
251
|
+
Neeraj Singh
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useBreathingStyle = useBreathingStyle;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
+
/**
|
|
10
|
+
* A slow, very gentle scale + opacity oscillation — softer and slower than
|
|
11
|
+
* "pulse" — intended as the most reduced-motion-friendly animation. This is
|
|
12
|
+
* the animation `Skeleton` falls back to (at a slowed rate) when the OS
|
|
13
|
+
* reduce-motion setting is on and the consumer hasn't explicitly chosen "none".
|
|
14
|
+
*/
|
|
15
|
+
function useBreathingStyle({
|
|
16
|
+
duration = 2200,
|
|
17
|
+
delay = 0,
|
|
18
|
+
disabled = false,
|
|
19
|
+
performanceMode = "balanced",
|
|
20
|
+
minScale = 0.97,
|
|
21
|
+
maxScale = 1,
|
|
22
|
+
minOpacity = 0.85
|
|
23
|
+
}) {
|
|
24
|
+
const progress = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
25
|
+
(0, _react.useEffect)(() => {
|
|
26
|
+
if (disabled) {
|
|
27
|
+
progress.value = 0;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.2 : duration;
|
|
31
|
+
progress.value = 0;
|
|
32
|
+
progress.value = (0, _reactNativeReanimated.withDelay)(delay, (0, _reactNativeReanimated.withRepeat)((0, _reactNativeReanimated.withTiming)(1, {
|
|
33
|
+
duration: effectiveDuration / 2,
|
|
34
|
+
easing: _reactNativeReanimated.Easing.inOut(_reactNativeReanimated.Easing.ease)
|
|
35
|
+
}), -1, true));
|
|
36
|
+
return () => {
|
|
37
|
+
(0, _reactNativeReanimated.cancelAnimation)(progress);
|
|
38
|
+
};
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
41
|
+
const style = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
42
|
+
const scale = minScale + progress.value * (maxScale - minScale);
|
|
43
|
+
const opacity = minOpacity + progress.value * (1 - minOpacity);
|
|
44
|
+
return {
|
|
45
|
+
opacity,
|
|
46
|
+
transform: [{
|
|
47
|
+
scale
|
|
48
|
+
}]
|
|
49
|
+
};
|
|
50
|
+
}, [minScale, maxScale, minOpacity]);
|
|
51
|
+
return style;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=breathing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNativeReanimated","useBreathingStyle","duration","delay","disabled","performanceMode","minScale","maxScale","minOpacity","progress","useSharedValue","useEffect","value","effectiveDuration","withDelay","withRepeat","withTiming","easing","Easing","inOut","ease","cancelAnimation","style","useAnimatedStyle","scale","opacity","transform"],"sourceRoot":"../../../src","sources":["animations/breathing.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAwBA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,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,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAElC,IAAAC,gBAAS,EAAC,MAAM;IACZ,IAAIP,QAAQ,EAAE;MACVK,QAAQ,CAACG,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBR,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEO,QAAQ,CAACG,KAAK,GAAG,CAAC;IAClBH,QAAQ,CAACG,KAAK,GAAG,IAAAE,gCAAS,EACtBX,KAAK,EACL,IAAAY,iCAAU,EACN,IAAAC,iCAAU,EAAC,CAAC,EAAE;MACVd,QAAQ,EAAEW,iBAAiB,GAAG,CAAC;MAC/BI,MAAM,EAAEC,6BAAM,CAACC,KAAK,CAACD,6BAAM,CAACE,IAAI;IACpC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,IACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACT,IAAAC,sCAAe,EAACZ,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACP,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMiB,KAAK,GAAG,IAAAC,uCAAgB,EAAC,MAAM;IACjC,MAAMC,KAAK,GAAGlB,QAAQ,GAAGG,QAAQ,CAACG,KAAK,IAAIL,QAAQ,GAAGD,QAAQ,CAAC;IAC/D,MAAMmB,OAAO,GAAGjB,UAAU,GAAGC,QAAQ,CAACG,KAAK,IAAI,CAAC,GAAGJ,UAAU,CAAC;IAC9D,OAAO;MACHiB,OAAO;MACPC,SAAS,EAAE,CAAC;QAAEF;MAAM,CAAC;IACzB,CAAC;EACL,CAAC,EAAE,CAAClB,QAAQ,EAAEC,QAAQ,EAAEC,UAAU,CAAC,CAAC;EAEpC,OAAOc,KAAK;AAChB","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.usePulseStyle = usePulseStyle;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
+
/**
|
|
10
|
+
* Classic fade in/out pulse: opacity oscillates between minOpacity and
|
|
11
|
+
* maxOpacity using an ease-in-out curve, looping indefinitely.
|
|
12
|
+
*
|
|
13
|
+
* Returns an animated style with just `opacity`, ready to spread onto the
|
|
14
|
+
* skeleton's base View.
|
|
15
|
+
*/
|
|
16
|
+
function usePulseStyle({
|
|
17
|
+
duration = 1000,
|
|
18
|
+
delay = 0,
|
|
19
|
+
disabled = false,
|
|
20
|
+
performanceMode = "balanced",
|
|
21
|
+
minOpacity = 0.4,
|
|
22
|
+
maxOpacity = 1
|
|
23
|
+
}) {
|
|
24
|
+
const progress = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
25
|
+
(0, _react.useEffect)(() => {
|
|
26
|
+
if (disabled) {
|
|
27
|
+
progress.value = 0;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.3 : duration;
|
|
31
|
+
progress.value = 0;
|
|
32
|
+
progress.value = (0, _reactNativeReanimated.withDelay)(delay, (0, _reactNativeReanimated.withRepeat)((0, _reactNativeReanimated.withTiming)(1, {
|
|
33
|
+
duration: effectiveDuration / 2,
|
|
34
|
+
easing: _reactNativeReanimated.Easing.inOut(_reactNativeReanimated.Easing.ease)
|
|
35
|
+
}), -1, true // reverse, giving the fade-in/fade-out loop
|
|
36
|
+
));
|
|
37
|
+
return () => {
|
|
38
|
+
(0, _reactNativeReanimated.cancelAnimation)(progress);
|
|
39
|
+
};
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
42
|
+
const style = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
43
|
+
const opacity = minOpacity + progress.value * (maxOpacity - minOpacity);
|
|
44
|
+
return {
|
|
45
|
+
opacity
|
|
46
|
+
};
|
|
47
|
+
}, [minOpacity, maxOpacity]);
|
|
48
|
+
return style;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=pulse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNativeReanimated","usePulseStyle","duration","delay","disabled","performanceMode","minOpacity","maxOpacity","progress","useSharedValue","useEffect","value","effectiveDuration","withDelay","withRepeat","withTiming","easing","Easing","inOut","ease","cancelAnimation","style","useAnimatedStyle","opacity"],"sourceRoot":"../../../src","sources":["animations/pulse.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,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,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAElC,IAAAC,gBAAS,EAAC,MAAM;IACZ,IAAIN,QAAQ,EAAE;MACVI,QAAQ,CAACG,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBP,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEM,QAAQ,CAACG,KAAK,GAAG,CAAC;IAClBH,QAAQ,CAACG,KAAK,GAAG,IAAAE,gCAAS,EACtBV,KAAK,EACL,IAAAW,iCAAU,EACN,IAAAC,iCAAU,EAAC,CAAC,EAAE;MACVb,QAAQ,EAAEU,iBAAiB,GAAG,CAAC;MAC/BI,MAAM,EAAEC,6BAAM,CAACC,KAAK,CAACD,6BAAM,CAACE,IAAI;IACpC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,IAAI,CAAC;IACT,CACJ,CAAC;IAED,OAAO,MAAM;MACT,IAAAC,sCAAe,EAACZ,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACN,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMgB,KAAK,GAAG,IAAAC,uCAAgB,EAAC,MAAM;IACjC,MAAMC,OAAO,GAAGjB,UAAU,GAAGE,QAAQ,CAACG,KAAK,IAAIJ,UAAU,GAAGD,UAAU,CAAC;IACvE,OAAO;MAAEiB;IAAQ,CAAC;EACtB,CAAC,EAAE,CAACjB,UAAU,EAAEC,UAAU,CAAC,CAAC;EAE5B,OAAOc,KAAK;AAChB","ignoreList":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useShimmerProgress = useShimmerProgress;
|
|
7
|
+
exports.useShimmerTransform = useShimmerTransform;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
10
|
+
/**
|
|
11
|
+
* Drives a 0 -> 1 -> 0 progress value looping indefinitely, intended to be
|
|
12
|
+
* mapped (by the consuming component) onto a translateX of a gradient
|
|
13
|
+
* overlay to create the classic "shimmer sweep" effect.
|
|
14
|
+
*
|
|
15
|
+
* Returns both the raw shared value-derived animated style (opacity passthrough,
|
|
16
|
+
* so it can be spread directly) and the progress itself isn't exposed —
|
|
17
|
+
* components should use `useShimmerTransform` below to get a transform style
|
|
18
|
+
* sized to their own width.
|
|
19
|
+
*/
|
|
20
|
+
function useShimmerProgress({
|
|
21
|
+
duration = 1200,
|
|
22
|
+
delay = 0,
|
|
23
|
+
disabled = false,
|
|
24
|
+
performanceMode = "balanced"
|
|
25
|
+
}) {
|
|
26
|
+
const progress = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
27
|
+
(0, _react.useEffect)(() => {
|
|
28
|
+
if (disabled) {
|
|
29
|
+
progress.value = 0;
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.4 : duration;
|
|
33
|
+
progress.value = 0;
|
|
34
|
+
progress.value = (0, _reactNativeReanimated.withDelay)(delay, (0, _reactNativeReanimated.withRepeat)((0, _reactNativeReanimated.withTiming)(1, {
|
|
35
|
+
duration: effectiveDuration,
|
|
36
|
+
easing: _reactNativeReanimated.Easing.linear
|
|
37
|
+
}), -1, false));
|
|
38
|
+
return () => {
|
|
39
|
+
(0, _reactNativeReanimated.cancelAnimation)(progress);
|
|
40
|
+
};
|
|
41
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
43
|
+
return progress;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convenience hook: given a measured width, returns an animated style that
|
|
48
|
+
* translates a highlight overlay (assumed ~60% of `width` wide) from off-screen
|
|
49
|
+
* left to off-screen right, looping. Use on an absolutely-positioned overlay
|
|
50
|
+
* View/LinearGradient layered on top of the base skeleton rect.
|
|
51
|
+
*/
|
|
52
|
+
function useShimmerTransform(width, options) {
|
|
53
|
+
const progress = useShimmerProgress(options);
|
|
54
|
+
const sweepWidth = Math.max(width, 1) * 0.6;
|
|
55
|
+
const style = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
56
|
+
const translateX = -sweepWidth + progress.value * (width + sweepWidth);
|
|
57
|
+
return {
|
|
58
|
+
transform: [{
|
|
59
|
+
translateX
|
|
60
|
+
}]
|
|
61
|
+
};
|
|
62
|
+
}, [width, sweepWidth]);
|
|
63
|
+
return {
|
|
64
|
+
style,
|
|
65
|
+
sweepWidth
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=shimmer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNativeReanimated","useShimmerProgress","duration","delay","disabled","performanceMode","progress","useSharedValue","useEffect","value","effectiveDuration","withDelay","withRepeat","withTiming","easing","Easing","linear","cancelAnimation","useShimmerTransform","width","options","sweepWidth","Math","max","style","useAnimatedStyle","translateX","transform"],"sourceRoot":"../../../src","sources":["animations/shimmer.tsx"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,kBAAkBA,CAAC;EAC/BC,QAAQ,GAAG,IAAI;EACfC,KAAK,GAAG,CAAC;EACTC,QAAQ,GAAG,KAAK;EAChBC,eAAe,GAAG;AACN,CAAC,EAAE;EACf,MAAMC,QAAQ,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAElC,IAAAC,gBAAS,EAAC,MAAM;IACZ,IAAIJ,QAAQ,EAAE;MACVE,QAAQ,CAACG,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBL,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEI,QAAQ,CAACG,KAAK,GAAG,CAAC;IAClBH,QAAQ,CAACG,KAAK,GAAG,IAAAE,gCAAS,EACtBR,KAAK,EACL,IAAAS,iCAAU,EACN,IAAAC,iCAAU,EAAC,CAAC,EAAE;MACVX,QAAQ,EAAEQ,iBAAiB;MAC3BI,MAAM,EAAEC,6BAAM,CAACC;IACnB,CAAC,CAAC,EACF,CAAC,CAAC,EACF,KACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACT,IAAAC,sCAAe,EAACX,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;AACO,SAASY,mBAAmBA,CAACC,KAAa,EAAEC,OAAuB,EAAE;EACxE,MAAMd,QAAQ,GAAGL,kBAAkB,CAACmB,OAAO,CAAC;EAC5C,MAAMC,UAAU,GAAGC,IAAI,CAACC,GAAG,CAACJ,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG;EAE3C,MAAMK,KAAK,GAAG,IAAAC,uCAAgB,EAAC,MAAM;IACjC,MAAMC,UAAU,GAAG,CAACL,UAAU,GAAGf,QAAQ,CAACG,KAAK,IAAIU,KAAK,GAAGE,UAAU,CAAC;IACtE,OAAO;MACHM,SAAS,EAAE,CAAC;QAAED;MAAW,CAAC;IAC9B,CAAC;EACL,CAAC,EAAE,CAACP,KAAK,EAAEE,UAAU,CAAC,CAAC;EAEvB,OAAO;IAAEG,KAAK;IAAEH;EAAW,CAAC;AAChC","ignoreList":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useWaveTransform = useWaveTransform;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
+
/**
|
|
10
|
+
* Similar to shimmer, but drives a smoother sine-like sweep (ease-in-out
|
|
11
|
+
* instead of linear) intended for a softer "ripple" look, typically paired
|
|
12
|
+
* with a wider, lower-contrast gradient than shimmer uses.
|
|
13
|
+
*
|
|
14
|
+
* Returns a translateX-based animated style for a given measured width.
|
|
15
|
+
*/
|
|
16
|
+
function useWaveTransform(width, options) {
|
|
17
|
+
const {
|
|
18
|
+
duration = 1500,
|
|
19
|
+
delay = 0,
|
|
20
|
+
disabled = false,
|
|
21
|
+
performanceMode = "balanced"
|
|
22
|
+
} = options;
|
|
23
|
+
const progress = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
24
|
+
(0, _react.useEffect)(() => {
|
|
25
|
+
if (disabled) {
|
|
26
|
+
progress.value = 0;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const effectiveDuration = performanceMode === "battery-saver" ? duration * 1.4 : duration;
|
|
30
|
+
progress.value = 0;
|
|
31
|
+
progress.value = (0, _reactNativeReanimated.withDelay)(delay, (0, _reactNativeReanimated.withRepeat)((0, _reactNativeReanimated.withTiming)(1, {
|
|
32
|
+
duration: effectiveDuration,
|
|
33
|
+
easing: _reactNativeReanimated.Easing.inOut(_reactNativeReanimated.Easing.sin)
|
|
34
|
+
}), -1, false));
|
|
35
|
+
return () => {
|
|
36
|
+
(0, _reactNativeReanimated.cancelAnimation)(progress);
|
|
37
|
+
};
|
|
38
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
+
}, [duration, delay, disabled, performanceMode]);
|
|
40
|
+
const sweepWidth = Math.max(width, 1) * 0.8;
|
|
41
|
+
const style = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
42
|
+
const translateX = (0, _reactNativeReanimated.interpolate)(progress.value, [0, 1], [-sweepWidth, width + sweepWidth]);
|
|
43
|
+
return {
|
|
44
|
+
transform: [{
|
|
45
|
+
translateX
|
|
46
|
+
}]
|
|
47
|
+
};
|
|
48
|
+
}, [width, sweepWidth]);
|
|
49
|
+
return {
|
|
50
|
+
style,
|
|
51
|
+
sweepWidth
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=wave.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNativeReanimated","useWaveTransform","width","options","duration","delay","disabled","performanceMode","progress","useSharedValue","useEffect","value","effectiveDuration","withDelay","withRepeat","withTiming","easing","Easing","inOut","sin","cancelAnimation","sweepWidth","Math","max","style","useAnimatedStyle","translateX","interpolate","transform"],"sourceRoot":"../../../src","sources":["animations/wave.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,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,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAElC,IAAAC,gBAAS,EAAC,MAAM;IACZ,IAAIJ,QAAQ,EAAE;MACVE,QAAQ,CAACG,KAAK,GAAG,CAAC;MAClB;IACJ;IAEA,MAAMC,iBAAiB,GACnBL,eAAe,KAAK,eAAe,GAAGH,QAAQ,GAAG,GAAG,GAAGA,QAAQ;IAEnEI,QAAQ,CAACG,KAAK,GAAG,CAAC;IAClBH,QAAQ,CAACG,KAAK,GAAG,IAAAE,gCAAS,EACtBR,KAAK,EACL,IAAAS,iCAAU,EACN,IAAAC,iCAAU,EAAC,CAAC,EAAE;MACVX,QAAQ,EAAEQ,iBAAiB;MAC3BI,MAAM,EAAEC,6BAAM,CAACC,KAAK,CAACD,6BAAM,CAACE,GAAG;IACnC,CAAC,CAAC,EACF,CAAC,CAAC,EACF,KACJ,CACJ,CAAC;IAED,OAAO,MAAM;MACT,IAAAC,sCAAe,EAACZ,QAAQ,CAAC;IAC7B,CAAC;IACD;EACJ,CAAC,EAAE,CAACJ,QAAQ,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,eAAe,CAAC,CAAC;EAEhD,MAAMc,UAAU,GAAGC,IAAI,CAACC,GAAG,CAACrB,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG;EAE3C,MAAMsB,KAAK,GAAG,IAAAC,uCAAgB,EAAC,MAAM;IACjC,MAAMC,UAAU,GAAG,IAAAC,kCAAW,EAC1BnB,QAAQ,CAACG,KAAK,EACd,CAAC,CAAC,EAAE,CAAC,CAAC,EACN,CAAC,CAACU,UAAU,EAAEnB,KAAK,GAAGmB,UAAU,CACpC,CAAC;IACD,OAAO;MACHO,SAAS,EAAE,CAAC;QAAEF;MAAW,CAAC;IAC9B,CAAC;EACL,CAAC,EAAE,CAACxB,KAAK,EAAEmB,UAAU,CAAC,CAAC;EAEvB,OAAO;IAAEG,KAAK;IAAEH;EAAW,CAAC;AAChC","ignoreList":[]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = SkeletonClone;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _Skeleton = _interopRequireDefault(require("../components/Skeleton"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
function renderNode(node, animation, keyPrefix) {
|
|
12
|
+
const {
|
|
13
|
+
shape = "rect",
|
|
14
|
+
width,
|
|
15
|
+
height,
|
|
16
|
+
borderRadius,
|
|
17
|
+
style,
|
|
18
|
+
children,
|
|
19
|
+
direction = "column",
|
|
20
|
+
gap = 8
|
|
21
|
+
} = node;
|
|
22
|
+
let resolvedBorderRadius = borderRadius;
|
|
23
|
+
if (shape === "circle") {
|
|
24
|
+
const numericSize = typeof width === "number" ? width : typeof height === "number" ? height : 50;
|
|
25
|
+
resolvedBorderRadius = numericSize / 2;
|
|
26
|
+
} else if (shape === "pill") {
|
|
27
|
+
const numericHeight = typeof height === "number" ? height : 24;
|
|
28
|
+
resolvedBorderRadius = resolvedBorderRadius ?? numericHeight / 2;
|
|
29
|
+
}
|
|
30
|
+
if (children && children.length > 0) {
|
|
31
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
32
|
+
key: keyPrefix,
|
|
33
|
+
style: [{
|
|
34
|
+
flexDirection: direction === "row" ? "row" : "column"
|
|
35
|
+
}, style]
|
|
36
|
+
}, children.map((child, i) => /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
37
|
+
key: `${keyPrefix}-${i}`,
|
|
38
|
+
style: direction === "row" ? {
|
|
39
|
+
marginLeft: i === 0 ? 0 : gap
|
|
40
|
+
} : {
|
|
41
|
+
marginTop: i === 0 ? 0 : gap
|
|
42
|
+
}
|
|
43
|
+
}, renderNode(child, animation, `${keyPrefix}-${i}`))));
|
|
44
|
+
}
|
|
45
|
+
return /*#__PURE__*/_react.default.createElement(_Skeleton.default, {
|
|
46
|
+
width: width ?? "100%",
|
|
47
|
+
height: height ?? 16,
|
|
48
|
+
borderRadius: resolvedBorderRadius ?? 4,
|
|
49
|
+
animation: animation,
|
|
50
|
+
style: style
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clones an arbitrary layout tree as skeleton placeholders. Useful when you
|
|
56
|
+
* have a complex, bespoke screen layout and don't want to hand-place a
|
|
57
|
+
* Skeleton for every element — instead describe the rough shape once as a
|
|
58
|
+
* `SkeletonCloneNode` tree (mirroring your real layout's structure) and let
|
|
59
|
+
* SkeletonClone render matching placeholders.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <SkeletonClone
|
|
63
|
+
* layout={{
|
|
64
|
+
* direction: "row",
|
|
65
|
+
* gap: 12,
|
|
66
|
+
* children: [
|
|
67
|
+
* { shape: "circle", width: 48, height: 48 },
|
|
68
|
+
* {
|
|
69
|
+
* direction: "column",
|
|
70
|
+
* gap: 6,
|
|
71
|
+
* children: [
|
|
72
|
+
* { width: 120, height: 14 },
|
|
73
|
+
* { width: 80, height: 12 },
|
|
74
|
+
* ],
|
|
75
|
+
* },
|
|
76
|
+
* ],
|
|
77
|
+
* }}
|
|
78
|
+
* />
|
|
79
|
+
*/
|
|
80
|
+
function SkeletonClone({
|
|
81
|
+
layout,
|
|
82
|
+
animation,
|
|
83
|
+
style,
|
|
84
|
+
testID
|
|
85
|
+
}) {
|
|
86
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
87
|
+
style: style,
|
|
88
|
+
testID: testID
|
|
89
|
+
}, renderNode(layout, animation, "clone-root"));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=SkeletonClone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_Skeleton","e","__esModule","default","renderNode","node","animation","keyPrefix","shape","width","height","borderRadius","style","children","direction","gap","resolvedBorderRadius","numericSize","numericHeight","length","createElement","View","key","flexDirection","map","child","i","marginLeft","marginTop","SkeletonClone","layout","testID"],"sourceRoot":"../../../src","sources":["clone/SkeletonClone.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Circle;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _Skeleton = _interopRequireDefault(require("./Skeleton"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
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); }
|
|
11
|
+
/**
|
|
12
|
+
* A circular skeleton placeholder, commonly used for avatars.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* <Skeleton.Circle size={48} />
|
|
16
|
+
*/
|
|
17
|
+
function Circle({
|
|
18
|
+
size = 50,
|
|
19
|
+
...props
|
|
20
|
+
}) {
|
|
21
|
+
return /*#__PURE__*/_react.default.createElement(_Skeleton.default, _extends({
|
|
22
|
+
width: size,
|
|
23
|
+
height: size,
|
|
24
|
+
borderRadius: size / 2
|
|
25
|
+
}, props));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=Circle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireDefault","require","_Skeleton","e","__esModule","default","_extends","Object","assign","bind","n","arguments","length","t","r","hasOwnProperty","call","apply","Circle","size","props","createElement","width","height","borderRadius"],"sourceRoot":"../../../src","sources":["components/Circle.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,SAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAkC,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAAA,SAAAG,SAAA,WAAAA,QAAA,GAAAC,MAAA,CAAAC,MAAA,GAAAD,MAAA,CAAAC,MAAA,CAAAC,IAAA,eAAAC,CAAA,aAAAP,CAAA,MAAAA,CAAA,GAAAQ,SAAA,CAAAC,MAAA,EAAAT,CAAA,UAAAU,CAAA,GAAAF,SAAA,CAAAR,CAAA,YAAAW,CAAA,IAAAD,CAAA,OAAAE,cAAA,CAAAC,IAAA,CAAAH,CAAA,EAAAC,CAAA,MAAAJ,CAAA,CAAAI,CAAA,IAAAD,CAAA,CAAAC,CAAA,aAAAJ,CAAA,KAAAJ,QAAA,CAAAW,KAAA,OAAAN,SAAA;AAGlC;AACA;AACA;AACA;AACA;AACA;AACe,SAASO,MAAMA,CAAC;EAAEC,IAAI,GAAG,EAAE;EAAE,GAAGC;AAA2B,CAAC,EAAE;EACzE,oBAAOrB,MAAA,CAAAM,OAAA,CAAAgB,aAAA,CAACnB,SAAA,CAAAG,OAAQ,EAAAC,QAAA;IAACgB,KAAK,EAAEH,IAAK;IAACI,MAAM,EAAEJ,IAAK;IAACK,YAAY,EAAEL,IAAI,GAAG;EAAE,GAAKC,KAAK,CAAG,CAAC;AACrF","ignoreList":[]}
|