phase 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -388,18 +388,19 @@ Easing, interpolation, and your value range are three separate concerns. `phase`
388
388
 
389
389
  ## Choosing a primitive
390
390
 
391
- | Need | Use |
392
- | -------------------------------------------------------- | ----------------------------------------------------------------------- |
393
- | Check on-screen visibility | `useSight` (visibility only) |
394
- | Run a frame loop via `phase` | `useLoop` (DOM) / `useCanvas` (canvas) |
395
- | Pause/resume your own loop (WebGL, three.js, Web Worker) | `useLifecycle` (active/paused signal) |
396
- | Animate a single value in render output | `useTween` |
397
- | Animate mount/unmount transitions | `Presence` / `Swap` / `WhenVisible` |
398
- | Skip painting off-screen content (keep in DOM) | `Defer` |
399
- | Defer non-critical UI until the browser is idle | `WhenIdle` / `useIdle` |
400
- | Run a side effect or prefetch when idle | `useWhenIdle` |
401
- | Pause non-`phase` work inside a `Defer` subtree | `useRenderState` |
402
- | Subscribe to scroll, size, or media values reactively | `useScrollProgress` / `useSize` / `useContainerQuery` / `useMediaQuery` |
391
+ | Need | Use |
392
+ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
393
+ | Check on-screen visibility | `useSight` (visibility only) |
394
+ | Run a frame loop via `phase` | `useLoop` (DOM) / `useCanvas` (canvas) |
395
+ | Pause/resume your own loop (WebGL, three.js, Web Worker) | `useLifecycle` (active/paused signal) |
396
+ | Animate a single value in render output | `useTween` |
397
+ | Animate mount/unmount transitions | `Presence` / `Swap` / `WhenVisible` |
398
+ | Skip painting off-screen content (keep in DOM) | `Defer` |
399
+ | Defer non-critical UI until the browser is idle | `WhenIdle` / `useIdle` |
400
+ | Run a side effect or prefetch when idle | `useWhenIdle` |
401
+ | Pause non-`phase` work inside a `Defer` subtree | `useRenderState` |
402
+ | Subscribe to scroll, size, or media values reactively | `useScrollProgress` / `useSize` / `useContainerQuery` / `useMediaQuery` |
403
+ | Scroll/size/visibility without re-renders? | Same hooks with a callback (`onProgress` / `onResize` / `onVisibilityChange`), read via ref |
403
404
 
404
405
  **`useSight` vs `useLifecycle`:** `useSight` reports pure visibility (for lazy-mounting, analytics, `WhenVisible`). `useLifecycle` folds in reduced motion and a manual pause, so you can't accidentally animate for users who asked not to. If you're gating an animation, use `useLifecycle`. If you're gating content, use `useSight`.
405
406
 
