shimmer-trace 1.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/AGENTS.md +657 -0
- package/LICENSE +21 -0
- package/README.md +424 -0
- package/dist/index.d.mts +224 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.js +601 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +590 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import React__default, { ReactNode, RefObject } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a measured rectangle of a traced DOM element,
|
|
7
|
+
* positioned relative to the Master Shimmer container.
|
|
8
|
+
*/
|
|
9
|
+
interface ShimmerRect {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
borderRadius: string;
|
|
15
|
+
}
|
|
16
|
+
/** Available animation types for the shimmer effect. */
|
|
17
|
+
type AnimationType = 'wave' | 'pulse' | 'shine' | 'glow' | 'gradient';
|
|
18
|
+
/** Configuration options for the shimmer effect (all optional). */
|
|
19
|
+
interface ShimmerConfig {
|
|
20
|
+
/** Animation style. Defaults to 'wave'. */
|
|
21
|
+
animation?: AnimationType;
|
|
22
|
+
/** Base color of the shimmer blocks. Defaults to '#e0e0e0'. */
|
|
23
|
+
baseColor?: string;
|
|
24
|
+
/** Highlight color of the shimmer animation. Defaults to '#f5f5f5'. */
|
|
25
|
+
highlightColor?: string;
|
|
26
|
+
/** Animation duration in seconds. Defaults to 1.5. */
|
|
27
|
+
speed?: number;
|
|
28
|
+
/** Global border-radius override. If omitted, auto-detected from each element (defaults to 4px if detection is 0px). */
|
|
29
|
+
borderRadius?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Keep container backgrounds, borders, and padding visible while loading.
|
|
32
|
+
* When `true` (default), only text and media leaves are hidden via
|
|
33
|
+
* `color:transparent` / `opacity:0` so card backgrounds, borders, and
|
|
34
|
+
* spacing remain visible underneath the shimmer overlay.
|
|
35
|
+
*
|
|
36
|
+
* Set `false` for legacy behavior (`visibility:hidden` on whole tree).
|
|
37
|
+
*/
|
|
38
|
+
preserveBackground?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Props for the Shimmer component. */
|
|
41
|
+
interface ShimmerProps extends ShimmerConfig {
|
|
42
|
+
/** Whether the loading state is active. */
|
|
43
|
+
loading?: boolean;
|
|
44
|
+
/** The children to trace and render shimmer over. */
|
|
45
|
+
children: ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Number of placeholder clones to generate for list-like loading states.
|
|
48
|
+
*
|
|
49
|
+
* When `loading=true` and `dummyLength` is set, Shimmer grabs the first
|
|
50
|
+
* available child (or a cached template from the last loaded render) and
|
|
51
|
+
* clones it `dummyLength` times to produce skeleton placeholders.
|
|
52
|
+
*
|
|
53
|
+
* When `loading=false`, children are rendered as-is.
|
|
54
|
+
*/
|
|
55
|
+
dummyLength?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Props injected into each child element while `loading=true` so the
|
|
58
|
+
* skeleton renders with realistic shape without requiring real data.
|
|
59
|
+
*
|
|
60
|
+
* Example:
|
|
61
|
+
* ```tsx
|
|
62
|
+
* <Shimmer
|
|
63
|
+
* loading={loading}
|
|
64
|
+
* dummyData={{ user: { name: 'Loading...', role: '...', avatar: '' } }}
|
|
65
|
+
* >
|
|
66
|
+
* <UserCard user={user} />
|
|
67
|
+
* </Shimmer>
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* While loading, each direct child is cloned with these props merged on top
|
|
71
|
+
* of its own props. Ignored when `loading=false`.
|
|
72
|
+
*/
|
|
73
|
+
dummyData?: Record<string, any>;
|
|
74
|
+
/**
|
|
75
|
+
* Component used to auto-generate skeleton elements while `loading=true`.
|
|
76
|
+
*
|
|
77
|
+
* When set, Shimmer ignores `children` during loading and renders
|
|
78
|
+
* `dummyLength` (defaults to 1) instances of `<as {...dummyData} />`
|
|
79
|
+
* to derive shape. Real children render once `loading=false`.
|
|
80
|
+
*
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <Shimmer
|
|
83
|
+
* loading={loading}
|
|
84
|
+
* as={MovieCard}
|
|
85
|
+
* dummyData={{ movie: movieTemplate }}
|
|
86
|
+
* dummyLength={10}
|
|
87
|
+
* >
|
|
88
|
+
* {movies.map((m) => <MovieCard movie={m} key={m.id} />)}
|
|
89
|
+
* </Shimmer>
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
as?: React__default.ComponentType<any>;
|
|
93
|
+
/** Force this Shimmer to be a Master renderer even if nested inside another Shimmer. */
|
|
94
|
+
stopPropagation?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* className applied to the Master container div.
|
|
97
|
+
* Use to control layout (e.g. display:flex) without losing position:relative.
|
|
98
|
+
*/
|
|
99
|
+
className?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Inline styles merged into the Master container div.
|
|
102
|
+
* position:relative is always applied; everything else is overridable.
|
|
103
|
+
*/
|
|
104
|
+
style?: React__default.CSSProperties;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The main Shimmer component.
|
|
109
|
+
*
|
|
110
|
+
* Auto-detects **Master** (no parent Shimmer) vs **Reporter** (nested).
|
|
111
|
+
* - Master: renders children hidden, traces DOM, paints overlay.
|
|
112
|
+
* - Reporter: measures own rects, reports to parent Master.
|
|
113
|
+
*
|
|
114
|
+
* ### Skeleton shape via `dummyData`
|
|
115
|
+
*
|
|
116
|
+
* Pass `dummyData` so children render with realistic data while loading.
|
|
117
|
+
* No render-prop, no manual `data || fallback` in JSX.
|
|
118
|
+
*
|
|
119
|
+
* ```tsx
|
|
120
|
+
* const userTemplate = { name: 'Loading...', role: '...', avatar: '' };
|
|
121
|
+
*
|
|
122
|
+
* <Shimmer loading={loading} dummyData={{ user: userTemplate }}>
|
|
123
|
+
* <UserCard user={user} />
|
|
124
|
+
* </Shimmer>
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* ### List mode (`dummyLength`)
|
|
128
|
+
*
|
|
129
|
+
* Combined with `dummyData`, clones the first child N times with
|
|
130
|
+
* template props merged in:
|
|
131
|
+
*
|
|
132
|
+
* ```tsx
|
|
133
|
+
* <Shimmer
|
|
134
|
+
* loading={loading}
|
|
135
|
+
* dummyLength={5}
|
|
136
|
+
* dummyData={{ fruit: { name: 'xxxxx', price: '$0.00' } }}
|
|
137
|
+
* >
|
|
138
|
+
* <FruitCard fruit={undefined as any} />
|
|
139
|
+
* </Shimmer>
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function Shimmer({ loading, children, dummyLength, dummyData, as, stopPropagation, animation, baseColor, highlightColor, speed, borderRadius, preserveBackground, className, style, }: ShimmerProps): react_jsx_runtime.JSX.Element;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Factory function to create a pre-configured Shimmer component.
|
|
146
|
+
* Avoids "Provider Hell" by baking config into the returned component.
|
|
147
|
+
*
|
|
148
|
+
* All config properties are optional — defaults are used for anything
|
|
149
|
+
* not specified.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const AppShimmer = createShimmer({
|
|
154
|
+
* animation: 'pulse',
|
|
155
|
+
* baseColor: '#1a1a2e',
|
|
156
|
+
* highlightColor: '#16213e',
|
|
157
|
+
* speed: 2,
|
|
158
|
+
* });
|
|
159
|
+
*
|
|
160
|
+
* <AppShimmer loading={isLoading}>
|
|
161
|
+
* <MyComponent />
|
|
162
|
+
* </AppShimmer>
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
declare function createShimmer(config?: ShimmerConfig): (props: Omit<ShimmerProps, keyof ShimmerConfig> & Partial<ShimmerConfig>) => react_jsx_runtime.JSX.Element;
|
|
166
|
+
|
|
167
|
+
interface ShimmerContextValue {
|
|
168
|
+
register: (id: string, rects: ShimmerRect[]) => void;
|
|
169
|
+
unregister: (id: string) => void;
|
|
170
|
+
/** Ref object (not .current) so Reporters always read a fresh value. */
|
|
171
|
+
masterRef: RefObject<HTMLElement | null>;
|
|
172
|
+
loading: boolean;
|
|
173
|
+
config: Required<ShimmerConfig>;
|
|
174
|
+
}
|
|
175
|
+
declare const ShimmerContext: React.Context<ShimmerContextValue | null>;
|
|
176
|
+
declare function useShimmerContext(): ShimmerContextValue | null;
|
|
177
|
+
declare function useIsShimmering(): boolean;
|
|
178
|
+
|
|
179
|
+
interface ShimmerSuspenseProps extends ShimmerConfig {
|
|
180
|
+
children: React__default.ReactNode;
|
|
181
|
+
/**
|
|
182
|
+
* Explicit skeleton template. Rendered hidden and traced for shimmer shape.
|
|
183
|
+
*
|
|
184
|
+
* Preferred — pass the same component with no data props:
|
|
185
|
+
* ```tsx
|
|
186
|
+
* <ShimmerSuspense template={<UserCard />}>
|
|
187
|
+
* <UserCard />
|
|
188
|
+
* </ShimmerSuspense>
|
|
189
|
+
* ```
|
|
190
|
+
*
|
|
191
|
+
* If omitted, falls back to Option B: children are re-rendered with
|
|
192
|
+
* `useIsShimmering()=true` so they can return an empty shape themselves.
|
|
193
|
+
*/
|
|
194
|
+
template?: React__default.ReactNode;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Suspense boundary that automatically shows a shimmer skeleton while
|
|
198
|
+
* children are suspended (e.g. useSuspenseQuery, use(promise), etc).
|
|
199
|
+
*
|
|
200
|
+
* **Option A — explicit template (preferred):**
|
|
201
|
+
* ```tsx
|
|
202
|
+
* <ShimmerSuspense template={<UserCard />}>
|
|
203
|
+
* <UserCard />
|
|
204
|
+
* </ShimmerSuspense>
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* **Option B — useIsShimmering hook (no template):**
|
|
208
|
+
* ```tsx
|
|
209
|
+
* function UserCard() {
|
|
210
|
+
* const isShimmering = useIsShimmering();
|
|
211
|
+
* const data = isShimmering ? null : useSuspenseQuery(...);
|
|
212
|
+
* return <div><h3>{data?.name}</h3></div>;
|
|
213
|
+
* }
|
|
214
|
+
*
|
|
215
|
+
* <ShimmerSuspense>
|
|
216
|
+
* <UserCard />
|
|
217
|
+
* </ShimmerSuspense>
|
|
218
|
+
* ```
|
|
219
|
+
* Components must use `useIsShimmering()` to skip data fetching in shimmer mode,
|
|
220
|
+
* otherwise they will also suspend inside the fallback (causing an empty skeleton).
|
|
221
|
+
*/
|
|
222
|
+
declare function ShimmerSuspense({ children, template, ...shimmerConfig }: ShimmerSuspenseProps): react_jsx_runtime.JSX.Element;
|
|
223
|
+
|
|
224
|
+
export { type AnimationType, Shimmer, type ShimmerConfig, ShimmerContext, type ShimmerProps, type ShimmerRect, ShimmerSuspense, type ShimmerSuspenseProps, createShimmer, useIsShimmering, useShimmerContext };
|