shimmer-from-structure 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shimmer From Structure Contributors
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 ADDED
@@ -0,0 +1,273 @@
1
+ # ✨ Shimmer From Structure
2
+
3
+ A React shimmer/skeleton library that **automatically adapts to your component's runtime structure**. Unlike traditional shimmer libraries that require pre-defined skeleton structures, this library analyzes your actual component's DOM at runtime and generates a shimmer effect that perfectly matches its layout.
4
+
5
+ ![Shimmer From Structure Demo](./example/preview.gif)
6
+
7
+ ## Why This Library?
8
+
9
+ Traditional shimmer libraries require you to:
10
+ - Manually create skeleton components that mirror your real components
11
+ - Maintain two versions of each component (real + skeleton)
12
+ - Update skeletons every time your layout changes
13
+
14
+ **Shimmer From Structure** eliminates all of that:
15
+ - ✅ Automatically measures your component's structure at runtime
16
+ - ✅ Generates shimmer effects that match actual dimensions
17
+ - ✅ Zero maintenance - works with any layout changes
18
+ - ✅ Works with complex nested structures
19
+ - ✅ Supports dynamic data with `templateProps`
20
+ - ✅ Preserves container backgrounds during loading
21
+ - ✅ Auto-detects border-radius from your CSS
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install shimmer-from-structure
27
+ # or
28
+ yarn add shimmer-from-structure
29
+ # or
30
+ pnpm add shimmer-from-structure
31
+ ```
32
+
33
+ # 📖 Basic Usage
34
+
35
+ ### Static Content
36
+
37
+ For components with hardcoded/static content:
38
+
39
+ ```tsx
40
+ import { Shimmer } from 'shimmer-from-structure';
41
+
42
+ function UserCard() {
43
+ return (
44
+ <Shimmer loading={isLoading}>
45
+ <div className="card">
46
+ <img src="avatar.jpg" className="avatar" />
47
+ <h2>John Doe</h2>
48
+ <p>Software Engineer</p>
49
+ </div>
50
+ </Shimmer>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ### Dynamic Content with `templateProps`
56
+
57
+ For components that receive dynamic data via props, use `templateProps` to provide mock data for skeleton generation:
58
+
59
+ ```tsx
60
+ import { Shimmer } from 'shimmer-from-structure';
61
+
62
+ // Your component that accepts props
63
+ const UserCard = ({ user }) => (
64
+ <div className="card">
65
+ <img src={user.avatar} className="avatar" />
66
+ <h2>{user.name}</h2>
67
+ <p>{user.role}</p>
68
+ </div>
69
+ );
70
+
71
+ // Template data for the skeleton
72
+ const userTemplate = {
73
+ name: 'Loading...',
74
+ role: 'Loading role...',
75
+ avatar: 'placeholder.jpg',
76
+ };
77
+
78
+ function App() {
79
+ const [loading, setLoading] = useState(true);
80
+ const [user, setUser] = useState(null);
81
+
82
+ return (
83
+ <Shimmer
84
+ loading={loading}
85
+ templateProps={{ user: userTemplate }}
86
+ >
87
+ <UserCard user={user || userTemplate} />
88
+ </Shimmer>
89
+ );
90
+ }
91
+ ```
92
+
93
+ The `templateProps` object is spread onto the first child component when loading, allowing it to render with mock data for measurement.
94
+
95
+ ## 🎨 API Reference
96
+
97
+ ### `<Shimmer>` Props
98
+
99
+ | Prop | Type | Default | Description |
100
+ |------|------|---------|-------------|
101
+ | `loading` | `boolean` | `true` | Whether to show shimmer effect or actual content |
102
+ | `children` | `React.ReactNode` | required | The content to render/measure |
103
+ | `shimmerColor` | `string` | `'rgba(255,255,255,0.15)'` | Color of the shimmer wave |
104
+ | `backgroundColor` | `string` | `'rgba(255,255,255,0.08)'` | Background color of shimmer blocks |
105
+ | `duration` | `number` | `1.5` | Animation duration in seconds |
106
+ | `fallbackBorderRadius` | `number` | `4` | Border radius (px) for elements with no CSS border-radius |
107
+ | `templateProps` | `Record<string, unknown>` | - | Props to inject into first child for skeleton rendering |
108
+
109
+ ### Example with All Props
110
+
111
+ ```tsx
112
+ <Shimmer
113
+ loading={isLoading}
114
+ shimmerColor="rgba(255, 255, 255, 0.2)"
115
+ backgroundColor="rgba(255, 255, 255, 0.1)"
116
+ duration={2}
117
+ fallbackBorderRadius={8}
118
+ templateProps={{
119
+ user: userTemplate,
120
+ settings: settingsTemplate
121
+ }}
122
+ >
123
+ <MyComponent user={user} settings={settings} />
124
+ </Shimmer>
125
+ ```
126
+
127
+ ## 🔧 How It Works
128
+
129
+ 1. **Visible Container Rendering**: When `loading={true}`, your component renders with transparent text but **visible container backgrounds**
130
+ 2. **Template Props Injection**: If `templateProps` is provided, it's spread onto the first child so dynamic components can render
131
+ 3. **DOM Measurement**: Uses `useLayoutEffect` to synchronously measure all leaf elements via `getBoundingClientRect()`
132
+ 4. **Border Radius Detection**: Automatically captures each element's computed `border-radius` from CSS
133
+ 5. **Shimmer Generation**: Creates absolutely-positioned shimmer blocks matching measured dimensions
134
+ 6. **Animation**: Applies smooth gradient animation that sweeps across each block
135
+
136
+ ### Key Features
137
+
138
+ - **Container backgrounds visible**: Unlike `opacity: 0`, we use `color: transparent` so card backgrounds/borders show during loading
139
+ - **Auto border-radius**: Circular avatars get circular shimmer blocks automatically
140
+ - **Fallback radius**: Text elements (which have `border-radius: 0`) use `fallbackBorderRadius` to avoid sharp rectangles
141
+ - **Dark-mode friendly**: Default colors use semi-transparent whites that work on any background
142
+
143
+ ## Examples
144
+
145
+ ### Dashboard with Multiple Sections
146
+
147
+ Each section can have its own independent loading state:
148
+
149
+ ```tsx
150
+ function Dashboard() {
151
+ const [loadingUser, setLoadingUser] = useState(true);
152
+ const [loadingStats, setLoadingStats] = useState(true);
153
+
154
+ return (
155
+ <>
156
+ {/* User profile section */}
157
+ <Shimmer loading={loadingUser} templateProps={{ user: userTemplate }}>
158
+ <UserProfile user={user} />
159
+ </Shimmer>
160
+
161
+ {/* Stats section - with custom colors */}
162
+ <Shimmer
163
+ loading={loadingStats}
164
+ templateProps={{ stats: statsTemplate }}
165
+ shimmerColor="rgba(20, 184, 166, 0.2)"
166
+ >
167
+ <StatsGrid stats={stats} />
168
+ </Shimmer>
169
+ </>
170
+ );
171
+ }
172
+ ```
173
+
174
+ ### Transactions List
175
+
176
+ ```tsx
177
+ <Shimmer
178
+ loading={loadingTransactions}
179
+ templateProps={{ transactions: transactionsTemplate }}
180
+ >
181
+ <TransactionsList transactions={transactions} />
182
+ </Shimmer>
183
+ ```
184
+
185
+ ### Team Members Grid
186
+
187
+ ```tsx
188
+ <Shimmer loading={loadingTeam} templateProps={{ members: teamTemplate }}>
189
+ <TeamMembers members={team} />
190
+ </Shimmer>
191
+ ```
192
+
193
+ ## Best Practices
194
+
195
+ ### 1. Use `templateProps` for Dynamic Data
196
+ When your component receives data via props, always provide `templateProps` with mock data that matches the expected structure.
197
+
198
+ ### 2. Match Template Structure to Real Data
199
+ Ensure your template data has the same array length and property structure as real data for accurate shimmer layout.
200
+
201
+ ### 3. Use Individual Shimmer Components
202
+ Wrap each section in its own Shimmer for independent loading states:
203
+
204
+ ```tsx
205
+ // ✅ Good - independent loading
206
+ <Shimmer loading={loadingUsers}><UserList /></Shimmer>
207
+ <Shimmer loading={loadingPosts}><PostList /></Shimmer>
208
+
209
+ // ❌ Avoid - all-or-nothing loading
210
+ <Shimmer loading={loadingUsers || loadingPosts}>
211
+ <UserList />
212
+ <PostList />
213
+ </Shimmer>
214
+ ```
215
+
216
+ ### 4. Consider Element Widths
217
+ Block elements like `<h1>`, `<p>` take full container width. If you want shimmer to match text width:
218
+ ```css
219
+ .title {
220
+ width: fit-content;
221
+ }
222
+ ```
223
+
224
+ ### 5. Provide Container Dimensions
225
+ For async components (like charts), ensure containers have explicit dimensions so shimmer has something to measure.
226
+
227
+ ## ⚡ Performance Considerations
228
+
229
+ - Measurement happens only when `loading` changes to `true`
230
+ - Uses `useLayoutEffect` for synchronous measurement (no flicker)
231
+ - Minimal re-renders - only updates when loading state or children change
232
+ - Lightweight DOM measurements using native browser APIs
233
+
234
+ ## 🛠️ Development
235
+
236
+ ```bash
237
+ # Install dependencies
238
+ npm install
239
+
240
+ # Run development server with example
241
+ npm run dev
242
+
243
+ # Build library
244
+ npm run build
245
+ ```
246
+
247
+ ## 📝 License
248
+
249
+ MIT
250
+
251
+ ## 🤝 Contributing
252
+
253
+ Contributions are welcome! Please feel free to submit a Pull Request.
254
+
255
+ ## 🐛 Known Limitations
256
+
257
+ - **Async components**: Components that render asynchronously (like charts using `ResponsiveContainer`) may need explicit container dimensions
258
+ - **Zero-dimension elements**: Elements with `display: none` or zero dimensions won't be captured
259
+ - **SVG internals**: Only the outer `<svg>` element is captured, not internal paths/shapes
260
+
261
+ ## 🚧 Roadmap
262
+
263
+ - [x] Dynamic data support via `templateProps`
264
+ - [x] Auto border-radius detection
265
+ - [x] Container background visibility
266
+ - [ ] Better async component support
267
+ - [ ] Customizable shimmer direction (vertical, diagonal)
268
+ - [ ] React Native support
269
+ - [ ] Vue.js adapter
270
+
271
+ ---
272
+
273
+ Made with ❤️ for developers tired of maintaining skeleton screens
@@ -0,0 +1,6 @@
1
+ import { default as React } from 'react';
2
+ import { ShimmerProps } from './types';
3
+ /**
4
+ * Shimmer component that adapts to the actual rendered structure of its children
5
+ */
6
+ export declare const Shimmer: React.FC<ShimmerProps>;
@@ -0,0 +1,2 @@
1
+ export { Shimmer } from './Shimmer';
2
+ export type { ShimmerProps, ElementInfo } from './types';
package/dist/index.esm ADDED
@@ -0,0 +1,762 @@
1
+ import I, { useState as dr, useRef as xe, useLayoutEffect as vr } from "react";
2
+ var ee = { exports: {} }, L = {};
3
+ /**
4
+ * @license React
5
+ * react-jsx-runtime.production.min.js
6
+ *
7
+ * Copyright (c) Facebook, Inc. and its affiliates.
8
+ *
9
+ * This source code is licensed under the MIT license found in the
10
+ * LICENSE file in the root directory of this source tree.
11
+ */
12
+ var Se;
13
+ function pr() {
14
+ if (Se) return L;
15
+ Se = 1;
16
+ var f = I, d = Symbol.for("react.element"), R = Symbol.for("react.fragment"), h = Object.prototype.hasOwnProperty, T = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, S = { key: !0, ref: !0, __self: !0, __source: !0 };
17
+ function _(C, v, O) {
18
+ var p, b = {}, s = null, w = null;
19
+ O !== void 0 && (s = "" + O), v.key !== void 0 && (s = "" + v.key), v.ref !== void 0 && (w = v.ref);
20
+ for (p in v) h.call(v, p) && !S.hasOwnProperty(p) && (b[p] = v[p]);
21
+ if (C && C.defaultProps) for (p in v = C.defaultProps, v) b[p] === void 0 && (b[p] = v[p]);
22
+ return { $$typeof: d, type: C, key: s, ref: w, props: b, _owner: T.current };
23
+ }
24
+ return L.Fragment = R, L.jsx = _, L.jsxs = _, L;
25
+ }
26
+ var V = {};
27
+ /**
28
+ * @license React
29
+ * react-jsx-runtime.development.js
30
+ *
31
+ * Copyright (c) Facebook, Inc. and its affiliates.
32
+ *
33
+ * This source code is licensed under the MIT license found in the
34
+ * LICENSE file in the root directory of this source tree.
35
+ */
36
+ var Oe;
37
+ function hr() {
38
+ return Oe || (Oe = 1, process.env.NODE_ENV !== "production" && function() {
39
+ var f = I, d = Symbol.for("react.element"), R = Symbol.for("react.portal"), h = Symbol.for("react.fragment"), T = Symbol.for("react.strict_mode"), S = Symbol.for("react.profiler"), _ = Symbol.for("react.provider"), C = Symbol.for("react.context"), v = Symbol.for("react.forward_ref"), O = Symbol.for("react.suspense"), p = Symbol.for("react.suspense_list"), b = Symbol.for("react.memo"), s = Symbol.for("react.lazy"), w = Symbol.for("react.offscreen"), A = Symbol.iterator, J = "@@iterator";
40
+ function Pe(e) {
41
+ if (e === null || typeof e != "object")
42
+ return null;
43
+ var r = A && e[A] || e[J];
44
+ return typeof r == "function" ? r : null;
45
+ }
46
+ var D = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
47
+ function m(e) {
48
+ {
49
+ for (var r = arguments.length, t = new Array(r > 1 ? r - 1 : 0), n = 1; n < r; n++)
50
+ t[n - 1] = arguments[n];
51
+ ke("error", e, t);
52
+ }
53
+ }
54
+ function ke(e, r, t) {
55
+ {
56
+ var n = D.ReactDebugCurrentFrame, o = n.getStackAddendum();
57
+ o !== "" && (r += "%s", t = t.concat([o]));
58
+ var u = t.map(function(i) {
59
+ return String(i);
60
+ });
61
+ u.unshift("Warning: " + r), Function.prototype.apply.call(console[e], console, u);
62
+ }
63
+ }
64
+ var Ae = !1, De = !1, Fe = !1, $e = !1, Ie = !1, re;
65
+ re = Symbol.for("react.module.reference");
66
+ function We(e) {
67
+ return !!(typeof e == "string" || typeof e == "function" || e === h || e === S || Ie || e === T || e === O || e === p || $e || e === w || Ae || De || Fe || typeof e == "object" && e !== null && (e.$$typeof === s || e.$$typeof === b || e.$$typeof === _ || e.$$typeof === C || e.$$typeof === v || // This needs to include all possible module reference object
68
+ // types supported by any Flight configuration anywhere since
69
+ // we don't know which Flight build this will end up being used
70
+ // with.
71
+ e.$$typeof === re || e.getModuleId !== void 0));
72
+ }
73
+ function Ye(e, r, t) {
74
+ var n = e.displayName;
75
+ if (n)
76
+ return n;
77
+ var o = r.displayName || r.name || "";
78
+ return o !== "" ? t + "(" + o + ")" : t;
79
+ }
80
+ function te(e) {
81
+ return e.displayName || "Context";
82
+ }
83
+ function j(e) {
84
+ if (e == null)
85
+ return null;
86
+ if (typeof e.tag == "number" && m("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof e == "function")
87
+ return e.displayName || e.name || null;
88
+ if (typeof e == "string")
89
+ return e;
90
+ switch (e) {
91
+ case h:
92
+ return "Fragment";
93
+ case R:
94
+ return "Portal";
95
+ case S:
96
+ return "Profiler";
97
+ case T:
98
+ return "StrictMode";
99
+ case O:
100
+ return "Suspense";
101
+ case p:
102
+ return "SuspenseList";
103
+ }
104
+ if (typeof e == "object")
105
+ switch (e.$$typeof) {
106
+ case C:
107
+ var r = e;
108
+ return te(r) + ".Consumer";
109
+ case _:
110
+ var t = e;
111
+ return te(t._context) + ".Provider";
112
+ case v:
113
+ return Ye(e, e.render, "ForwardRef");
114
+ case b:
115
+ var n = e.displayName || null;
116
+ return n !== null ? n : j(e.type) || "Memo";
117
+ case s: {
118
+ var o = e, u = o._payload, i = o._init;
119
+ try {
120
+ return j(i(u));
121
+ } catch {
122
+ return null;
123
+ }
124
+ }
125
+ }
126
+ return null;
127
+ }
128
+ var P = Object.assign, W = 0, ne, ae, ie, oe, ue, se, le;
129
+ function ce() {
130
+ }
131
+ ce.__reactDisabledLog = !0;
132
+ function Le() {
133
+ {
134
+ if (W === 0) {
135
+ ne = console.log, ae = console.info, ie = console.warn, oe = console.error, ue = console.group, se = console.groupCollapsed, le = console.groupEnd;
136
+ var e = {
137
+ configurable: !0,
138
+ enumerable: !0,
139
+ value: ce,
140
+ writable: !0
141
+ };
142
+ Object.defineProperties(console, {
143
+ info: e,
144
+ log: e,
145
+ warn: e,
146
+ error: e,
147
+ group: e,
148
+ groupCollapsed: e,
149
+ groupEnd: e
150
+ });
151
+ }
152
+ W++;
153
+ }
154
+ }
155
+ function Ve() {
156
+ {
157
+ if (W--, W === 0) {
158
+ var e = {
159
+ configurable: !0,
160
+ enumerable: !0,
161
+ writable: !0
162
+ };
163
+ Object.defineProperties(console, {
164
+ log: P({}, e, {
165
+ value: ne
166
+ }),
167
+ info: P({}, e, {
168
+ value: ae
169
+ }),
170
+ warn: P({}, e, {
171
+ value: ie
172
+ }),
173
+ error: P({}, e, {
174
+ value: oe
175
+ }),
176
+ group: P({}, e, {
177
+ value: ue
178
+ }),
179
+ groupCollapsed: P({}, e, {
180
+ value: se
181
+ }),
182
+ groupEnd: P({}, e, {
183
+ value: le
184
+ })
185
+ });
186
+ }
187
+ W < 0 && m("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
188
+ }
189
+ }
190
+ var K = D.ReactCurrentDispatcher, q;
191
+ function M(e, r, t) {
192
+ {
193
+ if (q === void 0)
194
+ try {
195
+ throw Error();
196
+ } catch (o) {
197
+ var n = o.stack.trim().match(/\n( *(at )?)/);
198
+ q = n && n[1] || "";
199
+ }
200
+ return `
201
+ ` + q + e;
202
+ }
203
+ }
204
+ var X = !1, N;
205
+ {
206
+ var Me = typeof WeakMap == "function" ? WeakMap : Map;
207
+ N = new Me();
208
+ }
209
+ function fe(e, r) {
210
+ if (!e || X)
211
+ return "";
212
+ {
213
+ var t = N.get(e);
214
+ if (t !== void 0)
215
+ return t;
216
+ }
217
+ var n;
218
+ X = !0;
219
+ var o = Error.prepareStackTrace;
220
+ Error.prepareStackTrace = void 0;
221
+ var u;
222
+ u = K.current, K.current = null, Le();
223
+ try {
224
+ if (r) {
225
+ var i = function() {
226
+ throw Error();
227
+ };
228
+ if (Object.defineProperty(i.prototype, "props", {
229
+ set: function() {
230
+ throw Error();
231
+ }
232
+ }), typeof Reflect == "object" && Reflect.construct) {
233
+ try {
234
+ Reflect.construct(i, []);
235
+ } catch (y) {
236
+ n = y;
237
+ }
238
+ Reflect.construct(e, [], i);
239
+ } else {
240
+ try {
241
+ i.call();
242
+ } catch (y) {
243
+ n = y;
244
+ }
245
+ e.call(i.prototype);
246
+ }
247
+ } else {
248
+ try {
249
+ throw Error();
250
+ } catch (y) {
251
+ n = y;
252
+ }
253
+ e();
254
+ }
255
+ } catch (y) {
256
+ if (y && n && typeof y.stack == "string") {
257
+ for (var a = y.stack.split(`
258
+ `), g = n.stack.split(`
259
+ `), l = a.length - 1, c = g.length - 1; l >= 1 && c >= 0 && a[l] !== g[c]; )
260
+ c--;
261
+ for (; l >= 1 && c >= 0; l--, c--)
262
+ if (a[l] !== g[c]) {
263
+ if (l !== 1 || c !== 1)
264
+ do
265
+ if (l--, c--, c < 0 || a[l] !== g[c]) {
266
+ var E = `
267
+ ` + a[l].replace(" at new ", " at ");
268
+ return e.displayName && E.includes("<anonymous>") && (E = E.replace("<anonymous>", e.displayName)), typeof e == "function" && N.set(e, E), E;
269
+ }
270
+ while (l >= 1 && c >= 0);
271
+ break;
272
+ }
273
+ }
274
+ } finally {
275
+ X = !1, K.current = u, Ve(), Error.prepareStackTrace = o;
276
+ }
277
+ var $ = e ? e.displayName || e.name : "", k = $ ? M($) : "";
278
+ return typeof e == "function" && N.set(e, k), k;
279
+ }
280
+ function Ne(e, r, t) {
281
+ return fe(e, !1);
282
+ }
283
+ function Ue(e) {
284
+ var r = e.prototype;
285
+ return !!(r && r.isReactComponent);
286
+ }
287
+ function U(e, r, t) {
288
+ if (e == null)
289
+ return "";
290
+ if (typeof e == "function")
291
+ return fe(e, Ue(e));
292
+ if (typeof e == "string")
293
+ return M(e);
294
+ switch (e) {
295
+ case O:
296
+ return M("Suspense");
297
+ case p:
298
+ return M("SuspenseList");
299
+ }
300
+ if (typeof e == "object")
301
+ switch (e.$$typeof) {
302
+ case v:
303
+ return Ne(e.render);
304
+ case b:
305
+ return U(e.type, r, t);
306
+ case s: {
307
+ var n = e, o = n._payload, u = n._init;
308
+ try {
309
+ return U(u(o), r, t);
310
+ } catch {
311
+ }
312
+ }
313
+ }
314
+ return "";
315
+ }
316
+ var Y = Object.prototype.hasOwnProperty, de = {}, ve = D.ReactDebugCurrentFrame;
317
+ function B(e) {
318
+ if (e) {
319
+ var r = e._owner, t = U(e.type, e._source, r ? r.type : null);
320
+ ve.setExtraStackFrame(t);
321
+ } else
322
+ ve.setExtraStackFrame(null);
323
+ }
324
+ function Be(e, r, t, n, o) {
325
+ {
326
+ var u = Function.call.bind(Y);
327
+ for (var i in e)
328
+ if (u(e, i)) {
329
+ var a = void 0;
330
+ try {
331
+ if (typeof e[i] != "function") {
332
+ var g = Error((n || "React class") + ": " + t + " type `" + i + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof e[i] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
333
+ throw g.name = "Invariant Violation", g;
334
+ }
335
+ a = e[i](r, i, n, t, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
336
+ } catch (l) {
337
+ a = l;
338
+ }
339
+ a && !(a instanceof Error) && (B(o), m("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", n || "React class", t, i, typeof a), B(null)), a instanceof Error && !(a.message in de) && (de[a.message] = !0, B(o), m("Failed %s type: %s", t, a.message), B(null));
340
+ }
341
+ }
342
+ }
343
+ var Je = Array.isArray;
344
+ function G(e) {
345
+ return Je(e);
346
+ }
347
+ function Ke(e) {
348
+ {
349
+ var r = typeof Symbol == "function" && Symbol.toStringTag, t = r && e[Symbol.toStringTag] || e.constructor.name || "Object";
350
+ return t;
351
+ }
352
+ }
353
+ function qe(e) {
354
+ try {
355
+ return pe(e), !1;
356
+ } catch {
357
+ return !0;
358
+ }
359
+ }
360
+ function pe(e) {
361
+ return "" + e;
362
+ }
363
+ function he(e) {
364
+ if (qe(e))
365
+ return m("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", Ke(e)), pe(e);
366
+ }
367
+ var me = D.ReactCurrentOwner, Xe = {
368
+ key: !0,
369
+ ref: !0,
370
+ __self: !0,
371
+ __source: !0
372
+ }, ge, ye;
373
+ function Ge(e) {
374
+ if (Y.call(e, "ref")) {
375
+ var r = Object.getOwnPropertyDescriptor(e, "ref").get;
376
+ if (r && r.isReactWarning)
377
+ return !1;
378
+ }
379
+ return e.ref !== void 0;
380
+ }
381
+ function ze(e) {
382
+ if (Y.call(e, "key")) {
383
+ var r = Object.getOwnPropertyDescriptor(e, "key").get;
384
+ if (r && r.isReactWarning)
385
+ return !1;
386
+ }
387
+ return e.key !== void 0;
388
+ }
389
+ function He(e, r) {
390
+ typeof e.ref == "string" && me.current;
391
+ }
392
+ function Ze(e, r) {
393
+ {
394
+ var t = function() {
395
+ ge || (ge = !0, m("%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://reactjs.org/link/special-props)", r));
396
+ };
397
+ t.isReactWarning = !0, Object.defineProperty(e, "key", {
398
+ get: t,
399
+ configurable: !0
400
+ });
401
+ }
402
+ }
403
+ function Qe(e, r) {
404
+ {
405
+ var t = function() {
406
+ ye || (ye = !0, m("%s: `ref` 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://reactjs.org/link/special-props)", r));
407
+ };
408
+ t.isReactWarning = !0, Object.defineProperty(e, "ref", {
409
+ get: t,
410
+ configurable: !0
411
+ });
412
+ }
413
+ }
414
+ var er = function(e, r, t, n, o, u, i) {
415
+ var a = {
416
+ // This tag allows us to uniquely identify this as a React Element
417
+ $$typeof: d,
418
+ // Built-in properties that belong on the element
419
+ type: e,
420
+ key: r,
421
+ ref: t,
422
+ props: i,
423
+ // Record the component responsible for creating this element.
424
+ _owner: u
425
+ };
426
+ return a._store = {}, Object.defineProperty(a._store, "validated", {
427
+ configurable: !1,
428
+ enumerable: !1,
429
+ writable: !0,
430
+ value: !1
431
+ }), Object.defineProperty(a, "_self", {
432
+ configurable: !1,
433
+ enumerable: !1,
434
+ writable: !1,
435
+ value: n
436
+ }), Object.defineProperty(a, "_source", {
437
+ configurable: !1,
438
+ enumerable: !1,
439
+ writable: !1,
440
+ value: o
441
+ }), Object.freeze && (Object.freeze(a.props), Object.freeze(a)), a;
442
+ };
443
+ function rr(e, r, t, n, o) {
444
+ {
445
+ var u, i = {}, a = null, g = null;
446
+ t !== void 0 && (he(t), a = "" + t), ze(r) && (he(r.key), a = "" + r.key), Ge(r) && (g = r.ref, He(r, o));
447
+ for (u in r)
448
+ Y.call(r, u) && !Xe.hasOwnProperty(u) && (i[u] = r[u]);
449
+ if (e && e.defaultProps) {
450
+ var l = e.defaultProps;
451
+ for (u in l)
452
+ i[u] === void 0 && (i[u] = l[u]);
453
+ }
454
+ if (a || g) {
455
+ var c = typeof e == "function" ? e.displayName || e.name || "Unknown" : e;
456
+ a && Ze(i, c), g && Qe(i, c);
457
+ }
458
+ return er(e, a, g, o, n, me.current, i);
459
+ }
460
+ }
461
+ var z = D.ReactCurrentOwner, be = D.ReactDebugCurrentFrame;
462
+ function F(e) {
463
+ if (e) {
464
+ var r = e._owner, t = U(e.type, e._source, r ? r.type : null);
465
+ be.setExtraStackFrame(t);
466
+ } else
467
+ be.setExtraStackFrame(null);
468
+ }
469
+ var H;
470
+ H = !1;
471
+ function Z(e) {
472
+ return typeof e == "object" && e !== null && e.$$typeof === d;
473
+ }
474
+ function Ee() {
475
+ {
476
+ if (z.current) {
477
+ var e = j(z.current.type);
478
+ if (e)
479
+ return `
480
+
481
+ Check the render method of \`` + e + "`.";
482
+ }
483
+ return "";
484
+ }
485
+ }
486
+ function tr(e) {
487
+ return "";
488
+ }
489
+ var Re = {};
490
+ function nr(e) {
491
+ {
492
+ var r = Ee();
493
+ if (!r) {
494
+ var t = typeof e == "string" ? e : e.displayName || e.name;
495
+ t && (r = `
496
+
497
+ Check the top-level render call using <` + t + ">.");
498
+ }
499
+ return r;
500
+ }
501
+ }
502
+ function _e(e, r) {
503
+ {
504
+ if (!e._store || e._store.validated || e.key != null)
505
+ return;
506
+ e._store.validated = !0;
507
+ var t = nr(r);
508
+ if (Re[t])
509
+ return;
510
+ Re[t] = !0;
511
+ var n = "";
512
+ e && e._owner && e._owner !== z.current && (n = " It was passed a child from " + j(e._owner.type) + "."), F(e), m('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', t, n), F(null);
513
+ }
514
+ }
515
+ function we(e, r) {
516
+ {
517
+ if (typeof e != "object")
518
+ return;
519
+ if (G(e))
520
+ for (var t = 0; t < e.length; t++) {
521
+ var n = e[t];
522
+ Z(n) && _e(n, r);
523
+ }
524
+ else if (Z(e))
525
+ e._store && (e._store.validated = !0);
526
+ else if (e) {
527
+ var o = Pe(e);
528
+ if (typeof o == "function" && o !== e.entries)
529
+ for (var u = o.call(e), i; !(i = u.next()).done; )
530
+ Z(i.value) && _e(i.value, r);
531
+ }
532
+ }
533
+ }
534
+ function ar(e) {
535
+ {
536
+ var r = e.type;
537
+ if (r == null || typeof r == "string")
538
+ return;
539
+ var t;
540
+ if (typeof r == "function")
541
+ t = r.propTypes;
542
+ else if (typeof r == "object" && (r.$$typeof === v || // Note: Memo only checks outer props here.
543
+ // Inner props are checked in the reconciler.
544
+ r.$$typeof === b))
545
+ t = r.propTypes;
546
+ else
547
+ return;
548
+ if (t) {
549
+ var n = j(r);
550
+ Be(t, e.props, "prop", n, e);
551
+ } else if (r.PropTypes !== void 0 && !H) {
552
+ H = !0;
553
+ var o = j(r);
554
+ m("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", o || "Unknown");
555
+ }
556
+ typeof r.getDefaultProps == "function" && !r.getDefaultProps.isReactClassApproved && m("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
557
+ }
558
+ }
559
+ function ir(e) {
560
+ {
561
+ for (var r = Object.keys(e.props), t = 0; t < r.length; t++) {
562
+ var n = r[t];
563
+ if (n !== "children" && n !== "key") {
564
+ F(e), m("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", n), F(null);
565
+ break;
566
+ }
567
+ }
568
+ e.ref !== null && (F(e), m("Invalid attribute `ref` supplied to `React.Fragment`."), F(null));
569
+ }
570
+ }
571
+ var Te = {};
572
+ function Ce(e, r, t, n, o, u) {
573
+ {
574
+ var i = We(e);
575
+ if (!i) {
576
+ var a = "";
577
+ (e === void 0 || typeof e == "object" && e !== null && Object.keys(e).length === 0) && (a += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
578
+ var g = tr();
579
+ g ? a += g : a += Ee();
580
+ var l;
581
+ e === null ? l = "null" : G(e) ? l = "array" : e !== void 0 && e.$$typeof === d ? (l = "<" + (j(e.type) || "Unknown") + " />", a = " Did you accidentally export a JSX literal instead of a component?") : l = typeof e, m("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", l, a);
582
+ }
583
+ var c = rr(e, r, t, o, u);
584
+ if (c == null)
585
+ return c;
586
+ if (i) {
587
+ var E = r.children;
588
+ if (E !== void 0)
589
+ if (n)
590
+ if (G(E)) {
591
+ for (var $ = 0; $ < E.length; $++)
592
+ we(E[$], e);
593
+ Object.freeze && Object.freeze(E);
594
+ } else
595
+ m("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
596
+ else
597
+ we(E, e);
598
+ }
599
+ if (Y.call(r, "key")) {
600
+ var k = j(e), y = Object.keys(r).filter(function(fr) {
601
+ return fr !== "key";
602
+ }), Q = y.length > 0 ? "{key: someKey, " + y.join(": ..., ") + ": ...}" : "{key: someKey}";
603
+ if (!Te[k + Q]) {
604
+ var cr = y.length > 0 ? "{" + y.join(": ..., ") + ": ...}" : "{}";
605
+ m(`A props object containing a "key" prop is being spread into JSX:
606
+ let props = %s;
607
+ <%s {...props} />
608
+ React keys must be passed directly to JSX without using spread:
609
+ let props = %s;
610
+ <%s key={someKey} {...props} />`, Q, k, cr, k), Te[k + Q] = !0;
611
+ }
612
+ }
613
+ return e === h ? ir(c) : ar(c), c;
614
+ }
615
+ }
616
+ function or(e, r, t) {
617
+ return Ce(e, r, t, !0);
618
+ }
619
+ function ur(e, r, t) {
620
+ return Ce(e, r, t, !1);
621
+ }
622
+ var sr = ur, lr = or;
623
+ V.Fragment = h, V.jsx = sr, V.jsxs = lr;
624
+ }()), V;
625
+ }
626
+ process.env.NODE_ENV === "production" ? ee.exports = pr() : ee.exports = hr();
627
+ var x = ee.exports;
628
+ function mr(f) {
629
+ const d = f.tagName.toLowerCase();
630
+ return !!(["img", "svg", "video", "canvas", "iframe", "input", "textarea", "button"].includes(d) || !(Array.from(f.children).length > 0));
631
+ }
632
+ function je(f, d) {
633
+ const R = [], h = f.getBoundingClientRect();
634
+ if (h.width === 0 || h.height === 0)
635
+ return R;
636
+ if (mr(f)) {
637
+ const S = window.getComputedStyle(f).borderRadius || "0px", _ = {
638
+ x: h.left - d.left,
639
+ y: h.top - d.top,
640
+ width: h.width,
641
+ height: h.height,
642
+ tag: f.tagName.toLowerCase(),
643
+ borderRadius: S
644
+ };
645
+ R.push(_);
646
+ } else
647
+ Array.from(f.children).forEach((T) => {
648
+ R.push(...je(T, d));
649
+ });
650
+ return R;
651
+ }
652
+ const yr = ({
653
+ children: f,
654
+ loading: d = !0,
655
+ shimmerColor: R = "rgba(255, 255, 255, 0.15)",
656
+ backgroundColor: h = "rgba(255, 255, 255, 0.08)",
657
+ duration: T = 1.5,
658
+ fallbackBorderRadius: S = 4,
659
+ templateProps: _
660
+ }) => {
661
+ const [C, v] = dr([]), O = xe(null), p = xe(null), b = I.useMemo(() => {
662
+ if (!d || !_)
663
+ return f;
664
+ const s = I.Children.toArray(f);
665
+ if (s.length === 0)
666
+ return f;
667
+ const w = s[0];
668
+ return I.isValidElement(w) ? [I.cloneElement(w, {
669
+ ..._
670
+ }), ...s.slice(1)] : f;
671
+ }, [f, d, _]);
672
+ return vr(() => {
673
+ if (!d || !p.current) return;
674
+ const s = p.current, w = s.getBoundingClientRect(), A = [];
675
+ Array.from(s.children).forEach((J) => {
676
+ A.push(...je(J, w));
677
+ }), v(A);
678
+ }, [d, b]), d ? /* @__PURE__ */ x.jsxs("div", { style: { position: "relative" }, children: [
679
+ /* @__PURE__ */ x.jsx("style", { children: `
680
+ .shimmer-measure-container * {
681
+ color: transparent !important;
682
+ border-color: transparent !important;
683
+ }
684
+ .shimmer-measure-container img,
685
+ .shimmer-measure-container svg,
686
+ .shimmer-measure-container video {
687
+ opacity: 0;
688
+ }
689
+ ` }),
690
+ /* @__PURE__ */ x.jsx(
691
+ "div",
692
+ {
693
+ ref: p,
694
+ className: "shimmer-measure-container",
695
+ style: {
696
+ pointerEvents: "none"
697
+ },
698
+ "aria-hidden": "true",
699
+ children: b
700
+ }
701
+ ),
702
+ /* @__PURE__ */ x.jsxs(
703
+ "div",
704
+ {
705
+ ref: O,
706
+ style: {
707
+ position: "absolute",
708
+ top: 0,
709
+ left: 0,
710
+ right: 0,
711
+ bottom: 0,
712
+ overflow: "hidden"
713
+ },
714
+ children: [
715
+ /* @__PURE__ */ x.jsx("style", { children: `
716
+ @keyframes shimmer {
717
+ 0% {
718
+ transform: translateX(-100%);
719
+ }
720
+ 100% {
721
+ transform: translateX(100%);
722
+ }
723
+ }
724
+ ` }),
725
+ C.map((s, w) => /* @__PURE__ */ x.jsx(
726
+ "div",
727
+ {
728
+ style: {
729
+ position: "absolute",
730
+ left: `${s.x}px`,
731
+ top: `${s.y}px`,
732
+ width: `${s.width}px`,
733
+ height: `${s.height}px`,
734
+ backgroundColor: h,
735
+ borderRadius: s.borderRadius === "0px" ? `${S}px` : s.borderRadius,
736
+ overflow: "hidden"
737
+ },
738
+ children: /* @__PURE__ */ x.jsx(
739
+ "div",
740
+ {
741
+ style: {
742
+ position: "absolute",
743
+ top: 0,
744
+ left: 0,
745
+ width: "100%",
746
+ height: "100%",
747
+ background: `linear-gradient(90deg, transparent, ${R}, transparent)`,
748
+ animation: `shimmer ${T}s infinite`
749
+ }
750
+ }
751
+ )
752
+ },
753
+ w
754
+ ))
755
+ ]
756
+ }
757
+ )
758
+ ] }) : /* @__PURE__ */ x.jsx(x.Fragment, { children: f });
759
+ };
760
+ export {
761
+ yr as Shimmer
762
+ };
package/dist/index.js ADDED
@@ -0,0 +1,49 @@
1
+ (function(k,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],y):(k=typeof globalThis<"u"?globalThis:k||self,y(k.ShimmerFromStructure={},k.React))})(this,function(k,y){"use strict";var q={exports:{}},Y={};/**
2
+ * @license React
3
+ * react-jsx-runtime.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */var te;function Pe(){if(te)return Y;te=1;var c=y,d=Symbol.for("react.element"),_=Symbol.for("react.fragment"),h=Object.prototype.hasOwnProperty,x=c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,O={key:!0,ref:!0,__self:!0,__source:!0};function T(C,v,j){var p,E={},s=null,w=null;j!==void 0&&(s=""+j),v.key!==void 0&&(s=""+v.key),v.ref!==void 0&&(w=v.ref);for(p in v)h.call(v,p)&&!O.hasOwnProperty(p)&&(E[p]=v[p]);if(C&&C.defaultProps)for(p in v=C.defaultProps,v)E[p]===void 0&&(E[p]=v[p]);return{$$typeof:d,type:C,key:s,ref:w,props:E,_owner:x.current}}return Y.Fragment=_,Y.jsx=T,Y.jsxs=T,Y}var L={};/**
10
+ * @license React
11
+ * react-jsx-runtime.development.js
12
+ *
13
+ * Copyright (c) Facebook, Inc. and its affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */var ne;function ke(){return ne||(ne=1,process.env.NODE_ENV!=="production"&&function(){var c=y,d=Symbol.for("react.element"),_=Symbol.for("react.portal"),h=Symbol.for("react.fragment"),x=Symbol.for("react.strict_mode"),O=Symbol.for("react.profiler"),T=Symbol.for("react.provider"),C=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),j=Symbol.for("react.suspense"),p=Symbol.for("react.suspense_list"),E=Symbol.for("react.memo"),s=Symbol.for("react.lazy"),w=Symbol.for("react.offscreen"),D=Symbol.iterator,K="@@iterator";function De(e){if(e===null||typeof e!="object")return null;var r=D&&e[D]||e[K];return typeof r=="function"?r:null}var $=c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function m(e){{for(var r=arguments.length,t=new Array(r>1?r-1:0),n=1;n<r;n++)t[n-1]=arguments[n];$e("error",e,t)}}function $e(e,r,t){{var n=$.ReactDebugCurrentFrame,o=n.getStackAddendum();o!==""&&(r+="%s",t=t.concat([o]));var u=t.map(function(i){return String(i)});u.unshift("Warning: "+r),Function.prototype.apply.call(console[e],console,u)}}var Ie=!1,We=!1,Ye=!1,Le=!1,Me=!1,ie;ie=Symbol.for("react.module.reference");function Ve(e){return!!(typeof e=="string"||typeof e=="function"||e===h||e===O||Me||e===x||e===j||e===p||Le||e===w||Ie||We||Ye||typeof e=="object"&&e!==null&&(e.$$typeof===s||e.$$typeof===E||e.$$typeof===T||e.$$typeof===C||e.$$typeof===v||e.$$typeof===ie||e.getModuleId!==void 0))}function Ne(e,r,t){var n=e.displayName;if(n)return n;var o=r.displayName||r.name||"";return o!==""?t+"("+o+")":t}function oe(e){return e.displayName||"Context"}function P(e){if(e==null)return null;if(typeof e.tag=="number"&&m("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case h:return"Fragment";case _:return"Portal";case O:return"Profiler";case x:return"StrictMode";case j:return"Suspense";case p:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case C:var r=e;return oe(r)+".Consumer";case T:var t=e;return oe(t._context)+".Provider";case v:return Ne(e,e.render,"ForwardRef");case E:var n=e.displayName||null;return n!==null?n:P(e.type)||"Memo";case s:{var o=e,u=o._payload,i=o._init;try{return P(i(u))}catch{return null}}}return null}var A=Object.assign,M=0,ue,se,le,fe,ce,de,ve;function pe(){}pe.__reactDisabledLog=!0;function Ue(){{if(M===0){ue=console.log,se=console.info,le=console.warn,fe=console.error,ce=console.group,de=console.groupCollapsed,ve=console.groupEnd;var e={configurable:!0,enumerable:!0,value:pe,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}M++}}function Be(){{if(M--,M===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:A({},e,{value:ue}),info:A({},e,{value:se}),warn:A({},e,{value:le}),error:A({},e,{value:fe}),group:A({},e,{value:ce}),groupCollapsed:A({},e,{value:de}),groupEnd:A({},e,{value:ve})})}M<0&&m("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var X=$.ReactCurrentDispatcher,G;function N(e,r,t){{if(G===void 0)try{throw Error()}catch(o){var n=o.stack.trim().match(/\n( *(at )?)/);G=n&&n[1]||""}return`
18
+ `+G+e}}var z=!1,U;{var Je=typeof WeakMap=="function"?WeakMap:Map;U=new Je}function he(e,r){if(!e||z)return"";{var t=U.get(e);if(t!==void 0)return t}var n;z=!0;var o=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var u;u=X.current,X.current=null,Ue();try{if(r){var i=function(){throw Error()};if(Object.defineProperty(i.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(i,[])}catch(b){n=b}Reflect.construct(e,[],i)}else{try{i.call()}catch(b){n=b}e.call(i.prototype)}}else{try{throw Error()}catch(b){n=b}e()}}catch(b){if(b&&n&&typeof b.stack=="string"){for(var a=b.stack.split(`
19
+ `),g=n.stack.split(`
20
+ `),l=a.length-1,f=g.length-1;l>=1&&f>=0&&a[l]!==g[f];)f--;for(;l>=1&&f>=0;l--,f--)if(a[l]!==g[f]){if(l!==1||f!==1)do if(l--,f--,f<0||a[l]!==g[f]){var R=`
21
+ `+a[l].replace(" at new "," at ");return e.displayName&&R.includes("<anonymous>")&&(R=R.replace("<anonymous>",e.displayName)),typeof e=="function"&&U.set(e,R),R}while(l>=1&&f>=0);break}}}finally{z=!1,X.current=u,Be(),Error.prepareStackTrace=o}var W=e?e.displayName||e.name:"",F=W?N(W):"";return typeof e=="function"&&U.set(e,F),F}function qe(e,r,t){return he(e,!1)}function Ke(e){var r=e.prototype;return!!(r&&r.isReactComponent)}function B(e,r,t){if(e==null)return"";if(typeof e=="function")return he(e,Ke(e));if(typeof e=="string")return N(e);switch(e){case j:return N("Suspense");case p:return N("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case v:return qe(e.render);case E:return B(e.type,r,t);case s:{var n=e,o=n._payload,u=n._init;try{return B(u(o),r,t)}catch{}}}return""}var V=Object.prototype.hasOwnProperty,me={},ge=$.ReactDebugCurrentFrame;function J(e){if(e){var r=e._owner,t=B(e.type,e._source,r?r.type:null);ge.setExtraStackFrame(t)}else ge.setExtraStackFrame(null)}function Xe(e,r,t,n,o){{var u=Function.call.bind(V);for(var i in e)if(u(e,i)){var a=void 0;try{if(typeof e[i]!="function"){var g=Error((n||"React class")+": "+t+" type `"+i+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[i]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw g.name="Invariant Violation",g}a=e[i](r,i,n,t,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(l){a=l}a&&!(a instanceof Error)&&(J(o),m("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",n||"React class",t,i,typeof a),J(null)),a instanceof Error&&!(a.message in me)&&(me[a.message]=!0,J(o),m("Failed %s type: %s",t,a.message),J(null))}}}var Ge=Array.isArray;function H(e){return Ge(e)}function ze(e){{var r=typeof Symbol=="function"&&Symbol.toStringTag,t=r&&e[Symbol.toStringTag]||e.constructor.name||"Object";return t}}function He(e){try{return ye(e),!1}catch{return!0}}function ye(e){return""+e}function be(e){if(He(e))return m("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",ze(e)),ye(e)}var Ee=$.ReactCurrentOwner,Ze={key:!0,ref:!0,__self:!0,__source:!0},Re,_e;function Qe(e){if(V.call(e,"ref")){var r=Object.getOwnPropertyDescriptor(e,"ref").get;if(r&&r.isReactWarning)return!1}return e.ref!==void 0}function er(e){if(V.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function rr(e,r){typeof e.ref=="string"&&Ee.current}function tr(e,r){{var t=function(){Re||(Re=!0,m("%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://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}}function nr(e,r){{var t=function(){_e||(_e=!0,m("%s: `ref` 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://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"ref",{get:t,configurable:!0})}}var ar=function(e,r,t,n,o,u,i){var a={$$typeof:d,type:e,key:r,ref:t,props:i,_owner:u};return a._store={},Object.defineProperty(a._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(a,"_self",{configurable:!1,enumerable:!1,writable:!1,value:n}),Object.defineProperty(a,"_source",{configurable:!1,enumerable:!1,writable:!1,value:o}),Object.freeze&&(Object.freeze(a.props),Object.freeze(a)),a};function ir(e,r,t,n,o){{var u,i={},a=null,g=null;t!==void 0&&(be(t),a=""+t),er(r)&&(be(r.key),a=""+r.key),Qe(r)&&(g=r.ref,rr(r,o));for(u in r)V.call(r,u)&&!Ze.hasOwnProperty(u)&&(i[u]=r[u]);if(e&&e.defaultProps){var l=e.defaultProps;for(u in l)i[u]===void 0&&(i[u]=l[u])}if(a||g){var f=typeof e=="function"?e.displayName||e.name||"Unknown":e;a&&tr(i,f),g&&nr(i,f)}return ar(e,a,g,o,n,Ee.current,i)}}var Z=$.ReactCurrentOwner,Te=$.ReactDebugCurrentFrame;function I(e){if(e){var r=e._owner,t=B(e.type,e._source,r?r.type:null);Te.setExtraStackFrame(t)}else Te.setExtraStackFrame(null)}var Q;Q=!1;function ee(e){return typeof e=="object"&&e!==null&&e.$$typeof===d}function we(){{if(Z.current){var e=P(Z.current.type);if(e)return`
22
+
23
+ Check the render method of \``+e+"`."}return""}}function or(e){return""}var Se={};function ur(e){{var r=we();if(!r){var t=typeof e=="string"?e:e.displayName||e.name;t&&(r=`
24
+
25
+ Check the top-level render call using <`+t+">.")}return r}}function xe(e,r){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var t=ur(r);if(Se[t])return;Se[t]=!0;var n="";e&&e._owner&&e._owner!==Z.current&&(n=" It was passed a child from "+P(e._owner.type)+"."),I(e),m('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',t,n),I(null)}}function Ce(e,r){{if(typeof e!="object")return;if(H(e))for(var t=0;t<e.length;t++){var n=e[t];ee(n)&&xe(n,r)}else if(ee(e))e._store&&(e._store.validated=!0);else if(e){var o=De(e);if(typeof o=="function"&&o!==e.entries)for(var u=o.call(e),i;!(i=u.next()).done;)ee(i.value)&&xe(i.value,r)}}}function sr(e){{var r=e.type;if(r==null||typeof r=="string")return;var t;if(typeof r=="function")t=r.propTypes;else if(typeof r=="object"&&(r.$$typeof===v||r.$$typeof===E))t=r.propTypes;else return;if(t){var n=P(r);Xe(t,e.props,"prop",n,e)}else if(r.PropTypes!==void 0&&!Q){Q=!0;var o=P(r);m("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",o||"Unknown")}typeof r.getDefaultProps=="function"&&!r.getDefaultProps.isReactClassApproved&&m("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function lr(e){{for(var r=Object.keys(e.props),t=0;t<r.length;t++){var n=r[t];if(n!=="children"&&n!=="key"){I(e),m("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",n),I(null);break}}e.ref!==null&&(I(e),m("Invalid attribute `ref` supplied to `React.Fragment`."),I(null))}}var Oe={};function je(e,r,t,n,o,u){{var i=Ve(e);if(!i){var a="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(a+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var g=or();g?a+=g:a+=we();var l;e===null?l="null":H(e)?l="array":e!==void 0&&e.$$typeof===d?(l="<"+(P(e.type)||"Unknown")+" />",a=" Did you accidentally export a JSX literal instead of a component?"):l=typeof e,m("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",l,a)}var f=ir(e,r,t,o,u);if(f==null)return f;if(i){var R=r.children;if(R!==void 0)if(n)if(H(R)){for(var W=0;W<R.length;W++)Ce(R[W],e);Object.freeze&&Object.freeze(R)}else m("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 Ce(R,e)}if(V.call(r,"key")){var F=P(e),b=Object.keys(r).filter(function(hr){return hr!=="key"}),re=b.length>0?"{key: someKey, "+b.join(": ..., ")+": ...}":"{key: someKey}";if(!Oe[F+re]){var pr=b.length>0?"{"+b.join(": ..., ")+": ...}":"{}";m(`A props object containing a "key" prop is being spread into JSX:
26
+ let props = %s;
27
+ <%s {...props} />
28
+ React keys must be passed directly to JSX without using spread:
29
+ let props = %s;
30
+ <%s key={someKey} {...props} />`,re,F,pr,F),Oe[F+re]=!0}}return e===h?lr(f):sr(f),f}}function fr(e,r,t){return je(e,r,t,!0)}function cr(e,r,t){return je(e,r,t,!1)}var dr=cr,vr=fr;L.Fragment=h,L.jsx=dr,L.jsxs=vr}()),L}process.env.NODE_ENV==="production"?q.exports=Pe():q.exports=ke();var S=q.exports;function Ae(c){const d=c.tagName.toLowerCase();return!!(["img","svg","video","canvas","iframe","input","textarea","button"].includes(d)||!(Array.from(c.children).length>0))}function ae(c,d){const _=[],h=c.getBoundingClientRect();if(h.width===0||h.height===0)return _;if(Ae(c)){const O=window.getComputedStyle(c).borderRadius||"0px",T={x:h.left-d.left,y:h.top-d.top,width:h.width,height:h.height,tag:c.tagName.toLowerCase(),borderRadius:O};_.push(T)}else Array.from(c.children).forEach(x=>{_.push(...ae(x,d))});return _}const Fe=({children:c,loading:d=!0,shimmerColor:_="rgba(255, 255, 255, 0.15)",backgroundColor:h="rgba(255, 255, 255, 0.08)",duration:x=1.5,fallbackBorderRadius:O=4,templateProps:T})=>{const[C,v]=y.useState([]),j=y.useRef(null),p=y.useRef(null),E=y.useMemo(()=>{if(!d||!T)return c;const s=y.Children.toArray(c);if(s.length===0)return c;const w=s[0];return y.isValidElement(w)?[y.cloneElement(w,{...T}),...s.slice(1)]:c},[c,d,T]);return y.useLayoutEffect(()=>{if(!d||!p.current)return;const s=p.current,w=s.getBoundingClientRect(),D=[];Array.from(s.children).forEach(K=>{D.push(...ae(K,w))}),v(D)},[d,E]),d?S.jsxs("div",{style:{position:"relative"},children:[S.jsx("style",{children:`
31
+ .shimmer-measure-container * {
32
+ color: transparent !important;
33
+ border-color: transparent !important;
34
+ }
35
+ .shimmer-measure-container img,
36
+ .shimmer-measure-container svg,
37
+ .shimmer-measure-container video {
38
+ opacity: 0;
39
+ }
40
+ `}),S.jsx("div",{ref:p,className:"shimmer-measure-container",style:{pointerEvents:"none"},"aria-hidden":"true",children:E}),S.jsxs("div",{ref:j,style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflow:"hidden"},children:[S.jsx("style",{children:`
41
+ @keyframes shimmer {
42
+ 0% {
43
+ transform: translateX(-100%);
44
+ }
45
+ 100% {
46
+ transform: translateX(100%);
47
+ }
48
+ }
49
+ `}),C.map((s,w)=>S.jsx("div",{style:{position:"absolute",left:`${s.x}px`,top:`${s.y}px`,width:`${s.width}px`,height:`${s.height}px`,backgroundColor:h,borderRadius:s.borderRadius==="0px"?`${O}px`:s.borderRadius,overflow:"hidden"},children:S.jsx("div",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",background:`linear-gradient(90deg, transparent, ${_}, transparent)`,animation:`shimmer ${x}s infinite`}})},w))]})]}):S.jsx(S.Fragment,{children:c})};k.Shimmer=Fe,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,27 @@
1
+ export interface ElementInfo {
2
+ x: number;
3
+ y: number;
4
+ width: number;
5
+ height: number;
6
+ tag: string;
7
+ borderRadius: string;
8
+ }
9
+ export interface ShimmerProps {
10
+ children: React.ReactNode;
11
+ loading?: boolean;
12
+ shimmerColor?: string;
13
+ backgroundColor?: string;
14
+ duration?: number;
15
+ /**
16
+ * Fallback border radius (in pixels) used when an element has no border-radius.
17
+ * Helps avoid square-ish shimmer blocks, especially for text elements.
18
+ * @default 4
19
+ */
20
+ fallbackBorderRadius?: number;
21
+ /**
22
+ * Object mapping prop names to their mock/template values.
23
+ * These props will be injected into the first child when loading.
24
+ * Example: { user: { name: "Lorem" }, settings: { theme: "dark" } }
25
+ */
26
+ templateProps?: Record<string, unknown>;
27
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "shimmer-from-structure",
3
+ "version": "0.1.0",
4
+ "description": "A React shimmer/skeleton library that automatically adapts to your component's runtime structure",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "dev": "vite",
13
+ "build": "tsc && vite build",
14
+ "preview": "vite preview",
15
+ "test": "vitest"
16
+ },
17
+ "keywords": [
18
+ "react",
19
+ "shimmer",
20
+ "skeleton",
21
+ "loading",
22
+ "placeholder",
23
+ "runtime"
24
+ ],
25
+ "author": "",
26
+ "license": "MIT",
27
+ "peerDependencies": {
28
+ "react": "^18.0.0",
29
+ "react-dom": "^18.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@testing-library/jest-dom": "^6.9.1",
33
+ "@testing-library/react": "^16.3.2",
34
+ "@types/node": "^25.0.9",
35
+ "@types/react": "^18.2.0",
36
+ "@types/react-dom": "^18.2.0",
37
+ "@vitejs/plugin-react": "^4.2.1",
38
+ "@vitest/ui": "^4.0.17",
39
+ "jsdom": "^27.4.0",
40
+ "react": "^18.2.0",
41
+ "react-dom": "^18.2.0",
42
+ "typescript": "^5.3.0",
43
+ "vite": "^5.0.0",
44
+ "vite-plugin-dts": "^4.5.4",
45
+ "vitest": "^4.0.17",
46
+ "recharts": "^3.6.0"
47
+ }
48
+ }