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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/ShimmerContext.tsx","../src/ShimmerOverlay.tsx","../src/utils.ts","../src/useTrace.ts","../src/styles.ts","../src/Shimmer.tsx","../src/createShimmer.tsx","../src/ShimmerSuspense.tsx"],"names":["createContext","useContext","jsx","React","useState","useCallback","useLayoutEffect","useId","useMemo","useRef","jsxs","createElement"],"mappings":"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","file":"index.js","sourcesContent":["import React, { ReactNode } from 'react';\r\n\r\n/**\r\n * Represents a measured rectangle of a traced DOM element,\r\n * positioned relative to the Master Shimmer container.\r\n */\r\nexport interface ShimmerRect {\r\n x: number;\r\n y: number;\r\n width: number;\r\n height: number;\r\n borderRadius: string;\r\n}\r\n\r\n/** Available animation types for the shimmer effect. */\r\nexport type AnimationType =\r\n | 'wave'\r\n | 'pulse'\r\n | 'shine'\r\n | 'glow'\r\n | 'gradient';\r\n\r\n/** Configuration options for the shimmer effect (all optional). */\r\nexport interface ShimmerConfig {\r\n /** Animation style. Defaults to 'wave'. */\r\n animation?: AnimationType;\r\n /** Base color of the shimmer blocks. Defaults to '#e0e0e0'. */\r\n baseColor?: string;\r\n /** Highlight color of the shimmer animation. Defaults to '#f5f5f5'. */\r\n highlightColor?: string;\r\n /** Animation duration in seconds. Defaults to 1.5. */\r\n speed?: number;\r\n /** Global border-radius override. If omitted, auto-detected from each element (defaults to 4px if detection is 0px). */\r\n borderRadius?: string;\r\n /**\r\n * Keep container backgrounds, borders, and padding visible while loading.\r\n * When `true` (default), only text and media leaves are hidden via\r\n * `color:transparent` / `opacity:0` so card backgrounds, borders, and\r\n * spacing remain visible underneath the shimmer overlay.\r\n *\r\n * Set `false` for legacy behavior (`visibility:hidden` on whole tree).\r\n */\r\n preserveBackground?: boolean;\r\n}\r\n\r\n/** Props for the Shimmer component. */\r\nexport interface ShimmerProps extends ShimmerConfig {\r\n /** Whether the loading state is active. */\r\n loading?: boolean;\r\n /** The children to trace and render shimmer over. */\r\n children: ReactNode;\r\n /**\r\n * Number of placeholder clones to generate for list-like loading states.\r\n *\r\n * When `loading=true` and `dummyLength` is set, Shimmer grabs the first\r\n * available child (or a cached template from the last loaded render) and\r\n * clones it `dummyLength` times to produce skeleton placeholders.\r\n *\r\n * When `loading=false`, children are rendered as-is.\r\n */\r\n dummyLength?: number;\r\n /**\r\n * Props injected into each child element while `loading=true` so the\r\n * skeleton renders with realistic shape without requiring real data.\r\n *\r\n * Example:\r\n * ```tsx\r\n * <Shimmer\r\n * loading={loading}\r\n * dummyData={{ user: { name: 'Loading...', role: '...', avatar: '' } }}\r\n * >\r\n * <UserCard user={user} />\r\n * </Shimmer>\r\n * ```\r\n *\r\n * While loading, each direct child is cloned with these props merged on top\r\n * of its own props. Ignored when `loading=false`.\r\n */\r\n dummyData?: Record<string, any>;\r\n /**\r\n * Component used to auto-generate skeleton elements while `loading=true`.\r\n *\r\n * When set, Shimmer ignores `children` during loading and renders\r\n * `dummyLength` (defaults to 1) instances of `<as {...dummyData} />`\r\n * to derive shape. Real children render once `loading=false`.\r\n *\r\n * ```tsx\r\n * <Shimmer\r\n * loading={loading}\r\n * as={MovieCard}\r\n * dummyData={{ movie: movieTemplate }}\r\n * dummyLength={10}\r\n * >\r\n * {movies.map((m) => <MovieCard movie={m} key={m.id} />)}\r\n * </Shimmer>\r\n * ```\r\n */\r\n as?: React.ComponentType<any>;\r\n /** Force this Shimmer to be a Master renderer even if nested inside another Shimmer. */\r\n stopPropagation?: boolean;\r\n /**\r\n * className applied to the Master container div.\r\n * Use to control layout (e.g. display:flex) without losing position:relative.\r\n */\r\n className?: string;\r\n /**\r\n * Inline styles merged into the Master container div.\r\n * position:relative is always applied; everything else is overridable.\r\n */\r\n style?: React.CSSProperties;\r\n}\r\n\r\n/** Default configuration values. */\r\nexport const DEFAULTS: Required<ShimmerConfig> = {\r\n animation: 'wave',\r\n baseColor: '#e0e0e0',\r\n highlightColor: '#f5f5f5',\r\n speed: 1.5,\r\n borderRadius: '',\r\n preserveBackground: true,\r\n};\r\n","import { createContext, useContext, RefObject } from 'react';\r\nimport { ShimmerRect, ShimmerConfig } from './types';\r\n\r\nexport interface ShimmerContextValue {\r\n register: (id: string, rects: ShimmerRect[]) => void;\r\n unregister: (id: string) => void;\r\n /** Ref object (not .current) so Reporters always read a fresh value. */\r\n masterRef: RefObject<HTMLElement | null>;\r\n loading: boolean;\r\n config: Required<ShimmerConfig>;\r\n}\r\n\r\nexport const ShimmerContext = createContext<ShimmerContextValue | null>(null);\r\n\r\nexport function useShimmerContext(): ShimmerContextValue | null {\r\n return useContext(ShimmerContext);\r\n}\r\n\r\n/**\r\n * True when rendered inside a ShimmerSuspense fallback (Option B).\r\n * Components use this to skip data fetching and return an empty shape.\r\n */\r\nexport const IsShimmeringContext = createContext<boolean>(false);\r\n\r\nexport function useIsShimmering(): boolean {\r\n return useContext(IsShimmeringContext);\r\n}\r\n","import React from 'react';\r\nimport { ShimmerRect, AnimationType } from './types';\r\n\r\ninterface ShimmerOverlayProps {\r\n rects: ShimmerRect[];\r\n animation: AnimationType;\r\n baseColor: string;\r\n highlightColor: string;\r\n speed: number;\r\n}\r\n\r\n/**\r\n * Returns animation-specific inline styles for each shimmer block.\r\n * For sweep-style animations (wave, shine), the colored gradient is rendered\r\n * as a child layer so the sweep can extend across the container in sync.\r\n */\r\nfunction getBlockStyles(\r\n animation: AnimationType,\r\n baseColor: string,\r\n highlightColor: string,\r\n speed: number,\r\n rect: ShimmerRect,\r\n): React.CSSProperties {\r\n const base: React.CSSProperties = {\r\n position: 'absolute',\r\n top: rect.y,\r\n left: rect.x,\r\n width: rect.width,\r\n height: rect.height,\r\n borderRadius: rect.borderRadius,\r\n overflow: 'hidden',\r\n };\r\n\r\n switch (animation) {\r\n case 'wave':\r\n case 'shine':\r\n return { ...base, background: baseColor };\r\n case 'pulse':\r\n return {\r\n ...base,\r\n background: baseColor,\r\n animation: `shimmer-pulse ${speed}s ease-in-out infinite`,\r\n };\r\n case 'glow':\r\n return {\r\n ...base,\r\n background: baseColor,\r\n animation: `shimmer-glow ${speed}s ease-in-out infinite`,\r\n };\r\n case 'gradient':\r\n return {\r\n ...base,\r\n backgroundImage: `linear-gradient(90deg, ${baseColor}, ${highlightColor}, ${baseColor})`,\r\n backgroundSize: '200% 100%',\r\n animation: `shimmer-gradient ${speed * 1.5}s ease-in-out infinite`,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Sweeping shine layer used by `wave` and `shine` animations.\r\n * Spans the full container width so the highlight sweeps in sync across all blocks.\r\n */\r\nconst SweepLayer: React.FC<{\r\n rect: ShimmerRect;\r\n highlightColor: string;\r\n speed: number;\r\n containerWidth: number;\r\n variant: 'wave' | 'shine';\r\n}> = ({ rect, highlightColor, speed, containerWidth, variant }) => {\r\n const isShine = variant === 'shine';\r\n return (\r\n <div\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: -rect.x,\r\n width: containerWidth > 0 ? containerWidth : '100vw',\r\n height: '100%',\r\n background: isShine\r\n ? `linear-gradient(115deg, transparent 30%, ${highlightColor} 50%, transparent 70%)`\r\n : `linear-gradient(90deg, transparent 0%, ${highlightColor} 50%, transparent 100%)`,\r\n animation: `${isShine ? 'shimmer-shine' : 'shimmer-wave'} ${speed}s ease-in-out infinite`,\r\n }}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * The overlay component rendered by the Master Shimmer.\r\n *\r\n * Renders one absolutely-positioned div per traced rect. Sweep-style\r\n * animations (`wave`, `shine`) get an additional gradient layer that spans\r\n * the container so the highlight passes across all blocks in sync.\r\n */\r\nexport const ShimmerOverlay: React.FC<ShimmerOverlayProps> = ({\r\n rects,\r\n animation,\r\n baseColor,\r\n highlightColor,\r\n speed,\r\n}) => {\r\n const overlayRef = React.useRef<HTMLDivElement>(null);\r\n const [containerWidth, setContainerWidth] = React.useState(0);\r\n\r\n React.useLayoutEffect(() => {\r\n if (!overlayRef.current?.parentElement) return;\r\n setContainerWidth(overlayRef.current.parentElement.offsetWidth);\r\n }, [rects]);\r\n\r\n if (rects.length === 0) return null;\r\n\r\n const isSweep = animation === 'wave' || animation === 'shine';\r\n\r\n return (\r\n <div\r\n ref={overlayRef}\r\n role=\"status\"\r\n aria-busy=\"true\"\r\n aria-label=\"Loading content\"\r\n data-shimmer-ignore=\"true\"\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n zIndex: 1,\r\n pointerEvents: 'none',\r\n visibility: 'visible',\r\n }}\r\n >\r\n {rects.map((rect, i) => (\r\n <div\r\n key={i}\r\n style={getBlockStyles(animation, baseColor, highlightColor, speed, rect)}\r\n >\r\n {isSweep && (\r\n <SweepLayer\r\n rect={rect}\r\n highlightColor={highlightColor}\r\n speed={speed}\r\n containerWidth={containerWidth}\r\n variant={animation as 'wave' | 'shine'}\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n};\r\n","/**\r\n * Generates a unique key for cloned elements to prevent\r\n * React \"missing key\" warnings during loading state.\r\n */\r\nlet counter = 0;\r\nexport function generateShimmerKey(prefix: string = 'shimmer'): string {\r\n return `${prefix}-clone-${++counter}`;\r\n}\r\n\r\n/**\r\n * Default fallback dimensions for common elements when their\r\n * measured dimensions are 0px (e.g., empty inputs, images not yet loaded).\r\n */\r\nexport const FALLBACK_DIMENSIONS: Record<string, { width: number; height: number }> = {\r\n INPUT: { width: 200, height: 36 },\r\n BUTTON: { width: 120, height: 36 },\r\n TEXTAREA: { width: 300, height: 80 },\r\n SELECT: { width: 200, height: 36 },\r\n IMG: { width: 100, height: 100 },\r\n H1: { width: 300, height: 36 },\r\n H2: { width: 260, height: 30 },\r\n H3: { width: 220, height: 26 },\r\n H4: { width: 200, height: 22 },\r\n H5: { width: 180, height: 20 },\r\n H6: { width: 160, height: 18 },\r\n P: { width: 250, height: 16 },\r\n SPAN: { width: 100, height: 16 },\r\n};\r\n","import { useLayoutEffect, useState, RefObject, useCallback } from 'react';\r\nimport { ShimmerRect } from './types';\r\nimport { FALLBACK_DIMENSIONS } from './utils';\r\n\r\n/**\r\n * Tags that are always considered \"traceable\" leaf elements\r\n * whose dimensions should be captured for the shimmer overlay.\r\n */\r\nconst TRACEABLE_TAGS = new Set([\r\n // Text\r\n 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P', 'SPAN', 'A', 'LI',\r\n 'LABEL', 'TD', 'TH', 'BLOCKQUOTE', 'CODE', 'PRE',\r\n // Media\r\n 'IMG', 'VIDEO', 'SVG', 'CANVAS', 'PICTURE',\r\n // Form\r\n 'INPUT', 'TEXTAREA', 'SELECT', 'BUTTON',\r\n // Misc\r\n 'HR',\r\n]);\r\n\r\n/**\r\n * Determines if an element should be traced.\r\n * Explicit data attributes override automatic detection.\r\n */\r\nfunction isTraceable(el: Element): boolean {\r\n if (el.hasAttribute('data-shimmer-ignore')) return false;\r\n if (el.hasAttribute('data-shimmer')) return true;\r\n if (TRACEABLE_TAGS.has(el.tagName)) return true;\r\n\r\n // Leaf element with visible dimensions → trace it\r\n if (el.children.length === 0) {\r\n const rect = el.getBoundingClientRect();\r\n return rect.width > 0 && rect.height > 0;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Recursively walks the DOM tree and collects all traceable elements.\r\n */\r\nfunction collectTraceableElements(root: Element): Element[] {\r\n const result: Element[] = [];\r\n\r\n function walk(el: Element) {\r\n if (el.hasAttribute('data-shimmer-ignore')) return;\r\n if (el.hasAttribute('data-shimmer-reporter')) return; // Ignore nested reporters, they report their own rects\r\n\r\n if (isTraceable(el)) {\r\n result.push(el);\r\n return; // Don't recurse into traced elements\r\n }\r\n\r\n for (let i = 0; i < el.children.length; i++) {\r\n walk(el.children[i]);\r\n }\r\n }\r\n\r\n for (let i = 0; i < root.children.length; i++) {\r\n walk(root.children[i]);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Measures an element and returns its ShimmerRect relative to the container.\r\n */\r\nfunction measureElement(\r\n el: Element,\r\n containerRect: DOMRect,\r\n globalBorderRadius?: string,\r\n): ShimmerRect | null {\r\n const elRect = el.getBoundingClientRect();\r\n\r\n // If the element is display: none or detached, getBoundingClientRect returns all zeros.\r\n // We must not trace it, otherwise it ends up at the left edge of the screen.\r\n if (elRect.width === 0 && elRect.height === 0 && elRect.left === 0 && elRect.top === 0) {\r\n return null;\r\n }\r\n\r\n const computedStyle = window.getComputedStyle(el);\r\n let borderRadius = globalBorderRadius || computedStyle.borderRadius;\r\n\r\n // If the element has no border radius (common for text tags),\r\n // apply a small default to avoid sharp edges in the shimmer.\r\n const isZero = !borderRadius || borderRadius === 'none' || borderRadius.split(' ').every(v => v === '0' || v === '0px' || v === '0%');\r\n if (isZero) {\r\n borderRadius = '4px';\r\n }\r\n\r\n let width = elRect.width;\r\n let height = elRect.height;\r\n\r\n // Apply fallback dimensions if element has 0 size but is actually visible (e.g. empty inline element)\r\n if (width === 0 || height === 0) {\r\n const fallback = FALLBACK_DIMENSIONS[el.tagName];\r\n if (fallback) {\r\n width = width || fallback.width;\r\n height = height || fallback.height;\r\n }\r\n }\r\n\r\n return {\r\n x: elRect.left - containerRect.left,\r\n y: elRect.top - containerRect.top,\r\n width,\r\n height,\r\n borderRadius,\r\n };\r\n}\r\n\r\n/**\r\n * Performs a full trace of all traceable elements within the container.\r\n *\r\n * @param anchorRef - When provided (Reporter mode), elements are measured\r\n * relative to this element instead of the container. Allows Reporter's\r\n * wrapper to use display:contents without breaking measurement.\r\n */\r\nfunction performTrace(\r\n container: HTMLElement,\r\n globalBorderRadius?: string,\r\n anchorRef?: RefObject<HTMLElement | null>,\r\n): ShimmerRect[] {\r\n const anchor = anchorRef?.current ?? container;\r\n const anchorRect = anchor.getBoundingClientRect();\r\n const elements = collectTraceableElements(container);\r\n\r\n return elements\r\n .map((el) => measureElement(el, anchorRect, globalBorderRadius))\r\n .filter((r): r is ShimmerRect => r !== null && r.width > 0 && r.height > 0);\r\n}\r\n\r\n/**\r\n * Hook that traces all visible leaf DOM elements within a container\r\n * and returns their measured ShimmerRects.\r\n *\r\n * Uses ResizeObserver to re-trace on container resize.\r\n *\r\n * @param anchorRef - When set, rects are relative to this element (Master).\r\n * Used by Reporter so its display:contents wrapper doesn't break measurement.\r\n */\r\nexport function useTrace(\r\n containerRef: RefObject<HTMLElement | null>,\r\n loading: boolean,\r\n globalBorderRadius?: string,\r\n anchorRef?: RefObject<HTMLElement | null>,\r\n): ShimmerRect[] {\r\n const [rects, setRects] = useState<ShimmerRect[]>([]);\r\n\r\n const trace = useCallback(() => {\r\n if (!containerRef.current) return;\r\n const traced = performTrace(containerRef.current, globalBorderRadius, anchorRef);\r\n setRects(traced);\r\n }, [containerRef, globalBorderRadius, anchorRef]);\r\n\r\n useLayoutEffect(() => {\r\n if (!loading || !containerRef.current) {\r\n setRects([]);\r\n return;\r\n }\r\n\r\n // Initial trace\r\n trace();\r\n\r\n // Re-trace on resize\r\n const observer = new ResizeObserver(() => {\r\n trace();\r\n });\r\n observer.observe(containerRef.current);\r\n\r\n return () => observer.disconnect();\r\n }, [loading, trace]);\r\n\r\n return rects;\r\n}\r\n","const SHIMMER_STYLES_ID = 'shimmer-trace-styles';\r\n\r\nconst CSS = `\r\n@keyframes shimmer-wave {\r\n 0% { transform: translateX(-100%); }\r\n 100% { transform: translateX(100%); }\r\n}\r\n\r\n@keyframes shimmer-pulse {\r\n 0%, 100% { opacity: 0.4; }\r\n 50% { opacity: 1; }\r\n}\r\n\r\n@keyframes shimmer-shine {\r\n 0% { transform: translateX(-150%) skewX(-20deg); }\r\n 100% { transform: translateX(150%) skewX(-20deg); }\r\n}\r\n\r\n@keyframes shimmer-glow {\r\n 0%, 100% { filter: brightness(1); }\r\n 50% { filter: brightness(1.35); }\r\n}\r\n\r\n@keyframes shimmer-gradient {\r\n 0% { background-position: 0% 50%; }\r\n 50% { background-position: 100% 50%; }\r\n 100% { background-position: 0% 50%; }\r\n}\r\n\r\n/* preserveBackground mode: hide text + media but keep container styles */\r\n[data-shimmer-master][data-shimmer-preserve-bg=\"true\"] :is(h1,h2,h3,h4,h5,h6,p,span,a,li,label,td,th,blockquote,code,pre,strong,em,small) {\r\n color: transparent !important;\r\n text-shadow: none !important;\r\n}\r\n[data-shimmer-master][data-shimmer-preserve-bg=\"true\"] :is(img,video,svg,canvas,picture) {\r\n opacity: 0 !important;\r\n}\r\n[data-shimmer-master][data-shimmer-preserve-bg=\"true\"] :is(input,textarea,select,button) {\r\n color: transparent !important;\r\n opacity: 0 !important;\r\n}\r\n[data-shimmer-master][data-shimmer-preserve-bg=\"true\"] {\r\n pointer-events: none !important;\r\n user-select: none !important;\r\n}\r\n`;\r\n\r\n/**\r\n * Injects the shimmer keyframe animations into the document head.\r\n * Safe to call multiple times — only injects once.\r\n */\r\nexport function injectStyles(): void {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(SHIMMER_STYLES_ID)) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = SHIMMER_STYLES_ID;\r\n style.textContent = CSS;\r\n document.head.appendChild(style);\r\n}\r\n","import React, { useRef, useCallback, useState, useId, useMemo } from \"react\";\r\nimport { ShimmerProps, ShimmerRect, DEFAULTS } from \"./types\";\r\nimport { ShimmerContext, useShimmerContext } from \"./ShimmerContext\";\r\nimport { ShimmerOverlay } from \"./ShimmerOverlay\";\r\nimport { useTrace } from \"./useTrace\";\r\nimport { injectStyles } from \"./styles\";\r\nimport { generateShimmerKey } from \"./utils\";\r\n\r\n/**\r\n * The main Shimmer component.\r\n *\r\n * Auto-detects **Master** (no parent Shimmer) vs **Reporter** (nested).\r\n * - Master: renders children hidden, traces DOM, paints overlay.\r\n * - Reporter: measures own rects, reports to parent Master.\r\n *\r\n * ### Skeleton shape via `dummyData`\r\n *\r\n * Pass `dummyData` so children render with realistic data while loading.\r\n * No render-prop, no manual `data || fallback` in JSX.\r\n *\r\n * ```tsx\r\n * const userTemplate = { name: 'Loading...', role: '...', avatar: '' };\r\n *\r\n * <Shimmer loading={loading} dummyData={{ user: userTemplate }}>\r\n * <UserCard user={user} />\r\n * </Shimmer>\r\n * ```\r\n *\r\n * ### List mode (`dummyLength`)\r\n *\r\n * Combined with `dummyData`, clones the first child N times with\r\n * template props merged in:\r\n *\r\n * ```tsx\r\n * <Shimmer\r\n * loading={loading}\r\n * dummyLength={5}\r\n * dummyData={{ fruit: { name: 'xxxxx', price: '$0.00' } }}\r\n * >\r\n * <FruitCard fruit={undefined as any} />\r\n * </Shimmer>\r\n * ```\r\n */\r\nexport function Shimmer({\r\n\tloading = false,\r\n\tchildren,\r\n\tdummyLength,\r\n\tdummyData,\r\n\tas,\r\n\tstopPropagation = false,\r\n\tanimation,\r\n\tbaseColor,\r\n\thighlightColor,\r\n\tspeed,\r\n\tborderRadius,\r\n\tpreserveBackground,\r\n\tclassName,\r\n\tstyle,\r\n}: ShimmerProps) {\r\n\tconst parentContext = useShimmerContext();\r\n\tconst isMaster = !parentContext || stopPropagation;\r\n\tconst id = useId();\r\n\r\n\tconst config = useMemo(\r\n\t\t() => ({\r\n\t\t\tanimation:\r\n\t\t\t\tanimation ?? parentContext?.config.animation ?? DEFAULTS.animation,\r\n\t\t\tbaseColor:\r\n\t\t\t\tbaseColor ?? parentContext?.config.baseColor ?? DEFAULTS.baseColor,\r\n\t\t\thighlightColor:\r\n\t\t\t\thighlightColor ??\r\n\t\t\t\tparentContext?.config.highlightColor ??\r\n\t\t\t\tDEFAULTS.highlightColor,\r\n\t\t\tspeed: speed ?? parentContext?.config.speed ?? DEFAULTS.speed,\r\n\t\t\tborderRadius:\r\n\t\t\t\tborderRadius ??\r\n\t\t\t\tparentContext?.config.borderRadius ??\r\n\t\t\t\tDEFAULTS.borderRadius,\r\n\t\t\tpreserveBackground:\r\n\t\t\t\tpreserveBackground ??\r\n\t\t\t\tparentContext?.config.preserveBackground ??\r\n\t\t\t\tDEFAULTS.preserveBackground,\r\n\t\t}),\r\n\t\t[\r\n\t\t\tanimation,\r\n\t\t\tbaseColor,\r\n\t\t\thighlightColor,\r\n\t\t\tspeed,\r\n\t\t\tborderRadius,\r\n\t\t\tpreserveBackground,\r\n\t\t\tparentContext?.config,\r\n\t\t],\r\n\t);\r\n\r\n\tif (isMaster) {\r\n\t\treturn (\r\n\t\t\t<MasterShimmer\r\n\t\t\t\tid={id}\r\n\t\t\t\tloading={loading}\r\n\t\t\t\tconfig={config}\r\n\t\t\t\tdummyLength={dummyLength}\r\n\t\t\t\tdummyData={dummyData}\r\n\t\t\t\tas={as}\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={style}\r\n\t\t\t>\r\n\t\t\t\t{children}\r\n\t\t\t</MasterShimmer>\r\n\t\t);\r\n\t}\r\n\r\n\treturn (\r\n\t\t<ReporterShimmer\r\n\t\t\tid={id}\r\n\t\t\tparentContext={parentContext!}\r\n\t\t\tconfig={config}\r\n\t\t\tdummyLength={dummyLength}\r\n\t\t\tdummyData={dummyData}\r\n\t\t\tas={as}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</ReporterShimmer>\r\n\t);\r\n}\r\n\r\n/* ─────────────────── Master ─────────────────── */\r\n\r\ninterface MasterShimmerProps {\r\n\tid: string;\r\n\tloading: boolean;\r\n\tconfig: Required<typeof DEFAULTS>;\r\n\tchildren: React.ReactNode;\r\n\tdummyLength?: number;\r\n\tdummyData?: Record<string, any>;\r\n\tas?: React.ComponentType<any>;\r\n\tclassName?: string;\r\n\tstyle?: React.CSSProperties;\r\n}\r\n\r\nfunction MasterShimmer({\r\n\tid,\r\n\tloading,\r\n\tconfig,\r\n\tchildren,\r\n\tdummyLength,\r\n\tdummyData,\r\n\tas,\r\n\tclassName,\r\n\tstyle,\r\n}: MasterShimmerProps) {\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\tconst [reporterRects, setReporterRects] = useState<\r\n\t\tRecord<string, ShimmerRect[]>\r\n\t>({});\r\n\r\n\tconst register = useCallback((rid: string, rects: ShimmerRect[]) => {\r\n\t\tsetReporterRects((prev) => ({ ...prev, [rid]: rects }));\r\n\t}, []);\r\n\r\n\tconst unregister = useCallback((rid: string) => {\r\n\t\tsetReporterRects((prev) => {\r\n\t\t\tconst next = { ...prev };\r\n\t\t\tdelete next[rid];\r\n\t\t\treturn next;\r\n\t\t});\r\n\t}, []);\r\n\r\n\tReact.useEffect(() => {\r\n\t\tinjectStyles();\r\n\t}, []);\r\n\r\n\tconst tracedRects = useTrace(\r\n\t\tcontainerRef,\r\n\t\tloading,\r\n\t\tconfig.borderRadius || undefined,\r\n\t);\r\n\r\n\tconst allRects = useMemo(() => {\r\n\t\tconst reported = Object.values(reporterRects).flat();\r\n\t\treturn [...tracedRects, ...reported];\r\n\t}, [tracedRects, reporterRects]);\r\n\r\n\tconst renderedChildren = useSkeletonChildren({\r\n\t\tloading,\r\n\t\tchildren,\r\n\t\tdummyLength,\r\n\t\tdummyData,\r\n\t\tas,\r\n\t\tid,\r\n\t});\r\n\r\n\tconst contextValue = useMemo(\r\n\t\t() => ({\r\n\t\t\tregister,\r\n\t\t\tunregister,\r\n\t\t\tmasterRef: containerRef,\r\n\t\t\tloading,\r\n\t\t\tconfig,\r\n\t\t}),\r\n\t\t[register, unregister, loading, config],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<ShimmerContext.Provider value={contextValue}>\r\n\t\t\t<div\r\n\t\t\t\tref={containerRef}\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"relative\",\r\n\t\t\t\t\tvisibility:\r\n\t\t\t\t\t\tloading && !config.preserveBackground ? \"hidden\" : undefined,\r\n\t\t\t\t\t...style,\r\n\t\t\t\t}}\r\n\t\t\t\taria-hidden={loading || undefined}\r\n\t\t\t\tdata-shimmer-master\r\n\t\t\t\tdata-shimmer-preserve-bg={\r\n\t\t\t\t\tloading && config.preserveBackground ? \"true\" : undefined\r\n\t\t\t\t}\r\n\t\t\t>\r\n\t\t\t\t{renderedChildren}\r\n\r\n\t\t\t\t{loading && (\r\n\t\t\t\t\t<ShimmerOverlay\r\n\t\t\t\t\t\trects={allRects}\r\n\t\t\t\t\t\tanimation={config.animation}\r\n\t\t\t\t\t\tbaseColor={config.baseColor}\r\n\t\t\t\t\t\thighlightColor={config.highlightColor}\r\n\t\t\t\t\t\tspeed={config.speed}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</ShimmerContext.Provider>\r\n\t);\r\n}\r\n\r\n/* ─────────────────── Reporter ─────────────────── */\r\n\r\ninterface ReporterShimmerProps {\r\n\tid: string;\r\n\tparentContext: NonNullable<ReturnType<typeof useShimmerContext>>;\r\n\tconfig: Required<typeof DEFAULTS>;\r\n\tchildren: React.ReactNode;\r\n\tdummyLength?: number;\r\n\tdummyData?: Record<string, any>;\r\n\tas?: React.ComponentType<any>;\r\n}\r\n\r\nfunction ReporterShimmer({\r\n\tid,\r\n\tparentContext,\r\n\tconfig,\r\n\tchildren,\r\n\tdummyLength,\r\n\tdummyData,\r\n\tas,\r\n}: ReporterShimmerProps) {\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\tconst tracedRects = useTrace(\r\n\t\tcontainerRef,\r\n\t\tparentContext.loading,\r\n\t\tconfig.borderRadius || undefined,\r\n\t\tparentContext.masterRef,\r\n\t);\r\n\r\n\tReact.useLayoutEffect(() => {\r\n\t\tif (!parentContext.loading || tracedRects.length === 0) {\r\n\t\t\tparentContext.unregister(id);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tparentContext.register(id, tracedRects);\r\n\t\treturn () => {\r\n\t\t\tparentContext.unregister(id);\r\n\t\t};\r\n\t}, [tracedRects, parentContext, id]);\r\n\r\n\tconst renderedChildren = useSkeletonChildren({\r\n\t\tloading: parentContext.loading,\r\n\t\tchildren,\r\n\t\tdummyLength,\r\n\t\tdummyData,\r\n\t\tas,\r\n\t\tid,\r\n\t});\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={containerRef}\r\n\t\t\tdata-shimmer-reporter\r\n\t\t\tstyle={{ display: \"contents\" }}\r\n\t\t>\r\n\t\t\t{renderedChildren}\r\n\t\t</div>\r\n\t);\r\n}\r\n\r\n/* ─────────────── Skeleton Children ─────────────── */\r\n\r\ninterface UseSkeletonChildrenParams {\r\n\tloading: boolean;\r\n\tchildren: React.ReactNode;\r\n\tdummyLength?: number;\r\n\tdummyData?: Record<string, any>;\r\n\tas?: React.ComponentType<any>;\r\n\tid: string;\r\n}\r\n\r\n/**\r\n * Build the rendered children tree.\r\n *\r\n * Priority during `loading=true`:\r\n * 1. `as` set → render `dummyLength` (or 1) instances of `<as {...dummyData} />`.\r\n * Children ignored. Cold-start safe.\r\n * 2. `dummyData` set + children present → clone each child merging\r\n * dummyData over its props. If `dummyLength` set, clone first\r\n * templated child N times.\r\n * 3. None → pass children through (e.g. `useIsShimmering` flow).\r\n *\r\n * `loading=false` → children untouched.\r\n */\r\nfunction useSkeletonChildren({\r\n\tloading,\r\n\tchildren,\r\n\tdummyLength,\r\n\tdummyData,\r\n\tas,\r\n\tid,\r\n}: UseSkeletonChildrenParams): React.ReactNode {\r\n\tif (!loading) return children;\r\n\r\n\tif (as) {\r\n\t\tconst count = dummyLength && dummyLength > 0 ? dummyLength : 1;\r\n\t\tconst Component = as;\r\n\t\treturn Array.from({ length: count }, (_, i) => (\r\n\t\t\t<Component\r\n\t\t\t\t{...(dummyData || {})}\r\n\t\t\t\tkey={generateShimmerKey(`${id}-as-${i}`)}\r\n\t\t\t/>\r\n\t\t));\r\n\t}\r\n\r\n\tconst childArray = React.Children.toArray(children);\r\n\r\n\tconst templated = childArray.map((c, i) => {\r\n\t\tif (!React.isValidElement(c)) return c;\r\n\t\tconst key = generateShimmerKey(`${id}-tpl-${i}`);\r\n\t\tconst props = dummyData ? { ...dummyData, key } : { key };\r\n\t\treturn React.cloneElement(c as React.ReactElement, props as any);\r\n\t});\r\n\r\n\tif (dummyLength && dummyLength > 0) {\r\n\t\tconst first = templated.find((c) => React.isValidElement(c)) as\r\n\t\t\t| React.ReactElement\r\n\t\t\t| undefined;\r\n\t\tif (!first) return null;\r\n\t\treturn Array.from({ length: dummyLength }, (_, i) =>\r\n\t\t\tReact.cloneElement(first, {\r\n\t\t\t\tkey: generateShimmerKey(`${id}-clone-${i}`),\r\n\t\t\t} as any),\r\n\t\t);\r\n\t}\r\n\r\n\treturn templated;\r\n}\r\n","import React from 'react';\r\nimport { Shimmer } from './Shimmer';\r\nimport { ShimmerConfig, ShimmerProps, DEFAULTS } from './types';\r\n\r\n/**\r\n * Factory function to create a pre-configured Shimmer component.\r\n * Avoids \"Provider Hell\" by baking config into the returned component.\r\n *\r\n * All config properties are optional — defaults are used for anything\r\n * not specified.\r\n *\r\n * @example\r\n * ```tsx\r\n * const AppShimmer = createShimmer({\r\n * animation: 'pulse',\r\n * baseColor: '#1a1a2e',\r\n * highlightColor: '#16213e',\r\n * speed: 2,\r\n * });\r\n *\r\n * <AppShimmer loading={isLoading}>\r\n * <MyComponent />\r\n * </AppShimmer>\r\n * ```\r\n */\r\nexport function createShimmer(config: ShimmerConfig = {}) {\r\n const mergedConfig: Required<ShimmerConfig> = {\r\n animation: config.animation ?? DEFAULTS.animation,\r\n baseColor: config.baseColor ?? DEFAULTS.baseColor,\r\n highlightColor: config.highlightColor ?? DEFAULTS.highlightColor,\r\n speed: config.speed ?? DEFAULTS.speed,\r\n borderRadius: config.borderRadius ?? DEFAULTS.borderRadius,\r\n preserveBackground: config.preserveBackground ?? DEFAULTS.preserveBackground,\r\n };\r\n\r\n function ConfiguredShimmer(props: Omit<ShimmerProps, keyof ShimmerConfig> & Partial<ShimmerConfig>) {\r\n return (\r\n <Shimmer\r\n {...mergedConfig}\r\n {...props}\r\n />\r\n );\r\n }\r\n\r\n // Removed ConfiguredShimmer.displayName\r\n return ConfiguredShimmer;\r\n}\r\n","import React from 'react';\r\nimport { Shimmer } from './Shimmer';\r\nimport { IsShimmeringContext } from './ShimmerContext';\r\nimport { ShimmerConfig } from './types';\r\n\r\nexport interface ShimmerSuspenseProps extends ShimmerConfig {\r\n children: React.ReactNode;\r\n /**\r\n * Explicit skeleton template. Rendered hidden and traced for shimmer shape.\r\n *\r\n * Preferred — pass the same component with no data props:\r\n * ```tsx\r\n * <ShimmerSuspense template={<UserCard />}>\r\n * <UserCard />\r\n * </ShimmerSuspense>\r\n * ```\r\n *\r\n * If omitted, falls back to Option B: children are re-rendered with\r\n * `useIsShimmering()=true` so they can return an empty shape themselves.\r\n */\r\n template?: React.ReactNode;\r\n}\r\n\r\n/**\r\n * Suspense boundary that automatically shows a shimmer skeleton while\r\n * children are suspended (e.g. useSuspenseQuery, use(promise), etc).\r\n *\r\n * **Option A — explicit template (preferred):**\r\n * ```tsx\r\n * <ShimmerSuspense template={<UserCard />}>\r\n * <UserCard />\r\n * </ShimmerSuspense>\r\n * ```\r\n *\r\n * **Option B — useIsShimmering hook (no template):**\r\n * ```tsx\r\n * function UserCard() {\r\n * const isShimmering = useIsShimmering();\r\n * const data = isShimmering ? null : useSuspenseQuery(...);\r\n * return <div><h3>{data?.name}</h3></div>;\r\n * }\r\n *\r\n * <ShimmerSuspense>\r\n * <UserCard />\r\n * </ShimmerSuspense>\r\n * ```\r\n * Components must use `useIsShimmering()` to skip data fetching in shimmer mode,\r\n * otherwise they will also suspend inside the fallback (causing an empty skeleton).\r\n */\r\nexport function ShimmerSuspense({\r\n children,\r\n template,\r\n ...shimmerConfig\r\n}: ShimmerSuspenseProps) {\r\n const skeletonContent =\r\n template !== undefined ? (\r\n template\r\n ) : (\r\n <IsShimmeringContext.Provider value={true}>\r\n {children}\r\n </IsShimmeringContext.Provider>\r\n );\r\n\r\n return (\r\n <React.Suspense\r\n fallback={\r\n <Shimmer loading={true} {...shimmerConfig}>\r\n {skeletonContent}\r\n </Shimmer>\r\n }\r\n >\r\n {children}\r\n </React.Suspense>\r\n );\r\n}\r\n"]}
|