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.
@@ -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 };