use-scroll-animate 1.5.0 → 2.0.1
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/CHANGELOG.md +67 -0
- package/README.md +145 -10
- package/README_ja.md +57 -1
- package/README_zh.md +68 -1
- package/dist/{index.esm.js → chunks/core-BP-a1iNc.js} +297 -404
- package/dist/chunks/core-BP-a1iNc.js.map +1 -0
- package/dist/{index.mjs → chunks/core-B_J4rXbC.cjs} +312 -404
- package/dist/chunks/core-B_J4rXbC.cjs.map +1 -0
- package/dist/chunks/stagger-DHw0ExuR.cjs +86 -0
- package/dist/chunks/stagger-DHw0ExuR.cjs.map +1 -0
- package/dist/chunks/stagger-DTv_WiUQ.js +84 -0
- package/dist/chunks/stagger-DTv_WiUQ.js.map +1 -0
- package/dist/element.cjs +97 -0
- package/dist/element.cjs.map +1 -0
- package/dist/{types/types.d.ts → element.d.cts} +73 -10
- package/dist/element.d.ts +216 -0
- package/dist/element.js +95 -0
- package/dist/element.js.map +1 -0
- package/dist/element.umd.js +2 -0
- package/dist/element.umd.js.map +1 -0
- package/dist/index.cjs +241 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{index.d.mts → index.d.cts} +84 -51
- package/dist/index.d.ts +84 -51
- package/dist/index.js +98 -1133
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +5 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/react.cjs +67 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +159 -0
- package/dist/react.d.ts +159 -0
- package/dist/react.js +64 -0
- package/dist/react.js.map +1 -0
- package/dist/solid.cjs +62 -0
- package/dist/solid.cjs.map +1 -0
- package/dist/solid.d.cts +245 -0
- package/dist/solid.d.ts +245 -0
- package/dist/solid.js +58 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +65 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.d.cts +244 -0
- package/dist/svelte.d.ts +244 -0
- package/dist/svelte.js +62 -0
- package/dist/svelte.js.map +1 -0
- package/dist/vue.cjs +61 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +159 -0
- package/dist/vue.d.ts +159 -0
- package/dist/vue.js +59 -0
- package/dist/vue.js.map +1 -0
- package/docs/API.md +139 -0
- package/docs/deprecations.md +20 -0
- package/docs/migration-from-aos.md +67 -0
- package/docs/migration-from-gsap-scrolltrigger.md +80 -0
- package/package.json +86 -15
- package/dist/index.esm.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/types/core.d.ts +0 -41
- package/dist/types/index.d.ts +0 -36
- package/dist/types/presets.d.ts +0 -15
- package/dist/types/react.d.ts +0 -29
- package/dist/types/sequence.d.ts +0 -38
- package/dist/types/stagger.d.ts +0 -25
- package/dist/types/vue.d.ts +0 -28
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* use-scroll-animate - Core Type Definitions
|
|
3
|
+
* A lightweight, high-performance scroll animation library
|
|
4
|
+
*/
|
|
5
|
+
/** Built-in animation presets */
|
|
6
|
+
type AnimationPreset = 'fade-in' | 'fade-in-up' | 'fade-in-down' | 'fade-in-left' | 'fade-in-right' | 'zoom-in' | 'zoom-out' | 'flip-x' | 'flip-y' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'bounce' | 'rotate-in' | 'blur-in' | 'skew-in' | 'scale-x' | 'scale-y' | 'shimmer' | 'pulse' | 'swing' | 'scale-up' | 'blur-in-up' | 'flip-up' | 'flip-down' | 'rotate-left' | 'rotate-right' | 'clip-up' | 'clip-down' | 'clip-left' | 'clip-right' | 'clip-circle';
|
|
7
|
+
/**
|
|
8
|
+
* How `onProgress` (and parallax) progress is measured.
|
|
9
|
+
* - `'ratio'` (default): the element's visible ratio (IntersectionObserver `intersectionRatio`).
|
|
10
|
+
* - `'scroll'`: true scroll progress, 0 when the element's top touches the bottom of the
|
|
11
|
+
* viewport and 1 when its bottom leaves the top. Works for elements taller than the screen.
|
|
12
|
+
*/
|
|
13
|
+
type ProgressMode = 'ratio' | 'scroll';
|
|
14
|
+
/**
|
|
15
|
+
* Which engine runs the entrance animation.
|
|
16
|
+
* - `'js'`: IntersectionObserver triggers a time-based Web Animation.
|
|
17
|
+
* - `'css'`: the preset runs on the browser's native scroll-driven timeline
|
|
18
|
+
* (`animation-timeline: view()`), so its progress follows the scroll position
|
|
19
|
+
* off the main thread. Falls back to `'js'` where unsupported.
|
|
20
|
+
* - `'auto'` (default since 2.0): native when supported, JS otherwise — and JS
|
|
21
|
+
* whenever the element sets `duration`, `delay`, `offset` or `stagger` itself,
|
|
22
|
+
* since those only mean something for a time-based animation.
|
|
23
|
+
*/
|
|
24
|
+
type ScrollEngine = 'auto' | 'js' | 'css';
|
|
25
|
+
/** Easing function types */
|
|
26
|
+
type EasingType = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring' | 'soft-spring' | 'heavy-bounce' | [number, number, number, number] | ((t: number) => number) | string;
|
|
27
|
+
/** Keyframe definition for custom animations */
|
|
28
|
+
interface AnimationKeyframe {
|
|
29
|
+
[property: string]: string | number;
|
|
30
|
+
}
|
|
31
|
+
/** Custom animation definition */
|
|
32
|
+
interface CustomAnimation {
|
|
33
|
+
from: AnimationKeyframe;
|
|
34
|
+
to: AnimationKeyframe;
|
|
35
|
+
}
|
|
36
|
+
/** Parallax configuration */
|
|
37
|
+
interface ParallaxOptions {
|
|
38
|
+
/** Movement on X axis (e.g., '100px', '20%') */
|
|
39
|
+
x?: string | number;
|
|
40
|
+
/** Movement on Y axis (e.g., '100px', '20%') */
|
|
41
|
+
y?: string | number;
|
|
42
|
+
/** Rotation in degrees */
|
|
43
|
+
rotate?: number;
|
|
44
|
+
/** Scale factor */
|
|
45
|
+
scale?: number;
|
|
46
|
+
/** Speed multiplier (default: 1) */
|
|
47
|
+
speed?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Per-element animation options */
|
|
50
|
+
interface AnimateOptions {
|
|
51
|
+
/** Animation preset name, array of presets, or custom animation object */
|
|
52
|
+
animation?: AnimationPreset | AnimationPreset[] | CustomAnimation;
|
|
53
|
+
/** Duration in milliseconds (default: 600) */
|
|
54
|
+
duration?: number;
|
|
55
|
+
/** Delay in milliseconds (default: 0) */
|
|
56
|
+
delay?: number;
|
|
57
|
+
/** Easing function (default: 'ease') */
|
|
58
|
+
easing?: EasingType;
|
|
59
|
+
/** Intersection threshold 0-1 (default: 0.1) */
|
|
60
|
+
threshold?: number | number[];
|
|
61
|
+
/** Root margin for IntersectionObserver (default: '0px') */
|
|
62
|
+
rootMargin?: string;
|
|
63
|
+
/** Whether to replay animation each time element enters viewport (default: false) */
|
|
64
|
+
repeat?: boolean;
|
|
65
|
+
/** Whether to trigger animation only once (default: true if repeat is false) */
|
|
66
|
+
once?: boolean;
|
|
67
|
+
/** Offset in pixels from the viewport edge to trigger animation (default: 0) */
|
|
68
|
+
offset?: number;
|
|
69
|
+
/** Stagger delay for child elements in ms (default: 0) */
|
|
70
|
+
stagger?: number;
|
|
71
|
+
/** Parallax effect configuration */
|
|
72
|
+
parallax?: ParallaxOptions;
|
|
73
|
+
/** Callback fired when animation starts */
|
|
74
|
+
onStart?: (element: Element) => void;
|
|
75
|
+
/** Callback fired when animation completes */
|
|
76
|
+
onComplete?: (element: Element) => void;
|
|
77
|
+
/** Callback fired when element enters viewport */
|
|
78
|
+
onEnter?: (element: Element) => void;
|
|
79
|
+
/** Callback fired when element leaves viewport */
|
|
80
|
+
onLeave?: (element: Element) => void;
|
|
81
|
+
/** Callback fired with scroll progress (0 to 1) */
|
|
82
|
+
onProgress?: (element: Element, progress: number) => void;
|
|
83
|
+
/** How progress for `onProgress`/parallax is measured (default: 'ratio') */
|
|
84
|
+
progressMode?: ProgressMode;
|
|
85
|
+
/**
|
|
86
|
+
* Name of a CSS custom property (e.g. `'--sa-progress'`) that receives the
|
|
87
|
+
* element's progress (0 to 1, same value as `onProgress`) as an inline
|
|
88
|
+
* style, for scroll-driven effects written in plain CSS. Off by default.
|
|
89
|
+
*/
|
|
90
|
+
progressVar?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Animation engine (default: `'auto'`, see `ScrollEngine`). With the native
|
|
93
|
+
* engine the animation is linked to scroll position: `duration`, `delay`,
|
|
94
|
+
* `threshold`, `offset` and `stagger` do not apply; `viewRange` does.
|
|
95
|
+
*/
|
|
96
|
+
engine?: ScrollEngine;
|
|
97
|
+
/**
|
|
98
|
+
* Native engine only: the view-timeline range the entrance animation spans,
|
|
99
|
+
* as `[rangeStart, rangeEnd]` (default: `['entry 0%', 'entry 100%']`).
|
|
100
|
+
*/
|
|
101
|
+
viewRange?: [string, string];
|
|
102
|
+
/**
|
|
103
|
+
* Animate out when the element leaves the viewport, and back in when it
|
|
104
|
+
* re-enters (implies `repeat: true` unless `repeat` is set).
|
|
105
|
+
* - `true`: play the entrance animation in reverse.
|
|
106
|
+
* - a preset / presets / `{ from, to }`: play that animation in reverse
|
|
107
|
+
* (e.g. `exit: 'fade-in-down'` leaves upwards).
|
|
108
|
+
* Skipped under reduced motion. (default: `false`)
|
|
109
|
+
*/
|
|
110
|
+
exit?: boolean | AnimationPreset | AnimationPreset[] | CustomAnimation;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* use-scroll-animate - Staggered children
|
|
115
|
+
* Reveal a container's children one after another when the container scrolls
|
|
116
|
+
* into view, optionally also animating children that are added later.
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface StaggerOptions extends AnimateOptions {
|
|
120
|
+
/** Delay between consecutive children in ms (default: 80) */
|
|
121
|
+
stagger?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Watch the container with a MutationObserver and animate children added
|
|
124
|
+
* later (e.g. infinite lists). Children added after the container was
|
|
125
|
+
* revealed animate when they scroll into view, staggered per batch.
|
|
126
|
+
* (default: false)
|
|
127
|
+
*/
|
|
128
|
+
observeChildren?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* use-scroll-animate - React Integration
|
|
133
|
+
* Provides useScrollAnimate and useScrollStagger hooks for React applications.
|
|
134
|
+
* `useScrollStagger({ observeChildren: true })` also animates children added later.
|
|
135
|
+
*
|
|
136
|
+
* Both hooks are thin wrappers around the core engine, so they share its
|
|
137
|
+
* behaviour: `once`, `offset`, custom easing functions, parallax,
|
|
138
|
+
* `prefers-reduced-motion` support, and proper cleanup on unmount.
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
type ReactRef<T> = {
|
|
142
|
+
current: T | null;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Wrap the callbacks that exist at mount so they always call the latest
|
|
146
|
+
* version from the most recent render (avoids stale closures without
|
|
147
|
+
* re-creating observers on every render).
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
declare function withLatestCallbacks(latest: ReactRef<AnimateOptions>): AnimateOptions;
|
|
151
|
+
declare function createReactHooks(React: {
|
|
152
|
+
useRef: <T>(initial: T | null) => ReactRef<T>;
|
|
153
|
+
useEffect: (effect: () => (() => void) | void, deps?: unknown[]) => void;
|
|
154
|
+
}): {
|
|
155
|
+
useScrollAnimate: (options?: AnimateOptions) => ReactRef<Element>;
|
|
156
|
+
useScrollStagger: (options?: StaggerOptions) => ReactRef<Element>;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export { createReactHooks, withLatestCallbacks };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* use-scroll-animate - Core Type Definitions
|
|
3
|
+
* A lightweight, high-performance scroll animation library
|
|
4
|
+
*/
|
|
5
|
+
/** Built-in animation presets */
|
|
6
|
+
type AnimationPreset = 'fade-in' | 'fade-in-up' | 'fade-in-down' | 'fade-in-left' | 'fade-in-right' | 'zoom-in' | 'zoom-out' | 'flip-x' | 'flip-y' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'bounce' | 'rotate-in' | 'blur-in' | 'skew-in' | 'scale-x' | 'scale-y' | 'shimmer' | 'pulse' | 'swing' | 'scale-up' | 'blur-in-up' | 'flip-up' | 'flip-down' | 'rotate-left' | 'rotate-right' | 'clip-up' | 'clip-down' | 'clip-left' | 'clip-right' | 'clip-circle';
|
|
7
|
+
/**
|
|
8
|
+
* How `onProgress` (and parallax) progress is measured.
|
|
9
|
+
* - `'ratio'` (default): the element's visible ratio (IntersectionObserver `intersectionRatio`).
|
|
10
|
+
* - `'scroll'`: true scroll progress, 0 when the element's top touches the bottom of the
|
|
11
|
+
* viewport and 1 when its bottom leaves the top. Works for elements taller than the screen.
|
|
12
|
+
*/
|
|
13
|
+
type ProgressMode = 'ratio' | 'scroll';
|
|
14
|
+
/**
|
|
15
|
+
* Which engine runs the entrance animation.
|
|
16
|
+
* - `'js'`: IntersectionObserver triggers a time-based Web Animation.
|
|
17
|
+
* - `'css'`: the preset runs on the browser's native scroll-driven timeline
|
|
18
|
+
* (`animation-timeline: view()`), so its progress follows the scroll position
|
|
19
|
+
* off the main thread. Falls back to `'js'` where unsupported.
|
|
20
|
+
* - `'auto'` (default since 2.0): native when supported, JS otherwise — and JS
|
|
21
|
+
* whenever the element sets `duration`, `delay`, `offset` or `stagger` itself,
|
|
22
|
+
* since those only mean something for a time-based animation.
|
|
23
|
+
*/
|
|
24
|
+
type ScrollEngine = 'auto' | 'js' | 'css';
|
|
25
|
+
/** Easing function types */
|
|
26
|
+
type EasingType = 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring' | 'soft-spring' | 'heavy-bounce' | [number, number, number, number] | ((t: number) => number) | string;
|
|
27
|
+
/** Keyframe definition for custom animations */
|
|
28
|
+
interface AnimationKeyframe {
|
|
29
|
+
[property: string]: string | number;
|
|
30
|
+
}
|
|
31
|
+
/** Custom animation definition */
|
|
32
|
+
interface CustomAnimation {
|
|
33
|
+
from: AnimationKeyframe;
|
|
34
|
+
to: AnimationKeyframe;
|
|
35
|
+
}
|
|
36
|
+
/** Parallax configuration */
|
|
37
|
+
interface ParallaxOptions {
|
|
38
|
+
/** Movement on X axis (e.g., '100px', '20%') */
|
|
39
|
+
x?: string | number;
|
|
40
|
+
/** Movement on Y axis (e.g., '100px', '20%') */
|
|
41
|
+
y?: string | number;
|
|
42
|
+
/** Rotation in degrees */
|
|
43
|
+
rotate?: number;
|
|
44
|
+
/** Scale factor */
|
|
45
|
+
scale?: number;
|
|
46
|
+
/** Speed multiplier (default: 1) */
|
|
47
|
+
speed?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Per-element animation options */
|
|
50
|
+
interface AnimateOptions {
|
|
51
|
+
/** Animation preset name, array of presets, or custom animation object */
|
|
52
|
+
animation?: AnimationPreset | AnimationPreset[] | CustomAnimation;
|
|
53
|
+
/** Duration in milliseconds (default: 600) */
|
|
54
|
+
duration?: number;
|
|
55
|
+
/** Delay in milliseconds (default: 0) */
|
|
56
|
+
delay?: number;
|
|
57
|
+
/** Easing function (default: 'ease') */
|
|
58
|
+
easing?: EasingType;
|
|
59
|
+
/** Intersection threshold 0-1 (default: 0.1) */
|
|
60
|
+
threshold?: number | number[];
|
|
61
|
+
/** Root margin for IntersectionObserver (default: '0px') */
|
|
62
|
+
rootMargin?: string;
|
|
63
|
+
/** Whether to replay animation each time element enters viewport (default: false) */
|
|
64
|
+
repeat?: boolean;
|
|
65
|
+
/** Whether to trigger animation only once (default: true if repeat is false) */
|
|
66
|
+
once?: boolean;
|
|
67
|
+
/** Offset in pixels from the viewport edge to trigger animation (default: 0) */
|
|
68
|
+
offset?: number;
|
|
69
|
+
/** Stagger delay for child elements in ms (default: 0) */
|
|
70
|
+
stagger?: number;
|
|
71
|
+
/** Parallax effect configuration */
|
|
72
|
+
parallax?: ParallaxOptions;
|
|
73
|
+
/** Callback fired when animation starts */
|
|
74
|
+
onStart?: (element: Element) => void;
|
|
75
|
+
/** Callback fired when animation completes */
|
|
76
|
+
onComplete?: (element: Element) => void;
|
|
77
|
+
/** Callback fired when element enters viewport */
|
|
78
|
+
onEnter?: (element: Element) => void;
|
|
79
|
+
/** Callback fired when element leaves viewport */
|
|
80
|
+
onLeave?: (element: Element) => void;
|
|
81
|
+
/** Callback fired with scroll progress (0 to 1) */
|
|
82
|
+
onProgress?: (element: Element, progress: number) => void;
|
|
83
|
+
/** How progress for `onProgress`/parallax is measured (default: 'ratio') */
|
|
84
|
+
progressMode?: ProgressMode;
|
|
85
|
+
/**
|
|
86
|
+
* Name of a CSS custom property (e.g. `'--sa-progress'`) that receives the
|
|
87
|
+
* element's progress (0 to 1, same value as `onProgress`) as an inline
|
|
88
|
+
* style, for scroll-driven effects written in plain CSS. Off by default.
|
|
89
|
+
*/
|
|
90
|
+
progressVar?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Animation engine (default: `'auto'`, see `ScrollEngine`). With the native
|
|
93
|
+
* engine the animation is linked to scroll position: `duration`, `delay`,
|
|
94
|
+
* `threshold`, `offset` and `stagger` do not apply; `viewRange` does.
|
|
95
|
+
*/
|
|
96
|
+
engine?: ScrollEngine;
|
|
97
|
+
/**
|
|
98
|
+
* Native engine only: the view-timeline range the entrance animation spans,
|
|
99
|
+
* as `[rangeStart, rangeEnd]` (default: `['entry 0%', 'entry 100%']`).
|
|
100
|
+
*/
|
|
101
|
+
viewRange?: [string, string];
|
|
102
|
+
/**
|
|
103
|
+
* Animate out when the element leaves the viewport, and back in when it
|
|
104
|
+
* re-enters (implies `repeat: true` unless `repeat` is set).
|
|
105
|
+
* - `true`: play the entrance animation in reverse.
|
|
106
|
+
* - a preset / presets / `{ from, to }`: play that animation in reverse
|
|
107
|
+
* (e.g. `exit: 'fade-in-down'` leaves upwards).
|
|
108
|
+
* Skipped under reduced motion. (default: `false`)
|
|
109
|
+
*/
|
|
110
|
+
exit?: boolean | AnimationPreset | AnimationPreset[] | CustomAnimation;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* use-scroll-animate - Staggered children
|
|
115
|
+
* Reveal a container's children one after another when the container scrolls
|
|
116
|
+
* into view, optionally also animating children that are added later.
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface StaggerOptions extends AnimateOptions {
|
|
120
|
+
/** Delay between consecutive children in ms (default: 80) */
|
|
121
|
+
stagger?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Watch the container with a MutationObserver and animate children added
|
|
124
|
+
* later (e.g. infinite lists). Children added after the container was
|
|
125
|
+
* revealed animate when they scroll into view, staggered per batch.
|
|
126
|
+
* (default: false)
|
|
127
|
+
*/
|
|
128
|
+
observeChildren?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* use-scroll-animate - React Integration
|
|
133
|
+
* Provides useScrollAnimate and useScrollStagger hooks for React applications.
|
|
134
|
+
* `useScrollStagger({ observeChildren: true })` also animates children added later.
|
|
135
|
+
*
|
|
136
|
+
* Both hooks are thin wrappers around the core engine, so they share its
|
|
137
|
+
* behaviour: `once`, `offset`, custom easing functions, parallax,
|
|
138
|
+
* `prefers-reduced-motion` support, and proper cleanup on unmount.
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
type ReactRef<T> = {
|
|
142
|
+
current: T | null;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Wrap the callbacks that exist at mount so they always call the latest
|
|
146
|
+
* version from the most recent render (avoids stale closures without
|
|
147
|
+
* re-creating observers on every render).
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
declare function withLatestCallbacks(latest: ReactRef<AnimateOptions>): AnimateOptions;
|
|
151
|
+
declare function createReactHooks(React: {
|
|
152
|
+
useRef: <T>(initial: T | null) => ReactRef<T>;
|
|
153
|
+
useEffect: (effect: () => (() => void) | void, deps?: unknown[]) => void;
|
|
154
|
+
}): {
|
|
155
|
+
useScrollAnimate: (options?: AnimateOptions) => ReactRef<Element>;
|
|
156
|
+
useScrollStagger: (options?: StaggerOptions) => ReactRef<Element>;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export { createReactHooks, withLatestCallbacks };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { c as createScrollAnimate } from './chunks/core-BP-a1iNc.js';
|
|
2
|
+
import { s as staggerChildren } from './chunks/stagger-DTv_WiUQ.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* use-scroll-animate - React Integration
|
|
6
|
+
* Provides useScrollAnimate and useScrollStagger hooks for React applications.
|
|
7
|
+
* `useScrollStagger({ observeChildren: true })` also animates children added later.
|
|
8
|
+
*
|
|
9
|
+
* Both hooks are thin wrappers around the core engine, so they share its
|
|
10
|
+
* behaviour: `once`, `offset`, custom easing functions, parallax,
|
|
11
|
+
* `prefers-reduced-motion` support, and proper cleanup on unmount.
|
|
12
|
+
*/
|
|
13
|
+
const CALLBACKS = ['onStart', 'onComplete', 'onEnter', 'onLeave', 'onProgress'];
|
|
14
|
+
/**
|
|
15
|
+
* Wrap the callbacks that exist at mount so they always call the latest
|
|
16
|
+
* version from the most recent render (avoids stale closures without
|
|
17
|
+
* re-creating observers on every render).
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
function withLatestCallbacks(latest) {
|
|
21
|
+
const initial = latest.current || {};
|
|
22
|
+
const opts = { ...initial };
|
|
23
|
+
CALLBACKS.forEach((name) => {
|
|
24
|
+
if (typeof initial[name] === 'function') {
|
|
25
|
+
opts[name] = (...args) => latest.current?.[name]?.(...args);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return opts;
|
|
29
|
+
}
|
|
30
|
+
function createReactHooks(React) {
|
|
31
|
+
// Created lazily on the client so importing on the server is side-effect free.
|
|
32
|
+
let instance = null;
|
|
33
|
+
const getInstance = () => instance || (instance = createScrollAnimate());
|
|
34
|
+
function useScrollAnimate(options = {}) {
|
|
35
|
+
const ref = React.useRef(null);
|
|
36
|
+
const optionsRef = React.useRef(options);
|
|
37
|
+
optionsRef.current = options;
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
const el = ref.current;
|
|
40
|
+
if (!el)
|
|
41
|
+
return;
|
|
42
|
+
const sa = getInstance();
|
|
43
|
+
sa.observe(el, withLatestCallbacks(optionsRef));
|
|
44
|
+
return () => sa.unobserve(el);
|
|
45
|
+
}, []);
|
|
46
|
+
return ref;
|
|
47
|
+
}
|
|
48
|
+
function useScrollStagger(options = {}) {
|
|
49
|
+
const ref = React.useRef(null);
|
|
50
|
+
const optionsRef = React.useRef(options);
|
|
51
|
+
optionsRef.current = options;
|
|
52
|
+
React.useEffect(() => {
|
|
53
|
+
const container = ref.current;
|
|
54
|
+
if (!container)
|
|
55
|
+
return;
|
|
56
|
+
return staggerChildren(container, withLatestCallbacks(optionsRef), getInstance());
|
|
57
|
+
}, []);
|
|
58
|
+
return ref;
|
|
59
|
+
}
|
|
60
|
+
return { useScrollAnimate, useScrollStagger };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { createReactHooks, withLatestCallbacks };
|
|
64
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sources":["../src/react.ts"],"sourcesContent":["/**\n * use-scroll-animate - React Integration\n * Provides useScrollAnimate and useScrollStagger hooks for React applications.\n * `useScrollStagger({ observeChildren: true })` also animates children added later.\n *\n * Both hooks are thin wrappers around the core engine, so they share its\n * behaviour: `once`, `offset`, custom easing functions, parallax,\n * `prefers-reduced-motion` support, and proper cleanup on unmount.\n */\n\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate } from './core';\nimport { staggerChildren, type StaggerOptions } from './stagger';\n\ntype ReactRef<T> = { current: T | null };\n\nconst CALLBACKS = ['onStart', 'onComplete', 'onEnter', 'onLeave', 'onProgress'] as const;\n\n/**\n * Wrap the callbacks that exist at mount so they always call the latest\n * version from the most recent render (avoids stale closures without\n * re-creating observers on every render).\n * @internal\n */\nexport function withLatestCallbacks(latest: ReactRef<AnimateOptions>): AnimateOptions {\n const initial = latest.current || {};\n const opts: AnimateOptions = { ...initial };\n CALLBACKS.forEach((name) => {\n if (typeof initial[name] === 'function') {\n (opts as any)[name] = (...args: unknown[]) => (latest.current?.[name] as any)?.(...args);\n }\n });\n return opts;\n}\n\nexport function createReactHooks(React: {\n useRef: <T>(initial: T | null) => ReactRef<T>;\n useEffect: (effect: () => (() => void) | void, deps?: unknown[]) => void;\n}) {\n // Created lazily on the client so importing on the server is side-effect free.\n let instance: ScrollAnimateInstance | null = null;\n const getInstance = () => instance || (instance = createScrollAnimate());\n\n function useScrollAnimate(options: AnimateOptions = {}) {\n const ref = React.useRef<Element>(null);\n const optionsRef = React.useRef<AnimateOptions>(options);\n optionsRef.current = options;\n\n React.useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const sa = getInstance();\n sa.observe(el, withLatestCallbacks(optionsRef));\n return () => sa.unobserve(el);\n }, []);\n\n return ref;\n }\n\n function useScrollStagger(options: StaggerOptions = {}) {\n const ref = React.useRef<Element>(null);\n const optionsRef = React.useRef<AnimateOptions>(options);\n optionsRef.current = options;\n\n React.useEffect(() => {\n const container = ref.current;\n if (!container) return;\n return staggerChildren(container, withLatestCallbacks(optionsRef) as StaggerOptions, getInstance());\n }, []);\n\n return ref;\n }\n\n return { useScrollAnimate, useScrollStagger };\n}\n"],"names":[],"mappings":";;;AAAA;;;;;;;;AAQG;AAQH,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAU;AAExF;;;;;AAKG;AACG,SAAU,mBAAmB,CAAC,MAAgC,EAAA;AAClE,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE;AACpC,IAAA,MAAM,IAAI,GAAmB,EAAE,GAAG,OAAO,EAAE;AAC3C,IAAA,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;QACzB,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE;YACtC,IAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAe,KAAM,MAAM,CAAC,OAAO,GAAG,IAAI,CAAS,GAAG,GAAG,IAAI,CAAC;QAC1F;AACF,IAAA,CAAC,CAAC;AACF,IAAA,OAAO,IAAI;AACb;AAEM,SAAU,gBAAgB,CAAC,KAGhC,EAAA;;IAEC,IAAI,QAAQ,GAAiC,IAAI;AACjD,IAAA,MAAM,WAAW,GAAG,MAAM,QAAQ,KAAK,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IAExE,SAAS,gBAAgB,CAAC,OAAA,GAA0B,EAAE,EAAA;QACpD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAU,IAAI,CAAC;QACvC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAiB,OAAO,CAAC;AACxD,QAAA,UAAU,CAAC,OAAO,GAAG,OAAO;AAE5B,QAAA,KAAK,CAAC,SAAS,CAAC,MAAK;AACnB,YAAA,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO;AACtB,YAAA,IAAI,CAAC,EAAE;gBAAE;AACT,YAAA,MAAM,EAAE,GAAG,WAAW,EAAE;YACxB,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC;YAC/C,OAAO,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,CAAC,EAAE,EAAE,CAAC;AAEN,QAAA,OAAO,GAAG;IACZ;IAEA,SAAS,gBAAgB,CAAC,OAAA,GAA0B,EAAE,EAAA;QACpD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAU,IAAI,CAAC;QACvC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAiB,OAAO,CAAC;AACxD,QAAA,UAAU,CAAC,OAAO,GAAG,OAAO;AAE5B,QAAA,KAAK,CAAC,SAAS,CAAC,MAAK;AACnB,YAAA,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO;AAC7B,YAAA,IAAI,CAAC,SAAS;gBAAE;AAChB,YAAA,OAAO,eAAe,CAAC,SAAS,EAAE,mBAAmB,CAAC,UAAU,CAAmB,EAAE,WAAW,EAAE,CAAC;QACrG,CAAC,EAAE,EAAE,CAAC;AAEN,QAAA,OAAO,GAAG;IACZ;AAEA,IAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE;AAC/C;;;;"}
|
package/dist/solid.cjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var solidJs = require('solid-js');
|
|
4
|
+
var core = require('./chunks/core-B_J4rXbC.cjs');
|
|
5
|
+
var stagger = require('./chunks/stagger-DHw0ExuR.cjs');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* use-scroll-animate - Solid integration
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { scrollAnimate, scrollStagger, useScrollAnimate } from 'use-scroll-animate/solid';
|
|
12
|
+
* false && scrollAnimate; // keep the directive import (TypeScript)
|
|
13
|
+
*
|
|
14
|
+
* <div use:scrollAnimate={{ animation: 'zoom-in' }}>…</div>
|
|
15
|
+
* <ul use:scrollStagger={{ stagger: 60 }}>…</ul>
|
|
16
|
+
* <div ref={useScrollAnimate({ animation: 'fade-in-up' })}>…</div>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* `solid-js` is an optional peer dependency (only needed for this entry).
|
|
20
|
+
*/
|
|
21
|
+
let shared = null;
|
|
22
|
+
const getInstance = (own) => own || shared || (shared = core.createScrollAnimate());
|
|
23
|
+
function read(accessor) {
|
|
24
|
+
const v = accessor?.();
|
|
25
|
+
return (v && v !== true ? v : {});
|
|
26
|
+
}
|
|
27
|
+
function observe(el, options) {
|
|
28
|
+
const { instance, ...opts } = options;
|
|
29
|
+
const sa = getInstance(instance);
|
|
30
|
+
// Wait until the element is in the document (directives/refs run before insertion).
|
|
31
|
+
solidJs.onMount(() => sa.observe(el, opts));
|
|
32
|
+
solidJs.onCleanup(() => sa.unobserve(el));
|
|
33
|
+
}
|
|
34
|
+
/** Directive: `<div use:scrollAnimate={{ animation: 'fade-in' }} />` */
|
|
35
|
+
function scrollAnimate(el, accessor) {
|
|
36
|
+
observe(el, read(accessor));
|
|
37
|
+
}
|
|
38
|
+
/** Directive: `<ul use:scrollStagger={{ stagger: 60, observeChildren: true }} />` */
|
|
39
|
+
function scrollStagger(el, accessor) {
|
|
40
|
+
const { instance, ...opts } = read(accessor);
|
|
41
|
+
let stop;
|
|
42
|
+
solidJs.onMount(() => {
|
|
43
|
+
stop = stagger.staggerChildren(el, opts, getInstance(instance));
|
|
44
|
+
});
|
|
45
|
+
solidJs.onCleanup(() => stop?.());
|
|
46
|
+
}
|
|
47
|
+
/** Primitive returning a `ref` callback: `<div ref={useScrollAnimate({ animation: 'fade-in-up' })} />` */
|
|
48
|
+
function useScrollAnimate(options = {}) {
|
|
49
|
+
let el;
|
|
50
|
+
const { instance, ...opts } = options;
|
|
51
|
+
const sa = getInstance(instance);
|
|
52
|
+
solidJs.onMount(() => el && sa.observe(el, opts));
|
|
53
|
+
solidJs.onCleanup(() => el && sa.unobserve(el));
|
|
54
|
+
return (node) => {
|
|
55
|
+
el = node;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
exports.scrollAnimate = scrollAnimate;
|
|
60
|
+
exports.scrollStagger = scrollStagger;
|
|
61
|
+
exports.useScrollAnimate = useScrollAnimate;
|
|
62
|
+
//# sourceMappingURL=solid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solid.cjs","sources":["../src/solid.ts"],"sourcesContent":["/**\n * use-scroll-animate - Solid integration\n *\n * ```tsx\n * import { scrollAnimate, scrollStagger, useScrollAnimate } from 'use-scroll-animate/solid';\n * false && scrollAnimate; // keep the directive import (TypeScript)\n *\n * <div use:scrollAnimate={{ animation: 'zoom-in' }}>…</div>\n * <ul use:scrollStagger={{ stagger: 60 }}>…</ul>\n * <div ref={useScrollAnimate({ animation: 'fade-in-up' })}>…</div>\n * ```\n *\n * `solid-js` is an optional peer dependency (only needed for this entry).\n */\n\nimport { onCleanup, onMount } from 'solid-js';\nimport type { AnimateOptions, ScrollAnimateInstance } from './types';\nimport { createScrollAnimate } from './core';\nimport { staggerChildren, type StaggerOptions } from './stagger';\n\nexport interface SolidScrollAnimateOptions extends AnimateOptions {\n instance?: ScrollAnimateInstance;\n}\nexport interface SolidScrollStaggerOptions extends StaggerOptions {\n instance?: ScrollAnimateInstance;\n}\n\ndeclare module 'solid-js' {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace JSX {\n interface Directives {\n scrollAnimate: SolidScrollAnimateOptions | true;\n scrollStagger: SolidScrollStaggerOptions | true;\n }\n }\n}\n\nlet shared: ScrollAnimateInstance | null = null;\nconst getInstance = (own?: ScrollAnimateInstance) => own || shared || (shared = createScrollAnimate());\n\nfunction read<T>(accessor?: () => T | true | undefined): T {\n const v = accessor?.();\n return (v && v !== true ? v : {}) as T;\n}\n\nfunction observe(el: Element, options: SolidScrollAnimateOptions): void {\n const { instance, ...opts } = options;\n const sa = getInstance(instance);\n // Wait until the element is in the document (directives/refs run before insertion).\n onMount(() => sa.observe(el, opts));\n onCleanup(() => sa.unobserve(el));\n}\n\n/** Directive: `<div use:scrollAnimate={{ animation: 'fade-in' }} />` */\nexport function scrollAnimate(el: Element, accessor?: () => SolidScrollAnimateOptions | true | undefined): void {\n observe(el, read(accessor));\n}\n\n/** Directive: `<ul use:scrollStagger={{ stagger: 60, observeChildren: true }} />` */\nexport function scrollStagger(el: Element, accessor?: () => SolidScrollStaggerOptions | true | undefined): void {\n const { instance, ...opts } = read<SolidScrollStaggerOptions>(accessor);\n let stop: (() => void) | undefined;\n onMount(() => {\n stop = staggerChildren(el, opts, getInstance(instance));\n });\n onCleanup(() => stop?.());\n}\n\n/** Primitive returning a `ref` callback: `<div ref={useScrollAnimate({ animation: 'fade-in-up' })} />` */\nexport function useScrollAnimate(options: SolidScrollAnimateOptions = {}): (el: Element) => void {\n let el: Element | undefined;\n const { instance, ...opts } = options;\n const sa = getInstance(instance);\n onMount(() => el && sa.observe(el, opts));\n onCleanup(() => el && sa.unobserve(el));\n return (node: Element) => {\n el = node;\n };\n}\n"],"names":["createScrollAnimate","onMount","onCleanup","staggerChildren"],"mappings":";;;;;;AAAA;;;;;;;;;;;;;AAaG;AAwBH,IAAI,MAAM,GAAiC,IAAI;AAC/C,MAAM,WAAW,GAAG,CAAC,GAA2B,KAAK,GAAG,IAAI,MAAM,KAAK,MAAM,GAAGA,wBAAmB,EAAE,CAAC;AAEtG,SAAS,IAAI,CAAI,QAAqC,EAAA;AACpD,IAAA,MAAM,CAAC,GAAG,QAAQ,IAAI;AACtB,IAAA,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE;AAClC;AAEA,SAAS,OAAO,CAAC,EAAW,EAAE,OAAkC,EAAA;IAC9D,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO;AACrC,IAAA,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;;AAEhC,IAAAC,eAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACnCC,iBAAS,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACnC;AAEA;AACM,SAAU,aAAa,CAAC,EAAW,EAAE,QAA6D,EAAA;IACtG,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7B;AAEA;AACM,SAAU,aAAa,CAAC,EAAW,EAAE,QAA6D,EAAA;IACtG,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAA4B,QAAQ,CAAC;AACvE,IAAA,IAAI,IAA8B;IAClCD,eAAO,CAAC,MAAK;AACX,QAAA,IAAI,GAAGE,uBAAe,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;AACzD,IAAA,CAAC,CAAC;IACFD,iBAAS,CAAC,MAAM,IAAI,IAAI,CAAC;AAC3B;AAEA;AACM,SAAU,gBAAgB,CAAC,OAAA,GAAqC,EAAE,EAAA;AACtE,IAAA,IAAI,EAAuB;IAC3B,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO;AACrC,IAAA,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;AAChC,IAAAD,eAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;AACzC,IAAAC,iBAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,IAAa,KAAI;QACvB,EAAE,GAAG,IAAI;AACX,IAAA,CAAC;AACH;;;;;;"}
|