phase 0.0.5 → 0.0.7
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 +98 -19
- package/dist/{index-BynP-ee0.d.ts → index-BRyL_Inx.d.ts} +89 -2
- package/dist/index-BRyL_Inx.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react.d.ts +83 -20
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +179 -52
- package/dist/react.js.map +1 -1
- package/dist/{mutation-BDx6r5D3.js → scroll-DZvWyPQE.js} +355 -2
- package/dist/scroll-DZvWyPQE.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-BynP-ee0.d.ts.map +0 -1
- package/dist/mutation-BDx6r5D3.js.map +0 -1
package/dist/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { clamp01, easeOutCubic } from "./ease.js";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as REDUCED_MOTION_QUERY, c as readDpr, d as createScrollProgress, f as createLoop, g as createSight, h as subscribeMediaQuery, i as createMutation, l as subscribeDpr, m as readMediaQuery, n as observeResize, o as prefersReducedMotion, p as createLifecycle, r as createPointer, s as whenIdle, t as createScroll, u as createRenderState, x as missingContextError, y as invalidDurationError } from "./scroll-DZvWyPQE.js";
|
|
4
4
|
import { createContext, createElement, use, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region src/react/use-synced-ref/index.ts
|
|
@@ -53,7 +53,7 @@ function degradedConfig(degraded, degradedFps) {
|
|
|
53
53
|
}
|
|
54
54
|
//#endregion
|
|
55
55
|
//#region src/react/use-loop/index.ts
|
|
56
|
-
const INITIAL_STATE$
|
|
56
|
+
const INITIAL_STATE$6 = {
|
|
57
57
|
phase: "idle",
|
|
58
58
|
phaseReason: "initial",
|
|
59
59
|
quality: "full",
|
|
@@ -75,12 +75,12 @@ function useLoop(options) {
|
|
|
75
75
|
const onTickRef = useSyncedRef(options.onTick);
|
|
76
76
|
const internalRef = useRef(null);
|
|
77
77
|
const ref = options.ref ?? internalRef;
|
|
78
|
-
const [state, setState] = useState(INITIAL_STATE$
|
|
78
|
+
const [state, setState] = useState(INITIAL_STATE$6);
|
|
79
79
|
const loopRef = useRef(null);
|
|
80
80
|
useEffect(() => {
|
|
81
81
|
const element = ref.current;
|
|
82
82
|
if (!element || !enabled) {
|
|
83
|
-
setState(INITIAL_STATE$
|
|
83
|
+
setState(INITIAL_STATE$6);
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
const loop = createLoop({
|
|
@@ -119,7 +119,7 @@ function useLoop(options) {
|
|
|
119
119
|
}
|
|
120
120
|
//#endregion
|
|
121
121
|
//#region src/react/use-lifecycle/index.ts
|
|
122
|
-
const INITIAL_STATE$
|
|
122
|
+
const INITIAL_STATE$5 = {
|
|
123
123
|
phase: "idle",
|
|
124
124
|
phaseReason: "initial"
|
|
125
125
|
};
|
|
@@ -148,12 +148,12 @@ function useLifecycle(options) {
|
|
|
148
148
|
const onPhaseChangeRef = useSyncedRef(options?.onPhaseChange);
|
|
149
149
|
const internalRef = useRef(null);
|
|
150
150
|
const ref = options?.ref ?? internalRef;
|
|
151
|
-
const [state, setState] = useState(INITIAL_STATE$
|
|
151
|
+
const [state, setState] = useState(INITIAL_STATE$5);
|
|
152
152
|
const lifecycleRef = useRef(null);
|
|
153
153
|
useEffect(() => {
|
|
154
154
|
const element = ref.current;
|
|
155
155
|
if (!element || !enabled) {
|
|
156
|
-
setState(INITIAL_STATE$
|
|
156
|
+
setState(INITIAL_STATE$5);
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
159
159
|
const lifecycle = createLifecycle({
|
|
@@ -235,12 +235,12 @@ function usePrefersReducedMotion() {
|
|
|
235
235
|
}
|
|
236
236
|
//#endregion
|
|
237
237
|
//#region src/react/use-sight/index.ts
|
|
238
|
-
const INITIAL_STATE$
|
|
238
|
+
const INITIAL_STATE$4 = {
|
|
239
239
|
phase: "unknown",
|
|
240
240
|
phaseReason: "initial"
|
|
241
241
|
};
|
|
242
242
|
function useSight(options) {
|
|
243
|
-
const [state, setState] = useState(INITIAL_STATE$
|
|
243
|
+
const [state, setState] = useState(INITIAL_STATE$4);
|
|
244
244
|
const observe = options?.observe ?? "continuous";
|
|
245
245
|
const phaseRef = useRef("unknown");
|
|
246
246
|
const phaseReasonRef = useRef("initial");
|
|
@@ -283,40 +283,6 @@ function useSight(options) {
|
|
|
283
283
|
};
|
|
284
284
|
}
|
|
285
285
|
//#endregion
|
|
286
|
-
//#region src/core/_internal/pool/ro-pool.ts
|
|
287
|
-
let observer = null;
|
|
288
|
-
const callbacks = /* @__PURE__ */ new Map();
|
|
289
|
-
/**
|
|
290
|
-
* Observe an element via a singleton ResizeObserver.
|
|
291
|
-
* One RO instance for the entire page. Per-element `box` options are
|
|
292
|
-
* forwarded to `ResizeObserver.observe()`.
|
|
293
|
-
*
|
|
294
|
-
* @returns Cleanup function that unobserves the element.
|
|
295
|
-
*/
|
|
296
|
-
function observeResize(element, callback, box) {
|
|
297
|
-
callbacks.set(element, callback);
|
|
298
|
-
getObserver().observe(element, box ? { box } : void 0);
|
|
299
|
-
let disposed = false;
|
|
300
|
-
return () => {
|
|
301
|
-
if (disposed) return;
|
|
302
|
-
disposed = true;
|
|
303
|
-
if (callbacks.get(element) === callback) {
|
|
304
|
-
callbacks.delete(element);
|
|
305
|
-
observer?.unobserve(element);
|
|
306
|
-
}
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
/** Lazy-created singleton. RO takes zero constructor options, so one instance can observe everything. */
|
|
310
|
-
function getObserver() {
|
|
311
|
-
if (!observer) observer = new ResizeObserver((entries) => {
|
|
312
|
-
for (const entry of entries) {
|
|
313
|
-
const cb = callbacks.get(entry.target);
|
|
314
|
-
if (cb) cb(entry);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
return observer;
|
|
318
|
-
}
|
|
319
|
-
//#endregion
|
|
320
286
|
//#region src/react/use-size/index.ts
|
|
321
287
|
function useSize(options) {
|
|
322
288
|
const [size, setSize] = useState(null);
|
|
@@ -512,7 +478,7 @@ function useWhenIdle(callback, options) {
|
|
|
512
478
|
}
|
|
513
479
|
//#endregion
|
|
514
480
|
//#region src/react/use-canvas/index.ts
|
|
515
|
-
const INITIAL_STATE$
|
|
481
|
+
const INITIAL_STATE$3 = {
|
|
516
482
|
phase: "idle",
|
|
517
483
|
phaseReason: "initial",
|
|
518
484
|
quality: "full",
|
|
@@ -535,7 +501,7 @@ const INITIAL_STATE$1 = {
|
|
|
535
501
|
function useCanvas(options) {
|
|
536
502
|
const { containerRef, canvasRef, fps, enabled = true, reducedMotion, degraded, degradedFps } = options;
|
|
537
503
|
const drawRef = useSyncedRef(options.draw);
|
|
538
|
-
const [state, setState] = useState(INITIAL_STATE$
|
|
504
|
+
const [state, setState] = useState(INITIAL_STATE$3);
|
|
539
505
|
const [restartNonce, setRestartNonce] = useState(0);
|
|
540
506
|
const ctxRef = useRef(null);
|
|
541
507
|
const sizeRef = useRef({
|
|
@@ -647,23 +613,32 @@ function useCanvas(options) {
|
|
|
647
613
|
}
|
|
648
614
|
//#endregion
|
|
649
615
|
//#region src/react/use-mutation/index.ts
|
|
650
|
-
const INITIAL_STATE = {
|
|
616
|
+
const INITIAL_STATE$2 = {
|
|
651
617
|
phase: "paused",
|
|
652
618
|
phaseReason: "initial"
|
|
653
619
|
};
|
|
620
|
+
/**
|
|
621
|
+
* Lifecycle-aware MutationObserver with rAF-coalesced callbacks.
|
|
622
|
+
* Auto-pauses off-screen and tears down on unmount.
|
|
623
|
+
*
|
|
624
|
+
* Records are always delivered imperatively via `onMutations` (never state).
|
|
625
|
+
* Phase transitions (observing/paused) are infrequent, so `phase`/`phaseReason`
|
|
626
|
+
* are reactive state; read `phaseRef`/`phaseReasonRef` for the latest value
|
|
627
|
+
* inside `onMutations` without closure staleness. For synchronous phase
|
|
628
|
+
* reactions, use the core `createMutation` primitive.
|
|
629
|
+
*/
|
|
654
630
|
function useMutation(options) {
|
|
655
|
-
const [state, setState] = useState(INITIAL_STATE);
|
|
631
|
+
const [state, setState] = useState(INITIAL_STATE$2);
|
|
656
632
|
const { mutation: mutationInit, visibility = "pause", enabled = true, intersectionOptions } = options;
|
|
657
633
|
const phaseRef = useRef("paused");
|
|
658
634
|
const phaseReasonRef = useRef("initial");
|
|
659
635
|
const onMutationsRef = useSyncedRef(options.onMutations);
|
|
660
|
-
const onPhaseChangeRef = useSyncedRef(options.onPhaseChange);
|
|
661
636
|
const internalRef = useRef(null);
|
|
662
637
|
const ref = options.ref ?? internalRef;
|
|
663
638
|
useEffect(() => {
|
|
664
639
|
const element = ref.current;
|
|
665
640
|
if (!element || !enabled) {
|
|
666
|
-
setState(INITIAL_STATE);
|
|
641
|
+
setState(INITIAL_STATE$2);
|
|
667
642
|
phaseRef.current = "paused";
|
|
668
643
|
phaseReasonRef.current = "initial";
|
|
669
644
|
return;
|
|
@@ -675,8 +650,7 @@ function useMutation(options) {
|
|
|
675
650
|
onPhaseChange: (phase, reason) => {
|
|
676
651
|
phaseRef.current = phase;
|
|
677
652
|
phaseReasonRef.current = reason;
|
|
678
|
-
|
|
679
|
-
else setState({
|
|
653
|
+
setState({
|
|
680
654
|
phase,
|
|
681
655
|
phaseReason: reason
|
|
682
656
|
});
|
|
@@ -694,6 +668,159 @@ function useMutation(options) {
|
|
|
694
668
|
};
|
|
695
669
|
}
|
|
696
670
|
//#endregion
|
|
671
|
+
//#region src/react/use-pointer/index.ts
|
|
672
|
+
const INITIAL_STATE$1 = {
|
|
673
|
+
phase: "idle",
|
|
674
|
+
phaseReason: "initial"
|
|
675
|
+
};
|
|
676
|
+
/**
|
|
677
|
+
* Lifecycle-aware pointer tracker with rAF-batched `getBoundingClientRect`.
|
|
678
|
+
* Auto-pauses off-screen and tears down on unmount.
|
|
679
|
+
*
|
|
680
|
+
* Position is always delivered imperatively via `onPointer` (never state) and
|
|
681
|
+
* mirrored in `stateRef` for on-demand reads (e.g. inside a `useLoop` tick).
|
|
682
|
+
* Phase transitions (tracking/idle) are infrequent, so `phase`/`phaseReason`
|
|
683
|
+
* are reactive state; read `phaseRef`/`phaseReasonRef` for the latest value
|
|
684
|
+
* without closure staleness. For synchronous phase reactions, use the core
|
|
685
|
+
* `createPointer` primitive.
|
|
686
|
+
*/
|
|
687
|
+
function usePointer(options) {
|
|
688
|
+
const [state, setState] = useState(INITIAL_STATE$1);
|
|
689
|
+
const { visibility = "pause", enabled = true, intersectionOptions } = options;
|
|
690
|
+
const phaseRef = useRef("idle");
|
|
691
|
+
const phaseReasonRef = useRef("initial");
|
|
692
|
+
const stateRef = useRef({
|
|
693
|
+
x: 0,
|
|
694
|
+
y: 0,
|
|
695
|
+
active: false
|
|
696
|
+
});
|
|
697
|
+
const onPointerRef = useSyncedRef(options.onPointer);
|
|
698
|
+
const internalRef = useRef(null);
|
|
699
|
+
const ref = options.ref ?? internalRef;
|
|
700
|
+
useEffect(() => {
|
|
701
|
+
const element = ref.current;
|
|
702
|
+
if (!element || !enabled) {
|
|
703
|
+
setState(INITIAL_STATE$1);
|
|
704
|
+
phaseRef.current = "idle";
|
|
705
|
+
phaseReasonRef.current = "initial";
|
|
706
|
+
stateRef.current = {
|
|
707
|
+
x: 0,
|
|
708
|
+
y: 0,
|
|
709
|
+
active: false
|
|
710
|
+
};
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const instance = createPointer({
|
|
714
|
+
element,
|
|
715
|
+
onPointer: (pointerState) => {
|
|
716
|
+
stateRef.current = pointerState;
|
|
717
|
+
onPointerRef.current(pointerState);
|
|
718
|
+
},
|
|
719
|
+
onPhaseChange: (phase, reason) => {
|
|
720
|
+
phaseRef.current = phase;
|
|
721
|
+
phaseReasonRef.current = reason;
|
|
722
|
+
setState({
|
|
723
|
+
phase,
|
|
724
|
+
phaseReason: reason
|
|
725
|
+
});
|
|
726
|
+
},
|
|
727
|
+
visibility,
|
|
728
|
+
intersectionOptions
|
|
729
|
+
});
|
|
730
|
+
return () => instance.stop();
|
|
731
|
+
}, [enabled, visibility]);
|
|
732
|
+
return {
|
|
733
|
+
ref,
|
|
734
|
+
...state,
|
|
735
|
+
phaseRef,
|
|
736
|
+
phaseReasonRef,
|
|
737
|
+
stateRef
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
//#endregion
|
|
741
|
+
//#region src/react/use-scroll/index.ts
|
|
742
|
+
const INITIAL_STATE = {
|
|
743
|
+
phase: "paused",
|
|
744
|
+
phaseReason: "initial"
|
|
745
|
+
};
|
|
746
|
+
function initialState() {
|
|
747
|
+
return {
|
|
748
|
+
x: 0,
|
|
749
|
+
y: 0,
|
|
750
|
+
maxX: 0,
|
|
751
|
+
maxY: 0,
|
|
752
|
+
progressX: 0,
|
|
753
|
+
progressY: 0,
|
|
754
|
+
visibleX: 1,
|
|
755
|
+
visibleY: 1
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Lifecycle-aware scroll tracker. Scroll position is delivered imperatively via
|
|
760
|
+
* `onScroll` (never state) and mirrored in `stateRef` for on-demand reads; only
|
|
761
|
+
* the phase (tracking/paused) is reactive, since it flips rarely. This mirrors
|
|
762
|
+
* `usePointer`. Auto-pauses off-screen and tears down on unmount.
|
|
763
|
+
*
|
|
764
|
+
* Reads `scrollLeft`/`scrollTop` once per rAF frame; the reflow-heavy geometry
|
|
765
|
+
* (`scrollWidth`/`clientWidth`) is read only on resize or via `measure()`, never
|
|
766
|
+
* on the scroll path. Call `measure()` after mutating scrollable content.
|
|
767
|
+
*/
|
|
768
|
+
function useScroll(options) {
|
|
769
|
+
const [state, setState] = useState(INITIAL_STATE);
|
|
770
|
+
const { visibility = "pause", enabled = true, intersectionOptions } = options;
|
|
771
|
+
const phaseRef = useRef("paused");
|
|
772
|
+
const phaseReasonRef = useRef("initial");
|
|
773
|
+
const stateRef = useRef(initialState());
|
|
774
|
+
const onScrollRef = useSyncedRef(options.onScroll);
|
|
775
|
+
const instanceRef = useRef(null);
|
|
776
|
+
const internalRef = useRef(null);
|
|
777
|
+
const ref = options.ref ?? internalRef;
|
|
778
|
+
const measure = useCallback(() => {
|
|
779
|
+
instanceRef.current?.measure();
|
|
780
|
+
}, []);
|
|
781
|
+
useEffect(() => {
|
|
782
|
+
const element = ref.current;
|
|
783
|
+
if (!element || !enabled) {
|
|
784
|
+
instanceRef.current = null;
|
|
785
|
+
setState(INITIAL_STATE);
|
|
786
|
+
phaseRef.current = "paused";
|
|
787
|
+
phaseReasonRef.current = "initial";
|
|
788
|
+
stateRef.current = initialState();
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const instance = createScroll({
|
|
792
|
+
element,
|
|
793
|
+
onScroll: (scrollState) => {
|
|
794
|
+
stateRef.current = scrollState;
|
|
795
|
+
onScrollRef.current(scrollState);
|
|
796
|
+
},
|
|
797
|
+
onPhaseChange: (phase, reason) => {
|
|
798
|
+
phaseRef.current = phase;
|
|
799
|
+
phaseReasonRef.current = reason;
|
|
800
|
+
setState({
|
|
801
|
+
phase,
|
|
802
|
+
phaseReason: reason
|
|
803
|
+
});
|
|
804
|
+
},
|
|
805
|
+
visibility,
|
|
806
|
+
intersectionOptions
|
|
807
|
+
});
|
|
808
|
+
instanceRef.current = instance;
|
|
809
|
+
return () => {
|
|
810
|
+
instance.stop();
|
|
811
|
+
instanceRef.current = null;
|
|
812
|
+
};
|
|
813
|
+
}, [enabled, visibility]);
|
|
814
|
+
return {
|
|
815
|
+
ref,
|
|
816
|
+
...state,
|
|
817
|
+
phaseRef,
|
|
818
|
+
phaseReasonRef,
|
|
819
|
+
stateRef,
|
|
820
|
+
measure
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
//#endregion
|
|
697
824
|
//#region src/react/use-tween/index.ts
|
|
698
825
|
/**
|
|
699
826
|
* Animate a value from its current position to `target` over `duration`.
|
|
@@ -1093,6 +1220,6 @@ function SwapState({ id, ref: forwardedRef, children, ...divProps }) {
|
|
|
1093
1220
|
}
|
|
1094
1221
|
const Swap = Object.assign(SwapRoot, { State: SwapState });
|
|
1095
1222
|
//#endregion
|
|
1096
|
-
export { Defer, Presence, Swap, WhenIdle, WhenVisible, useCanvas, useContainerQuery, useDevicePixelRatio, useIdle, useLifecycle, useLoop, useMediaQuery, useMutation, usePrefersReducedMotion, usePresence, useRenderState, useScrollProgress, useSight, useSize, useStableCallback, useSyncedRef, useTween, useWhenIdle };
|
|
1223
|
+
export { Defer, Presence, Swap, WhenIdle, WhenVisible, useCanvas, useContainerQuery, useDevicePixelRatio, useIdle, useLifecycle, useLoop, useMediaQuery, useMutation, usePointer, usePrefersReducedMotion, usePresence, useRenderState, useScroll, useScrollProgress, useSight, useSize, useStableCallback, useSyncedRef, useTween, useWhenIdle };
|
|
1097
1224
|
|
|
1098
1225
|
//# sourceMappingURL=react.js.map
|