auto-loading-skeleton 1.0.2 â 2.0.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 +21 -21
- package/README.md +242 -242
- package/package.json +48 -48
- package/src/AutoSkeleton.js +117 -0
- package/src/analyzer.js +302 -79
- package/src/cache.js +47 -0
- package/src/context.js +38 -0
- package/src/hooks.js +161 -0
- package/src/index.d.ts +149 -33
- package/src/index.js +52 -102
- package/src/primitives.js +293 -0
- package/src/renderer.js +231 -56
- package/src/styles.js +162 -48
- package/src/AutoSkeleton.jsx +0 -72
- package/src/SkeletonItem.jsx +0 -99
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Virendra Patil
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,242 +1,242 @@
|
|
|
1
|
-
# auto-loading-skeleton ðĶī
|
|
2
|
-
|
|
3
|
-
> Automatically generate loading skeleton UIs from your existing React components â no manual skeleton screens needed.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/auto-loading-skeleton)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## The Problem
|
|
11
|
-
|
|
12
|
-
Every React developer has written this pattern manually:
|
|
13
|
-
|
|
14
|
-
```jsx
|
|
15
|
-
// â The old way â maintain TWO versions of every component
|
|
16
|
-
{loading ? <SkeletonCard /> : <ProductCard product={data} />}
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
This means duplicating structure, breaking skeletons every time the real component changes, and wasting hours on boilerplate.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## The Solution
|
|
24
|
-
|
|
25
|
-
```jsx
|
|
26
|
-
// â
The new way â one wrapper, zero effort
|
|
27
|
-
import { AutoSkeleton } from 'auto-loading-skeleton';
|
|
28
|
-
|
|
29
|
-
<AutoSkeleton loading={loading}>
|
|
30
|
-
<ProductCard product={data} />
|
|
31
|
-
</AutoSkeleton>
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
`AutoSkeleton` analyzes your component tree and automatically renders matching skeleton placeholders â preserving layout, spacing, and proportions.
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Installation
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm install auto-loading-skeleton
|
|
42
|
-
# or
|
|
43
|
-
yarn add auto-loading-skeleton
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Peer dependencies:** React >= 16.8
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Quick Start
|
|
51
|
-
|
|
52
|
-
```jsx
|
|
53
|
-
import React, { useState, useEffect } from 'react';
|
|
54
|
-
import { AutoSkeleton } from 'auto-loading-skeleton';
|
|
55
|
-
|
|
56
|
-
function App() {
|
|
57
|
-
const [loading, setLoading] = useState(true);
|
|
58
|
-
const [product, setProduct] = useState(null);
|
|
59
|
-
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
fetchProduct().then(data => {
|
|
62
|
-
setProduct(data);
|
|
63
|
-
setLoading(false);
|
|
64
|
-
});
|
|
65
|
-
}, []);
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<AutoSkeleton loading={loading}>
|
|
69
|
-
<ProductCard product={product} />
|
|
70
|
-
</AutoSkeleton>
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## API Reference
|
|
78
|
-
|
|
79
|
-
### `<AutoSkeleton>`
|
|
80
|
-
|
|
81
|
-
| Prop | Type | Default | Description |
|
|
82
|
-
|-------------|-----------|--------------|------------------------------------------------------|
|
|
83
|
-
| `loading` | `boolean` | **required** | Show skeleton when true, real content when false |
|
|
84
|
-
| `animation` | `string` | `'shimmer'` | `'shimmer'` / `'pulse'` / `'wave'` / `'none'` |
|
|
85
|
-
| `theme` | `object` | `{}` | CSS custom property overrides (see Theming) |
|
|
86
|
-
| `count` | `number` | `1` | Repeat the skeleton N times (great for lists) |
|
|
87
|
-
| `className` | `string` | `''` | Extra CSS class on the wrapper |
|
|
88
|
-
| `style` | `object` | `{}` | Extra inline styles on the wrapper |
|
|
89
|
-
|
|
90
|
-
```jsx
|
|
91
|
-
<AutoSkeleton loading={isLoading} animation="wave" count={3}
|
|
92
|
-
theme={{ baseColor: '#f0f0f0', duration: '1.2s' }}>
|
|
93
|
-
<ArticleCard article={article} />
|
|
94
|
-
</AutoSkeleton>
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
### `<SkeletonBlock>`
|
|
100
|
-
|
|
101
|
-
A single configurable skeleton rectangle, circle, or pill.
|
|
102
|
-
|
|
103
|
-
```jsx
|
|
104
|
-
import { SkeletonBlock } from 'auto-loading-skeleton';
|
|
105
|
-
|
|
106
|
-
<SkeletonBlock width="200px" height="20px" />
|
|
107
|
-
<SkeletonBlock width="48px" height="48px" shape="circle" />
|
|
108
|
-
<SkeletonBlock width="120px" height="36px" shape="pill" animation="pulse" />
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### `<SkeletonText>`
|
|
114
|
-
|
|
115
|
-
One or more text-line placeholders.
|
|
116
|
-
|
|
117
|
-
```jsx
|
|
118
|
-
import { SkeletonText } from 'auto-loading-skeleton';
|
|
119
|
-
<SkeletonText lines={4} lastLineWidth="50%" />
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
### `<SkeletonAvatar>`
|
|
125
|
-
|
|
126
|
-
A circular avatar placeholder.
|
|
127
|
-
|
|
128
|
-
```jsx
|
|
129
|
-
import { SkeletonAvatar } from 'auto-loading-skeleton';
|
|
130
|
-
<SkeletonAvatar size="56px" animation="pulse" />
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
### `useSkeleton` hook
|
|
136
|
-
|
|
137
|
-
```jsx
|
|
138
|
-
const { loading, setLoading, skeletonProps } = useSkeleton(true);
|
|
139
|
-
|
|
140
|
-
<AutoSkeleton {...skeletonProps} animation="wave">
|
|
141
|
-
<ProfileCard />
|
|
142
|
-
</AutoSkeleton>
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
### `withSkeleton` HOC
|
|
148
|
-
|
|
149
|
-
```jsx
|
|
150
|
-
const SkeletonProductCard = withSkeleton(ProductCard, { animation: 'shimmer' });
|
|
151
|
-
|
|
152
|
-
// Just pass a `loading` prop alongside your component's own props
|
|
153
|
-
<SkeletonProductCard loading={isLoading} product={data} />
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Animations
|
|
159
|
-
|
|
160
|
-
| Value | Description |
|
|
161
|
-
|-----------|-------------------------------------|
|
|
162
|
-
| `shimmer` | Left-to-right light sweep (default) |
|
|
163
|
-
| `pulse` | Gentle fade in / fade out |
|
|
164
|
-
| `wave` | Soft ripple wave effect |
|
|
165
|
-
| `none` | Static blocks, no animation |
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Theming
|
|
170
|
-
|
|
171
|
-
```jsx
|
|
172
|
-
<AutoSkeleton loading={loading} theme={{
|
|
173
|
-
baseColor: '#dde3ea',
|
|
174
|
-
shimmerColor: 'rgba(255,255,255,0.6)',
|
|
175
|
-
duration: '1.2s',
|
|
176
|
-
borderRadius: '6px',
|
|
177
|
-
}}>
|
|
178
|
-
<MyComponent />
|
|
179
|
-
</AutoSkeleton>
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Or globally via CSS custom properties:
|
|
183
|
-
|
|
184
|
-
```css
|
|
185
|
-
:root {
|
|
186
|
-
--ask-base-color: #dde3ea;
|
|
187
|
-
--ask-shimmer-color: rgba(255, 255, 255, 0.6);
|
|
188
|
-
--ask-duration: 1.2s;
|
|
189
|
-
--ask-border-radius: 6px;
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Dark mode is handled automatically via `@media (prefers-color-scheme: dark)`.
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## How It Works
|
|
198
|
-
|
|
199
|
-
1. **Analyze** â Traverses the React element tree when `loading` is `true`
|
|
200
|
-
2. **Classify** â Tags each node as `text`, `image`, `avatar`, `button`, `input`, `icon`, or `container`
|
|
201
|
-
3. **Render** â Converts each node into a proportional skeleton block
|
|
202
|
-
4. **Animate** â Injects CSS animations once into `<head>`
|
|
203
|
-
|
|
204
|
-
### Element Detection
|
|
205
|
-
|
|
206
|
-
| Element / Pattern | Detected As |
|
|
207
|
-
|---------------------------------------|---------------|
|
|
208
|
-
| `<img>` | IMAGE |
|
|
209
|
-
| `<img className="avatar">` | AVATAR |
|
|
210
|
-
| `<button>`, `role="button"` | BUTTON |
|
|
211
|
-
| `<input>`, `<textarea>`, `<select>` | INPUT |
|
|
212
|
-
| `<svg>`, `.icon-*` | ICON |
|
|
213
|
-
| `<h1>`â`<h6>` with text | TEXT (heading)|
|
|
214
|
-
| `<p>`, `<span>` with text | TEXT |
|
|
215
|
-
| Any element with children | CONTAINER |
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## List Skeletons
|
|
220
|
-
|
|
221
|
-
```jsx
|
|
222
|
-
<AutoSkeleton loading={loading} count={5}>
|
|
223
|
-
<ProductCard product={sampleProduct} />
|
|
224
|
-
</AutoSkeleton>
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## Low-Level API
|
|
230
|
-
|
|
231
|
-
```js
|
|
232
|
-
import { analyzeElement, renderNode, injectStyles } from 'auto-loading-skeleton';
|
|
233
|
-
|
|
234
|
-
const tree = analyzeElement(<MyComponent />);
|
|
235
|
-
const skeletonEl = renderNode(tree, { animation: 'shimmer' });
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
## License
|
|
241
|
-
|
|
242
|
-
MIT ÂĐ
|
|
1
|
+
# auto-loading-skeleton ðĶī
|
|
2
|
+
|
|
3
|
+
> Automatically generate loading skeleton UIs from your existing React components â no manual skeleton screens needed.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/auto-loading-skeleton)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## The Problem
|
|
11
|
+
|
|
12
|
+
Every React developer has written this pattern manually:
|
|
13
|
+
|
|
14
|
+
```jsx
|
|
15
|
+
// â The old way â maintain TWO versions of every component
|
|
16
|
+
{loading ? <SkeletonCard /> : <ProductCard product={data} />}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This means duplicating structure, breaking skeletons every time the real component changes, and wasting hours on boilerplate.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## The Solution
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
// â
The new way â one wrapper, zero effort
|
|
27
|
+
import { AutoSkeleton } from 'auto-loading-skeleton';
|
|
28
|
+
|
|
29
|
+
<AutoSkeleton loading={loading}>
|
|
30
|
+
<ProductCard product={data} />
|
|
31
|
+
</AutoSkeleton>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`AutoSkeleton` analyzes your component tree and automatically renders matching skeleton placeholders â preserving layout, spacing, and proportions.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install auto-loading-skeleton
|
|
42
|
+
# or
|
|
43
|
+
yarn add auto-loading-skeleton
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Peer dependencies:** React >= 16.8
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```jsx
|
|
53
|
+
import React, { useState, useEffect } from 'react';
|
|
54
|
+
import { AutoSkeleton } from 'auto-loading-skeleton';
|
|
55
|
+
|
|
56
|
+
function App() {
|
|
57
|
+
const [loading, setLoading] = useState(true);
|
|
58
|
+
const [product, setProduct] = useState(null);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
fetchProduct().then(data => {
|
|
62
|
+
setProduct(data);
|
|
63
|
+
setLoading(false);
|
|
64
|
+
});
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<AutoSkeleton loading={loading}>
|
|
69
|
+
<ProductCard product={product} />
|
|
70
|
+
</AutoSkeleton>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## API Reference
|
|
78
|
+
|
|
79
|
+
### `<AutoSkeleton>`
|
|
80
|
+
|
|
81
|
+
| Prop | Type | Default | Description |
|
|
82
|
+
|-------------|-----------|--------------|------------------------------------------------------|
|
|
83
|
+
| `loading` | `boolean` | **required** | Show skeleton when true, real content when false |
|
|
84
|
+
| `animation` | `string` | `'shimmer'` | `'shimmer'` / `'pulse'` / `'wave'` / `'none'` |
|
|
85
|
+
| `theme` | `object` | `{}` | CSS custom property overrides (see Theming) |
|
|
86
|
+
| `count` | `number` | `1` | Repeat the skeleton N times (great for lists) |
|
|
87
|
+
| `className` | `string` | `''` | Extra CSS class on the wrapper |
|
|
88
|
+
| `style` | `object` | `{}` | Extra inline styles on the wrapper |
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
<AutoSkeleton loading={isLoading} animation="wave" count={3}
|
|
92
|
+
theme={{ baseColor: '#f0f0f0', duration: '1.2s' }}>
|
|
93
|
+
<ArticleCard article={article} />
|
|
94
|
+
</AutoSkeleton>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### `<SkeletonBlock>`
|
|
100
|
+
|
|
101
|
+
A single configurable skeleton rectangle, circle, or pill.
|
|
102
|
+
|
|
103
|
+
```jsx
|
|
104
|
+
import { SkeletonBlock } from 'auto-loading-skeleton';
|
|
105
|
+
|
|
106
|
+
<SkeletonBlock width="200px" height="20px" />
|
|
107
|
+
<SkeletonBlock width="48px" height="48px" shape="circle" />
|
|
108
|
+
<SkeletonBlock width="120px" height="36px" shape="pill" animation="pulse" />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### `<SkeletonText>`
|
|
114
|
+
|
|
115
|
+
One or more text-line placeholders.
|
|
116
|
+
|
|
117
|
+
```jsx
|
|
118
|
+
import { SkeletonText } from 'auto-loading-skeleton';
|
|
119
|
+
<SkeletonText lines={4} lastLineWidth="50%" />
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### `<SkeletonAvatar>`
|
|
125
|
+
|
|
126
|
+
A circular avatar placeholder.
|
|
127
|
+
|
|
128
|
+
```jsx
|
|
129
|
+
import { SkeletonAvatar } from 'auto-loading-skeleton';
|
|
130
|
+
<SkeletonAvatar size="56px" animation="pulse" />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### `useSkeleton` hook
|
|
136
|
+
|
|
137
|
+
```jsx
|
|
138
|
+
const { loading, setLoading, skeletonProps } = useSkeleton(true);
|
|
139
|
+
|
|
140
|
+
<AutoSkeleton {...skeletonProps} animation="wave">
|
|
141
|
+
<ProfileCard />
|
|
142
|
+
</AutoSkeleton>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### `withSkeleton` HOC
|
|
148
|
+
|
|
149
|
+
```jsx
|
|
150
|
+
const SkeletonProductCard = withSkeleton(ProductCard, { animation: 'shimmer' });
|
|
151
|
+
|
|
152
|
+
// Just pass a `loading` prop alongside your component's own props
|
|
153
|
+
<SkeletonProductCard loading={isLoading} product={data} />
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Animations
|
|
159
|
+
|
|
160
|
+
| Value | Description |
|
|
161
|
+
|-----------|-------------------------------------|
|
|
162
|
+
| `shimmer` | Left-to-right light sweep (default) |
|
|
163
|
+
| `pulse` | Gentle fade in / fade out |
|
|
164
|
+
| `wave` | Soft ripple wave effect |
|
|
165
|
+
| `none` | Static blocks, no animation |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Theming
|
|
170
|
+
|
|
171
|
+
```jsx
|
|
172
|
+
<AutoSkeleton loading={loading} theme={{
|
|
173
|
+
baseColor: '#dde3ea',
|
|
174
|
+
shimmerColor: 'rgba(255,255,255,0.6)',
|
|
175
|
+
duration: '1.2s',
|
|
176
|
+
borderRadius: '6px',
|
|
177
|
+
}}>
|
|
178
|
+
<MyComponent />
|
|
179
|
+
</AutoSkeleton>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Or globally via CSS custom properties:
|
|
183
|
+
|
|
184
|
+
```css
|
|
185
|
+
:root {
|
|
186
|
+
--ask-base-color: #dde3ea;
|
|
187
|
+
--ask-shimmer-color: rgba(255, 255, 255, 0.6);
|
|
188
|
+
--ask-duration: 1.2s;
|
|
189
|
+
--ask-border-radius: 6px;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Dark mode is handled automatically via `@media (prefers-color-scheme: dark)`.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## How It Works
|
|
198
|
+
|
|
199
|
+
1. **Analyze** â Traverses the React element tree when `loading` is `true`
|
|
200
|
+
2. **Classify** â Tags each node as `text`, `image`, `avatar`, `button`, `input`, `icon`, or `container`
|
|
201
|
+
3. **Render** â Converts each node into a proportional skeleton block
|
|
202
|
+
4. **Animate** â Injects CSS animations once into `<head>`
|
|
203
|
+
|
|
204
|
+
### Element Detection
|
|
205
|
+
|
|
206
|
+
| Element / Pattern | Detected As |
|
|
207
|
+
|---------------------------------------|---------------|
|
|
208
|
+
| `<img>` | IMAGE |
|
|
209
|
+
| `<img className="avatar">` | AVATAR |
|
|
210
|
+
| `<button>`, `role="button"` | BUTTON |
|
|
211
|
+
| `<input>`, `<textarea>`, `<select>` | INPUT |
|
|
212
|
+
| `<svg>`, `.icon-*` | ICON |
|
|
213
|
+
| `<h1>`â`<h6>` with text | TEXT (heading)|
|
|
214
|
+
| `<p>`, `<span>` with text | TEXT |
|
|
215
|
+
| Any element with children | CONTAINER |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## List Skeletons
|
|
220
|
+
|
|
221
|
+
```jsx
|
|
222
|
+
<AutoSkeleton loading={loading} count={5}>
|
|
223
|
+
<ProductCard product={sampleProduct} />
|
|
224
|
+
</AutoSkeleton>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Low-Level API
|
|
230
|
+
|
|
231
|
+
```js
|
|
232
|
+
import { analyzeElement, renderNode, injectStyles } from 'auto-loading-skeleton';
|
|
233
|
+
|
|
234
|
+
const tree = analyzeElement(<MyComponent />);
|
|
235
|
+
const skeletonEl = renderNode(tree, { animation: 'shimmer' });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
MIT ÂĐ Virendra Patil
|
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "auto-loading-skeleton",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Automatically generate loading skeleton UIs from your existing React components â no manual skeleton screens needed.",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"types": "src/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./src/index.js",
|
|
10
|
-
"types": "./src/index.d.ts"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"files": [
|
|
14
|
-
"src",
|
|
15
|
-
"README.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"test": "echo \"Run tests with your preferred test runner\""
|
|
20
|
-
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"react",
|
|
23
|
-
"skeleton",
|
|
24
|
-
"loading",
|
|
25
|
-
"placeholder",
|
|
26
|
-
"ui",
|
|
27
|
-
"shimmer",
|
|
28
|
-
"auto-skeleton",
|
|
29
|
-
"loading-skeleton",
|
|
30
|
-
"skeleton-screen",
|
|
31
|
-
"pulse",
|
|
32
|
-
"wave"
|
|
33
|
-
],
|
|
34
|
-
"author": "Virendra Patil",
|
|
35
|
-
"license": "MIT",
|
|
36
|
-
"peerDependencies": {
|
|
37
|
-
"react": ">=16.8.0",
|
|
38
|
-
"react-dom": ">=16.8.0"
|
|
39
|
-
},
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "git+https://github.com/virendra2902/auto-loading-skeleton.git"
|
|
43
|
-
},
|
|
44
|
-
"bugs": {
|
|
45
|
-
"url": "https://github.com/virendra2902/auto-loading-skeleton/issues"
|
|
46
|
-
},
|
|
47
|
-
"homepage": "https://github.com/virendra2902/auto-loading-skeleton#readme"
|
|
48
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "auto-loading-skeleton",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Automatically generate loading skeleton UIs from your existing React components â no manual skeleton screens needed.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"types": "src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./src/index.js",
|
|
10
|
+
"types": "./src/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "echo \"Run tests with your preferred test runner\""
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"react",
|
|
23
|
+
"skeleton",
|
|
24
|
+
"loading",
|
|
25
|
+
"placeholder",
|
|
26
|
+
"ui",
|
|
27
|
+
"shimmer",
|
|
28
|
+
"auto-skeleton",
|
|
29
|
+
"loading-skeleton",
|
|
30
|
+
"skeleton-screen",
|
|
31
|
+
"pulse",
|
|
32
|
+
"wave"
|
|
33
|
+
],
|
|
34
|
+
"author": "Virendra Patil",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"react": ">=16.8.0",
|
|
38
|
+
"react-dom": ">=16.8.0"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/virendra2902/auto-loading-skeleton.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/virendra2902/auto-loading-skeleton/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/virendra2902/auto-loading-skeleton#readme"
|
|
48
|
+
}
|