@@ -572,15 +573,17 @@ Re-renders only at threshold crossings (~20 per full viewport traversal at defau
572
573
 
573
574
  ### Utility hooks
574
575
 
575
- | Hook | Purpose |
576
- | ------------------- | ---------------------------------------------------- |
577
- | `useSight` | Element visibility as a phase (`visible` / `hidden`) |
578
- | `useSize` | Element dimensions via shared ResizeObserver |
579
- | `useContainerQuery` | Breakpoint matching against element width |
580
- | `useScrollProgress` | Element visibility ratio as a 0–1 value |
581
- | `useMediaQuery` | CSS media query subscription (shared MQL pool) |
582
- | `useSyncedRef` | Ref always in sync with latest value |
583
- | `useStableCallback` | Stable-identity function that calls latest closure |
576
+ | Hook | Purpose |
577
+ | ------------------- | ------------------------------------------------------------------------------------- |
578
+ | `useSight` | Element visibility as a phase. Pass `onVisibilityChange` for zero-re-render mode |
579
+ | `useSize` | Element dimensions via shared ResizeObserver. Pass `onResize` for zero-re-render mode |
580
+ | `useContainerQuery` | Breakpoint matching against element width |
581
+ | `useScrollProgress` | Element visibility ratio (0–1). Pass `onProgress` for zero-re-render mode |
582
+ | `useMediaQuery` | CSS media query subscription (shared MQL pool) |
583
+ | `useSyncedRef` | Ref always in sync with latest value |
584
+ | `useStableCallback` | Stable-identity function that calls latest closure |
585
+
586
+ `useSight`, `useSize`, and `useScrollProgress` each support a transient mode: pass a callback (`onVisibilityChange`, `onResize`, `onProgress`) and the hook delivers updates via callback with zero re-renders. The reactive state field is omitted from the return type so accessing it is a compile-time error. An always-current ref (`phaseRef`, `sizeRef`, `progressRef`) is available in both modes.
584
587
 
585
588
  ## React components
586
589
 
@@ -875,24 +878,24 @@ Minimal footprint is a core promise (see [Why phase](#why-phase)). Every export
875
878
  | **React** | |
876
879
  | `useLoop` | 2.81 kB |
877
880
  | `useLifecycle` | 1.68 kB |
878
- | `useSight` | 1.1 kB |
879
- | `useCanvas` | 3.43 kB |
880
- | `useTween` | 612 B |
881
- | `usePresence` | 591 B |
882
- | `useScrollProgress` | 927 B |
883
- | `useSize` | 266 B |
884
- | `useContainerQuery` | 339 B |
881
+ | `useSight` | 1.19 kB |
882
+ | `useCanvas` | 3.44 kB |
883
+ | `useTween` | 614 B |
884
+ | `usePresence` | 592 B |
885
+ | `useScrollProgress` | 996 B |
886
+ | `useSize` | 388 B |
887
+ | `useContainerQuery` | 347 B |
885
888
  | `useMediaQuery` | 245 B |
886
889
  | `usePrefersReducedMotion` | 272 B |
887
890
  | `useDevicePixelRatio` | 231 B |
888
891
  | `useSyncedRef` | 22 B |
889
892
  | `useStableCallback` | 39 B |
890
- | `Presence` | 746 B |
891
- | `WhenVisible` | 1.34 kB |
892
- | `WhenIdle` | 591 B |
893
- | `Defer` | 103 B |
893
+ | `Presence` | 745 B |
894
+ | `WhenVisible` | 1.44 kB |
895
+ | `WhenIdle` | 592 B |
896
+ | `Defer` | 104 B |
894
897
  | `useIdle` | 435 B |
895
- | `useWhenIdle` | 445 B |
898
+ | `useWhenIdle` | 448 B |
896
899
  | `useRenderState` | 527 B |
897
900
  | `Swap` | 1.12 kB |
898
901
 
package/dist/react.d.ts CHANGED
@@ -155,6 +155,7 @@ declare function useMediaQuery(query: string): boolean;
155
155
  declare function usePrefersReducedMotion(): boolean;
156
156
  //#endregion
157
157
  //#region src/react/use-sight/index.d.ts
158
+ type SightCallback = (phase: SightPhase, phaseReason: SightReason) => void;
158
159
  interface UseSightOptions<T extends Element = HTMLDivElement> extends IntersectionObserverInit {
159
160
  /**
160
161
  * Element to observe. Optional. When omitted, attach the returned `ref`.
@@ -162,27 +163,53 @@ interface UseSightOptions<T extends Element = HTMLDivElement> extends Intersecti
162
163
  ref?: RefObject<T | null>;
163
164
  /** `'continuous'` keeps observing. `'once'` freezes at `'visible'` after first intersection. */
164
165
  observe?: 'continuous' | 'once';
166
+ /**
167
+ * Called on every visibility transition. When provided, `phase` and
168
+ * `phaseReason` stay at initial values and no re-renders occur.
169
+ */
170
+ onVisibilityChange?: SightCallback;
165
171
  }
166
- interface UseSightResult<T extends Element = HTMLDivElement> {
167
- /** Attach to the element whose visibility you want to track. */
172
+ interface UseSightReactiveResult<T extends Element = HTMLDivElement> {
168
173
  ref: RefObject<T | null>;
169
174
  phase: SightPhase;
170
175
  phaseReason: SightReason;
176
+ /** Visibility phase via ref. Always current, never triggers re-render. */
177
+ phaseRef: RefObject<SightPhase>;
178
+ /** Phase reason via ref. Always current, never triggers re-render. */
179
+ phaseReasonRef: RefObject<SightReason>;
180
+ }
181
+ interface UseSightTransientResult<T extends Element = HTMLDivElement> {
182
+ ref: RefObject<T | null>;
183
+ /** Visibility phase via ref. Always current, never triggers re-render. */
184
+ phaseRef: RefObject<SightPhase>;
185
+ /** Phase reason via ref. Always current, never triggers re-render. */
186
+ phaseReasonRef: RefObject<SightReason>;
171
187
  }
188
+ /** @deprecated Use `UseSightReactiveResult` or `UseSightTransientResult`. */
189
+ type UseSightResult<T extends Element = HTMLDivElement> = UseSightReactiveResult<T>;
172
190
  /**
173
191
  * Intersection + document visibility as a phase.
174
192
  *
175
- * Returns `'unknown'` during SSR and before first observation.
176
- * `observe: 'once'` freezes at `'visible'` after first intersection and unobserves.
193
+ * Pass `onVisibilityChange` for zero-re-render mode (animation gating,
194
+ * many-element observation). Without it, `phase` and `phaseReason` update
195
+ * via state on every transition. `phaseRef`/`phaseReasonRef` are always current.
177
196
  *
178
197
  * @example
198
+ * // Reactive
179
199
  * const { ref, phase } = useSight();
180
- * if (phase === 'visible') startAnimation();
181
- * return <div ref={ref} />;
200
+ *
201
+ * // Transient (no re-renders)
202
+ * const { ref, phaseRef } = useSight({
203
+ * onVisibilityChange: (phase) => { worker.postMessage({ visible: phase === 'visible' }); },
204
+ * });
182
205
  */
183
- declare function useSight<T extends Element = HTMLDivElement>(options?: UseSightOptions<T>): UseSightResult<T>;
206
+ declare function useSight<T extends Element = HTMLDivElement>(options: UseSightOptions<T> & {
207
+ onVisibilityChange: SightCallback;
208
+ }): UseSightTransientResult<T>;
209
+ declare function useSight<T extends Element = HTMLDivElement>(options?: UseSightOptions<T>): UseSightReactiveResult<T>;
184
210
  //#endregion
185
211
  //#region src/react/use-size/index.d.ts
212
+ type SizeCallback = (size: Size) => void;
186
213
  interface Size {
187
214
  width: number;
188
215
  height: number;
@@ -192,24 +219,51 @@ interface UseSizeOptions<T extends Element = HTMLDivElement> {
192
219
  * Element to measure. Optional. When omitted, attach the returned `ref`.
193
220
  */
194
221
  ref?: RefObject<T | null>;
222
+ /**
223
+ * Which CSS box model to measure. `'content-box'` returns the content area
224
+ * (inside padding). `'border-box'` returns content + padding + border.
225
+ * Default `'content-box'`.
226
+ */
227
+ box?: 'content-box' | 'border-box';
228
+ /**
229
+ * Called on every resize. When provided, `size` is omitted from the return
230
+ * type and no re-renders occur, the right path for canvas and animation
231
+ * consumers that read dimensions imperatively.
232
+ */
233
+ onResize?: SizeCallback;
195
234
  }
196
- interface UseSizeResult<T extends Element = HTMLDivElement> {
197
- /** Attach to the element you want to measure. */
235
+ interface UseSizeReactiveResult<T extends Element = HTMLDivElement> {
198
236
  ref: RefObject<T | null>;
199
- /** Element dimensions, or `null` until the first observation. */
237
+ /** Element dimensions via state, or `null` until first observation. */
200
238
  size: Size | null;
239
+ /** Element dimensions via ref. Always current, never triggers re-render. */
240
+ sizeRef: RefObject<Size | null>;
201
241
  }
242
+ interface UseSizeTransientResult<T extends Element = HTMLDivElement> {
243
+ ref: RefObject<T | null>;
244
+ /** Element dimensions via ref. Always current, never triggers re-render. */
245
+ sizeRef: RefObject<Size | null>;
246
+ }
247
+ /** @deprecated Use `UseSizeReactiveResult` or `UseSizeTransientResult`. */
248
+ type UseSizeResult<T extends Element = HTMLDivElement> = UseSizeReactiveResult<T>;
202
249
  /**
203
250
  * Element dimensions via the shared ResizeObserver singleton.
204
251
  *
205
- * `size` is `null` until the first observation. Never calls `getBoundingClientRect()`.
206
- * RO callbacks are compositor-aligned (once per frame), so no rAF coalescing needed.
252
+ * Pass `onResize` for zero-re-render mode (canvas, animation loops).
253
+ * Without it, `size` updates via state on every dimension change.
254
+ * `sizeRef` is always current in both modes.
207
255
  *
208
256
  * @example
257
+ * // Reactive (re-renders on resize)
209
258
  * const { ref, size } = useSize();
210
- * return <div ref={ref}>{size?.width}</div>;
259
+ *
260
+ * // Transient (no re-renders — read sizeRef in onTick/draw)
261
+ * const { ref, sizeRef } = useSize({ onResize: (s) => applySize(s) });
211
262
  */
212
- declare function useSize<T extends Element = HTMLDivElement>(options?: UseSizeOptions<T>): UseSizeResult<T>;
263
+ declare function useSize<T extends Element = HTMLDivElement>(options: UseSizeOptions<T> & {
264
+ onResize: SizeCallback;
265
+ }): UseSizeTransientResult<T>;
266
+ declare function useSize<T extends Element = HTMLDivElement>(options?: UseSizeOptions<T>): UseSizeReactiveResult<T>;
213
267
  //#endregion
214
268
  //#region src/react/use-container-query/index.d.ts
215
269
  interface ContainerBreakpoint {
@@ -244,6 +298,7 @@ interface UseContainerQueryResult<T extends Element = HTMLDivElement> {
244
298
  declare function useContainerQuery<T extends Element = HTMLDivElement>(breakpoint: ContainerBreakpoint, options?: UseContainerQueryOptions<T>): UseContainerQueryResult<T>;
245
299
  //#endregion
246
300
  //#region src/react/use-scroll-progress/index.d.ts
301
+ type ScrollProgressCallback = (progress: number) => void;
247
302
  interface UseScrollProgressOptions<T extends Element = HTMLDivElement> {
248
303
  /**
249
304
  * Element to observe. Optional. When omitted, attach the returned `ref`.
@@ -253,27 +308,47 @@ interface UseScrollProgressOptions<T extends Element = HTMLDivElement> {
253
308
  steps?: number;
254
309
  root?: Element | null;
255
310
  rootMargin?: string;
311
+ /**
312
+ * Called on every threshold crossing. When provided, `progress` stays `0`
313
+ * and no re-renders occur, the right path for scroll-driven animation
314
+ * consumers that read progress imperatively.
315
+ */
316
+ onProgress?: ScrollProgressCallback;
256
317
  }
257
- interface UseScrollProgressResult<T extends Element = HTMLDivElement> {
258
- /** Attach to the element whose visibility ratio you want to track. */
318
+ interface UseScrollProgressReactiveResult<T extends Element = HTMLDivElement> {
259
319
  ref: RefObject<T | null>;
260
- /** Fraction of the element currently visible (0–1). See `createScrollProgress` for semantics. */
320
+ /** Fraction of the element currently visible (0–1). */
261
321
  progress: number;
322
+ /** Fraction visible via ref. Always current, never triggers re-render. */
323
+ progressRef: RefObject<number>;
262
324
  }
325
+ interface UseScrollProgressTransientResult<T extends Element = HTMLDivElement> {
326
+ ref: RefObject<T | null>;
327
+ /** Fraction visible via ref. Always current, never triggers re-render. */
328
+ progressRef: RefObject<number>;
329
+ }
330
+ /** @deprecated Use `UseScrollProgressReactiveResult` or `UseScrollProgressTransientResult`. */
331
+ type UseScrollProgressResult<T extends Element = HTMLDivElement> = UseScrollProgressReactiveResult<T>;
263
332
  /**
264
333
  * Element visibility ratio (0–1) via the shared IntersectionObserver pool.
265
334
  *
266
- * Reports the fraction of the element currently visible. Ideal for reveal/opacity
267
- * effects. Not a scroll-scrubbing engine: event-driven and quantized to `steps`.
268
- *
269
- * Re-renders only at threshold crossings (~20 per full viewport traversal).
270
- * `progress` is `0` before first observation and during SSR.
335
+ * Pass `onProgress` for zero-re-render mode (scroll-driven animation).
336
+ * Without it, `progress` updates via state at each threshold crossing.
337
+ * `progressRef` is always current in both modes.
271
338
  *
272
339
  * @example
340
+ * // Reactive (re-renders at threshold crossings)
273
341
  * const { ref, progress } = useScrollProgress();
274
- * return <div ref={ref} style={{ opacity: progress }} />;
342
+ *
343
+ * // Transient (no re-renders — read progressRef in onTick)
344
+ * const { ref, progressRef } = useScrollProgress({
345
+ * onProgress: (p) => { el.style.opacity = String(p); },
346
+ * });
275
347
  */
276
- declare function useScrollProgress<T extends Element = HTMLDivElement>(options?: UseScrollProgressOptions<T>): UseScrollProgressResult<T>;
348
+ declare function useScrollProgress<T extends Element = HTMLDivElement>(options: UseScrollProgressOptions<T> & {
349
+ onProgress: ScrollProgressCallback;
350
+ }): UseScrollProgressTransientResult<T>;
351
+ declare function useScrollProgress<T extends Element = HTMLDivElement>(options?: UseScrollProgressOptions<T>): UseScrollProgressReactiveResult<T>;
277
352
  //#endregion
278
353
  //#region src/react/use-render-state/index.d.ts
279
354
  /**
@@ -629,5 +704,5 @@ declare const Swap: typeof SwapRoot & {
629
704
  State: typeof SwapState;
630
705
  };
631
706
  //#endregion
632
- export { type CanvasDrawFn, type ContainerBreakpoint, Defer, type DeferProps, type IdleOptions, type LifecyclePhase, type LifecycleReason, type LifecycleReducedMotion, type LoopTickFn, Presence, type PresenceMode, type PresencePhase, type PresenceProps, type PresenceReason, type RenderPhase, type Size, Swap, type SwapProps, type SwapStateProps, type UseCanvasOptions, type UseCanvasResult, type UseContainerQueryOptions, type UseContainerQueryResult, type UseLifecycleOptions, type UseLifecycleResult, type UseLoopOptions, type UseLoopResult, type UsePresenceOptions, type UsePresenceResult, type UseScrollProgressOptions, type UseScrollProgressResult, type UseSightOptions, type UseSightResult, type UseSizeOptions, type UseSizeResult, type UseTweenOptions, WhenIdle, type WhenIdleProps, WhenVisible, type WhenVisibleProps, useCanvas, useContainerQuery, useDevicePixelRatio, useIdle, useLifecycle, useLoop, useMediaQuery, usePrefersReducedMotion, usePresence, useRenderState, useScrollProgress, useSight, useSize, useStableCallback, useSyncedRef, useTween, useWhenIdle };
707
+ export { type CanvasDrawFn, type ContainerBreakpoint, Defer, type DeferProps, type IdleOptions, type LifecyclePhase, type LifecycleReason, type LifecycleReducedMotion, type LoopTickFn, Presence, type PresenceMode, type PresencePhase, type PresenceProps, type PresenceReason, type RenderPhase, type ScrollProgressCallback, type SightCallback, type Size, type SizeCallback, Swap, type SwapProps, type SwapStateProps, type UseCanvasOptions, type UseCanvasResult, type UseContainerQueryOptions, type UseContainerQueryResult, type UseLifecycleOptions, type UseLifecycleResult, type UseLoopOptions, type UseLoopResult, type UsePresenceOptions, type UsePresenceResult, type UseScrollProgressOptions, type UseScrollProgressReactiveResult, type UseScrollProgressResult, type UseScrollProgressTransientResult, type UseSightOptions, type UseSightReactiveResult, type UseSightResult, type UseSightTransientResult, type UseSizeOptions, type UseSizeReactiveResult, type UseSizeResult, type UseSizeTransientResult, type UseTweenOptions, WhenIdle, type WhenIdleProps, WhenVisible, type WhenVisibleProps, useCanvas, useContainerQuery, useDevicePixelRatio, useIdle, useLifecycle, useLoop, useMediaQuery, usePrefersReducedMotion, usePresence, useRenderState, useScrollProgress, useSight, useSize, useStableCallback, useSyncedRef, useTween, useWhenIdle };
633
708
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react/use-synced-ref/index.ts","../src/react/use-stable-callback/index.ts","../src/react/use-loop/index.ts","../src/react/use-lifecycle/index.ts","../src/react/use-device-pixel-ratio/index.ts","../src/react/use-media/index.ts","../src/react/use-reduced-motion/index.ts","../src/react/use-sight/index.ts","../src/react/use-size/index.ts","../src/react/use-container-query/index.ts","../src/react/use-scroll-progress/index.ts","../src/react/use-render-state/index.ts","../src/react/use-idle/index.ts","../src/react/use-when-idle/index.ts","../src/react/use-canvas/index.ts","../src/react/use-tween/index.ts","../src/react/use-presence/index.ts","../src/react/presence/index.tsx","../src/react/when-visible/index.tsx","../src/react/when-idle/index.tsx","../src/react/defer/index.tsx","../src/react/swap/index.tsx"],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react/use-synced-ref/index.ts","../src/react/use-stable-callback/index.ts","../src/react/use-loop/index.ts","../src/react/use-lifecycle/index.ts","../src/react/use-device-pixel-ratio/index.ts","../src/react/use-media/index.ts","../src/react/use-reduced-motion/index.ts","../src/react/use-sight/index.ts","../src/react/use-size/index.ts","../src/react/use-container-query/index.ts","../src/react/use-scroll-progress/index.ts","../src/react/use-render-state/index.ts","../src/react/use-idle/index.ts","../src/react/use-when-idle/index.ts","../src/react/use-canvas/index.ts","../src/react/use-tween/index.ts","../src/react/use-presence/index.ts","../src/react/presence/index.tsx","../src/react/when-visible/index.tsx","../src/react/when-idle/index.tsx","../src/react/defer/index.tsx","../src/react/swap/index.tsx"],"mappings":"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"}
package/dist/react.js CHANGED
@@ -239,20 +239,12 @@ const INITIAL_STATE$1 = {
239
239
  phase: "unknown",
240
240
  phaseReason: "initial"
241
241
  };
242
- /**
243
- * Intersection + document visibility as a phase.
244
- *
245
- * Returns `'unknown'` during SSR and before first observation.
246
- * `observe: 'once'` freezes at `'visible'` after first intersection and unobserves.
247
- *
248
- * @example
249
- * const { ref, phase } = useSight();
250
- * if (phase === 'visible') startAnimation();
251
- * return <div ref={ref} />;
252
- */
253
242
  function useSight(options) {
254
243
  const [state, setState] = useState(INITIAL_STATE$1);
255
244
  const observe = options?.observe ?? "continuous";
245
+ const phaseRef = useRef("unknown");
246
+ const phaseReasonRef = useRef("initial");
247
+ const onVisibilityChangeRef = useSyncedRef(options?.onVisibilityChange);
256
248
  const internalRef = useRef(null);
257
249
  const ref = options?.ref ?? internalRef;
258
250
  useEffect(() => {
@@ -268,7 +260,10 @@ function useSight(options) {
268
260
  },
269
261
  onPhaseChange: (phase, reason) => {
270
262
  if (frozen) return;
271
- setState({
263
+ phaseRef.current = phase;
264
+ phaseReasonRef.current = reason;
265
+ if (onVisibilityChangeRef.current) onVisibilityChangeRef.current(phase, reason);
266
+ else setState({
272
267
  phase,
273
268
  phaseReason: reason
274
269
  });
@@ -282,7 +277,9 @@ function useSight(options) {
282
277
  }, [observe]);
283
278
  return {
284
279
  ref,
285
- ...state
280
+ ...state,
281
+ phaseRef,
282
+ phaseReasonRef
286
283
  };
287
284
  }
288
285
  //#endregion
@@ -291,13 +288,14 @@ let observer = null;
291
288
  const callbacks = /* @__PURE__ */ new Map();
292
289
  /**
293
290
  * Observe an element via a singleton ResizeObserver.
294
- * One RO instance for the entire page. RO takes zero constructor options.
291
+ * One RO instance for the entire page. Per-element `box` options are
292
+ * forwarded to `ResizeObserver.observe()`.
295
293
  *
296
294
  * @returns Cleanup function that unobserves the element.
297
295
  */
298
- function observeResize(element, callback) {
296
+ function observeResize(element, callback, box) {
299
297
  callbacks.set(element, callback);
300
- getObserver().observe(element);
298
+ getObserver().observe(element, box ? { box } : void 0);
301
299
  let disposed = false;
302
300
  return () => {
303
301
  if (disposed) return;
@@ -320,42 +318,39 @@ function getObserver() {
320
318
  }
321
319
  //#endregion
322
320
  //#region src/react/use-size/index.ts
323
- /**
324
- * Element dimensions via the shared ResizeObserver singleton.
325
- *
326
- * `size` is `null` until the first observation. Never calls `getBoundingClientRect()`.
327
- * RO callbacks are compositor-aligned (once per frame), so no rAF coalescing needed.
328
- *
329
- * @example
330
- * const { ref, size } = useSize();
331
- * return <div ref={ref}>{size?.width}</div>;
332
- */
333
321
  function useSize(options) {
334
322
  const [size, setSize] = useState(null);
323
+ const sizeRef = useRef(null);
335
324
  const prevWidth = useRef(null);
336
325
  const prevHeight = useRef(null);
326
+ const onResizeRef = useSyncedRef(options?.onResize);
337
327
  const internalRef = useRef(null);
338
328
  const ref = options?.ref ?? internalRef;
329
+ const boxOption = options?.box;
339
330
  useEffect(() => {
340
331
  const element = ref.current;
341
332
  if (!element) return;
342
333
  return observeResize(element, (entry) => {
343
- const box = entry.contentBoxSize[0];
344
- if (!box) return;
345
- const width = box.inlineSize;
346
- const height = box.blockSize;
334
+ const resolved = boxOption === "border-box" ? entry.borderBoxSize[0] : entry.contentBoxSize[0];
335
+ if (!resolved) return;
336
+ const width = resolved.inlineSize;
337
+ const height = resolved.blockSize;
347
338
  if (width === prevWidth.current && height === prevHeight.current) return;
348
339
  prevWidth.current = width;
349
340
  prevHeight.current = height;
350
- setSize({
341
+ const next = {
351
342
  width,
352
343
  height
353
- });
354
- });
355
- }, []);
344
+ };
345
+ sizeRef.current = next;
346
+ if (onResizeRef.current) onResizeRef.current(next);
347
+ else setSize(next);
348
+ }, boxOption);
349
+ }, [boxOption]);
356
350
  return {
357
351
  ref,
358
- size
352
+ size,
353
+ sizeRef
359
354
  };
360
355
  }
361
356
  //#endregion
@@ -411,23 +406,12 @@ function evaluateBreakpoint(width, height, minWidth, maxWidth, minHeight, maxHei
411
406
  }
412
407
  //#endregion
413
408
  //#region src/react/use-scroll-progress/index.ts
414
- /**
415
- * Element visibility ratio (0–1) via the shared IntersectionObserver pool.
416
- *
417
- * Reports the fraction of the element currently visible. Ideal for reveal/opacity
418
- * effects. Not a scroll-scrubbing engine: event-driven and quantized to `steps`.
419
- *
420
- * Re-renders only at threshold crossings (~20 per full viewport traversal).
421
- * `progress` is `0` before first observation and during SSR.
422
- *
423
- * @example
424
- * const { ref, progress } = useScrollProgress();
425
- * return <div ref={ref} style={{ opacity: progress }} />;
426
- */
427
409
  function useScrollProgress(options) {
428
410
  const [progress, setProgress] = useState(0);
411
+ const progressRef = useRef(0);
429
412
  const steps = options?.steps;
430
413
  const rootMargin = options?.rootMargin;
414
+ const onProgressRef = useSyncedRef(options?.onProgress);
431
415
  const internalRef = useRef(null);
432
416
  const ref = options?.ref ?? internalRef;
433
417
  useEffect(() => {
@@ -435,7 +419,11 @@ function useScrollProgress(options) {
435
419
  if (!element) return;
436
420
  const scrollProgress = createScrollProgress({
437
421
  element,
438
- onProgress: setProgress,
422
+ onProgress: (ratio) => {
423
+ progressRef.current = ratio;
424
+ if (onProgressRef.current) onProgressRef.current(ratio);
425
+ else setProgress(ratio);
426
+ },
439
427
  steps,
440
428
  root: options?.root,
441
429
  rootMargin
@@ -444,7 +432,8 @@ function useScrollProgress(options) {
444
432
  }, [steps, rootMargin]);
445
433
  return {
446
434
  ref,
447
- progress
435
+ progress,
436
+ progressRef
448
437
  };
449
438
  }
450
439
  //#endregion
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":["INITIAL_STATE","INITIAL_STATE","INITIAL_STATE"],"sources":["../src/react/use-synced-ref/index.ts","../src/react/use-stable-callback/index.ts","../src/react/_internal/degraded-config/index.ts","../src/react/use-loop/index.ts","../src/react/use-lifecycle/index.ts","../src/react/use-device-pixel-ratio/index.ts","../src/react/use-media/index.ts","../src/react/use-reduced-motion/index.ts","../src/react/use-sight/index.ts","../src/core/_internal/pool/ro-pool.ts","../src/react/use-size/index.ts","../src/react/use-container-query/index.ts","../src/react/use-scroll-progress/index.ts","../src/react/use-render-state/index.ts","../src/react/use-idle/index.ts","../src/react/use-when-idle/index.ts","../src/react/use-canvas/index.ts","../src/react/use-tween/index.ts","../src/react/_internal/use-update-effect/index.ts","../src/react/use-presence/index.ts","../src/react/presence/index.tsx","../src/react/when-visible/index.tsx","../src/react/when-idle/index.tsx","../src/react/defer/index.tsx","../src/react/swap/index.tsx"],"sourcesContent":["import { useRef, type RefObject } from 'react';\n\n/**\n * Ref whose `.current` is always the latest value, updated synchronously on\n * every render. Readable from any callback or effect without triggering re-render.\n *\n * @example\n * const propsRef = useSyncedRef(props);\n * useEffect(() => {\n * // propsRef.current is always fresh\n * }, []);\n */\nexport function useSyncedRef<T>(value: T): RefObject<T> {\n // Writes ref.current during render — opt out of React Compiler\n // memoization so the write is never skipped. No-op without the compiler.\n 'use no memo';\n\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","import { useRef, useCallback } from 'react';\n\n/**\n * Returns a function with **stable identity** that always calls the latest\n * version of `callback`. Safe in deps arrays and as a prop to `memo()`'d children.\n *\n * @example\n * const handleClick = useStableCallback((e: MouseEvent) => {\n * console.log(latestValue); // always fresh\n * });\n */\nexport function useStableCallback<Args extends unknown[], R>(\n callback: (...args: Args) => R,\n): (...args: Args) => R {\n // Writes callbackRef.current during render — opt out of React Compiler\n // memoization so the write is never skipped. No-op without the compiler.\n 'use no memo';\n\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n // Stable wrapper created once — delegates to the ref on every call.\n // Preserves the exact parameter and return types, no casts required.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useCallback((...args: Args) => callbackRef.current(...args), []);\n}\n","import type { DegradedBehavior } from '../../../core/loop';\n\nexport type DegradedConfig =\n | { degraded?: 'throttle'; degradedFps?: number }\n | { degraded: 'pause' }\n | { degraded: 'ignore' };\n\n/**\n * Map flat `degraded` / `degradedFps` hook options onto the loop's discriminated\n * union. `degradedFps` is only meaningful in `'throttle'` mode.\n */\nexport function degradedConfig(\n degraded: DegradedBehavior | undefined,\n degradedFps: number | undefined,\n): DegradedConfig {\n if (degraded === 'pause') return { degraded: 'pause' };\n if (degraded === 'ignore') return { degraded: 'ignore' };\n return { degraded: 'throttle', degradedFps };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createLoop,\n type LoopPhase,\n type LoopReason,\n type Quality,\n type DegradedBehavior,\n type DegradedReason,\n type ReducedMotionBehavior,\n} from '../../core/loop';\nimport type { FrameState } from '../../core/tick';\nimport { degradedConfig } from '../_internal/degraded-config';\nimport { useSyncedRef } from '../use-synced-ref';\n\n/**\n * Per-frame loop callback. Receives the current frame state. Write to refs or\n * DOM directly. Never call React `setState` here (60 calls/sec = 60\n * re-renders/sec).\n */\nexport type LoopTickFn = (frame: FrameState) => void;\n\nexport interface UseLoopOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n * Pass your own ref to share it or attach it elsewhere.\n */\n ref?: RefObject<T | null>;\n /**\n * Called every frame. Write to refs or DOM directly. Never call React\n * `setState` here (60 calls/sec = 60 re-renders/sec).\n */\n onTick: LoopTickFn;\n fps?: number;\n enabled?: boolean;\n reducedMotion?: ReducedMotionBehavior;\n /** Behavior when quality degrades (window blur, frame-budget). Default `'throttle'`. */\n degraded?: DegradedBehavior;\n /** FPS cap when `degraded` is `'throttle'`. Default `30`. */\n degradedFps?: number;\n intersectionOptions?: IntersectionObserverInit;\n}\n\nexport interface UseLoopResult<T extends Element = HTMLDivElement> {\n /** Attach to the element you want to animate. */\n ref: RefObject<T | null>;\n phase: LoopPhase;\n phaseReason: LoopReason;\n quality: Quality;\n qualityReason: DegradedReason | undefined;\n}\n\ntype LoopState = Omit<UseLoopResult, 'ref'>;\n\n// Disabled or unmounted: the loop isn't created, so it reports `idle` — matching\n// useCanvas and useLifecycle. (Toggling `enabled` tears down and recreates the\n// loop, so \"idle/will start fresh\" is more accurate than \"paused/will resume\".)\nconst INITIAL_STATE: LoopState = {\n phase: 'idle',\n phaseReason: 'initial',\n quality: 'full',\n qualityReason: undefined,\n};\n\n/**\n * Ref-based animation loop that never triggers re-renders from the frame loop.\n *\n * @example\n * const { ref, phase } = useLoop({\n * onTick: (frame) => {\n * ref.current.style.transform = `translateX(${frame.elapsed * 0.1}px)`;\n * },\n * });\n * return <div ref={ref} />;\n */\nexport function useLoop<T extends Element = HTMLDivElement>(\n options: UseLoopOptions<T>,\n): UseLoopResult<T> {\n const {\n fps,\n enabled = true,\n reducedMotion,\n degraded,\n degradedFps,\n intersectionOptions,\n } = options;\n const onTickRef = useSyncedRef(options.onTick);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options.ref ?? internalRef;\n\n const [state, setState] = useState<LoopState>(INITIAL_STATE);\n\n const loopRef = useRef<ReturnType<typeof createLoop> | null>(null);\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element || !enabled) {\n setState(INITIAL_STATE);\n return;\n }\n\n const loop = createLoop({\n element,\n onTick: (frame) => onTickRef.current(frame),\n fps,\n reducedMotion,\n intersectionOptions,\n ...degradedConfig(degraded, degradedFps),\n onPhaseChange: (phase, reason) => {\n // Read from loopRef instead of the local `loop` variable to avoid\n // accessing it before createLoop returns (start:'auto' fires\n // onPhaseChange synchronously during construction).\n const current = loopRef.current;\n setState({\n phase,\n phaseReason: reason,\n quality: current?.quality ?? 'full',\n qualityReason: current?.qualityReason,\n });\n },\n });\n loopRef.current = loop;\n\n return () => {\n loop.stop();\n loopRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, fps, reducedMotion, degraded, degradedFps]);\n\n return { ref, ...state };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createLifecycle,\n type Lifecycle,\n type LifecyclePhase,\n type LifecycleReason,\n type LifecycleReducedMotion,\n} from '../../core/lifecycle';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport interface UseLifecycleOptions<T extends Element = HTMLDivElement> {\n /**\n * Element whose visibility gates the lifecycle. Optional. When omitted, attach\n * the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** Whether reduced motion pauses the lifecycle. Default `'pause'`. */\n reducedMotion?: LifecycleReducedMotion;\n /** Manually pause regardless of visibility (e.g. a panel opened over the animation). */\n paused?: boolean;\n /** When `false`, the lifecycle is torn down and reports `idle`. Default `true`. */\n enabled?: boolean;\n intersectionOptions?: IntersectionObserverInit;\n /**\n * Synchronous callback fired in the observer/MQL callback, before React\n * schedules a render. Use to post messages to a worker or update a ref\n * without waiting for the React commit.\n */\n onPhaseChange?: (phase: LifecyclePhase, reason: LifecycleReason) => void;\n}\n\nexport interface UseLifecycleResult<T extends Element = HTMLDivElement> {\n /** Attach to the element whose visibility should gate your loop. */\n ref: RefObject<T | null>;\n phase: LifecyclePhase;\n phaseReason: LifecycleReason;\n /** Convenience: `phase === 'active'`. Drive your own render loop off this. */\n isActive: boolean;\n}\n\ntype LifecycleState = Omit<UseLifecycleResult, 'ref' | 'isActive'>;\n\nconst INITIAL_STATE: LifecycleState = {\n phase: 'idle',\n phaseReason: 'initial',\n};\n\n/**\n * React binding for `createLifecycle`. The activation signal for loops you own.\n *\n * Returns `active` / `paused` so a consumer-owned render loop (WebGL, three.js, a\n * Web Worker) can pause when off-screen or under reduced motion. When `phase`\n * should drive the loop for you, use `useLoop` or `useCanvas` instead.\n *\n * @example\n * const { ref, isActive } = useLifecycle();\n * useEffect(() => {\n * if (!isActive) return;\n * const id = requestAnimationFrame(function render() {\n * renderer.render();\n * requestAnimationFrame(render);\n * });\n * return () => cancelAnimationFrame(id);\n * }, [isActive]);\n * return <canvas ref={ref} />;\n */\nexport function useLifecycle<T extends Element = HTMLDivElement>(\n options?: UseLifecycleOptions<T>,\n): UseLifecycleResult<T> {\n const { reducedMotion, intersectionOptions, enabled = true } = options ?? {};\n const paused = options?.paused ?? false;\n const onPhaseChangeRef = useSyncedRef(options?.onPhaseChange);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n const [state, setState] = useState<LifecycleState>(INITIAL_STATE);\n const lifecycleRef = useRef<Lifecycle | null>(null);\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element || !enabled) {\n setState(INITIAL_STATE);\n return;\n }\n\n const lifecycle = createLifecycle({\n element,\n reducedMotion,\n intersectionOptions,\n onPhaseChange: (phase, phaseReason) => {\n onPhaseChangeRef.current?.(phase, phaseReason);\n setState({ phase, phaseReason });\n },\n });\n lifecycleRef.current = lifecycle;\n\n // Apply the manual pause that was requested at mount.\n if (paused) lifecycle.pause();\n\n return () => {\n lifecycle.stop();\n lifecycleRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, reducedMotion]);\n\n // Sync subsequent `paused` changes onto the live lifecycle.\n useEffect(() => {\n const lifecycle = lifecycleRef.current;\n if (!lifecycle) return;\n if (paused) lifecycle.pause();\n else lifecycle.resume();\n }, [paused]);\n\n return { ref, ...state, isActive: state.phase === 'active' };\n}\n","import { useState, useEffect } from 'react';\n\nimport { subscribeDpr, readDpr } from '../../core/_internal/pool/dpr';\n\n/**\n * Reactive devicePixelRatio that updates when the user moves the window\n * between monitors with different DPR values.\n *\n * Returns `1` during SSR and initial hydration, then the live value.\n */\nexport function useDevicePixelRatio(): number {\n const [dpr, setDpr] = useState(1);\n\n useEffect(() => {\n setDpr(readDpr());\n return subscribeDpr(setDpr);\n }, []);\n\n return dpr;\n}\n","import { useState, useEffect } from 'react';\n\nimport {\n subscribeMediaQuery,\n readMediaQuery,\n} from '../../core/_internal/pool/mql-pool';\n\n/**\n * Subscribe to a media query via the shared MQL pool.\n *\n * Returns `false` during SSR and initial hydration render,\n * then the live value from the first `useEffect`.\n *\n * @example\n * const isNarrow = useMediaQuery('(max-width: 600px)');\n */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(false);\n\n useEffect(() => {\n setMatches(readMediaQuery(query));\n return subscribeMediaQuery(query, setMatches);\n }, [query]);\n\n return matches;\n}\n","import { REDUCED_MOTION_QUERY } from '../../core/reduced-motion';\nimport { useMediaQuery } from '../use-media';\n\n/**\n * Reactive boolean that tracks the user's `prefers-reduced-motion` OS setting.\n *\n * Returns `false` during SSR and initial hydration, then the live value.\n * Re-renders only when the preference changes.\n */\nexport function usePrefersReducedMotion(): boolean {\n return useMediaQuery(REDUCED_MOTION_QUERY);\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createSight,\n type SightPhase,\n type SightReason,\n} from '../../core/sight';\n\nexport interface UseSightOptions<\n T extends Element = HTMLDivElement,\n> extends IntersectionObserverInit {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** `'continuous'` keeps observing. `'once'` freezes at `'visible'` after first intersection. */\n observe?: 'continuous' | 'once';\n}\n\nexport interface UseSightResult<T extends Element = HTMLDivElement> {\n /** Attach to the element whose visibility you want to track. */\n ref: RefObject<T | null>;\n phase: SightPhase;\n phaseReason: SightReason;\n}\n\ntype SightState = Omit<UseSightResult, 'ref'>;\n\nconst INITIAL_STATE: SightState = {\n phase: 'unknown',\n phaseReason: 'initial',\n};\n\n/**\n * Intersection + document visibility as a phase.\n *\n * Returns `'unknown'` during SSR and before first observation.\n * `observe: 'once'` freezes at `'visible'` after first intersection and unobserves.\n *\n * @example\n * const { ref, phase } = useSight();\n * if (phase === 'visible') startAnimation();\n * return <div ref={ref} />;\n */\nexport function useSight<T extends Element = HTMLDivElement>(\n options?: UseSightOptions<T>,\n): UseSightResult<T> {\n const [state, setState] = useState<SightState>(INITIAL_STATE);\n const observe = options?.observe ?? 'continuous';\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n let frozen = false;\n\n const sight = createSight({\n element,\n intersectionOptions: {\n root: options?.root,\n rootMargin: options?.rootMargin,\n threshold: options?.threshold,\n },\n onPhaseChange: (phase, reason) => {\n if (frozen) return;\n setState({ phase, phaseReason: reason });\n\n if (observe === 'once' && phase === 'visible') {\n frozen = true;\n sight.stop();\n }\n },\n });\n\n return () => sight.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [observe]);\n\n return { ref, ...state };\n}\n","type ROCallback = (entry: ResizeObserverEntry) => void;\n\nlet observer: ResizeObserver | null = null;\nconst callbacks = new Map<Element, ROCallback>();\n\n/**\n * Observe an element via a singleton ResizeObserver.\n * One RO instance for the entire page. RO takes zero constructor options.\n *\n * @returns Cleanup function that unobserves the element.\n */\nexport function observeResize(\n element: Element,\n callback: ROCallback,\n): () => void {\n callbacks.set(element, callback);\n getObserver().observe(element);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n // Only unobserve if our callback is still the registered one.\n // A later subscription on the same element would have overwritten it.\n if (callbacks.get(element) === callback) {\n callbacks.delete(element);\n observer?.unobserve(element);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Lazy-created singleton. RO takes zero constructor options, so one instance can observe everything. */\nfunction getObserver(): ResizeObserver {\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const cb: ROCallback | undefined = callbacks.get(entry.target);\n if (cb) cb(entry);\n }\n });\n }\n return observer;\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface UseSizeOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to measure. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n}\n\nexport interface UseSizeResult<T extends Element = HTMLDivElement> {\n /** Attach to the element you want to measure. */\n ref: RefObject<T | null>;\n /** Element dimensions, or `null` until the first observation. */\n size: Size | null;\n}\n\n/**\n * Element dimensions via the shared ResizeObserver singleton.\n *\n * `size` is `null` until the first observation. Never calls `getBoundingClientRect()`.\n * RO callbacks are compositor-aligned (once per frame), so no rAF coalescing needed.\n *\n * @example\n * const { ref, size } = useSize();\n * return <div ref={ref}>{size?.width}</div>;\n */\nexport function useSize<T extends Element = HTMLDivElement>(\n options?: UseSizeOptions<T>,\n): UseSizeResult<T> {\n const [size, setSize] = useState<Size | null>(null);\n const prevWidth = useRef<number | null>(null);\n const prevHeight = useRef<number | null>(null);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const unobserve: () => void = observeResize(element, (entry) => {\n const box = entry.contentBoxSize[0];\n if (!box) return;\n\n const width: number = box.inlineSize;\n const height: number = box.blockSize;\n\n // Skip setState if dimensions haven't changed — avoids entering the\n // component at all, vs React's bailout which still calls the function.\n if (width === prevWidth.current && height === prevHeight.current) return;\n prevWidth.current = width;\n prevHeight.current = height;\n\n setSize({ width, height });\n });\n\n return unobserve;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return { ref, size };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ContainerBreakpoint {\n minWidth?: number;\n maxWidth?: number;\n minHeight?: number;\n maxHeight?: number;\n}\n\nexport interface UseContainerQueryOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to measure. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n}\n\nexport interface UseContainerQueryResult<T extends Element = HTMLDivElement> {\n /** Attach to the element you want to match against the breakpoint. */\n ref: RefObject<T | null>;\n /** Whether the element currently matches the breakpoint. */\n matches: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// useContainerQuery\n// ---------------------------------------------------------------------------\n\n/**\n * Returns whether an element matches a size-based container breakpoint.\n *\n * Unlike `useSize` (which re-renders on every pixel of resize), this hook only\n * re-renders when the match result changes, i.e. when the element crosses a\n * breakpoint boundary. Uses the shared ResizeObserver singleton.\n *\n * @example\n * const { ref, matches } = useContainerQuery({ minWidth: 600 });\n * return <div ref={ref}>{matches ? 'wide' : 'narrow'}</div>;\n */\nexport function useContainerQuery<T extends Element = HTMLDivElement>(\n breakpoint: ContainerBreakpoint,\n options?: UseContainerQueryOptions<T>,\n): UseContainerQueryResult<T> {\n const [matches, setMatches] = useState(false);\n const matchesRef = useRef(false);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n const { minWidth, maxWidth, minHeight, maxHeight } = breakpoint;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const unobserve: () => void = observeResize(element, (entry) => {\n const box = entry.contentBoxSize[0];\n if (!box) return;\n\n const width: number = box.inlineSize;\n const height: number = box.blockSize;\n\n const nowMatches: boolean = evaluateBreakpoint(\n width,\n height,\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n );\n\n // Only re-render when the boolean flips — not on every pixel of resize.\n if (nowMatches !== matchesRef.current) {\n matchesRef.current = nowMatches;\n setMatches(nowMatches);\n }\n });\n\n return unobserve;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [minWidth, maxWidth, minHeight, maxHeight]);\n\n return { ref, matches };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction evaluateBreakpoint(\n width: number,\n height: number,\n minWidth?: number,\n maxWidth?: number,\n minHeight?: number,\n maxHeight?: number,\n): boolean {\n if (minWidth !== undefined && width < minWidth) return false;\n if (maxWidth !== undefined && width > maxWidth) return false;\n if (minHeight !== undefined && height < minHeight) return false;\n if (maxHeight !== undefined && height > maxHeight) return false;\n return true;\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { createScrollProgress } from '../../core/scroll-progress';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UseScrollProgressOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** Number of evenly-spaced thresholds. Default 20 (~5% granularity). */\n steps?: number;\n root?: Element | null;\n rootMargin?: string;\n}\n\nexport interface UseScrollProgressResult<T extends Element = HTMLDivElement> {\n /** Attach to the element whose visibility ratio you want to track. */\n ref: RefObject<T | null>;\n /** Fraction of the element currently visible (0–1). See `createScrollProgress` for semantics. */\n progress: number;\n}\n\n// ---------------------------------------------------------------------------\n// useScrollProgress\n// ---------------------------------------------------------------------------\n\n/**\n * Element visibility ratio (0–1) via the shared IntersectionObserver pool.\n *\n * Reports the fraction of the element currently visible. Ideal for reveal/opacity\n * effects. Not a scroll-scrubbing engine: event-driven and quantized to `steps`.\n *\n * Re-renders only at threshold crossings (~20 per full viewport traversal).\n * `progress` is `0` before first observation and during SSR.\n *\n * @example\n * const { ref, progress } = useScrollProgress();\n * return <div ref={ref} style={{ opacity: progress }} />;\n */\nexport function useScrollProgress<T extends Element = HTMLDivElement>(\n options?: UseScrollProgressOptions<T>,\n): UseScrollProgressResult<T> {\n const [progress, setProgress] = useState(0);\n const steps: number | undefined = options?.steps;\n const rootMargin: string | undefined = options?.rootMargin;\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const scrollProgress = createScrollProgress({\n element,\n onProgress: setProgress,\n steps,\n root: options?.root,\n rootMargin,\n });\n\n return () => scrollProgress.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [steps, rootMargin]);\n\n return { ref, progress };\n}\n","import { useState, useEffect, type RefObject } from 'react';\n\nimport { createRenderState, type RenderPhase } from '../../core/render-state';\n\nexport type { RenderPhase } from '../../core/render-state';\n\n/**\n * Track whether the browser is rendering an element or skipping it under\n * `content-visibility` (e.g. a `Defer` subtree). Returns `'rendered'` until the\n * browser reports otherwise.\n *\n * Use it to pause raw, non-phase work (a hand-written rAF loop, `setInterval`)\n * when the subtree stops painting. phase loops self-pause off-screen already.\n * Has no layout effect. Safe for CLS.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * const phase = useRenderState(ref);\n * useEffect(() => {\n * if (phase === 'skipped') clock.pause();\n * else clock.resume();\n * }, [phase]);\n * return <Defer ref={ref}><Heavy /></Defer>;\n */\nexport function useRenderState<T extends Element = HTMLDivElement>(\n ref: RefObject<T | null>,\n): RenderPhase {\n const [phase, setPhase] = useState<RenderPhase>('rendered');\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const render = createRenderState({\n element,\n onPhaseChange: setPhase,\n });\n\n return () => render.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return phase;\n}\n","import { useState, useEffect } from 'react';\n\nimport { whenIdle, type IdleOptions } from '../../core/idle';\n\nexport type { IdleOptions } from '../../core/idle';\n\n/**\n * Returns `false`, then `true` once the browser is idle after mount. Use it to\n * defer non-critical work or mounting until the main thread is free.\n *\n * SSR-safe: returns `false` on the server and during the first client render.\n *\n * @example\n * const idle = useIdle();\n * return idle ? <Analytics /> : null;\n */\nexport function useIdle(options?: IdleOptions): boolean {\n const [idle, setIdle] = useState(false);\n const timeout = options?.timeout;\n\n useEffect(() => {\n const cancel: () => void = whenIdle(() => setIdle(true), { timeout });\n return cancel;\n }, [timeout]);\n\n return idle;\n}\n","import { useEffect } from 'react';\n\nimport { whenIdle, type IdleOptions } from '../../core/idle';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport type { IdleOptions } from '../../core/idle';\n\n/**\n * Run a callback once, when the browser is idle after mount. The effect-shaped\n * counterpart to `useIdle`. Use it for side effects (prefetching a chunk,\n * warming a cache, `import()`) rather than rendering.\n *\n * Cancels automatically on unmount, and always calls the latest `callback`\n * without re-subscribing. SSR-safe: nothing runs on the server.\n *\n * @example\n * // Prefetch a heavy panel during idle time so it opens instantly later.\n * useWhenIdle(() => void import('./chat-panel'));\n */\nexport function useWhenIdle(callback: () => void, options?: IdleOptions): void {\n const callbackRef = useSyncedRef(callback);\n const timeout = options?.timeout;\n\n useEffect(() => {\n const cancel: () => void = whenIdle(() => callbackRef.current(), {\n timeout,\n });\n return cancel;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeout]);\n}\n","import {\n useState,\n useEffect,\n useRef,\n useCallback,\n type RefObject,\n} from 'react';\n\nimport { subscribeDpr, readDpr } from '../../core/_internal/pool/dpr';\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\nimport {\n createLoop,\n type LoopPhase,\n type LoopReason,\n type Quality,\n type DegradedBehavior,\n type DegradedReason,\n type ReducedMotionBehavior,\n} from '../../core/loop';\nimport type { FrameState } from '../../core/tick';\nimport { degradedConfig } from '../_internal/degraded-config';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Per-frame canvas draw callback. Receives the 2D context, frame state, and\n * current element size. Draw directly to the canvas. Never call React\n * `setState` here.\n */\nexport type CanvasDrawFn = (\n ctx: CanvasRenderingContext2D,\n frame: FrameState,\n size: Size,\n) => void;\n\nexport interface UseCanvasOptions {\n containerRef: RefObject<Element | null>;\n canvasRef: RefObject<HTMLCanvasElement | null>;\n /**\n * Called every frame with the 2D context, frame state, and current element size.\n * Draw directly to the canvas. Never call React `setState` here.\n */\n draw: CanvasDrawFn;\n fps?: number;\n enabled?: boolean;\n reducedMotion?: ReducedMotionBehavior;\n /** Behavior when quality degrades. Default `'throttle'`. For heavy GPU work, `'pause'` is often the right call. */\n degraded?: DegradedBehavior;\n /** FPS cap when `degraded` is `'throttle'`. Default `30`. */\n degradedFps?: number;\n}\n\nexport interface UseCanvasResult {\n restart: () => void;\n phase: LoopPhase;\n phaseReason: LoopReason;\n quality: Quality;\n qualityReason: DegradedReason | undefined;\n}\n\nconst INITIAL_STATE: Omit<UseCanvasResult, 'restart'> = {\n phase: 'idle',\n phaseReason: 'initial',\n quality: 'full',\n qualityReason: undefined,\n};\n\n/**\n * Canvas-specific animation with DPR-aware sizing, ResizeObserver coalescing,\n * context management, and GPU context loss recovery.\n *\n * @example\n * useCanvas({\n * containerRef,\n * canvasRef,\n * draw: (ctx, frame, size) => {\n * ctx.clearRect(0, 0, size.width, size.height);\n * // render...\n * },\n * });\n */\nexport function useCanvas(options: UseCanvasOptions): UseCanvasResult {\n const {\n containerRef,\n canvasRef,\n fps,\n enabled = true,\n reducedMotion,\n degraded,\n degradedFps,\n } = options;\n const drawRef = useSyncedRef(options.draw);\n\n const [state, setState] = useState(INITIAL_STATE);\n const [restartNonce, setRestartNonce] = useState(0);\n\n const ctxRef = useRef<CanvasRenderingContext2D | null>(null);\n const sizeRef = useRef<Size>({ width: 0, height: 0 });\n const qualityRef = useSyncedRef(state.quality);\n\n useEffect(() => {\n const container: Element | null = containerRef.current;\n const canvasEl: HTMLCanvasElement | null = canvasRef.current;\n if (!container || !canvasEl || !enabled) return;\n const canvas: HTMLCanvasElement = canvasEl;\n\n const initialCtx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n if (!initialCtx) return;\n ctxRef.current = initialCtx;\n\n let dpr: number = readDpr();\n let contextLost = false;\n\n // --- Canvas buffer sizing ---\n\n function applySize(\n width: number,\n height: number,\n physicalBox?: ResizeObserverSize,\n ): void {\n sizeRef.current = { width, height };\n const isDegraded: boolean = qualityRef.current === 'degraded';\n\n let bufferWidth: number;\n let bufferHeight: number;\n\n if (isDegraded) {\n bufferWidth = width;\n bufferHeight = height;\n } else if (physicalBox) {\n bufferWidth = physicalBox.inlineSize;\n bufferHeight = physicalBox.blockSize;\n } else {\n bufferWidth = width * dpr;\n bufferHeight = height * dpr;\n }\n\n canvas.width = bufferWidth;\n canvas.height = bufferHeight;\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n\n const effectiveDpr: number = isDegraded ? 1 : dpr;\n ctxRef.current?.setTransform(effectiveDpr, 0, 0, effectiveDpr, 0, 0);\n }\n\n // --- DPR monitoring (e.g. user drags window between monitors) ---\n\n const unsubDpr: () => void = subscribeDpr((newDpr) => {\n dpr = newDpr;\n applySize(sizeRef.current.width, sizeRef.current.height);\n });\n\n // --- Resize via shared RO pool ---\n\n const unobserve: () => void = observeResize(container, (entry) => {\n const box = entry.contentBoxSize[0];\n if (!box) return;\n const physicalBox: ResizeObserverSize | undefined =\n entry.devicePixelContentBoxSize?.[0];\n applySize(box.inlineSize, box.blockSize, physicalBox);\n });\n\n // --- GPU context loss recovery ---\n\n function onContextLost(event: Event): void {\n event.preventDefault();\n contextLost = true;\n }\n\n function onContextRestored(): void {\n const restoredCtx: CanvasRenderingContext2D | null =\n canvas.getContext('2d');\n if (!restoredCtx) return;\n ctxRef.current = restoredCtx;\n contextLost = false;\n applySize(sizeRef.current.width, sizeRef.current.height);\n }\n\n canvas.addEventListener('contextlost', onContextLost);\n canvas.addEventListener('contextrestored', onContextRestored);\n\n // --- Animation loop ---\n\n let loopInstance: ReturnType<typeof createLoop> | null = null;\n\n const loop = createLoop({\n element: container,\n fps,\n reducedMotion,\n ...degradedConfig(degraded, degradedFps),\n onTick: (frame) => {\n if (contextLost || !ctxRef.current) return;\n drawRef.current(ctxRef.current, frame, sizeRef.current);\n },\n onPhaseChange: (phase, reason) => {\n setState({\n phase,\n phaseReason: reason,\n quality: loopInstance?.quality ?? 'full',\n qualityReason: loopInstance?.qualityReason,\n });\n },\n });\n loopInstance = loop;\n\n // --- Teardown ---\n\n function teardown(): void {\n loop.stop();\n loopInstance = null;\n unobserve();\n unsubDpr();\n canvas.removeEventListener('contextlost', onContextLost);\n canvas.removeEventListener('contextrestored', onContextRestored);\n }\n\n return teardown;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, fps, reducedMotion, degraded, degradedFps, restartNonce]);\n\n // Restart bumps a nonce so the effect re-runs: it tears down the current\n // loop + observers and rebuilds them on the next cycle.\n const restart = useCallback(() => {\n setRestartNonce((n) => n + 1);\n }, []);\n\n return { restart, ...state };\n}\n","import { useState, useEffect, useRef } from 'react';\n\nimport { invalidDurationError } from '../../core/_internal/errors';\nimport type { ReducedMotionBehavior } from '../../core/loop';\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { clamp01, easeOutCubic } from '../../ease';\n\nexport interface UseTweenOptions {\n target: number;\n duration?: number;\n delay?: number;\n easing?: (progress: number) => number;\n enabled?: boolean;\n /** Default: `'complete'`. Tweens jump to target under reduced motion. */\n reducedMotion?: ReducedMotionBehavior;\n}\n\n/**\n * Animate a value from its current position to `target` over `duration`.\n *\n * Uses `useState` per frame. Appropriate for cheap renders (counters, opacity,\n * progress bars). For batch animations, use `useLoop` with ref-based DOM writes.\n *\n * @remarks\n * Unlike `createTicker`/`createLoop`, `useTween` drives its own rAF rather than\n * the shared frame-locked clock. It's a finite, self-completing tween whose value\n * must land in React state, so it doesn't need cross-loop visual sync, strong\n * pause, or delta clamping. Routing it through the shared clock would add bundle\n * weight for no benefit.\n *\n * @example\n * const value = useTween({ target: 100, duration: 500 });\n */\nexport function useTween(options: UseTweenOptions): number {\n const {\n target,\n duration = 300,\n delay = 0,\n easing = easeOutCubic,\n enabled = true,\n reducedMotion = 'complete',\n } = options;\n\n const [value, setValue] = useState(target);\n\n const fromRef = useRef(target);\n const currentRef = useRef(target);\n const isFirstRender = useRef(true);\n\n useEffect(() => {\n if (!Number.isFinite(duration) || duration <= 0) {\n invalidDurationError('useTween', duration);\n }\n\n // First render: sync refs without animating.\n if (isFirstRender.current) {\n isFirstRender.current = false;\n jumpToTarget({ target, fromRef, currentRef, setValue });\n return;\n }\n\n // Disabled or reduced motion: jump immediately.\n if (!enabled || (reducedMotion !== 'ignore' && prefersReducedMotion())) {\n jumpToTarget({ target, fromRef, currentRef, setValue });\n return;\n }\n\n // Already at target: nothing to animate.\n const from: number = currentRef.current;\n if (from === target) return;\n\n let rafId: number;\n let startTime: number | null = null;\n\n function tick(now: number): void {\n if (startTime === null) startTime = now;\n const elapsed: number = now - startTime - delay;\n\n // Still in the delay period — keep scheduling.\n if (elapsed < 0) {\n rafId = requestAnimationFrame(tick);\n return;\n }\n\n const progress: number = clamp01(elapsed / duration);\n const current: number = from + (target - from) * easing(progress);\n currentRef.current = current;\n setValue(current);\n\n if (progress < 1) {\n rafId = requestAnimationFrame(tick);\n } else {\n fromRef.current = target;\n }\n }\n\n rafId = requestAnimationFrame(tick);\n\n return () => {\n cancelAnimationFrame(rafId);\n // Preserve where we actually are so the next tween starts from here.\n fromRef.current = currentRef.current;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [target, duration, delay, enabled, reducedMotion]);\n\n return value;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface JumpToTargetOptions {\n target: number;\n fromRef: React.RefObject<number>;\n currentRef: React.RefObject<number>;\n setValue: (value: number) => void;\n}\n\nfunction jumpToTarget(options: JumpToTargetOptions): void {\n const { target, fromRef, currentRef, setValue } = options;\n fromRef.current = target;\n currentRef.current = target;\n setValue(target);\n}\n","import {\n useEffect,\n useRef,\n type EffectCallback,\n type DependencyList,\n} from 'react';\n\n/**\n * Like `useEffect` but skips the first invocation on mount.\n * Used by Presence to distinguish initial render from subsequent `show` changes.\n */\nexport function useUpdateEffect(\n effect: EffectCallback,\n deps: DependencyList,\n): void {\n const isMounted = useRef(false);\n\n useEffect(() => {\n if (!isMounted.current) {\n isMounted.current = true;\n return;\n }\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n","import {\n useState,\n useRef,\n useEffect,\n useCallback,\n type RefObject,\n} from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useUpdateEffect } from '../_internal/use-update-effect';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PresencePhase = 'idle' | 'entered' | 'exiting' | 'exited';\n\nexport type PresenceReason =\n | 'initial'\n | 'show'\n | 'hide'\n | 'animation-end'\n | 'interrupted';\n\nexport type PresenceMode = 'mount' | 'reveal';\n\nexport interface UsePresenceOptions {\n show: boolean;\n mode?: PresenceMode;\n /** Controls first-mount behavior. `'animate'` (default): enter animation plays. `'instant'`: appears immediately. */\n enter?: 'animate' | 'instant';\n /** Safety-net timeout in ms if transitionend/animationend doesn't fire during exit. Default 5000. */\n exitDuration?: number;\n /** Whether to respect the user's reduced motion preference. Default `'respect'`. */\n reducedMotion?: 'respect' | 'ignore';\n}\n\nexport interface UsePresenceResult {\n phase: PresencePhase;\n phaseReason: PresenceReason;\n /** Convenience: `phase !== 'idle' && phase !== 'exited'` for conditional rendering in mount mode. */\n mounted: boolean;\n ref: RefObject<Element | null>;\n /** Whether the component should stamp `data-enter=\"animate\"`. Accounts for enter option + reduced motion. */\n enter: 'animate' | 'instant';\n}\n\n// ---------------------------------------------------------------------------\n// usePresence\n// ---------------------------------------------------------------------------\n\n/**\n * Composable presence primitive for mount/unmount lifecycle with CSS transitions.\n *\n * Enter animations use CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Exit animations are JS-coordinated: waits for `transitionend`/`animationend`\n * before unmounting.\n *\n * @example\n * const { phase, ref, mounted, enter } = usePresence({ show: isOpen });\n * if (!mounted) return null;\n * return (\n * <div ref={ref} data-phase={phase} data-enter={enter === 'animate' ? 'animate' : undefined}\n * className=\"transition-opacity data-[enter=animate]:starting:opacity-0 data-[phase=exiting]:opacity-0\" />\n * );\n */\nexport function usePresence(options: UsePresenceOptions): UsePresenceResult {\n const {\n show,\n mode = 'mount',\n enter: enterOption = 'animate',\n exitDuration = 5000,\n reducedMotion = 'respect',\n } = options;\n\n const ref = useRef<Element | null>(null);\n\n const initialPhase: PresencePhase = show ? 'entered' : 'idle';\n\n const [phase, setPhase] = useState<PresencePhase>(initialPhase);\n const [reason, setReason] = useState<PresenceReason>('initial');\n\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const exitCleanupRef = useRef<(() => void) | null>(null);\n\n const clearTimers = useCallback(() => {\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n if (exitCleanupRef.current) {\n exitCleanupRef.current();\n exitCleanupRef.current = null;\n }\n }, []);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n useUpdateEffect(() => {\n clearTimers();\n\n if (show) {\n setPhase((prev) => {\n setReason(prev === 'exiting' ? 'interrupted' : 'show');\n return 'entered';\n });\n } else {\n const shouldSkipAnimation =\n reducedMotion === 'respect' && prefersReducedMotion();\n\n if (shouldSkipAnimation) {\n const exitTarget: PresencePhase = mode === 'reveal' ? 'idle' : 'exited';\n setPhase(exitTarget);\n setReason('animation-end');\n } else {\n handleExit(\n ref,\n mode,\n exitDuration,\n setPhase,\n setReason,\n clearTimers,\n exitTimerRef,\n exitCleanupRef,\n );\n }\n }\n }, [show]);\n\n const mounted: boolean = phase !== 'idle' && phase !== 'exited';\n\n const isFirstMount = reason === 'initial';\n const wantsAnimation = !(isFirstMount && enterOption === 'instant');\n const motionAllowed = reducedMotion === 'ignore' || !prefersReducedMotion();\n const enter: 'animate' | 'instant' =\n wantsAnimation && motionAllowed ? 'animate' : 'instant';\n\n return { phase, phaseReason: reason, mounted, ref, enter };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction handleExit(\n ref: RefObject<Element | null>,\n mode: PresenceMode,\n exitDuration: number,\n setPhase: (\n phase: PresencePhase | ((prev: PresencePhase) => PresencePhase),\n ) => void,\n setReason: (reason: PresenceReason) => void,\n clearTimers: () => void,\n exitTimerRef: React.RefObject<ReturnType<typeof setTimeout> | null>,\n exitCleanupRef: React.RefObject<(() => void) | null>,\n): void {\n setPhase('exiting');\n setReason('hide');\n\n const exitTarget: PresencePhase = mode === 'reveal' ? 'idle' : 'exited';\n const element: Element | null = ref.current;\n\n function completeExit(): void {\n clearTimers();\n setPhase((current) => {\n if (current !== 'exiting') return current;\n setReason('animation-end');\n return exitTarget;\n });\n }\n\n function cleanup(): void {\n if (element) {\n element.removeEventListener('transitionend', completeExit);\n element.removeEventListener('animationend', completeExit);\n }\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n exitCleanupRef.current = null;\n }\n\n exitCleanupRef.current = cleanup;\n\n if (element) {\n element.addEventListener('transitionend', completeExit, { once: true });\n element.addEventListener('animationend', completeExit, { once: true });\n }\n\n exitTimerRef.current = setTimeout(completeExit, exitDuration);\n}\n","import {\n useImperativeHandle,\n type ComponentProps,\n type JSX,\n type Ref,\n} from 'react';\n\nimport { usePresence, type PresenceMode } from '../use-presence';\n\nexport interface PresenceProps extends ComponentProps<'div'> {\n show: boolean;\n mode?: PresenceMode;\n /** Controls first-mount behavior. `'animate'` (default): enter animation plays. `'instant'`: appears immediately. */\n enter?: 'animate' | 'instant';\n /** Safety-net timeout in ms if transitionend/animationend doesn't fire during exit. Default 5000. */\n exitDuration?: number;\n /** Whether to respect the user's reduced motion preference. Default `'respect'`. */\n reducedMotion?: 'respect' | 'ignore';\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Renders a `div` that manages its own mounting lifecycle.\n *\n * Stamps `data-phase` for exit animations and `data-enter=\"animate\"` to gate\n * CSS `@starting-style` enter animations. Reduced motion is handled automatically.\n *\n * @example\n * <Presence\n * show={isOpen}\n * className=\"transition-opacity data-[enter=animate]:starting:opacity-0 data-[phase=exiting]:opacity-0\"\n * >\n * Modal content\n * </Presence>\n */\nexport function Presence({\n show,\n mode,\n enter: enterOption,\n exitDuration,\n reducedMotion,\n ref: forwardedRef,\n children,\n ...divProps\n}: PresenceProps): JSX.Element | null {\n const { phase, ref, mounted, enter } = usePresence({\n show,\n mode,\n enter: enterOption,\n exitDuration,\n reducedMotion,\n });\n\n useImperativeHandle(forwardedRef, () => ref.current as HTMLDivElement);\n\n if (!mounted && mode !== 'reveal') return null;\n\n return (\n <div\n {...divProps}\n ref={ref as React.RefObject<HTMLDivElement | null>}\n data-phase={phase}\n data-enter={enter === 'animate' ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n","import {\n useRef,\n type ComponentProps,\n type JSX,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useSight } from '../use-sight';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WhenVisibleProps extends ComponentProps<'div'> {\n /** IntersectionObserver rootMargin. Default `'200px'` (generous headroom for preloading). */\n rootMargin?: string;\n /** IntersectionObserver threshold. */\n threshold?: number | number[];\n /** IntersectionObserver root element. */\n root?: Element | null;\n /** Content shown while awaiting intersection. Sentinel div is always rendered for IO. */\n fallback?: ReactNode;\n /** Forwarded to the rendered div in both states (the sentinel before visible, the entered div after). Populated at mount. */\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// WhenVisible\n// ---------------------------------------------------------------------------\n\n/**\n * Mounts children when the element enters the viewport. One-shot (once\n * triggered, stays mounted).\n *\n * Enter animation uses CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Reduced motion is automatic: the attribute is not stamped when the user\n * prefers reduced motion.\n *\n * @example\n * <WhenVisible rootMargin=\"200px\" className=\"transition-opacity data-[enter=animate]:starting:opacity-0\">\n * <HeavyChart />\n * </WhenVisible>\n */\nexport function WhenVisible({\n rootMargin = '200px',\n threshold,\n root,\n fallback,\n children,\n ref: forwardedRef,\n ...divProps\n}: WhenVisibleProps): JSX.Element {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const { phase } = useSight({\n ref: sentinelRef,\n observe: 'once',\n rootMargin,\n threshold,\n root,\n });\n\n const setRef = (node: HTMLDivElement | null): void => {\n sentinelRef.current = node;\n assignRef(forwardedRef, node);\n };\n\n if (phase !== 'visible') {\n return (\n <div ref={setRef} {...divProps}>\n {fallback}\n </div>\n );\n }\n\n const motionAllowed = !prefersReducedMotion();\n\n return (\n <div\n {...divProps}\n ref={setRef}\n data-phase=\"entered\"\n data-enter={motionAllowed ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n\nfunction assignRef(\n ref: Ref<HTMLDivElement> | undefined,\n node: HTMLDivElement | null,\n): void {\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n}\n","import type { ComponentProps, JSX, ReactNode, Ref } from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useIdle } from '../use-idle';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WhenIdleProps extends ComponentProps<'div'> {\n /** Max ms to wait before mounting even if no idle period occurs. */\n timeout?: number;\n /** Content shown until the browser is idle. */\n fallback?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// WhenIdle\n// ---------------------------------------------------------------------------\n\n/**\n * Mounts children once the browser is idle after first paint. One-shot (once\n * mounted, stays mounted). Use it to defer non-critical UI off the critical path.\n *\n * Children are not server-rendered (idle never fires during SSR), so reserve\n * this for non-critical content. For viewport-gated mounting use `WhenVisible`;\n * to keep content in the DOM but skip painting use `Defer`.\n *\n * Enter animation uses CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Reduced motion is automatic: the attribute is not stamped when the user\n * prefers reduced motion.\n *\n * @example\n * <WhenIdle fallback={<Skeleton />}>\n * <SecondaryPanel />\n * </WhenIdle>\n */\nexport function WhenIdle({\n timeout,\n fallback,\n children,\n ref: forwardedRef,\n ...divProps\n}: WhenIdleProps): JSX.Element {\n const idle = useIdle({ timeout });\n\n if (!idle) {\n return <div {...divProps}>{fallback}</div>;\n }\n\n const motionAllowed = !prefersReducedMotion();\n\n return (\n <div\n {...divProps}\n ref={forwardedRef}\n data-phase=\"entered\"\n data-enter={motionAllowed ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n","import type { ComponentProps, CSSProperties, JSX, Ref } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface DeferProps extends Omit<ComponentProps<'div'>, 'style'> {\n /**\n * Approximate size reserved before first paint (any CSS length, e.g. `'800px'`).\n * After the first render the browser remembers the real size. Default `'1000px'`.\n */\n estimatedHeight?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Defer\n// ---------------------------------------------------------------------------\n\n/**\n * Skip the browser's rendering work (style, layout, paint) for off-screen\n * content via `content-visibility: auto`. Pure CSS, no JS, no observer.\n *\n * Children stay in the DOM and are server-rendered (SEO- and CLS-safe).\n * `contain-intrinsic-size: auto <estimatedHeight>` reserves space so the\n * scrollbar does not jump. Defers rendering only, not hydration or mounting.\n *\n * The render-skip styles are encapsulated and cannot be overridden. There is\n * no `style` prop. Style the wrapper with `className`; this keeps the\n * no-layout-shift guarantee intact.\n *\n * @example\n * <Defer estimatedHeight=\"600px\" className=\"my-section\">\n * <ArticleSection />\n * </Defer>\n *\n * @remarks\n * Animations inside a `Defer` keep running while paint is skipped. phase loops\n * self-pause off-screen on their own; for raw rAF/interval work, gate it with\n * `useRenderState`.\n */\nexport function Defer({\n estimatedHeight = '1000px',\n children,\n ref,\n ...divProps\n}: DeferProps): JSX.Element {\n const deferStyle: CSSProperties = {\n contentVisibility: 'auto',\n containIntrinsicSize: `auto ${estimatedHeight}`,\n };\n\n return (\n <div {...divProps} ref={ref} style={deferStyle}>\n {children}\n </div>\n );\n}\n","import {\n createContext,\n use,\n useState,\n useEffect,\n useMemo,\n useCallback,\n useImperativeHandle,\n type ComponentProps,\n type JSX,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { missingContextError } from '../../core/_internal/errors';\nimport { usePresence } from '../use-presence';\nimport { useSyncedRef } from '../use-synced-ref';\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface SwapContext {\n current: string;\n active: string;\n exitDuration: number;\n /** 'instant' on first mount (prevents CLS), 'animate' on subsequent swaps. */\n enter: 'animate' | 'instant';\n onExited: (id: string) => void;\n}\n\nconst SwapCtx = createContext<SwapContext | null>(null);\n\n// ---------------------------------------------------------------------------\n// Swap\n// ---------------------------------------------------------------------------\n\nexport interface SwapProps extends ComponentProps<'div'> {\n active: string;\n exitDuration?: number;\n children: ReactNode;\n}\n\n/**\n * Coordinated exit-then-enter transitions for N states.\n * Only one state is entering or exiting at a time (no overlap).\n *\n * The current state fully exits before the new state enters. Rapid changes\n * (A->B->C during A's exit) skip intermediate states and jump to the latest.\n *\n * @example\n * <Swap active={success ? 'success' : 'form'}>\n * <Swap.State id=\"form\" className=\"transition-all data-[phase=exiting]:opacity-0\">\n * <Form />\n * </Swap.State>\n * <Swap.State id=\"success\" className=\"transition-all data-[enter=animate]:starting:opacity-0\">\n * <SuccessMessage />\n * </Swap.State>\n * </Swap>\n */\nfunction SwapRoot({\n active,\n exitDuration = 5000,\n children,\n ...divProps\n}: SwapProps): JSX.Element {\n const [current, setCurrent] = useState(active);\n const [hasSwapped, setHasSwapped] = useState(false);\n const activeRef = useSyncedRef(active);\n\n const onExited = useCallback(\n (id: string): void => {\n setHasSwapped(true);\n setCurrent((cur) => (cur === id ? activeRef.current : cur));\n },\n [activeRef],\n );\n\n const enter: 'animate' | 'instant' = hasSwapped ? 'animate' : 'instant';\n\n const ctx: SwapContext = useMemo(\n () => ({ current, active, exitDuration, enter, onExited }),\n [current, active, exitDuration, enter, onExited],\n );\n\n return (\n <SwapCtx.Provider value={ctx}>\n <div {...divProps}>{children}</div>\n </SwapCtx.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Swap.State\n// ---------------------------------------------------------------------------\n\nexport interface SwapStateProps extends ComponentProps<'div'> {\n id: string;\n ref?: Ref<HTMLDivElement>;\n}\n\nfunction SwapState({\n id,\n ref: forwardedRef,\n children,\n ...divProps\n}: SwapStateProps): JSX.Element | null {\n const ctx = use(SwapCtx);\n if (!ctx) missingContextError('Swap.State', 'Swap');\n\n const isCurrent: boolean = ctx.current === id;\n const show: boolean = isCurrent && ctx.active === id;\n\n const { phase, ref, mounted, enter } = usePresence({\n show,\n mode: 'mount',\n enter: ctx.enter,\n exitDuration: ctx.exitDuration,\n });\n\n useImperativeHandle(forwardedRef, () => ref.current as HTMLDivElement);\n\n useEffect(() => {\n if (isCurrent && !show && phase === 'exited') {\n ctx.onExited(id);\n }\n }, [isCurrent, show, phase, id, ctx]);\n\n if (!isCurrent || !mounted) return null;\n\n return (\n <div\n {...divProps}\n ref={ref as React.RefObject<HTMLDivElement | null>}\n data-phase={phase}\n data-enter={enter === 'animate' ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Compound component export\n// ---------------------------------------------------------------------------\n\nexport const Swap: typeof SwapRoot & { State: typeof SwapState } =\n Object.assign(SwapRoot, { State: SwapState });\n"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","names":["INITIAL_STATE","INITIAL_STATE","INITIAL_STATE"],"sources":["../src/react/use-synced-ref/index.ts","../src/react/use-stable-callback/index.ts","../src/react/_internal/degraded-config/index.ts","../src/react/use-loop/index.ts","../src/react/use-lifecycle/index.ts","../src/react/use-device-pixel-ratio/index.ts","../src/react/use-media/index.ts","../src/react/use-reduced-motion/index.ts","../src/react/use-sight/index.ts","../src/core/_internal/pool/ro-pool.ts","../src/react/use-size/index.ts","../src/react/use-container-query/index.ts","../src/react/use-scroll-progress/index.ts","../src/react/use-render-state/index.ts","../src/react/use-idle/index.ts","../src/react/use-when-idle/index.ts","../src/react/use-canvas/index.ts","../src/react/use-tween/index.ts","../src/react/_internal/use-update-effect/index.ts","../src/react/use-presence/index.ts","../src/react/presence/index.tsx","../src/react/when-visible/index.tsx","../src/react/when-idle/index.tsx","../src/react/defer/index.tsx","../src/react/swap/index.tsx"],"sourcesContent":["import { useRef, type RefObject } from 'react';\n\n/**\n * Ref whose `.current` is always the latest value, updated synchronously on\n * every render. Readable from any callback or effect without triggering re-render.\n *\n * @example\n * const propsRef = useSyncedRef(props);\n * useEffect(() => {\n * // propsRef.current is always fresh\n * }, []);\n */\nexport function useSyncedRef<T>(value: T): RefObject<T> {\n // Writes ref.current during render — opt out of React Compiler\n // memoization so the write is never skipped. No-op without the compiler.\n 'use no memo';\n\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n","import { useRef, useCallback } from 'react';\n\n/**\n * Returns a function with **stable identity** that always calls the latest\n * version of `callback`. Safe in deps arrays and as a prop to `memo()`'d children.\n *\n * @example\n * const handleClick = useStableCallback((e: MouseEvent) => {\n * console.log(latestValue); // always fresh\n * });\n */\nexport function useStableCallback<Args extends unknown[], R>(\n callback: (...args: Args) => R,\n): (...args: Args) => R {\n // Writes callbackRef.current during render — opt out of React Compiler\n // memoization so the write is never skipped. No-op without the compiler.\n 'use no memo';\n\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n // Stable wrapper created once — delegates to the ref on every call.\n // Preserves the exact parameter and return types, no casts required.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useCallback((...args: Args) => callbackRef.current(...args), []);\n}\n","import type { DegradedBehavior } from '../../../core/loop';\n\nexport type DegradedConfig =\n | { degraded?: 'throttle'; degradedFps?: number }\n | { degraded: 'pause' }\n | { degraded: 'ignore' };\n\n/**\n * Map flat `degraded` / `degradedFps` hook options onto the loop's discriminated\n * union. `degradedFps` is only meaningful in `'throttle'` mode.\n */\nexport function degradedConfig(\n degraded: DegradedBehavior | undefined,\n degradedFps: number | undefined,\n): DegradedConfig {\n if (degraded === 'pause') return { degraded: 'pause' };\n if (degraded === 'ignore') return { degraded: 'ignore' };\n return { degraded: 'throttle', degradedFps };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createLoop,\n type LoopPhase,\n type LoopReason,\n type Quality,\n type DegradedBehavior,\n type DegradedReason,\n type ReducedMotionBehavior,\n} from '../../core/loop';\nimport type { FrameState } from '../../core/tick';\nimport { degradedConfig } from '../_internal/degraded-config';\nimport { useSyncedRef } from '../use-synced-ref';\n\n/**\n * Per-frame loop callback. Receives the current frame state. Write to refs or\n * DOM directly. Never call React `setState` here (60 calls/sec = 60\n * re-renders/sec).\n */\nexport type LoopTickFn = (frame: FrameState) => void;\n\nexport interface UseLoopOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n * Pass your own ref to share it or attach it elsewhere.\n */\n ref?: RefObject<T | null>;\n /**\n * Called every frame. Write to refs or DOM directly. Never call React\n * `setState` here (60 calls/sec = 60 re-renders/sec).\n */\n onTick: LoopTickFn;\n fps?: number;\n enabled?: boolean;\n reducedMotion?: ReducedMotionBehavior;\n /** Behavior when quality degrades (window blur, frame-budget). Default `'throttle'`. */\n degraded?: DegradedBehavior;\n /** FPS cap when `degraded` is `'throttle'`. Default `30`. */\n degradedFps?: number;\n intersectionOptions?: IntersectionObserverInit;\n}\n\nexport interface UseLoopResult<T extends Element = HTMLDivElement> {\n /** Attach to the element you want to animate. */\n ref: RefObject<T | null>;\n phase: LoopPhase;\n phaseReason: LoopReason;\n quality: Quality;\n qualityReason: DegradedReason | undefined;\n}\n\ntype LoopState = Omit<UseLoopResult, 'ref'>;\n\n// Disabled or unmounted: the loop isn't created, so it reports `idle` — matching\n// useCanvas and useLifecycle. (Toggling `enabled` tears down and recreates the\n// loop, so \"idle/will start fresh\" is more accurate than \"paused/will resume\".)\nconst INITIAL_STATE: LoopState = {\n phase: 'idle',\n phaseReason: 'initial',\n quality: 'full',\n qualityReason: undefined,\n};\n\n/**\n * Ref-based animation loop that never triggers re-renders from the frame loop.\n *\n * @example\n * const { ref, phase } = useLoop({\n * onTick: (frame) => {\n * ref.current.style.transform = `translateX(${frame.elapsed * 0.1}px)`;\n * },\n * });\n * return <div ref={ref} />;\n */\nexport function useLoop<T extends Element = HTMLDivElement>(\n options: UseLoopOptions<T>,\n): UseLoopResult<T> {\n const {\n fps,\n enabled = true,\n reducedMotion,\n degraded,\n degradedFps,\n intersectionOptions,\n } = options;\n const onTickRef = useSyncedRef(options.onTick);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options.ref ?? internalRef;\n\n const [state, setState] = useState<LoopState>(INITIAL_STATE);\n\n const loopRef = useRef<ReturnType<typeof createLoop> | null>(null);\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element || !enabled) {\n setState(INITIAL_STATE);\n return;\n }\n\n const loop = createLoop({\n element,\n onTick: (frame) => onTickRef.current(frame),\n fps,\n reducedMotion,\n intersectionOptions,\n ...degradedConfig(degraded, degradedFps),\n onPhaseChange: (phase, reason) => {\n // Read from loopRef instead of the local `loop` variable to avoid\n // accessing it before createLoop returns (start:'auto' fires\n // onPhaseChange synchronously during construction).\n const current = loopRef.current;\n setState({\n phase,\n phaseReason: reason,\n quality: current?.quality ?? 'full',\n qualityReason: current?.qualityReason,\n });\n },\n });\n loopRef.current = loop;\n\n return () => {\n loop.stop();\n loopRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, fps, reducedMotion, degraded, degradedFps]);\n\n return { ref, ...state };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createLifecycle,\n type Lifecycle,\n type LifecyclePhase,\n type LifecycleReason,\n type LifecycleReducedMotion,\n} from '../../core/lifecycle';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport interface UseLifecycleOptions<T extends Element = HTMLDivElement> {\n /**\n * Element whose visibility gates the lifecycle. Optional. When omitted, attach\n * the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** Whether reduced motion pauses the lifecycle. Default `'pause'`. */\n reducedMotion?: LifecycleReducedMotion;\n /** Manually pause regardless of visibility (e.g. a panel opened over the animation). */\n paused?: boolean;\n /** When `false`, the lifecycle is torn down and reports `idle`. Default `true`. */\n enabled?: boolean;\n intersectionOptions?: IntersectionObserverInit;\n /**\n * Synchronous callback fired in the observer/MQL callback, before React\n * schedules a render. Use to post messages to a worker or update a ref\n * without waiting for the React commit.\n */\n onPhaseChange?: (phase: LifecyclePhase, reason: LifecycleReason) => void;\n}\n\nexport interface UseLifecycleResult<T extends Element = HTMLDivElement> {\n /** Attach to the element whose visibility should gate your loop. */\n ref: RefObject<T | null>;\n phase: LifecyclePhase;\n phaseReason: LifecycleReason;\n /** Convenience: `phase === 'active'`. Drive your own render loop off this. */\n isActive: boolean;\n}\n\ntype LifecycleState = Omit<UseLifecycleResult, 'ref' | 'isActive'>;\n\nconst INITIAL_STATE: LifecycleState = {\n phase: 'idle',\n phaseReason: 'initial',\n};\n\n/**\n * React binding for `createLifecycle`. The activation signal for loops you own.\n *\n * Returns `active` / `paused` so a consumer-owned render loop (WebGL, three.js, a\n * Web Worker) can pause when off-screen or under reduced motion. When `phase`\n * should drive the loop for you, use `useLoop` or `useCanvas` instead.\n *\n * @example\n * const { ref, isActive } = useLifecycle();\n * useEffect(() => {\n * if (!isActive) return;\n * const id = requestAnimationFrame(function render() {\n * renderer.render();\n * requestAnimationFrame(render);\n * });\n * return () => cancelAnimationFrame(id);\n * }, [isActive]);\n * return <canvas ref={ref} />;\n */\nexport function useLifecycle<T extends Element = HTMLDivElement>(\n options?: UseLifecycleOptions<T>,\n): UseLifecycleResult<T> {\n const { reducedMotion, intersectionOptions, enabled = true } = options ?? {};\n const paused = options?.paused ?? false;\n const onPhaseChangeRef = useSyncedRef(options?.onPhaseChange);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n const [state, setState] = useState<LifecycleState>(INITIAL_STATE);\n const lifecycleRef = useRef<Lifecycle | null>(null);\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element || !enabled) {\n setState(INITIAL_STATE);\n return;\n }\n\n const lifecycle = createLifecycle({\n element,\n reducedMotion,\n intersectionOptions,\n onPhaseChange: (phase, phaseReason) => {\n onPhaseChangeRef.current?.(phase, phaseReason);\n setState({ phase, phaseReason });\n },\n });\n lifecycleRef.current = lifecycle;\n\n // Apply the manual pause that was requested at mount.\n if (paused) lifecycle.pause();\n\n return () => {\n lifecycle.stop();\n lifecycleRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, reducedMotion]);\n\n // Sync subsequent `paused` changes onto the live lifecycle.\n useEffect(() => {\n const lifecycle = lifecycleRef.current;\n if (!lifecycle) return;\n if (paused) lifecycle.pause();\n else lifecycle.resume();\n }, [paused]);\n\n return { ref, ...state, isActive: state.phase === 'active' };\n}\n","import { useState, useEffect } from 'react';\n\nimport { subscribeDpr, readDpr } from '../../core/_internal/pool/dpr';\n\n/**\n * Reactive devicePixelRatio that updates when the user moves the window\n * between monitors with different DPR values.\n *\n * Returns `1` during SSR and initial hydration, then the live value.\n */\nexport function useDevicePixelRatio(): number {\n const [dpr, setDpr] = useState(1);\n\n useEffect(() => {\n setDpr(readDpr());\n return subscribeDpr(setDpr);\n }, []);\n\n return dpr;\n}\n","import { useState, useEffect } from 'react';\n\nimport {\n subscribeMediaQuery,\n readMediaQuery,\n} from '../../core/_internal/pool/mql-pool';\n\n/**\n * Subscribe to a media query via the shared MQL pool.\n *\n * Returns `false` during SSR and initial hydration render,\n * then the live value from the first `useEffect`.\n *\n * @example\n * const isNarrow = useMediaQuery('(max-width: 600px)');\n */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(false);\n\n useEffect(() => {\n setMatches(readMediaQuery(query));\n return subscribeMediaQuery(query, setMatches);\n }, [query]);\n\n return matches;\n}\n","import { REDUCED_MOTION_QUERY } from '../../core/reduced-motion';\nimport { useMediaQuery } from '../use-media';\n\n/**\n * Reactive boolean that tracks the user's `prefers-reduced-motion` OS setting.\n *\n * Returns `false` during SSR and initial hydration, then the live value.\n * Re-renders only when the preference changes.\n */\nexport function usePrefersReducedMotion(): boolean {\n return useMediaQuery(REDUCED_MOTION_QUERY);\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport {\n createSight,\n type SightPhase,\n type SightReason,\n} from '../../core/sight';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport type SightCallback = (\n phase: SightPhase,\n phaseReason: SightReason,\n) => void;\n\nexport interface UseSightOptions<\n T extends Element = HTMLDivElement,\n> extends IntersectionObserverInit {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** `'continuous'` keeps observing. `'once'` freezes at `'visible'` after first intersection. */\n observe?: 'continuous' | 'once';\n /**\n * Called on every visibility transition. When provided, `phase` and\n * `phaseReason` stay at initial values and no re-renders occur.\n */\n onVisibilityChange?: SightCallback;\n}\n\nexport interface UseSightReactiveResult<T extends Element = HTMLDivElement> {\n ref: RefObject<T | null>;\n phase: SightPhase;\n phaseReason: SightReason;\n /** Visibility phase via ref. Always current, never triggers re-render. */\n phaseRef: RefObject<SightPhase>;\n /** Phase reason via ref. Always current, never triggers re-render. */\n phaseReasonRef: RefObject<SightReason>;\n}\n\nexport interface UseSightTransientResult<T extends Element = HTMLDivElement> {\n ref: RefObject<T | null>;\n /** Visibility phase via ref. Always current, never triggers re-render. */\n phaseRef: RefObject<SightPhase>;\n /** Phase reason via ref. Always current, never triggers re-render. */\n phaseReasonRef: RefObject<SightReason>;\n}\n\n/** @deprecated Use `UseSightReactiveResult` or `UseSightTransientResult`. */\nexport type UseSightResult<T extends Element = HTMLDivElement> =\n UseSightReactiveResult<T>;\n\ntype SightState = { phase: SightPhase; phaseReason: SightReason };\n\nconst INITIAL_STATE: SightState = {\n phase: 'unknown',\n phaseReason: 'initial',\n};\n\n/**\n * Intersection + document visibility as a phase.\n *\n * Pass `onVisibilityChange` for zero-re-render mode (animation gating,\n * many-element observation). Without it, `phase` and `phaseReason` update\n * via state on every transition. `phaseRef`/`phaseReasonRef` are always current.\n *\n * @example\n * // Reactive\n * const { ref, phase } = useSight();\n *\n * // Transient (no re-renders)\n * const { ref, phaseRef } = useSight({\n * onVisibilityChange: (phase) => { worker.postMessage({ visible: phase === 'visible' }); },\n * });\n */\nexport function useSight<T extends Element = HTMLDivElement>(\n options: UseSightOptions<T> & { onVisibilityChange: SightCallback },\n): UseSightTransientResult<T>;\nexport function useSight<T extends Element = HTMLDivElement>(\n options?: UseSightOptions<T>,\n): UseSightReactiveResult<T>;\nexport function useSight<T extends Element = HTMLDivElement>(\n options?: UseSightOptions<T>,\n): UseSightReactiveResult<T> | UseSightTransientResult<T> {\n const [state, setState] = useState<SightState>(INITIAL_STATE);\n const observe = options?.observe ?? 'continuous';\n const phaseRef = useRef<SightPhase>('unknown');\n const phaseReasonRef = useRef<SightReason>('initial');\n const onVisibilityChangeRef = useSyncedRef(options?.onVisibilityChange);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n let frozen = false;\n\n const sight = createSight({\n element,\n intersectionOptions: {\n root: options?.root,\n rootMargin: options?.rootMargin,\n threshold: options?.threshold,\n },\n onPhaseChange: (phase, reason) => {\n if (frozen) return;\n\n phaseRef.current = phase;\n phaseReasonRef.current = reason;\n\n if (onVisibilityChangeRef.current) {\n onVisibilityChangeRef.current(phase, reason);\n } else {\n setState({ phase, phaseReason: reason });\n }\n\n if (observe === 'once' && phase === 'visible') {\n frozen = true;\n sight.stop();\n }\n },\n });\n\n return () => sight.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [observe]);\n\n return { ref, ...state, phaseRef, phaseReasonRef };\n}\n","type ROCallback = (entry: ResizeObserverEntry) => void;\n\nlet observer: ResizeObserver | null = null;\nconst callbacks = new Map<Element, ROCallback>();\n\n/**\n * Observe an element via a singleton ResizeObserver.\n * One RO instance for the entire page. Per-element `box` options are\n * forwarded to `ResizeObserver.observe()`.\n *\n * @returns Cleanup function that unobserves the element.\n */\nexport function observeResize(\n element: Element,\n callback: ROCallback,\n box?: ResizeObserverBoxOptions,\n): () => void {\n callbacks.set(element, callback);\n getObserver().observe(element, box ? { box } : undefined);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n // Only unobserve if our callback is still the registered one.\n // A later subscription on the same element would have overwritten it.\n if (callbacks.get(element) === callback) {\n callbacks.delete(element);\n observer?.unobserve(element);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Lazy-created singleton. RO takes zero constructor options, so one instance can observe everything. */\nfunction getObserver(): ResizeObserver {\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const cb: ROCallback | undefined = callbacks.get(entry.target);\n if (cb) cb(entry);\n }\n });\n }\n return observer;\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport type SizeCallback = (size: Size) => void;\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface UseSizeOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to measure. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /**\n * Which CSS box model to measure. `'content-box'` returns the content area\n * (inside padding). `'border-box'` returns content + padding + border.\n * Default `'content-box'`.\n */\n box?: 'content-box' | 'border-box';\n /**\n * Called on every resize. When provided, `size` is omitted from the return\n * type and no re-renders occur, the right path for canvas and animation\n * consumers that read dimensions imperatively.\n */\n onResize?: SizeCallback;\n}\n\nexport interface UseSizeReactiveResult<T extends Element = HTMLDivElement> {\n ref: RefObject<T | null>;\n /** Element dimensions via state, or `null` until first observation. */\n size: Size | null;\n /** Element dimensions via ref. Always current, never triggers re-render. */\n sizeRef: RefObject<Size | null>;\n}\n\nexport interface UseSizeTransientResult<T extends Element = HTMLDivElement> {\n ref: RefObject<T | null>;\n /** Element dimensions via ref. Always current, never triggers re-render. */\n sizeRef: RefObject<Size | null>;\n}\n\n/** @deprecated Use `UseSizeReactiveResult` or `UseSizeTransientResult`. */\nexport type UseSizeResult<T extends Element = HTMLDivElement> =\n UseSizeReactiveResult<T>;\n\n/**\n * Element dimensions via the shared ResizeObserver singleton.\n *\n * Pass `onResize` for zero-re-render mode (canvas, animation loops).\n * Without it, `size` updates via state on every dimension change.\n * `sizeRef` is always current in both modes.\n *\n * @example\n * // Reactive (re-renders on resize)\n * const { ref, size } = useSize();\n *\n * // Transient (no re-renders — read sizeRef in onTick/draw)\n * const { ref, sizeRef } = useSize({ onResize: (s) => applySize(s) });\n */\nexport function useSize<T extends Element = HTMLDivElement>(\n options: UseSizeOptions<T> & { onResize: SizeCallback },\n): UseSizeTransientResult<T>;\nexport function useSize<T extends Element = HTMLDivElement>(\n options?: UseSizeOptions<T>,\n): UseSizeReactiveResult<T>;\nexport function useSize<T extends Element = HTMLDivElement>(\n options?: UseSizeOptions<T>,\n): UseSizeReactiveResult<T> | UseSizeTransientResult<T> {\n const [size, setSize] = useState<Size | null>(null);\n const sizeRef = useRef<Size | null>(null);\n const prevWidth = useRef<number | null>(null);\n const prevHeight = useRef<number | null>(null);\n const onResizeRef = useSyncedRef(options?.onResize);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n const boxOption: 'content-box' | 'border-box' | undefined = options?.box;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const unobserve: () => void = observeResize(\n element,\n (entry) => {\n const resolved: ResizeObserverSize | undefined =\n boxOption === 'border-box'\n ? entry.borderBoxSize[0]\n : entry.contentBoxSize[0];\n if (!resolved) return;\n\n const width: number = resolved.inlineSize;\n const height: number = resolved.blockSize;\n\n if (width === prevWidth.current && height === prevHeight.current)\n return;\n prevWidth.current = width;\n prevHeight.current = height;\n\n const next: Size = { width, height };\n sizeRef.current = next;\n\n if (onResizeRef.current) {\n onResizeRef.current(next);\n } else {\n setSize(next);\n }\n },\n boxOption,\n );\n\n return unobserve;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boxOption]);\n\n return { ref, size, sizeRef };\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ContainerBreakpoint {\n minWidth?: number;\n maxWidth?: number;\n minHeight?: number;\n maxHeight?: number;\n}\n\nexport interface UseContainerQueryOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to measure. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n}\n\nexport interface UseContainerQueryResult<T extends Element = HTMLDivElement> {\n /** Attach to the element you want to match against the breakpoint. */\n ref: RefObject<T | null>;\n /** Whether the element currently matches the breakpoint. */\n matches: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// useContainerQuery\n// ---------------------------------------------------------------------------\n\n/**\n * Returns whether an element matches a size-based container breakpoint.\n *\n * Unlike `useSize` (which re-renders on every pixel of resize), this hook only\n * re-renders when the match result changes, i.e. when the element crosses a\n * breakpoint boundary. Uses the shared ResizeObserver singleton.\n *\n * @example\n * const { ref, matches } = useContainerQuery({ minWidth: 600 });\n * return <div ref={ref}>{matches ? 'wide' : 'narrow'}</div>;\n */\nexport function useContainerQuery<T extends Element = HTMLDivElement>(\n breakpoint: ContainerBreakpoint,\n options?: UseContainerQueryOptions<T>,\n): UseContainerQueryResult<T> {\n const [matches, setMatches] = useState(false);\n const matchesRef = useRef(false);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n const { minWidth, maxWidth, minHeight, maxHeight } = breakpoint;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const unobserve: () => void = observeResize(element, (entry) => {\n const box = entry.contentBoxSize[0];\n if (!box) return;\n\n const width: number = box.inlineSize;\n const height: number = box.blockSize;\n\n const nowMatches: boolean = evaluateBreakpoint(\n width,\n height,\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n );\n\n // Only re-render when the boolean flips — not on every pixel of resize.\n if (nowMatches !== matchesRef.current) {\n matchesRef.current = nowMatches;\n setMatches(nowMatches);\n }\n });\n\n return unobserve;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [minWidth, maxWidth, minHeight, maxHeight]);\n\n return { ref, matches };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction evaluateBreakpoint(\n width: number,\n height: number,\n minWidth?: number,\n maxWidth?: number,\n minHeight?: number,\n maxHeight?: number,\n): boolean {\n if (minWidth !== undefined && width < minWidth) return false;\n if (maxWidth !== undefined && width > maxWidth) return false;\n if (minHeight !== undefined && height < minHeight) return false;\n if (maxHeight !== undefined && height > maxHeight) return false;\n return true;\n}\n","import { useState, useEffect, useRef, type RefObject } from 'react';\n\nimport { createScrollProgress } from '../../core/scroll-progress';\nimport { useSyncedRef } from '../use-synced-ref';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ScrollProgressCallback = (progress: number) => void;\n\nexport interface UseScrollProgressOptions<T extends Element = HTMLDivElement> {\n /**\n * Element to observe. Optional. When omitted, attach the returned `ref`.\n */\n ref?: RefObject<T | null>;\n /** Number of evenly-spaced thresholds. Default 20 (~5% granularity). */\n steps?: number;\n root?: Element | null;\n rootMargin?: string;\n /**\n * Called on every threshold crossing. When provided, `progress` stays `0`\n * and no re-renders occur, the right path for scroll-driven animation\n * consumers that read progress imperatively.\n */\n onProgress?: ScrollProgressCallback;\n}\n\nexport interface UseScrollProgressReactiveResult<\n T extends Element = HTMLDivElement,\n> {\n ref: RefObject<T | null>;\n /** Fraction of the element currently visible (0–1). */\n progress: number;\n /** Fraction visible via ref. Always current, never triggers re-render. */\n progressRef: RefObject<number>;\n}\n\nexport interface UseScrollProgressTransientResult<\n T extends Element = HTMLDivElement,\n> {\n ref: RefObject<T | null>;\n /** Fraction visible via ref. Always current, never triggers re-render. */\n progressRef: RefObject<number>;\n}\n\n/** @deprecated Use `UseScrollProgressReactiveResult` or `UseScrollProgressTransientResult`. */\nexport type UseScrollProgressResult<T extends Element = HTMLDivElement> =\n UseScrollProgressReactiveResult<T>;\n\n// ---------------------------------------------------------------------------\n// useScrollProgress\n// ---------------------------------------------------------------------------\n\n/**\n * Element visibility ratio (0–1) via the shared IntersectionObserver pool.\n *\n * Pass `onProgress` for zero-re-render mode (scroll-driven animation).\n * Without it, `progress` updates via state at each threshold crossing.\n * `progressRef` is always current in both modes.\n *\n * @example\n * // Reactive (re-renders at threshold crossings)\n * const { ref, progress } = useScrollProgress();\n *\n * // Transient (no re-renders — read progressRef in onTick)\n * const { ref, progressRef } = useScrollProgress({\n * onProgress: (p) => { el.style.opacity = String(p); },\n * });\n */\nexport function useScrollProgress<T extends Element = HTMLDivElement>(\n options: UseScrollProgressOptions<T> & {\n onProgress: ScrollProgressCallback;\n },\n): UseScrollProgressTransientResult<T>;\nexport function useScrollProgress<T extends Element = HTMLDivElement>(\n options?: UseScrollProgressOptions<T>,\n): UseScrollProgressReactiveResult<T>;\nexport function useScrollProgress<T extends Element = HTMLDivElement>(\n options?: UseScrollProgressOptions<T>,\n): UseScrollProgressReactiveResult<T> | UseScrollProgressTransientResult<T> {\n const [progress, setProgress] = useState(0);\n const progressRef = useRef(0);\n const steps: number | undefined = options?.steps;\n const rootMargin: string | undefined = options?.rootMargin;\n const onProgressRef = useSyncedRef(options?.onProgress);\n\n const internalRef = useRef<T | null>(null);\n const ref: RefObject<T | null> = options?.ref ?? internalRef;\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const scrollProgress = createScrollProgress({\n element,\n onProgress: (ratio: number) => {\n progressRef.current = ratio;\n\n if (onProgressRef.current) {\n onProgressRef.current(ratio);\n } else {\n setProgress(ratio);\n }\n },\n steps,\n root: options?.root,\n rootMargin,\n });\n\n return () => scrollProgress.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [steps, rootMargin]);\n\n return { ref, progress, progressRef };\n}\n","import { useState, useEffect, type RefObject } from 'react';\n\nimport { createRenderState, type RenderPhase } from '../../core/render-state';\n\nexport type { RenderPhase } from '../../core/render-state';\n\n/**\n * Track whether the browser is rendering an element or skipping it under\n * `content-visibility` (e.g. a `Defer` subtree). Returns `'rendered'` until the\n * browser reports otherwise.\n *\n * Use it to pause raw, non-phase work (a hand-written rAF loop, `setInterval`)\n * when the subtree stops painting. phase loops self-pause off-screen already.\n * Has no layout effect. Safe for CLS.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * const phase = useRenderState(ref);\n * useEffect(() => {\n * if (phase === 'skipped') clock.pause();\n * else clock.resume();\n * }, [phase]);\n * return <Defer ref={ref}><Heavy /></Defer>;\n */\nexport function useRenderState<T extends Element = HTMLDivElement>(\n ref: RefObject<T | null>,\n): RenderPhase {\n const [phase, setPhase] = useState<RenderPhase>('rendered');\n\n useEffect(() => {\n const element: Element | null = ref.current;\n if (!element) return;\n\n const render = createRenderState({\n element,\n onPhaseChange: setPhase,\n });\n\n return () => render.stop();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return phase;\n}\n","import { useState, useEffect } from 'react';\n\nimport { whenIdle, type IdleOptions } from '../../core/idle';\n\nexport type { IdleOptions } from '../../core/idle';\n\n/**\n * Returns `false`, then `true` once the browser is idle after mount. Use it to\n * defer non-critical work or mounting until the main thread is free.\n *\n * SSR-safe: returns `false` on the server and during the first client render.\n *\n * @example\n * const idle = useIdle();\n * return idle ? <Analytics /> : null;\n */\nexport function useIdle(options?: IdleOptions): boolean {\n const [idle, setIdle] = useState(false);\n const timeout = options?.timeout;\n\n useEffect(() => {\n const cancel: () => void = whenIdle(() => setIdle(true), { timeout });\n return cancel;\n }, [timeout]);\n\n return idle;\n}\n","import { useEffect } from 'react';\n\nimport { whenIdle, type IdleOptions } from '../../core/idle';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport type { IdleOptions } from '../../core/idle';\n\n/**\n * Run a callback once, when the browser is idle after mount. The effect-shaped\n * counterpart to `useIdle`. Use it for side effects (prefetching a chunk,\n * warming a cache, `import()`) rather than rendering.\n *\n * Cancels automatically on unmount, and always calls the latest `callback`\n * without re-subscribing. SSR-safe: nothing runs on the server.\n *\n * @example\n * // Prefetch a heavy panel during idle time so it opens instantly later.\n * useWhenIdle(() => void import('./chat-panel'));\n */\nexport function useWhenIdle(callback: () => void, options?: IdleOptions): void {\n const callbackRef = useSyncedRef(callback);\n const timeout = options?.timeout;\n\n useEffect(() => {\n const cancel: () => void = whenIdle(() => callbackRef.current(), {\n timeout,\n });\n return cancel;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [timeout]);\n}\n","import {\n useState,\n useEffect,\n useRef,\n useCallback,\n type RefObject,\n} from 'react';\n\nimport { subscribeDpr, readDpr } from '../../core/_internal/pool/dpr';\nimport { observeResize } from '../../core/_internal/pool/ro-pool';\nimport {\n createLoop,\n type LoopPhase,\n type LoopReason,\n type Quality,\n type DegradedBehavior,\n type DegradedReason,\n type ReducedMotionBehavior,\n} from '../../core/loop';\nimport type { FrameState } from '../../core/tick';\nimport { degradedConfig } from '../_internal/degraded-config';\nimport { useSyncedRef } from '../use-synced-ref';\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Per-frame canvas draw callback. Receives the 2D context, frame state, and\n * current element size. Draw directly to the canvas. Never call React\n * `setState` here.\n */\nexport type CanvasDrawFn = (\n ctx: CanvasRenderingContext2D,\n frame: FrameState,\n size: Size,\n) => void;\n\nexport interface UseCanvasOptions {\n containerRef: RefObject<Element | null>;\n canvasRef: RefObject<HTMLCanvasElement | null>;\n /**\n * Called every frame with the 2D context, frame state, and current element size.\n * Draw directly to the canvas. Never call React `setState` here.\n */\n draw: CanvasDrawFn;\n fps?: number;\n enabled?: boolean;\n reducedMotion?: ReducedMotionBehavior;\n /** Behavior when quality degrades. Default `'throttle'`. For heavy GPU work, `'pause'` is often the right call. */\n degraded?: DegradedBehavior;\n /** FPS cap when `degraded` is `'throttle'`. Default `30`. */\n degradedFps?: number;\n}\n\nexport interface UseCanvasResult {\n restart: () => void;\n phase: LoopPhase;\n phaseReason: LoopReason;\n quality: Quality;\n qualityReason: DegradedReason | undefined;\n}\n\nconst INITIAL_STATE: Omit<UseCanvasResult, 'restart'> = {\n phase: 'idle',\n phaseReason: 'initial',\n quality: 'full',\n qualityReason: undefined,\n};\n\n/**\n * Canvas-specific animation with DPR-aware sizing, ResizeObserver coalescing,\n * context management, and GPU context loss recovery.\n *\n * @example\n * useCanvas({\n * containerRef,\n * canvasRef,\n * draw: (ctx, frame, size) => {\n * ctx.clearRect(0, 0, size.width, size.height);\n * // render...\n * },\n * });\n */\nexport function useCanvas(options: UseCanvasOptions): UseCanvasResult {\n const {\n containerRef,\n canvasRef,\n fps,\n enabled = true,\n reducedMotion,\n degraded,\n degradedFps,\n } = options;\n const drawRef = useSyncedRef(options.draw);\n\n const [state, setState] = useState(INITIAL_STATE);\n const [restartNonce, setRestartNonce] = useState(0);\n\n const ctxRef = useRef<CanvasRenderingContext2D | null>(null);\n const sizeRef = useRef<Size>({ width: 0, height: 0 });\n const qualityRef = useSyncedRef(state.quality);\n\n useEffect(() => {\n const container: Element | null = containerRef.current;\n const canvasEl: HTMLCanvasElement | null = canvasRef.current;\n if (!container || !canvasEl || !enabled) return;\n const canvas: HTMLCanvasElement = canvasEl;\n\n const initialCtx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n if (!initialCtx) return;\n ctxRef.current = initialCtx;\n\n let dpr: number = readDpr();\n let contextLost = false;\n\n // --- Canvas buffer sizing ---\n\n function applySize(\n width: number,\n height: number,\n physicalBox?: ResizeObserverSize,\n ): void {\n sizeRef.current = { width, height };\n const isDegraded: boolean = qualityRef.current === 'degraded';\n\n let bufferWidth: number;\n let bufferHeight: number;\n\n if (isDegraded) {\n bufferWidth = width;\n bufferHeight = height;\n } else if (physicalBox) {\n bufferWidth = physicalBox.inlineSize;\n bufferHeight = physicalBox.blockSize;\n } else {\n bufferWidth = width * dpr;\n bufferHeight = height * dpr;\n }\n\n canvas.width = bufferWidth;\n canvas.height = bufferHeight;\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n\n const effectiveDpr: number = isDegraded ? 1 : dpr;\n ctxRef.current?.setTransform(effectiveDpr, 0, 0, effectiveDpr, 0, 0);\n }\n\n // --- DPR monitoring (e.g. user drags window between monitors) ---\n\n const unsubDpr: () => void = subscribeDpr((newDpr) => {\n dpr = newDpr;\n applySize(sizeRef.current.width, sizeRef.current.height);\n });\n\n // --- Resize via shared RO pool ---\n\n const unobserve: () => void = observeResize(container, (entry) => {\n const box = entry.contentBoxSize[0];\n if (!box) return;\n const physicalBox: ResizeObserverSize | undefined =\n entry.devicePixelContentBoxSize?.[0];\n applySize(box.inlineSize, box.blockSize, physicalBox);\n });\n\n // --- GPU context loss recovery ---\n\n function onContextLost(event: Event): void {\n event.preventDefault();\n contextLost = true;\n }\n\n function onContextRestored(): void {\n const restoredCtx: CanvasRenderingContext2D | null =\n canvas.getContext('2d');\n if (!restoredCtx) return;\n ctxRef.current = restoredCtx;\n contextLost = false;\n applySize(sizeRef.current.width, sizeRef.current.height);\n }\n\n canvas.addEventListener('contextlost', onContextLost);\n canvas.addEventListener('contextrestored', onContextRestored);\n\n // --- Animation loop ---\n\n let loopInstance: ReturnType<typeof createLoop> | null = null;\n\n const loop = createLoop({\n element: container,\n fps,\n reducedMotion,\n ...degradedConfig(degraded, degradedFps),\n onTick: (frame) => {\n if (contextLost || !ctxRef.current) return;\n drawRef.current(ctxRef.current, frame, sizeRef.current);\n },\n onPhaseChange: (phase, reason) => {\n setState({\n phase,\n phaseReason: reason,\n quality: loopInstance?.quality ?? 'full',\n qualityReason: loopInstance?.qualityReason,\n });\n },\n });\n loopInstance = loop;\n\n // --- Teardown ---\n\n function teardown(): void {\n loop.stop();\n loopInstance = null;\n unobserve();\n unsubDpr();\n canvas.removeEventListener('contextlost', onContextLost);\n canvas.removeEventListener('contextrestored', onContextRestored);\n }\n\n return teardown;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, fps, reducedMotion, degraded, degradedFps, restartNonce]);\n\n // Restart bumps a nonce so the effect re-runs: it tears down the current\n // loop + observers and rebuilds them on the next cycle.\n const restart = useCallback(() => {\n setRestartNonce((n) => n + 1);\n }, []);\n\n return { restart, ...state };\n}\n","import { useState, useEffect, useRef } from 'react';\n\nimport { invalidDurationError } from '../../core/_internal/errors';\nimport type { ReducedMotionBehavior } from '../../core/loop';\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { clamp01, easeOutCubic } from '../../ease';\n\nexport interface UseTweenOptions {\n target: number;\n duration?: number;\n delay?: number;\n easing?: (progress: number) => number;\n enabled?: boolean;\n /** Default: `'complete'`. Tweens jump to target under reduced motion. */\n reducedMotion?: ReducedMotionBehavior;\n}\n\n/**\n * Animate a value from its current position to `target` over `duration`.\n *\n * Uses `useState` per frame. Appropriate for cheap renders (counters, opacity,\n * progress bars). For batch animations, use `useLoop` with ref-based DOM writes.\n *\n * @remarks\n * Unlike `createTicker`/`createLoop`, `useTween` drives its own rAF rather than\n * the shared frame-locked clock. It's a finite, self-completing tween whose value\n * must land in React state, so it doesn't need cross-loop visual sync, strong\n * pause, or delta clamping. Routing it through the shared clock would add bundle\n * weight for no benefit.\n *\n * @example\n * const value = useTween({ target: 100, duration: 500 });\n */\nexport function useTween(options: UseTweenOptions): number {\n const {\n target,\n duration = 300,\n delay = 0,\n easing = easeOutCubic,\n enabled = true,\n reducedMotion = 'complete',\n } = options;\n\n const [value, setValue] = useState(target);\n\n const fromRef = useRef(target);\n const currentRef = useRef(target);\n const isFirstRender = useRef(true);\n\n useEffect(() => {\n if (!Number.isFinite(duration) || duration <= 0) {\n invalidDurationError('useTween', duration);\n }\n\n // First render: sync refs without animating.\n if (isFirstRender.current) {\n isFirstRender.current = false;\n jumpToTarget({ target, fromRef, currentRef, setValue });\n return;\n }\n\n // Disabled or reduced motion: jump immediately.\n if (!enabled || (reducedMotion !== 'ignore' && prefersReducedMotion())) {\n jumpToTarget({ target, fromRef, currentRef, setValue });\n return;\n }\n\n // Already at target: nothing to animate.\n const from: number = currentRef.current;\n if (from === target) return;\n\n let rafId: number;\n let startTime: number | null = null;\n\n function tick(now: number): void {\n if (startTime === null) startTime = now;\n const elapsed: number = now - startTime - delay;\n\n // Still in the delay period — keep scheduling.\n if (elapsed < 0) {\n rafId = requestAnimationFrame(tick);\n return;\n }\n\n const progress: number = clamp01(elapsed / duration);\n const current: number = from + (target - from) * easing(progress);\n currentRef.current = current;\n setValue(current);\n\n if (progress < 1) {\n rafId = requestAnimationFrame(tick);\n } else {\n fromRef.current = target;\n }\n }\n\n rafId = requestAnimationFrame(tick);\n\n return () => {\n cancelAnimationFrame(rafId);\n // Preserve where we actually are so the next tween starts from here.\n fromRef.current = currentRef.current;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [target, duration, delay, enabled, reducedMotion]);\n\n return value;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface JumpToTargetOptions {\n target: number;\n fromRef: React.RefObject<number>;\n currentRef: React.RefObject<number>;\n setValue: (value: number) => void;\n}\n\nfunction jumpToTarget(options: JumpToTargetOptions): void {\n const { target, fromRef, currentRef, setValue } = options;\n fromRef.current = target;\n currentRef.current = target;\n setValue(target);\n}\n","import {\n useEffect,\n useRef,\n type EffectCallback,\n type DependencyList,\n} from 'react';\n\n/**\n * Like `useEffect` but skips the first invocation on mount.\n * Used by Presence to distinguish initial render from subsequent `show` changes.\n */\nexport function useUpdateEffect(\n effect: EffectCallback,\n deps: DependencyList,\n): void {\n const isMounted = useRef(false);\n\n useEffect(() => {\n if (!isMounted.current) {\n isMounted.current = true;\n return;\n }\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n","import {\n useState,\n useRef,\n useEffect,\n useCallback,\n type RefObject,\n} from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useUpdateEffect } from '../_internal/use-update-effect';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PresencePhase = 'idle' | 'entered' | 'exiting' | 'exited';\n\nexport type PresenceReason =\n | 'initial'\n | 'show'\n | 'hide'\n | 'animation-end'\n | 'interrupted';\n\nexport type PresenceMode = 'mount' | 'reveal';\n\nexport interface UsePresenceOptions {\n show: boolean;\n mode?: PresenceMode;\n /** Controls first-mount behavior. `'animate'` (default): enter animation plays. `'instant'`: appears immediately. */\n enter?: 'animate' | 'instant';\n /** Safety-net timeout in ms if transitionend/animationend doesn't fire during exit. Default 5000. */\n exitDuration?: number;\n /** Whether to respect the user's reduced motion preference. Default `'respect'`. */\n reducedMotion?: 'respect' | 'ignore';\n}\n\nexport interface UsePresenceResult {\n phase: PresencePhase;\n phaseReason: PresenceReason;\n /** Convenience: `phase !== 'idle' && phase !== 'exited'` for conditional rendering in mount mode. */\n mounted: boolean;\n ref: RefObject<Element | null>;\n /** Whether the component should stamp `data-enter=\"animate\"`. Accounts for enter option + reduced motion. */\n enter: 'animate' | 'instant';\n}\n\n// ---------------------------------------------------------------------------\n// usePresence\n// ---------------------------------------------------------------------------\n\n/**\n * Composable presence primitive for mount/unmount lifecycle with CSS transitions.\n *\n * Enter animations use CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Exit animations are JS-coordinated: waits for `transitionend`/`animationend`\n * before unmounting.\n *\n * @example\n * const { phase, ref, mounted, enter } = usePresence({ show: isOpen });\n * if (!mounted) return null;\n * return (\n * <div ref={ref} data-phase={phase} data-enter={enter === 'animate' ? 'animate' : undefined}\n * className=\"transition-opacity data-[enter=animate]:starting:opacity-0 data-[phase=exiting]:opacity-0\" />\n * );\n */\nexport function usePresence(options: UsePresenceOptions): UsePresenceResult {\n const {\n show,\n mode = 'mount',\n enter: enterOption = 'animate',\n exitDuration = 5000,\n reducedMotion = 'respect',\n } = options;\n\n const ref = useRef<Element | null>(null);\n\n const initialPhase: PresencePhase = show ? 'entered' : 'idle';\n\n const [phase, setPhase] = useState<PresencePhase>(initialPhase);\n const [reason, setReason] = useState<PresenceReason>('initial');\n\n const exitTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const exitCleanupRef = useRef<(() => void) | null>(null);\n\n const clearTimers = useCallback(() => {\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n if (exitCleanupRef.current) {\n exitCleanupRef.current();\n exitCleanupRef.current = null;\n }\n }, []);\n\n useEffect(() => () => clearTimers(), [clearTimers]);\n\n useUpdateEffect(() => {\n clearTimers();\n\n if (show) {\n setPhase((prev) => {\n setReason(prev === 'exiting' ? 'interrupted' : 'show');\n return 'entered';\n });\n } else {\n const shouldSkipAnimation =\n reducedMotion === 'respect' && prefersReducedMotion();\n\n if (shouldSkipAnimation) {\n const exitTarget: PresencePhase = mode === 'reveal' ? 'idle' : 'exited';\n setPhase(exitTarget);\n setReason('animation-end');\n } else {\n handleExit(\n ref,\n mode,\n exitDuration,\n setPhase,\n setReason,\n clearTimers,\n exitTimerRef,\n exitCleanupRef,\n );\n }\n }\n }, [show]);\n\n const mounted: boolean = phase !== 'idle' && phase !== 'exited';\n\n const isFirstMount = reason === 'initial';\n const wantsAnimation = !(isFirstMount && enterOption === 'instant');\n const motionAllowed = reducedMotion === 'ignore' || !prefersReducedMotion();\n const enter: 'animate' | 'instant' =\n wantsAnimation && motionAllowed ? 'animate' : 'instant';\n\n return { phase, phaseReason: reason, mounted, ref, enter };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction handleExit(\n ref: RefObject<Element | null>,\n mode: PresenceMode,\n exitDuration: number,\n setPhase: (\n phase: PresencePhase | ((prev: PresencePhase) => PresencePhase),\n ) => void,\n setReason: (reason: PresenceReason) => void,\n clearTimers: () => void,\n exitTimerRef: React.RefObject<ReturnType<typeof setTimeout> | null>,\n exitCleanupRef: React.RefObject<(() => void) | null>,\n): void {\n setPhase('exiting');\n setReason('hide');\n\n const exitTarget: PresencePhase = mode === 'reveal' ? 'idle' : 'exited';\n const element: Element | null = ref.current;\n\n function completeExit(): void {\n clearTimers();\n setPhase((current) => {\n if (current !== 'exiting') return current;\n setReason('animation-end');\n return exitTarget;\n });\n }\n\n function cleanup(): void {\n if (element) {\n element.removeEventListener('transitionend', completeExit);\n element.removeEventListener('animationend', completeExit);\n }\n if (exitTimerRef.current !== null) {\n clearTimeout(exitTimerRef.current);\n exitTimerRef.current = null;\n }\n exitCleanupRef.current = null;\n }\n\n exitCleanupRef.current = cleanup;\n\n if (element) {\n element.addEventListener('transitionend', completeExit, { once: true });\n element.addEventListener('animationend', completeExit, { once: true });\n }\n\n exitTimerRef.current = setTimeout(completeExit, exitDuration);\n}\n","import {\n useImperativeHandle,\n type ComponentProps,\n type JSX,\n type Ref,\n} from 'react';\n\nimport { usePresence, type PresenceMode } from '../use-presence';\n\nexport interface PresenceProps extends ComponentProps<'div'> {\n show: boolean;\n mode?: PresenceMode;\n /** Controls first-mount behavior. `'animate'` (default): enter animation plays. `'instant'`: appears immediately. */\n enter?: 'animate' | 'instant';\n /** Safety-net timeout in ms if transitionend/animationend doesn't fire during exit. Default 5000. */\n exitDuration?: number;\n /** Whether to respect the user's reduced motion preference. Default `'respect'`. */\n reducedMotion?: 'respect' | 'ignore';\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Renders a `div` that manages its own mounting lifecycle.\n *\n * Stamps `data-phase` for exit animations and `data-enter=\"animate\"` to gate\n * CSS `@starting-style` enter animations. Reduced motion is handled automatically.\n *\n * @example\n * <Presence\n * show={isOpen}\n * className=\"transition-opacity data-[enter=animate]:starting:opacity-0 data-[phase=exiting]:opacity-0\"\n * >\n * Modal content\n * </Presence>\n */\nexport function Presence({\n show,\n mode,\n enter: enterOption,\n exitDuration,\n reducedMotion,\n ref: forwardedRef,\n children,\n ...divProps\n}: PresenceProps): JSX.Element | null {\n const { phase, ref, mounted, enter } = usePresence({\n show,\n mode,\n enter: enterOption,\n exitDuration,\n reducedMotion,\n });\n\n useImperativeHandle(forwardedRef, () => ref.current as HTMLDivElement);\n\n if (!mounted && mode !== 'reveal') return null;\n\n return (\n <div\n {...divProps}\n ref={ref as React.RefObject<HTMLDivElement | null>}\n data-phase={phase}\n data-enter={enter === 'animate' ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n","import {\n useRef,\n type ComponentProps,\n type JSX,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useSight } from '../use-sight';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WhenVisibleProps extends ComponentProps<'div'> {\n /** IntersectionObserver rootMargin. Default `'200px'` (generous headroom for preloading). */\n rootMargin?: string;\n /** IntersectionObserver threshold. */\n threshold?: number | number[];\n /** IntersectionObserver root element. */\n root?: Element | null;\n /** Content shown while awaiting intersection. Sentinel div is always rendered for IO. */\n fallback?: ReactNode;\n /** Forwarded to the rendered div in both states (the sentinel before visible, the entered div after). Populated at mount. */\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// WhenVisible\n// ---------------------------------------------------------------------------\n\n/**\n * Mounts children when the element enters the viewport. One-shot (once\n * triggered, stays mounted).\n *\n * Enter animation uses CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Reduced motion is automatic: the attribute is not stamped when the user\n * prefers reduced motion.\n *\n * @example\n * <WhenVisible rootMargin=\"200px\" className=\"transition-opacity data-[enter=animate]:starting:opacity-0\">\n * <HeavyChart />\n * </WhenVisible>\n */\nexport function WhenVisible({\n rootMargin = '200px',\n threshold,\n root,\n fallback,\n children,\n ref: forwardedRef,\n ...divProps\n}: WhenVisibleProps): JSX.Element {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const { phase } = useSight({\n ref: sentinelRef,\n observe: 'once',\n rootMargin,\n threshold,\n root,\n });\n\n const setRef = (node: HTMLDivElement | null): void => {\n sentinelRef.current = node;\n assignRef(forwardedRef, node);\n };\n\n if (phase !== 'visible') {\n return (\n <div ref={setRef} {...divProps}>\n {fallback}\n </div>\n );\n }\n\n const motionAllowed = !prefersReducedMotion();\n\n return (\n <div\n {...divProps}\n ref={setRef}\n data-phase=\"entered\"\n data-enter={motionAllowed ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n\nfunction assignRef(\n ref: Ref<HTMLDivElement> | undefined,\n node: HTMLDivElement | null,\n): void {\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n}\n","import type { ComponentProps, JSX, ReactNode, Ref } from 'react';\n\nimport { prefersReducedMotion } from '../../core/reduced-motion';\nimport { useIdle } from '../use-idle';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WhenIdleProps extends ComponentProps<'div'> {\n /** Max ms to wait before mounting even if no idle period occurs. */\n timeout?: number;\n /** Content shown until the browser is idle. */\n fallback?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// WhenIdle\n// ---------------------------------------------------------------------------\n\n/**\n * Mounts children once the browser is idle after first paint. One-shot (once\n * mounted, stays mounted). Use it to defer non-critical UI off the critical path.\n *\n * Children are not server-rendered (idle never fires during SSR), so reserve\n * this for non-critical content. For viewport-gated mounting use `WhenVisible`;\n * to keep content in the DOM but skip painting use `Defer`.\n *\n * Enter animation uses CSS `@starting-style`, gated by `data-enter=\"animate\"`.\n * Reduced motion is automatic: the attribute is not stamped when the user\n * prefers reduced motion.\n *\n * @example\n * <WhenIdle fallback={<Skeleton />}>\n * <SecondaryPanel />\n * </WhenIdle>\n */\nexport function WhenIdle({\n timeout,\n fallback,\n children,\n ref: forwardedRef,\n ...divProps\n}: WhenIdleProps): JSX.Element {\n const idle = useIdle({ timeout });\n\n if (!idle) {\n return <div {...divProps}>{fallback}</div>;\n }\n\n const motionAllowed = !prefersReducedMotion();\n\n return (\n <div\n {...divProps}\n ref={forwardedRef}\n data-phase=\"entered\"\n data-enter={motionAllowed ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n","import type { ComponentProps, CSSProperties, JSX, Ref } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface DeferProps extends Omit<ComponentProps<'div'>, 'style'> {\n /**\n * Approximate size reserved before first paint (any CSS length, e.g. `'800px'`).\n * After the first render the browser remembers the real size. Default `'1000px'`.\n */\n estimatedHeight?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\n// ---------------------------------------------------------------------------\n// Defer\n// ---------------------------------------------------------------------------\n\n/**\n * Skip the browser's rendering work (style, layout, paint) for off-screen\n * content via `content-visibility: auto`. Pure CSS, no JS, no observer.\n *\n * Children stay in the DOM and are server-rendered (SEO- and CLS-safe).\n * `contain-intrinsic-size: auto <estimatedHeight>` reserves space so the\n * scrollbar does not jump. Defers rendering only, not hydration or mounting.\n *\n * The render-skip styles are encapsulated and cannot be overridden. There is\n * no `style` prop. Style the wrapper with `className`; this keeps the\n * no-layout-shift guarantee intact.\n *\n * @example\n * <Defer estimatedHeight=\"600px\" className=\"my-section\">\n * <ArticleSection />\n * </Defer>\n *\n * @remarks\n * Animations inside a `Defer` keep running while paint is skipped. phase loops\n * self-pause off-screen on their own; for raw rAF/interval work, gate it with\n * `useRenderState`.\n */\nexport function Defer({\n estimatedHeight = '1000px',\n children,\n ref,\n ...divProps\n}: DeferProps): JSX.Element {\n const deferStyle: CSSProperties = {\n contentVisibility: 'auto',\n containIntrinsicSize: `auto ${estimatedHeight}`,\n };\n\n return (\n <div {...divProps} ref={ref} style={deferStyle}>\n {children}\n </div>\n );\n}\n","import {\n createContext,\n use,\n useState,\n useEffect,\n useMemo,\n useCallback,\n useImperativeHandle,\n type ComponentProps,\n type JSX,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { missingContextError } from '../../core/_internal/errors';\nimport { usePresence } from '../use-presence';\nimport { useSyncedRef } from '../use-synced-ref';\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ninterface SwapContext {\n current: string;\n active: string;\n exitDuration: number;\n /** 'instant' on first mount (prevents CLS), 'animate' on subsequent swaps. */\n enter: 'animate' | 'instant';\n onExited: (id: string) => void;\n}\n\nconst SwapCtx = createContext<SwapContext | null>(null);\n\n// ---------------------------------------------------------------------------\n// Swap\n// ---------------------------------------------------------------------------\n\nexport interface SwapProps extends ComponentProps<'div'> {\n active: string;\n exitDuration?: number;\n children: ReactNode;\n}\n\n/**\n * Coordinated exit-then-enter transitions for N states.\n * Only one state is entering or exiting at a time (no overlap).\n *\n * The current state fully exits before the new state enters. Rapid changes\n * (A->B->C during A's exit) skip intermediate states and jump to the latest.\n *\n * @example\n * <Swap active={success ? 'success' : 'form'}>\n * <Swap.State id=\"form\" className=\"transition-all data-[phase=exiting]:opacity-0\">\n * <Form />\n * </Swap.State>\n * <Swap.State id=\"success\" className=\"transition-all data-[enter=animate]:starting:opacity-0\">\n * <SuccessMessage />\n * </Swap.State>\n * </Swap>\n */\nfunction SwapRoot({\n active,\n exitDuration = 5000,\n children,\n ...divProps\n}: SwapProps): JSX.Element {\n const [current, setCurrent] = useState(active);\n const [hasSwapped, setHasSwapped] = useState(false);\n const activeRef = useSyncedRef(active);\n\n const onExited = useCallback(\n (id: string): void => {\n setHasSwapped(true);\n setCurrent((cur) => (cur === id ? activeRef.current : cur));\n },\n [activeRef],\n );\n\n const enter: 'animate' | 'instant' = hasSwapped ? 'animate' : 'instant';\n\n const ctx: SwapContext = useMemo(\n () => ({ current, active, exitDuration, enter, onExited }),\n [current, active, exitDuration, enter, onExited],\n );\n\n return (\n <SwapCtx.Provider value={ctx}>\n <div {...divProps}>{children}</div>\n </SwapCtx.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Swap.State\n// ---------------------------------------------------------------------------\n\nexport interface SwapStateProps extends ComponentProps<'div'> {\n id: string;\n ref?: Ref<HTMLDivElement>;\n}\n\nfunction SwapState({\n id,\n ref: forwardedRef,\n children,\n ...divProps\n}: SwapStateProps): JSX.Element | null {\n const ctx = use(SwapCtx);\n if (!ctx) missingContextError('Swap.State', 'Swap');\n\n const isCurrent: boolean = ctx.current === id;\n const show: boolean = isCurrent && ctx.active === id;\n\n const { phase, ref, mounted, enter } = usePresence({\n show,\n mode: 'mount',\n enter: ctx.enter,\n exitDuration: ctx.exitDuration,\n });\n\n useImperativeHandle(forwardedRef, () => ref.current as HTMLDivElement);\n\n useEffect(() => {\n if (isCurrent && !show && phase === 'exited') {\n ctx.onExited(id);\n }\n }, [isCurrent, show, phase, id, ctx]);\n\n if (!isCurrent || !mounted) return null;\n\n return (\n <div\n {...divProps}\n ref={ref as React.RefObject<HTMLDivElement | null>}\n data-phase={phase}\n data-enter={enter === 'animate' ? 'animate' : undefined}\n >\n {children}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Compound component export\n// ---------------------------------------------------------------------------\n\nexport const Swap: typeof SwapRoot & { State: typeof SwapState } =\n Object.assign(SwapRoot, { State: SwapState });\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phase",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A lightweight, lifecycle-aware UI performance layer for the web. Includes tools to optimize render performance, build performant animations, and manage layout and off-screen resources",
5
5
  "author": "Vercel",
6
6
  "license": "MIT",