shimmer-from-structure 0.4.0 → 0.6.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/README.md +142 -23
- package/dist/ShimmerContext.d.ts +51 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +171 -152
- package/dist/index.js +6 -6
- package/dist/types.d.ts +1 -0
- package/package.json +28 -3
package/README.md
CHANGED
|
@@ -7,11 +7,13 @@ A React shimmer/skeleton library that **automatically adapts to your component's
|
|
|
7
7
|
## Why This Library?
|
|
8
8
|
|
|
9
9
|
Traditional shimmer libraries require you to:
|
|
10
|
+
|
|
10
11
|
- Manually create skeleton components that mirror your real components
|
|
11
12
|
- Maintain two versions of each component (real + skeleton)
|
|
12
13
|
- Update skeletons every time your layout changes
|
|
13
14
|
|
|
14
15
|
**Shimmer From Structure** eliminates all of that:
|
|
16
|
+
|
|
15
17
|
- ✅ Automatically measures your component's structure at runtime
|
|
16
18
|
- ✅ Generates shimmer effects that match actual dimensions
|
|
17
19
|
- ✅ Zero maintenance - works with any layout changes
|
|
@@ -80,10 +82,7 @@ function App() {
|
|
|
80
82
|
const [user, setUser] = useState(null);
|
|
81
83
|
|
|
82
84
|
return (
|
|
83
|
-
<Shimmer
|
|
84
|
-
loading={loading}
|
|
85
|
-
templateProps={{ user: userTemplate }}
|
|
86
|
-
>
|
|
85
|
+
<Shimmer loading={loading} templateProps={{ user: userTemplate }}>
|
|
87
86
|
<UserCard user={user || userTemplate} />
|
|
88
87
|
</Shimmer>
|
|
89
88
|
);
|
|
@@ -96,15 +95,15 @@ The `templateProps` object is spread onto the first child component when loading
|
|
|
96
95
|
|
|
97
96
|
### `<Shimmer>` Props
|
|
98
97
|
|
|
99
|
-
| Prop
|
|
100
|
-
|
|
101
|
-
| `loading`
|
|
102
|
-
| `children`
|
|
103
|
-
| `shimmerColor`
|
|
104
|
-
| `backgroundColor`
|
|
105
|
-
| `duration`
|
|
106
|
-
| `fallbackBorderRadius` | `number`
|
|
107
|
-
| `templateProps`
|
|
98
|
+
| Prop | Type | Default | Description |
|
|
99
|
+
| ---------------------- | ------------------------- | -------------------------- | --------------------------------------------------------- |
|
|
100
|
+
| `loading` | `boolean` | `true` | Whether to show shimmer effect or actual content |
|
|
101
|
+
| `children` | `React.ReactNode` | required | The content to render/measure |
|
|
102
|
+
| `shimmerColor` | `string` | `'rgba(255,255,255,0.15)'` | Color of the shimmer wave |
|
|
103
|
+
| `backgroundColor` | `string` | `'rgba(255,255,255,0.08)'` | Background color of shimmer blocks |
|
|
104
|
+
| `duration` | `number` | `1.5` | Animation duration in seconds |
|
|
105
|
+
| `fallbackBorderRadius` | `number` | `4` | Border radius (px) for elements with no CSS border-radius |
|
|
106
|
+
| `templateProps` | `Record<string, unknown>` | - | Props to inject into first child for skeleton rendering |
|
|
108
107
|
|
|
109
108
|
### Example with All Props
|
|
110
109
|
|
|
@@ -115,9 +114,9 @@ The `templateProps` object is spread onto the first child component when loading
|
|
|
115
114
|
backgroundColor="rgba(255, 255, 255, 0.1)"
|
|
116
115
|
duration={2}
|
|
117
116
|
fallbackBorderRadius={8}
|
|
118
|
-
templateProps={{
|
|
117
|
+
templateProps={{
|
|
119
118
|
user: userTemplate,
|
|
120
|
-
settings: settingsTemplate
|
|
119
|
+
settings: settingsTemplate,
|
|
121
120
|
}}
|
|
122
121
|
>
|
|
123
122
|
<MyComponent user={user} settings={settings} />
|
|
@@ -150,17 +149,17 @@ Each section can have its own independent loading state:
|
|
|
150
149
|
function Dashboard() {
|
|
151
150
|
const [loadingUser, setLoadingUser] = useState(true);
|
|
152
151
|
const [loadingStats, setLoadingStats] = useState(true);
|
|
153
|
-
|
|
152
|
+
|
|
154
153
|
return (
|
|
155
154
|
<>
|
|
156
155
|
{/* User profile section */}
|
|
157
156
|
<Shimmer loading={loadingUser} templateProps={{ user: userTemplate }}>
|
|
158
157
|
<UserProfile user={user} />
|
|
159
158
|
</Shimmer>
|
|
160
|
-
|
|
159
|
+
|
|
161
160
|
{/* Stats section - with custom colors */}
|
|
162
|
-
<Shimmer
|
|
163
|
-
loading={loadingStats}
|
|
161
|
+
<Shimmer
|
|
162
|
+
loading={loadingStats}
|
|
164
163
|
templateProps={{ stats: statsTemplate }}
|
|
165
164
|
shimmerColor="rgba(20, 184, 166, 0.2)"
|
|
166
165
|
>
|
|
@@ -174,10 +173,7 @@ function Dashboard() {
|
|
|
174
173
|
### Transactions List
|
|
175
174
|
|
|
176
175
|
```tsx
|
|
177
|
-
<Shimmer
|
|
178
|
-
loading={loadingTransactions}
|
|
179
|
-
templateProps={{ transactions: transactionsTemplate }}
|
|
180
|
-
>
|
|
176
|
+
<Shimmer loading={loadingTransactions} templateProps={{ transactions: transactionsTemplate }}>
|
|
181
177
|
<TransactionsList transactions={transactions} />
|
|
182
178
|
</Shimmer>
|
|
183
179
|
```
|
|
@@ -190,15 +186,119 @@ function Dashboard() {
|
|
|
190
186
|
</Shimmer>
|
|
191
187
|
```
|
|
192
188
|
|
|
189
|
+
## 🔄 Using with React Suspense
|
|
190
|
+
|
|
191
|
+
Shimmer works seamlessly as a Suspense fallback. When used this way, `loading` is always `true` because React automatically unmounts the fallback and replaces it with the resolved component.
|
|
192
|
+
|
|
193
|
+
### Basic Suspense Pattern
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import { Suspense, lazy } from 'react';
|
|
197
|
+
import { Shimmer } from 'shimmer-from-structure';
|
|
198
|
+
|
|
199
|
+
const UserProfile = lazy(() => import('./UserProfile'));
|
|
200
|
+
|
|
201
|
+
function App() {
|
|
202
|
+
return (
|
|
203
|
+
<Suspense
|
|
204
|
+
fallback={
|
|
205
|
+
<Shimmer loading={true} templateProps={{ user: userTemplate }}>
|
|
206
|
+
<UserProfile />
|
|
207
|
+
</Shimmer>
|
|
208
|
+
}
|
|
209
|
+
>
|
|
210
|
+
<UserProfile userId="123" />
|
|
211
|
+
</Suspense>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Why `loading={true}` is Always Set
|
|
217
|
+
|
|
218
|
+
When using Shimmer as a Suspense fallback:
|
|
219
|
+
|
|
220
|
+
1. **Suspend**: React renders the fallback → Shimmer shows with `loading={true}`
|
|
221
|
+
2. **Resolve**: React **replaces** the entire fallback with the real component
|
|
222
|
+
3. The Shimmer is **unmounted**, not updated — so you never need to toggle `loading`
|
|
223
|
+
|
|
224
|
+
### Performance Tips for Suspense
|
|
225
|
+
|
|
226
|
+
**Memoize the fallback** to prevent re-renders:
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
const ShimmerFallback = React.memo(() => (
|
|
230
|
+
<Shimmer loading={true} templateProps={{ user: userTemplate }}>
|
|
231
|
+
<UserProfile />
|
|
232
|
+
</Shimmer>
|
|
233
|
+
));
|
|
234
|
+
|
|
235
|
+
// Usage
|
|
236
|
+
<Suspense fallback={<ShimmerFallback />}>
|
|
237
|
+
<UserProfile userId="123" />
|
|
238
|
+
</Suspense>;
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Keep templates lightweight** — the DOM is measured synchronously via `useLayoutEffect`, so avoid complex logic in your template.
|
|
242
|
+
|
|
243
|
+
## Global Configuration (Context API)
|
|
244
|
+
|
|
245
|
+
You can set default configuration for your entire app (or specific sections) using `ShimmerProvider`. This is perfect for maintaining consistent themes without repeating props.
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
import { Shimmer, ShimmerProvider } from 'shimmer-from-structure';
|
|
249
|
+
|
|
250
|
+
function App() {
|
|
251
|
+
return (
|
|
252
|
+
// Set global defaults
|
|
253
|
+
<ShimmerProvider
|
|
254
|
+
config={{
|
|
255
|
+
shimmerColor: 'rgba(56, 189, 248, 0.4)', // Blue shimmer
|
|
256
|
+
backgroundColor: 'rgba(56, 189, 248, 0.1)', // Blue background
|
|
257
|
+
duration: 2.5,
|
|
258
|
+
fallbackBorderRadius: 8,
|
|
259
|
+
}}
|
|
260
|
+
>
|
|
261
|
+
<Dashboard />
|
|
262
|
+
</ShimmerProvider>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Components inside the provider automatically inherit values. You can still override them locally:
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
// Inherits blue theme from provider
|
|
271
|
+
<Shimmer loading={true}><UserCard /></Shimmer>
|
|
272
|
+
|
|
273
|
+
// Overrides provider settings
|
|
274
|
+
<Shimmer loading={true} duration={0.5}><FastCard /></Shimmer>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Accessing Config in Hooks
|
|
278
|
+
|
|
279
|
+
If you need to access the current configuration in your own components:
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
import { useShimmerConfig } from 'shimmer-from-structure';
|
|
283
|
+
|
|
284
|
+
function MyComponent() {
|
|
285
|
+
const config = useShimmerConfig();
|
|
286
|
+
return <div style={{ background: config.backgroundColor }}>...</div>;
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
193
290
|
## Best Practices
|
|
194
291
|
|
|
195
292
|
### 1. Use `templateProps` for Dynamic Data
|
|
293
|
+
|
|
196
294
|
When your component receives data via props, always provide `templateProps` with mock data that matches the expected structure.
|
|
197
295
|
|
|
198
296
|
### 2. Match Template Structure to Real Data
|
|
297
|
+
|
|
199
298
|
Ensure your template data has the same array length and property structure as real data for accurate shimmer layout.
|
|
200
299
|
|
|
201
300
|
### 3. Use Individual Shimmer Components
|
|
301
|
+
|
|
202
302
|
Wrap each section in its own Shimmer for independent loading states:
|
|
203
303
|
|
|
204
304
|
```tsx
|
|
@@ -214,7 +314,9 @@ Wrap each section in its own Shimmer for independent loading states:
|
|
|
214
314
|
```
|
|
215
315
|
|
|
216
316
|
### 4. Consider Element Widths
|
|
317
|
+
|
|
217
318
|
Block elements like `<h1>`, `<p>` take full container width. If you want shimmer to match text width:
|
|
319
|
+
|
|
218
320
|
```css
|
|
219
321
|
.title {
|
|
220
322
|
width: fit-content;
|
|
@@ -222,6 +324,7 @@ Block elements like `<h1>`, `<p>` take full container width. If you want shimmer
|
|
|
222
324
|
```
|
|
223
325
|
|
|
224
326
|
### 5. Provide Container Dimensions
|
|
327
|
+
|
|
225
328
|
For async components (like charts), ensure containers have explicit dimensions so shimmer has something to measure.
|
|
226
329
|
|
|
227
330
|
## ⚡ Performance Considerations
|
|
@@ -231,6 +334,22 @@ For async components (like charts), ensure containers have explicit dimensions s
|
|
|
231
334
|
- Minimal re-renders - only updates when loading state or children change
|
|
232
335
|
- Lightweight DOM measurements using native browser APIs
|
|
233
336
|
|
|
337
|
+
### 6. Tables and Merged Shimmers
|
|
338
|
+
|
|
339
|
+
For tables, the library measures the entire cell (`<td>` or `<th>`), including padding. This can cause adjacent shimmer blocks to touch and merge visually. To prevent this:
|
|
340
|
+
|
|
341
|
+
Wrap the text content of your cells in `<span>` tags. The library will then measure the `<span>`, treating the cell padding as whitespace.
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
// ❌ Padded cell causes merging
|
|
345
|
+
<td style={{ padding: '16px' }}>Content</td>
|
|
346
|
+
|
|
347
|
+
// ✅ Wrapped content preserves spacing
|
|
348
|
+
<td style={{ padding: '16px' }}>
|
|
349
|
+
<span>Content</span>
|
|
350
|
+
</td>
|
|
351
|
+
```
|
|
352
|
+
|
|
234
353
|
## 🛠️ Development
|
|
235
354
|
|
|
236
355
|
```bash
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { default as React, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for shimmer appearance and behavior.
|
|
4
|
+
* All properties are optional when providing config to ShimmerProvider.
|
|
5
|
+
*/
|
|
6
|
+
export interface ShimmerConfig {
|
|
7
|
+
/** Color of the shimmer wave animation */
|
|
8
|
+
shimmerColor?: string;
|
|
9
|
+
/** Background color of shimmer placeholders */
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
/** Duration of one shimmer animation cycle in seconds */
|
|
12
|
+
duration?: number;
|
|
13
|
+
/** Fallback border radius (px) for elements without explicit border-radius */
|
|
14
|
+
fallbackBorderRadius?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Internal context value type with all required properties.
|
|
18
|
+
* Ensures consuming components always receive valid values.
|
|
19
|
+
*/
|
|
20
|
+
interface ShimmerContextValue {
|
|
21
|
+
shimmerColor: string;
|
|
22
|
+
backgroundColor: string;
|
|
23
|
+
duration: number;
|
|
24
|
+
fallbackBorderRadius: number;
|
|
25
|
+
}
|
|
26
|
+
/** Default configuration values */
|
|
27
|
+
declare const defaultConfig: ShimmerContextValue;
|
|
28
|
+
export interface ShimmerProviderProps {
|
|
29
|
+
/** Shimmer configuration to apply to all child Shimmer components */
|
|
30
|
+
config?: ShimmerConfig;
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Provider component for global shimmer configuration.
|
|
35
|
+
* Wrap your app or a section of your component tree to apply default shimmer settings.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <ShimmerProvider config={{ shimmerColor: '#fff', duration: 2 }}>
|
|
40
|
+
* <App />
|
|
41
|
+
* </ShimmerProvider>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare const ShimmerProvider: React.FC<ShimmerProviderProps>;
|
|
45
|
+
/**
|
|
46
|
+
* Hook to access the current shimmer configuration from context.
|
|
47
|
+
* Returns default values if no ShimmerProvider is present.
|
|
48
|
+
* All returned values are guaranteed to be defined.
|
|
49
|
+
*/
|
|
50
|
+
export declare const useShimmerConfig: () => ShimmerContextValue;
|
|
51
|
+
export { defaultConfig as shimmerDefaults };
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
var
|
|
1
|
+
import T, { createContext as ne, useMemo as ae, useContext as se, useState as ie, useRef as z, useLayoutEffect as le } from "react";
|
|
2
|
+
var L = { exports: {} }, g = {};
|
|
3
3
|
/**
|
|
4
4
|
* @license React
|
|
5
5
|
* react-jsx-runtime.production.js
|
|
@@ -9,29 +9,29 @@ var N = { exports: {} }, _ = {};
|
|
|
9
9
|
* This source code is licensed under the MIT license found in the
|
|
10
10
|
* LICENSE file in the root directory of this source tree.
|
|
11
11
|
*/
|
|
12
|
-
var
|
|
13
|
-
function
|
|
14
|
-
if (
|
|
15
|
-
|
|
12
|
+
var X;
|
|
13
|
+
function ue() {
|
|
14
|
+
if (X) return g;
|
|
15
|
+
X = 1;
|
|
16
16
|
var t = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment");
|
|
17
|
-
function
|
|
17
|
+
function l(u, i, f) {
|
|
18
18
|
var d = null;
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
for (var
|
|
22
|
-
|
|
23
|
-
} else
|
|
24
|
-
return i =
|
|
19
|
+
if (f !== void 0 && (d = "" + f), i.key !== void 0 && (d = "" + i.key), "key" in i) {
|
|
20
|
+
f = {};
|
|
21
|
+
for (var m in i)
|
|
22
|
+
m !== "key" && (f[m] = i[m]);
|
|
23
|
+
} else f = i;
|
|
24
|
+
return i = f.ref, {
|
|
25
25
|
$$typeof: t,
|
|
26
26
|
type: u,
|
|
27
27
|
key: d,
|
|
28
28
|
ref: i !== void 0 ? i : null,
|
|
29
|
-
props:
|
|
29
|
+
props: f
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
return
|
|
32
|
+
return g.Fragment = s, g.jsx = l, g.jsxs = l, g;
|
|
33
33
|
}
|
|
34
|
-
var
|
|
34
|
+
var k = {};
|
|
35
35
|
/**
|
|
36
36
|
* @license React
|
|
37
37
|
* react-jsx-runtime.development.js
|
|
@@ -41,44 +41,44 @@ var T = {};
|
|
|
41
41
|
* This source code is licensed under the MIT license found in the
|
|
42
42
|
* LICENSE file in the root directory of this source tree.
|
|
43
43
|
*/
|
|
44
|
-
var
|
|
45
|
-
function
|
|
46
|
-
return
|
|
44
|
+
var G;
|
|
45
|
+
function ce() {
|
|
46
|
+
return G || (G = 1, process.env.NODE_ENV !== "production" && function() {
|
|
47
47
|
function t(e) {
|
|
48
48
|
if (e == null) return null;
|
|
49
49
|
if (typeof e == "function")
|
|
50
|
-
return e.$$typeof ===
|
|
50
|
+
return e.$$typeof === re ? null : e.displayName || e.name || null;
|
|
51
51
|
if (typeof e == "string") return e;
|
|
52
52
|
switch (e) {
|
|
53
|
-
case
|
|
53
|
+
case p:
|
|
54
54
|
return "Fragment";
|
|
55
|
-
case
|
|
55
|
+
case b:
|
|
56
56
|
return "Profiler";
|
|
57
|
-
case
|
|
57
|
+
case c:
|
|
58
58
|
return "StrictMode";
|
|
59
|
-
case
|
|
59
|
+
case Z:
|
|
60
60
|
return "Suspense";
|
|
61
|
-
case H:
|
|
62
|
-
return "SuspenseList";
|
|
63
61
|
case Q:
|
|
62
|
+
return "SuspenseList";
|
|
63
|
+
case ee:
|
|
64
64
|
return "Activity";
|
|
65
65
|
}
|
|
66
66
|
if (typeof e == "object")
|
|
67
67
|
switch (typeof e.tag == "number" && console.error(
|
|
68
68
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
69
69
|
), e.$$typeof) {
|
|
70
|
-
case
|
|
70
|
+
case R:
|
|
71
71
|
return "Portal";
|
|
72
|
-
case
|
|
72
|
+
case P:
|
|
73
73
|
return e.displayName || "Context";
|
|
74
|
-
case
|
|
74
|
+
case _:
|
|
75
75
|
return (e._context.displayName || "Context") + ".Consumer";
|
|
76
|
-
case
|
|
76
|
+
case H:
|
|
77
77
|
var r = e.render;
|
|
78
78
|
return e = e.displayName, e || (e = r.displayName || r.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
|
|
79
|
-
case
|
|
79
|
+
case K:
|
|
80
80
|
return r = e.displayName || null, r !== null ? r : t(e.type) || "Memo";
|
|
81
|
-
case
|
|
81
|
+
case N:
|
|
82
82
|
r = e._payload, e = e._init;
|
|
83
83
|
try {
|
|
84
84
|
return t(e(r));
|
|
@@ -90,7 +90,7 @@ function ae() {
|
|
|
90
90
|
function s(e) {
|
|
91
91
|
return "" + e;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function l(e) {
|
|
94
94
|
try {
|
|
95
95
|
s(e);
|
|
96
96
|
var r = !1;
|
|
@@ -99,17 +99,17 @@ function ae() {
|
|
|
99
99
|
}
|
|
100
100
|
if (r) {
|
|
101
101
|
r = console;
|
|
102
|
-
var
|
|
103
|
-
return
|
|
102
|
+
var o = r.error, n = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
|
|
103
|
+
return o.call(
|
|
104
104
|
r,
|
|
105
105
|
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
106
|
-
|
|
106
|
+
n
|
|
107
107
|
), s(e);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
function u(e) {
|
|
111
|
-
if (e ===
|
|
112
|
-
if (typeof e == "object" && e !== null && e.$$typeof ===
|
|
111
|
+
if (e === p) return "<>";
|
|
112
|
+
if (typeof e == "object" && e !== null && e.$$typeof === N)
|
|
113
113
|
return "<...>";
|
|
114
114
|
try {
|
|
115
115
|
var r = t(e);
|
|
@@ -119,48 +119,48 @@ function ae() {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
function i() {
|
|
122
|
-
var e =
|
|
122
|
+
var e = $.A;
|
|
123
123
|
return e === null ? null : e.getOwner();
|
|
124
124
|
}
|
|
125
|
-
function
|
|
125
|
+
function f() {
|
|
126
126
|
return Error("react-stack-top-frame");
|
|
127
127
|
}
|
|
128
128
|
function d(e) {
|
|
129
|
-
if (
|
|
129
|
+
if (D.call(e, "key")) {
|
|
130
130
|
var r = Object.getOwnPropertyDescriptor(e, "key").get;
|
|
131
131
|
if (r && r.isReactWarning) return !1;
|
|
132
132
|
}
|
|
133
133
|
return e.key !== void 0;
|
|
134
134
|
}
|
|
135
|
-
function
|
|
136
|
-
function
|
|
137
|
-
|
|
135
|
+
function m(e, r) {
|
|
136
|
+
function o() {
|
|
137
|
+
B || (B = !0, console.error(
|
|
138
138
|
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
139
139
|
r
|
|
140
140
|
));
|
|
141
141
|
}
|
|
142
|
-
|
|
143
|
-
get:
|
|
142
|
+
o.isReactWarning = !0, Object.defineProperty(e, "key", {
|
|
143
|
+
get: o,
|
|
144
144
|
configurable: !0
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
|
-
function
|
|
147
|
+
function j() {
|
|
148
148
|
var e = t(this.type);
|
|
149
|
-
return
|
|
149
|
+
return M[e] || (M[e] = !0, console.error(
|
|
150
150
|
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
151
151
|
)), e = this.props.ref, e !== void 0 ? e : null;
|
|
152
152
|
}
|
|
153
|
-
function
|
|
154
|
-
var a =
|
|
153
|
+
function O(e, r, o, n, A, I) {
|
|
154
|
+
var a = o.ref;
|
|
155
155
|
return e = {
|
|
156
|
-
$$typeof:
|
|
156
|
+
$$typeof: S,
|
|
157
157
|
type: e,
|
|
158
158
|
key: r,
|
|
159
|
-
props:
|
|
160
|
-
_owner:
|
|
159
|
+
props: o,
|
|
160
|
+
_owner: n
|
|
161
161
|
}, (a !== void 0 ? a : null) !== null ? Object.defineProperty(e, "ref", {
|
|
162
162
|
enumerable: !1,
|
|
163
|
-
get:
|
|
163
|
+
get: j
|
|
164
164
|
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
|
|
165
165
|
configurable: !1,
|
|
166
166
|
enumerable: !1,
|
|
@@ -175,157 +175,174 @@ function ae() {
|
|
|
175
175
|
configurable: !1,
|
|
176
176
|
enumerable: !1,
|
|
177
177
|
writable: !0,
|
|
178
|
-
value:
|
|
178
|
+
value: A
|
|
179
179
|
}), Object.defineProperty(e, "_debugTask", {
|
|
180
180
|
configurable: !1,
|
|
181
181
|
enumerable: !1,
|
|
182
182
|
writable: !0,
|
|
183
|
-
value:
|
|
183
|
+
value: I
|
|
184
184
|
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
|
|
185
185
|
}
|
|
186
|
-
function
|
|
186
|
+
function x(e, r, o, n, A, I) {
|
|
187
187
|
var a = r.children;
|
|
188
188
|
if (a !== void 0)
|
|
189
|
-
if (
|
|
190
|
-
if (
|
|
191
|
-
for (
|
|
192
|
-
|
|
189
|
+
if (n)
|
|
190
|
+
if (te(a)) {
|
|
191
|
+
for (n = 0; n < a.length; n++)
|
|
192
|
+
C(a[n]);
|
|
193
193
|
Object.freeze && Object.freeze(a);
|
|
194
194
|
} else
|
|
195
195
|
console.error(
|
|
196
196
|
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
197
197
|
);
|
|
198
|
-
else
|
|
199
|
-
if (
|
|
198
|
+
else C(a);
|
|
199
|
+
if (D.call(r, "key")) {
|
|
200
200
|
a = t(e);
|
|
201
|
-
var v = Object.keys(r).filter(function(
|
|
202
|
-
return
|
|
201
|
+
var v = Object.keys(r).filter(function(oe) {
|
|
202
|
+
return oe !== "key";
|
|
203
203
|
});
|
|
204
|
-
|
|
204
|
+
n = 0 < v.length ? "{key: someKey, " + v.join(": ..., ") + ": ...}" : "{key: someKey}", V[a + n] || (v = 0 < v.length ? "{" + v.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
205
205
|
`A props object containing a "key" prop is being spread into JSX:
|
|
206
206
|
let props = %s;
|
|
207
207
|
<%s {...props} />
|
|
208
208
|
React keys must be passed directly to JSX without using spread:
|
|
209
209
|
let props = %s;
|
|
210
210
|
<%s key={someKey} {...props} />`,
|
|
211
|
-
|
|
211
|
+
n,
|
|
212
212
|
a,
|
|
213
213
|
v,
|
|
214
214
|
a
|
|
215
|
-
),
|
|
215
|
+
), V[a + n] = !0);
|
|
216
216
|
}
|
|
217
|
-
if (a = null,
|
|
218
|
-
|
|
219
|
-
for (var
|
|
220
|
-
|
|
221
|
-
} else
|
|
222
|
-
return a &&
|
|
223
|
-
|
|
217
|
+
if (a = null, o !== void 0 && (l(o), a = "" + o), d(r) && (l(r.key), a = "" + r.key), "key" in r) {
|
|
218
|
+
o = {};
|
|
219
|
+
for (var F in r)
|
|
220
|
+
F !== "key" && (o[F] = r[F]);
|
|
221
|
+
} else o = r;
|
|
222
|
+
return a && m(
|
|
223
|
+
o,
|
|
224
224
|
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
|
|
225
|
-
),
|
|
225
|
+
), O(
|
|
226
226
|
e,
|
|
227
227
|
a,
|
|
228
|
-
|
|
228
|
+
o,
|
|
229
229
|
i(),
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
A,
|
|
231
|
+
I
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
|
-
function
|
|
235
|
-
|
|
234
|
+
function C(e) {
|
|
235
|
+
w(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === N && (e._payload.status === "fulfilled" ? w(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
|
|
236
236
|
}
|
|
237
|
-
function
|
|
238
|
-
return typeof e == "object" && e !== null && e.$$typeof ===
|
|
237
|
+
function w(e) {
|
|
238
|
+
return typeof e == "object" && e !== null && e.$$typeof === S;
|
|
239
239
|
}
|
|
240
|
-
var
|
|
240
|
+
var E = T, S = Symbol.for("react.transitional.element"), R = Symbol.for("react.portal"), p = Symbol.for("react.fragment"), c = Symbol.for("react.strict_mode"), b = Symbol.for("react.profiler"), _ = Symbol.for("react.consumer"), P = Symbol.for("react.context"), H = Symbol.for("react.forward_ref"), Z = Symbol.for("react.suspense"), Q = Symbol.for("react.suspense_list"), K = Symbol.for("react.memo"), N = Symbol.for("react.lazy"), ee = Symbol.for("react.activity"), re = Symbol.for("react.client.reference"), $ = E.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, D = Object.prototype.hasOwnProperty, te = Array.isArray, Y = console.createTask ? console.createTask : function() {
|
|
241
241
|
return null;
|
|
242
242
|
};
|
|
243
|
-
|
|
243
|
+
E = {
|
|
244
244
|
react_stack_bottom_frame: function(e) {
|
|
245
245
|
return e();
|
|
246
246
|
}
|
|
247
247
|
};
|
|
248
|
-
var
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
)(),
|
|
252
|
-
|
|
253
|
-
var
|
|
254
|
-
return
|
|
248
|
+
var B, M = {}, W = E.react_stack_bottom_frame.bind(
|
|
249
|
+
E,
|
|
250
|
+
f
|
|
251
|
+
)(), U = Y(u(f)), V = {};
|
|
252
|
+
k.Fragment = p, k.jsx = function(e, r, o) {
|
|
253
|
+
var n = 1e4 > $.recentlyCreatedOwnerStacks++;
|
|
254
|
+
return x(
|
|
255
255
|
e,
|
|
256
256
|
r,
|
|
257
|
-
|
|
257
|
+
o,
|
|
258
258
|
!1,
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
n ? Error("react-stack-top-frame") : W,
|
|
260
|
+
n ? Y(u(e)) : U
|
|
261
261
|
);
|
|
262
|
-
},
|
|
263
|
-
var
|
|
264
|
-
return
|
|
262
|
+
}, k.jsxs = function(e, r, o) {
|
|
263
|
+
var n = 1e4 > $.recentlyCreatedOwnerStacks++;
|
|
264
|
+
return x(
|
|
265
265
|
e,
|
|
266
266
|
r,
|
|
267
|
-
|
|
267
|
+
o,
|
|
268
268
|
!0,
|
|
269
|
-
|
|
270
|
-
|
|
269
|
+
n ? Error("react-stack-top-frame") : W,
|
|
270
|
+
n ? Y(u(e)) : U
|
|
271
271
|
);
|
|
272
272
|
};
|
|
273
|
-
}()),
|
|
273
|
+
}()), k;
|
|
274
274
|
}
|
|
275
|
-
process.env.NODE_ENV === "production" ?
|
|
276
|
-
var
|
|
277
|
-
|
|
275
|
+
process.env.NODE_ENV === "production" ? L.exports = ue() : L.exports = ce();
|
|
276
|
+
var h = L.exports;
|
|
277
|
+
const y = {
|
|
278
|
+
shimmerColor: "rgba(255, 255, 255, 0.15)",
|
|
279
|
+
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
280
|
+
duration: 1.5,
|
|
281
|
+
fallbackBorderRadius: 4
|
|
282
|
+
}, J = ne(y), he = ({
|
|
283
|
+
config: t = {},
|
|
284
|
+
children: s
|
|
285
|
+
}) => {
|
|
286
|
+
const l = ae(() => ({
|
|
287
|
+
shimmerColor: t.shimmerColor ?? y.shimmerColor,
|
|
288
|
+
backgroundColor: t.backgroundColor ?? y.backgroundColor,
|
|
289
|
+
duration: t.duration ?? y.duration,
|
|
290
|
+
fallbackBorderRadius: t.fallbackBorderRadius ?? y.fallbackBorderRadius
|
|
291
|
+
}), [t.shimmerColor, t.backgroundColor, t.duration, t.fallbackBorderRadius]);
|
|
292
|
+
return /* @__PURE__ */ h.jsx(J.Provider, { value: l, children: s });
|
|
293
|
+
}, fe = () => se(J);
|
|
294
|
+
function de(t) {
|
|
278
295
|
const s = t.tagName.toLowerCase();
|
|
279
296
|
return !!(["img", "svg", "video", "canvas", "iframe", "input", "textarea", "button"].includes(s) || !(Array.from(t.children).length > 0));
|
|
280
297
|
}
|
|
281
|
-
function
|
|
282
|
-
const
|
|
298
|
+
function q(t, s) {
|
|
299
|
+
const l = [], u = t.getBoundingClientRect();
|
|
283
300
|
if (u.width === 0 || u.height === 0)
|
|
284
|
-
return
|
|
285
|
-
if (
|
|
286
|
-
const
|
|
301
|
+
return l;
|
|
302
|
+
if (de(t)) {
|
|
303
|
+
const f = window.getComputedStyle(t).borderRadius || "0px", d = {
|
|
287
304
|
x: u.left - s.left,
|
|
288
305
|
y: u.top - s.top,
|
|
289
306
|
width: u.width,
|
|
290
307
|
height: u.height,
|
|
291
308
|
tag: t.tagName.toLowerCase(),
|
|
292
|
-
borderRadius:
|
|
309
|
+
borderRadius: f
|
|
293
310
|
};
|
|
294
|
-
|
|
311
|
+
l.push(d);
|
|
295
312
|
} else
|
|
296
313
|
Array.from(t.children).forEach((i) => {
|
|
297
|
-
|
|
314
|
+
l.push(...q(i, s));
|
|
298
315
|
});
|
|
299
|
-
return
|
|
316
|
+
return l;
|
|
300
317
|
}
|
|
301
|
-
const
|
|
318
|
+
const be = ({
|
|
302
319
|
children: t,
|
|
303
320
|
loading: s = !0,
|
|
304
|
-
shimmerColor:
|
|
305
|
-
backgroundColor: u
|
|
306
|
-
duration: i
|
|
307
|
-
fallbackBorderRadius:
|
|
321
|
+
shimmerColor: l,
|
|
322
|
+
backgroundColor: u,
|
|
323
|
+
duration: i,
|
|
324
|
+
fallbackBorderRadius: f,
|
|
308
325
|
templateProps: d
|
|
309
326
|
}) => {
|
|
310
|
-
const [
|
|
327
|
+
const m = fe(), j = l ?? m.shimmerColor, O = u ?? m.backgroundColor, x = i ?? m.duration, C = f ?? m.fallbackBorderRadius, [w, E] = ie([]), S = z(null), R = z(null), p = T.useMemo(() => {
|
|
311
328
|
if (!s || !d)
|
|
312
329
|
return t;
|
|
313
|
-
const
|
|
314
|
-
if (
|
|
330
|
+
const c = T.Children.toArray(t);
|
|
331
|
+
if (c.length === 0)
|
|
315
332
|
return t;
|
|
316
|
-
const
|
|
317
|
-
return
|
|
333
|
+
const b = c[0];
|
|
334
|
+
return T.isValidElement(b) ? [T.cloneElement(b, {
|
|
318
335
|
...d
|
|
319
|
-
}), ...
|
|
336
|
+
}), ...c.slice(1)] : t;
|
|
320
337
|
}, [t, s, d]);
|
|
321
|
-
return
|
|
322
|
-
if (!s || !
|
|
323
|
-
const
|
|
324
|
-
Array.from(
|
|
325
|
-
|
|
326
|
-
}),
|
|
327
|
-
}, [s,
|
|
328
|
-
/* @__PURE__ */
|
|
338
|
+
return le(() => {
|
|
339
|
+
if (!s || !R.current) return;
|
|
340
|
+
const c = R.current, b = c.getBoundingClientRect(), _ = [];
|
|
341
|
+
Array.from(c.children).forEach((P) => {
|
|
342
|
+
_.push(...q(P, b));
|
|
343
|
+
}), E(_);
|
|
344
|
+
}, [s, p]), s ? /* @__PURE__ */ h.jsxs("div", { style: { position: "relative" }, children: [
|
|
345
|
+
/* @__PURE__ */ h.jsx("style", { children: `
|
|
329
346
|
.shimmer-measure-container * {
|
|
330
347
|
color: transparent !important;
|
|
331
348
|
border-color: transparent !important;
|
|
@@ -336,22 +353,22 @@ const le = ({
|
|
|
336
353
|
opacity: 0;
|
|
337
354
|
}
|
|
338
355
|
` }),
|
|
339
|
-
/* @__PURE__ */
|
|
356
|
+
/* @__PURE__ */ h.jsx(
|
|
340
357
|
"div",
|
|
341
358
|
{
|
|
342
|
-
ref:
|
|
359
|
+
ref: R,
|
|
343
360
|
className: "shimmer-measure-container",
|
|
344
361
|
style: {
|
|
345
362
|
pointerEvents: "none"
|
|
346
363
|
},
|
|
347
364
|
"aria-hidden": "true",
|
|
348
|
-
children:
|
|
365
|
+
children: p
|
|
349
366
|
}
|
|
350
367
|
),
|
|
351
|
-
/* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ h.jsxs(
|
|
352
369
|
"div",
|
|
353
370
|
{
|
|
354
|
-
ref:
|
|
371
|
+
ref: S,
|
|
355
372
|
style: {
|
|
356
373
|
position: "absolute",
|
|
357
374
|
top: 0,
|
|
@@ -361,7 +378,7 @@ const le = ({
|
|
|
361
378
|
overflow: "hidden"
|
|
362
379
|
},
|
|
363
380
|
children: [
|
|
364
|
-
/* @__PURE__ */
|
|
381
|
+
/* @__PURE__ */ h.jsx("style", { children: `
|
|
365
382
|
@keyframes shimmer {
|
|
366
383
|
0% {
|
|
367
384
|
transform: translateX(-100%);
|
|
@@ -371,20 +388,20 @@ const le = ({
|
|
|
371
388
|
}
|
|
372
389
|
}
|
|
373
390
|
` }),
|
|
374
|
-
|
|
391
|
+
w.map((c, b) => /* @__PURE__ */ h.jsx(
|
|
375
392
|
"div",
|
|
376
393
|
{
|
|
377
394
|
style: {
|
|
378
395
|
position: "absolute",
|
|
379
|
-
left: `${
|
|
380
|
-
top: `${
|
|
381
|
-
width: `${
|
|
382
|
-
height: `${
|
|
383
|
-
backgroundColor:
|
|
384
|
-
borderRadius:
|
|
396
|
+
left: `${c.x}px`,
|
|
397
|
+
top: `${c.y}px`,
|
|
398
|
+
width: `${c.width}px`,
|
|
399
|
+
height: `${c.height}px`,
|
|
400
|
+
backgroundColor: O,
|
|
401
|
+
borderRadius: c.borderRadius === "0px" ? `${C}px` : c.borderRadius,
|
|
385
402
|
overflow: "hidden"
|
|
386
403
|
},
|
|
387
|
-
children: /* @__PURE__ */
|
|
404
|
+
children: /* @__PURE__ */ h.jsx(
|
|
388
405
|
"div",
|
|
389
406
|
{
|
|
390
407
|
style: {
|
|
@@ -393,19 +410,21 @@ const le = ({
|
|
|
393
410
|
left: 0,
|
|
394
411
|
width: "100%",
|
|
395
412
|
height: "100%",
|
|
396
|
-
background: `linear-gradient(90deg, transparent, ${
|
|
397
|
-
animation: `shimmer ${
|
|
413
|
+
background: `linear-gradient(90deg, transparent, ${j}, transparent)`,
|
|
414
|
+
animation: `shimmer ${x}s infinite`
|
|
398
415
|
}
|
|
399
416
|
}
|
|
400
417
|
)
|
|
401
418
|
},
|
|
402
|
-
|
|
419
|
+
b
|
|
403
420
|
))
|
|
404
421
|
]
|
|
405
422
|
}
|
|
406
423
|
)
|
|
407
|
-
] }) : /* @__PURE__ */
|
|
424
|
+
] }) : /* @__PURE__ */ h.jsx(h.Fragment, { children: t });
|
|
408
425
|
};
|
|
409
426
|
export {
|
|
410
|
-
|
|
427
|
+
be as Shimmer,
|
|
428
|
+
he as ShimmerProvider,
|
|
429
|
+
fe as useShimmerConfig
|
|
411
430
|
};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(p,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],i):(p=typeof globalThis<"u"?globalThis:p||self,i(p.ShimmerFromStructure={},p.React))})(this,function(p,i){"use strict";var O={exports:{}},g={};/**
|
|
2
2
|
* @license React
|
|
3
3
|
* react-jsx-runtime.production.js
|
|
4
4
|
*
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This source code is licensed under the MIT license found in the
|
|
8
8
|
* LICENSE file in the root directory of this source tree.
|
|
9
|
-
*/var
|
|
9
|
+
*/var M;function Z(){if(M)return g;M=1;var t=Symbol.for("react.transitional.element"),s=Symbol.for("react.fragment");function l(c,u,d){var m=null;if(d!==void 0&&(m=""+d),u.key!==void 0&&(m=""+u.key),"key"in u){d={};for(var b in u)b!=="key"&&(d[b]=u[b])}else d=u;return u=d.ref,{$$typeof:t,type:c,key:m,ref:u!==void 0?u:null,props:d}}return g.Fragment=s,g.jsx=l,g.jsxs=l,g}var k={};/**
|
|
10
10
|
* @license React
|
|
11
11
|
* react-jsx-runtime.development.js
|
|
12
12
|
*
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
*
|
|
15
15
|
* This source code is licensed under the MIT license found in the
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/var
|
|
17
|
+
*/var B;function Q(){return B||(B=1,process.env.NODE_ENV!=="production"&&function(){function t(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===ie?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case _:return"Fragment";case E:return"Profiler";case f:return"StrictMode";case oe:return"Suspense";case ne:return"SuspenseList";case se:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case T:return"Portal";case $:return e.displayName||"Context";case C:return(e._context.displayName||"Context")+".Consumer";case te:var r=e.render;return e=e.displayName,e||(e=r.displayName||r.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ae:return r=e.displayName||null,r!==null?r:t(e.type)||"Memo";case Y:r=e._payload,e=e._init;try{return t(e(r))}catch{}}return null}function s(e){return""+e}function l(e){try{s(e);var r=!1}catch{r=!0}if(r){r=console;var o=r.error,n=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return o.call(r,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",n),s(e)}}function c(e){if(e===_)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===Y)return"<...>";try{var r=t(e);return r?"<"+r+">":"<...>"}catch{return"<...>"}}function u(){var e=I.A;return e===null?null:e.getOwner()}function d(){return Error("react-stack-top-frame")}function m(e){if(z.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function b(e,r){function o(){X||(X=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",r))}o.isReactWarning=!0,Object.defineProperty(e,"key",{get:o,configurable:!0})}function P(){var e=t(this.type);return q[e]||(q[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function N(e,r,o,n,A,L){var a=o.ref;return e={$$typeof:j,type:e,key:r,props:o,_owner:n},(a!==void 0?a:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:P}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:A}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:L}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function x(e,r,o,n,A,L){var a=r.children;if(a!==void 0)if(n)if(ue(a)){for(n=0;n<a.length;n++)S(a[n]);Object.freeze&&Object.freeze(a)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else S(a);if(z.call(r,"key")){a=t(e);var R=Object.keys(r).filter(function(le){return le!=="key"});n=0<R.length?"{key: someKey, "+R.join(": ..., ")+": ...}":"{key: someKey}",H[a+n]||(R=0<R.length?"{"+R.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
18
18
|
let props = %s;
|
|
19
19
|
<%s {...props} />
|
|
20
20
|
React keys must be passed directly to JSX without using spread:
|
|
21
21
|
let props = %s;
|
|
22
|
-
<%s key={someKey} {...props} />`,
|
|
22
|
+
<%s key={someKey} {...props} />`,n,a,R,a),H[a+n]=!0)}if(a=null,o!==void 0&&(l(o),a=""+o),m(r)&&(l(r.key),a=""+r.key),"key"in r){o={};for(var D in r)D!=="key"&&(o[D]=r[D])}else o=r;return a&&b(o,typeof e=="function"?e.displayName||e.name||"Unknown":e),N(e,a,o,u(),A,L)}function S(e){w(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===Y&&(e._payload.status==="fulfilled"?w(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function w(e){return typeof e=="object"&&e!==null&&e.$$typeof===j}var v=i,j=Symbol.for("react.transitional.element"),T=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),f=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),C=Symbol.for("react.consumer"),$=Symbol.for("react.context"),te=Symbol.for("react.forward_ref"),oe=Symbol.for("react.suspense"),ne=Symbol.for("react.suspense_list"),ae=Symbol.for("react.memo"),Y=Symbol.for("react.lazy"),se=Symbol.for("react.activity"),ie=Symbol.for("react.client.reference"),I=v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,z=Object.prototype.hasOwnProperty,ue=Array.isArray,F=console.createTask?console.createTask:function(){return null};v={react_stack_bottom_frame:function(e){return e()}};var X,q={},G=v.react_stack_bottom_frame.bind(v,d)(),J=F(c(d)),H={};k.Fragment=_,k.jsx=function(e,r,o){var n=1e4>I.recentlyCreatedOwnerStacks++;return x(e,r,o,!1,n?Error("react-stack-top-frame"):G,n?F(c(e)):J)},k.jsxs=function(e,r,o){var n=1e4>I.recentlyCreatedOwnerStacks++;return x(e,r,o,!0,n?Error("react-stack-top-frame"):G,n?F(c(e)):J)}}()),k}process.env.NODE_ENV==="production"?O.exports=Z():O.exports=Q();var h=O.exports;const y={shimmerColor:"rgba(255, 255, 255, 0.15)",backgroundColor:"rgba(255, 255, 255, 0.08)",duration:1.5,fallbackBorderRadius:4},W=i.createContext(y),K=({config:t={},children:s})=>{const l=i.useMemo(()=>({shimmerColor:t.shimmerColor??y.shimmerColor,backgroundColor:t.backgroundColor??y.backgroundColor,duration:t.duration??y.duration,fallbackBorderRadius:t.fallbackBorderRadius??y.fallbackBorderRadius}),[t.shimmerColor,t.backgroundColor,t.duration,t.fallbackBorderRadius]);return h.jsx(W.Provider,{value:l,children:s})},U=()=>i.useContext(W);function ee(t){const s=t.tagName.toLowerCase();return!!(["img","svg","video","canvas","iframe","input","textarea","button"].includes(s)||!(Array.from(t.children).length>0))}function V(t,s){const l=[],c=t.getBoundingClientRect();if(c.width===0||c.height===0)return l;if(ee(t)){const d=window.getComputedStyle(t).borderRadius||"0px",m={x:c.left-s.left,y:c.top-s.top,width:c.width,height:c.height,tag:t.tagName.toLowerCase(),borderRadius:d};l.push(m)}else Array.from(t.children).forEach(u=>{l.push(...V(u,s))});return l}const re=({children:t,loading:s=!0,shimmerColor:l,backgroundColor:c,duration:u,fallbackBorderRadius:d,templateProps:m})=>{const b=U(),P=l??b.shimmerColor,N=c??b.backgroundColor,x=u??b.duration,S=d??b.fallbackBorderRadius,[w,v]=i.useState([]),j=i.useRef(null),T=i.useRef(null),_=i.useMemo(()=>{if(!s||!m)return t;const f=i.Children.toArray(t);if(f.length===0)return t;const E=f[0];return i.isValidElement(E)?[i.cloneElement(E,{...m}),...f.slice(1)]:t},[t,s,m]);return i.useLayoutEffect(()=>{if(!s||!T.current)return;const f=T.current,E=f.getBoundingClientRect(),C=[];Array.from(f.children).forEach($=>{C.push(...V($,E))}),v(C)},[s,_]),s?h.jsxs("div",{style:{position:"relative"},children:[h.jsx("style",{children:`
|
|
23
23
|
.shimmer-measure-container * {
|
|
24
24
|
color: transparent !important;
|
|
25
25
|
border-color: transparent !important;
|
|
@@ -29,7 +29,7 @@ React keys must be passed directly to JSX without using spread:
|
|
|
29
29
|
.shimmer-measure-container video {
|
|
30
30
|
opacity: 0;
|
|
31
31
|
}
|
|
32
|
-
`}),h.jsx("div",{ref:
|
|
32
|
+
`}),h.jsx("div",{ref:T,className:"shimmer-measure-container",style:{pointerEvents:"none"},"aria-hidden":"true",children:_}),h.jsxs("div",{ref:j,style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflow:"hidden"},children:[h.jsx("style",{children:`
|
|
33
33
|
@keyframes shimmer {
|
|
34
34
|
0% {
|
|
35
35
|
transform: translateX(-100%);
|
|
@@ -38,4 +38,4 @@ React keys must be passed directly to JSX without using spread:
|
|
|
38
38
|
transform: translateX(100%);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
`}),
|
|
41
|
+
`}),w.map((f,E)=>h.jsx("div",{style:{position:"absolute",left:`${f.x}px`,top:`${f.y}px`,width:`${f.width}px`,height:`${f.height}px`,backgroundColor:N,borderRadius:f.borderRadius==="0px"?`${S}px`:f.borderRadius,overflow:"hidden"},children:h.jsx("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",background:`linear-gradient(90deg, transparent, ${P}, transparent)`,animation:`shimmer ${x}s infinite`}})},E))]})]}):h.jsx(h.Fragment,{children:t})};p.Shimmer=re,p.ShimmerProvider=K,p.useShimmerConfig=U,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shimmer-from-structure",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A React shimmer/skeleton library that automatically adapts to your component's runtime structure",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -12,7 +12,19 @@
|
|
|
12
12
|
"dev": "vite",
|
|
13
13
|
"build": "tsc && vite build",
|
|
14
14
|
"preview": "vite preview",
|
|
15
|
-
"test": "vitest"
|
|
15
|
+
"test": "vitest",
|
|
16
|
+
"lint": "eslint .",
|
|
17
|
+
"format": "prettier --write .",
|
|
18
|
+
"prepare": "husky"
|
|
19
|
+
},
|
|
20
|
+
"lint-staged": {
|
|
21
|
+
"*.{ts,tsx}": [
|
|
22
|
+
"eslint --fix",
|
|
23
|
+
"prettier --write"
|
|
24
|
+
],
|
|
25
|
+
"*.{json,css,md}": [
|
|
26
|
+
"prettier --write"
|
|
27
|
+
]
|
|
16
28
|
},
|
|
17
29
|
"keywords": [
|
|
18
30
|
"react",
|
|
@@ -38,15 +50,28 @@
|
|
|
38
50
|
"@types/node": "^25.0.9",
|
|
39
51
|
"@types/react": "^19.2.9",
|
|
40
52
|
"@types/react-dom": "^19.2.3",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
54
|
+
"@typescript-eslint/parser": "^8.53.1",
|
|
41
55
|
"@vitejs/plugin-react": "^4.2.1",
|
|
42
56
|
"@vitest/ui": "^4.0.17",
|
|
57
|
+
"eslint": "^9.39.2",
|
|
58
|
+
"eslint-config-prettier": "^10.1.8",
|
|
59
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
60
|
+
"eslint-plugin-react": "^7.37.5",
|
|
61
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
62
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
63
|
+
"globals": "^17.1.0",
|
|
64
|
+
"husky": "^9.1.7",
|
|
43
65
|
"jsdom": "^27.4.0",
|
|
66
|
+
"lint-staged": "^16.2.7",
|
|
67
|
+
"prettier": "^3.8.1",
|
|
44
68
|
"react": "^19.2.3",
|
|
45
69
|
"react-dom": "^19.2.3",
|
|
46
70
|
"recharts": "^3.6.0",
|
|
47
71
|
"typescript": "^5.3.0",
|
|
72
|
+
"typescript-eslint": "^8.53.1",
|
|
48
73
|
"vite": "^5.0.0",
|
|
49
74
|
"vite-plugin-dts": "^4.5.4",
|
|
50
75
|
"vitest": "^4.0.17"
|
|
51
76
|
}
|
|
52
|
-
}
|
|
77
|
+
}
|