lenis 1.1.13 → 1.1.14-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/lenis-react.d.ts +11 -11
- package/dist/lenis-react.mjs +159 -2
- package/dist/lenis-react.mjs.map +1 -1
- package/dist/lenis-snap.js +298 -332
- package/dist/lenis-snap.js.map +1 -1
- package/dist/lenis-snap.min.js +2 -2
- package/dist/lenis-snap.min.js.map +1 -1
- package/dist/lenis-snap.mjs +308 -2
- package/dist/lenis-snap.mjs.map +1 -1
- package/dist/lenis-vue.d.ts +68 -0
- package/dist/lenis-vue.mjs +198 -0
- package/dist/lenis-vue.mjs.map +1 -0
- package/dist/lenis.css +1 -20
- package/dist/lenis.js +816 -885
- package/dist/lenis.js.map +1 -1
- package/dist/lenis.min.js +2 -2
- package/dist/lenis.min.js.map +1 -1
- package/dist/lenis.mjs +854 -2
- package/dist/lenis.mjs.map +1 -1
- package/package.json +23 -32
package/README.md
CHANGED
|
@@ -317,6 +317,8 @@ This set of hooks is curated and maintained by the darkroom.engineering team:
|
|
|
317
317
|
- Clément Roche ([@clementroche\_](https://twitter.com/clementroche_)) – [darkroom.engineering](https://darkroom.engineering)
|
|
318
318
|
- Guido Fier ([@uido15](https://twitter.com/uido15)) – [darkroom.engineering](https://darkroom.engineering)
|
|
319
319
|
- Leandro Soengas ([@lsoengas](https://twitter.com/lsoengas)) - [darkroom.engineering](https://darkroom.engineering)
|
|
320
|
+
- Fermin Fernandez ([@Fermin_FerBridd](https://twitter.com/Fermin_FerBridd)) - [darkroom.engineering](https://darkroom.engineering)
|
|
321
|
+
- Felix Mayr ([@feledori](https://twitter.com/feledori)) - [darkroom.engineering](https://darkroom.engineering)
|
|
320
322
|
- Franco Arza ([@arzafran](https://twitter.com/arzafran)) - [darkroom.engineering](https://darkroom.engineering)
|
|
321
323
|
|
|
322
324
|
<br/>
|
package/dist/lenis-react.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import * as react from 'react';
|
|
3
2
|
import { ReactNode, ComponentPropsWithoutRef } from 'react';
|
|
4
|
-
import
|
|
3
|
+
import * as Lenis from 'lenis';
|
|
4
|
+
import Lenis__default, { ScrollCallback, LenisOptions } from 'lenis';
|
|
5
5
|
|
|
6
6
|
type LenisContextValue = {
|
|
7
|
-
lenis:
|
|
7
|
+
lenis: Lenis__default;
|
|
8
8
|
addCallback: (callback: ScrollCallback, priority: number) => void;
|
|
9
9
|
removeCallback: (callback: ScrollCallback) => void;
|
|
10
10
|
};
|
|
@@ -61,10 +61,14 @@ type LenisRef = {
|
|
|
61
61
|
/**
|
|
62
62
|
* The lenis instance
|
|
63
63
|
*/
|
|
64
|
-
lenis?:
|
|
64
|
+
lenis?: Lenis__default;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* React component to setup a Lenis instance
|
|
69
|
+
*/
|
|
70
|
+
declare const ReactLenis: react.ForwardRefExoticComponent<LenisProps & react.RefAttributes<LenisRef>>;
|
|
71
|
+
|
|
68
72
|
/**
|
|
69
73
|
* Hook to access the Lenis instance and its methods
|
|
70
74
|
*
|
|
@@ -105,10 +109,6 @@ declare const LenisContext: react.Context<LenisContextValue | null>;
|
|
|
105
109
|
* })
|
|
106
110
|
* }
|
|
107
111
|
*/
|
|
108
|
-
declare function useLenis(callback?: ScrollCallback, deps?: any[], priority?: number): Lenis | undefined;
|
|
109
|
-
/**
|
|
110
|
-
* React component to setup a Lenis instance
|
|
111
|
-
*/
|
|
112
|
-
declare const ReactLenis: react.ForwardRefExoticComponent<LenisProps & react.RefAttributes<LenisRef>>;
|
|
112
|
+
declare function useLenis(callback?: ScrollCallback, deps?: any[], priority?: number): Lenis.default | undefined;
|
|
113
113
|
|
|
114
|
-
export { ReactLenis as Lenis,
|
|
114
|
+
export { ReactLenis as Lenis, type LenisContextValue, type LenisProps, type LenisRef, ReactLenis, ReactLenis as default, useLenis };
|
package/dist/lenis-react.mjs
CHANGED
|
@@ -1,2 +1,159 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// packages/react/src/provider.tsx
|
|
4
|
+
import Tempus from "@darkroom.engineering/tempus";
|
|
5
|
+
import Lenis from "lenis";
|
|
6
|
+
import {
|
|
7
|
+
createContext,
|
|
8
|
+
forwardRef,
|
|
9
|
+
useCallback,
|
|
10
|
+
useEffect as useEffect2,
|
|
11
|
+
useImperativeHandle,
|
|
12
|
+
useRef,
|
|
13
|
+
useState as useState2
|
|
14
|
+
} from "react";
|
|
15
|
+
|
|
16
|
+
// packages/react/src/store.ts
|
|
17
|
+
import { useEffect, useState } from "react";
|
|
18
|
+
var Store = class {
|
|
19
|
+
constructor(state) {
|
|
20
|
+
this.state = state;
|
|
21
|
+
}
|
|
22
|
+
listeners = [];
|
|
23
|
+
set(state) {
|
|
24
|
+
this.state = state;
|
|
25
|
+
for (let listener of this.listeners) {
|
|
26
|
+
listener(this.state);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
subscribe(listener) {
|
|
30
|
+
this.listeners = [...this.listeners, listener];
|
|
31
|
+
return () => {
|
|
32
|
+
this.listeners = this.listeners.filter((l) => l !== listener);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
get() {
|
|
36
|
+
return this.state;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function useStore(store) {
|
|
40
|
+
const [state, setState] = useState(store.get());
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
return store.subscribe((state2) => setState(state2));
|
|
43
|
+
}, [store]);
|
|
44
|
+
return state;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// packages/react/src/provider.tsx
|
|
48
|
+
import { jsx } from "react/jsx-runtime";
|
|
49
|
+
var LenisContext = createContext(null);
|
|
50
|
+
var rootLenisContextStore = new Store(null);
|
|
51
|
+
var ReactLenis = forwardRef(
|
|
52
|
+
({
|
|
53
|
+
children,
|
|
54
|
+
root = false,
|
|
55
|
+
options = {},
|
|
56
|
+
autoRaf = true,
|
|
57
|
+
rafPriority = 0,
|
|
58
|
+
className,
|
|
59
|
+
props
|
|
60
|
+
}, ref) => {
|
|
61
|
+
const wrapperRef = useRef(null);
|
|
62
|
+
const contentRef = useRef(null);
|
|
63
|
+
const [lenis, setLenis] = useState2(void 0);
|
|
64
|
+
useImperativeHandle(
|
|
65
|
+
ref,
|
|
66
|
+
() => ({
|
|
67
|
+
wrapper: wrapperRef.current,
|
|
68
|
+
content: contentRef.current,
|
|
69
|
+
lenis
|
|
70
|
+
}),
|
|
71
|
+
[lenis]
|
|
72
|
+
);
|
|
73
|
+
useEffect2(() => {
|
|
74
|
+
const lenis2 = new Lenis({
|
|
75
|
+
...options,
|
|
76
|
+
...!root && {
|
|
77
|
+
wrapper: wrapperRef.current,
|
|
78
|
+
content: contentRef.current
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
setLenis(lenis2);
|
|
82
|
+
return () => {
|
|
83
|
+
lenis2.destroy();
|
|
84
|
+
setLenis(void 0);
|
|
85
|
+
};
|
|
86
|
+
}, [root, JSON.stringify(options)]);
|
|
87
|
+
useEffect2(() => {
|
|
88
|
+
if (!lenis || !autoRaf) return;
|
|
89
|
+
return Tempus.add((time) => lenis.raf(time), rafPriority);
|
|
90
|
+
}, [lenis, autoRaf, rafPriority]);
|
|
91
|
+
const callbacksRefs = useRef([]);
|
|
92
|
+
const addCallback = useCallback(
|
|
93
|
+
(callback, priority) => {
|
|
94
|
+
callbacksRefs.current.push({ callback, priority });
|
|
95
|
+
callbacksRefs.current.sort((a, b) => a.priority - b.priority);
|
|
96
|
+
},
|
|
97
|
+
[]
|
|
98
|
+
);
|
|
99
|
+
const removeCallback = useCallback(
|
|
100
|
+
(callback) => {
|
|
101
|
+
callbacksRefs.current = callbacksRefs.current.filter(
|
|
102
|
+
(cb) => cb.callback !== callback
|
|
103
|
+
);
|
|
104
|
+
},
|
|
105
|
+
[]
|
|
106
|
+
);
|
|
107
|
+
useEffect2(() => {
|
|
108
|
+
if (root && lenis) {
|
|
109
|
+
rootLenisContextStore.set({ lenis, addCallback, removeCallback });
|
|
110
|
+
return () => rootLenisContextStore.set(null);
|
|
111
|
+
}
|
|
112
|
+
}, [root, lenis, addCallback, removeCallback]);
|
|
113
|
+
useEffect2(() => {
|
|
114
|
+
if (!lenis) return;
|
|
115
|
+
const onScroll = (data) => {
|
|
116
|
+
for (let i = 0; i < callbacksRefs.current.length; i++) {
|
|
117
|
+
callbacksRefs.current[i]?.callback(data);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
lenis.on("scroll", onScroll);
|
|
121
|
+
return () => {
|
|
122
|
+
lenis.off("scroll", onScroll);
|
|
123
|
+
};
|
|
124
|
+
}, [lenis]);
|
|
125
|
+
return /* @__PURE__ */ jsx(
|
|
126
|
+
LenisContext.Provider,
|
|
127
|
+
{
|
|
128
|
+
value: { lenis, addCallback, removeCallback },
|
|
129
|
+
children: root ? children : /* @__PURE__ */ jsx("div", { ref: wrapperRef, className, ...props, children: /* @__PURE__ */ jsx("div", { ref: contentRef, children }) })
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// packages/react/src/use-lenis.ts
|
|
136
|
+
import { useContext, useEffect as useEffect3 } from "react";
|
|
137
|
+
var fallbackContext = {};
|
|
138
|
+
function useLenis(callback, deps = [], priority = 0) {
|
|
139
|
+
const localContext = useContext(LenisContext);
|
|
140
|
+
const rootContext = useStore(rootLenisContextStore);
|
|
141
|
+
const currentContext = localContext ?? rootContext ?? fallbackContext;
|
|
142
|
+
const { lenis, addCallback, removeCallback } = currentContext;
|
|
143
|
+
useEffect3(() => {
|
|
144
|
+
if (!callback || !addCallback || !removeCallback || !lenis) return;
|
|
145
|
+
addCallback(callback, priority);
|
|
146
|
+
callback(lenis);
|
|
147
|
+
return () => {
|
|
148
|
+
removeCallback(callback);
|
|
149
|
+
};
|
|
150
|
+
}, [lenis, addCallback, removeCallback, priority, ...deps]);
|
|
151
|
+
return lenis;
|
|
152
|
+
}
|
|
153
|
+
export {
|
|
154
|
+
ReactLenis as Lenis,
|
|
155
|
+
ReactLenis,
|
|
156
|
+
ReactLenis as default,
|
|
157
|
+
useLenis
|
|
158
|
+
};
|
|
159
|
+
//# sourceMappingURL=lenis-react.mjs.map
|
package/dist/lenis-react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lenis-react.mjs","sources":["../../src/index.tsx","../../src/store.ts"],"sourcesContent":["'use client'\r\n\r\nimport Tempus from '@darkroom.engineering/tempus'\r\nimport Lenis, { type ScrollCallback } from 'lenis'\r\nimport {\r\n createContext,\r\n forwardRef,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useImperativeHandle,\r\n useRef,\r\n useState,\r\n} from 'react'\r\nimport { Store, useStore } from './store'\r\nimport type { LenisContextValue, LenisProps, LenisRef } from './types'\r\n\r\nexport const LenisContext = createContext<LenisContextValue | null>(null)\r\n\r\nconst rootLenisContextStore = new Store<LenisContextValue | null>(null)\r\n\r\n// Fall back to an empty object if both context and store are not available\r\nconst fallbackContext: Partial<LenisContextValue> = {}\r\n\r\n/**\r\n * Hook to access the Lenis instance and its methods\r\n *\r\n * @example <caption>Scroll callback</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...')\r\n * }\r\n *\r\n * if (lenis.progress === 1) {\r\n * console.log('At the end!')\r\n * }\r\n * })\r\n *\r\n * @example <caption>Scroll callback with dependencies</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...', someDependency)\r\n * }\r\n * }, [someDependency])\r\n * @example <caption>Scroll callback with priority</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...')\r\n * }\r\n * }, [], 1)\r\n * @example <caption>Instance access</caption>\r\n * const lenis = useLenis()\r\n *\r\n * handleClick() {\r\n * lenis.scrollTo(100, {\r\n * lerp: 0.1,\r\n * duration: 1,\r\n * easing: (t) => t,\r\n * onComplete: () => {\r\n * console.log('Complete!')\r\n * }\r\n * })\r\n * }\r\n */\r\nexport function useLenis(\r\n callback?: ScrollCallback,\r\n deps: any[] = [],\r\n priority = 0\r\n) {\r\n // Try to get the lenis instance from the context first\r\n const localContext = useContext(LenisContext)\r\n // Fall back to the root store if the context is not available\r\n const rootContext = useStore(rootLenisContextStore)\r\n // Fall back to the fallback context if all else fails\r\n const currentContext = localContext ?? rootContext ?? fallbackContext\r\n\r\n const { lenis, addCallback, removeCallback } = currentContext\r\n\r\n useEffect(() => {\r\n if (!callback || !addCallback || !removeCallback || !lenis) return\r\n\r\n addCallback(callback, priority)\r\n callback(lenis)\r\n\r\n return () => {\r\n removeCallback(callback)\r\n }\r\n }, [lenis, addCallback, removeCallback, priority, ...deps])\r\n\r\n return lenis\r\n}\r\n\r\n/**\r\n * React component to setup a Lenis instance\r\n */\r\nconst ReactLenis = forwardRef<LenisRef, LenisProps>(\r\n (\r\n {\r\n children,\r\n root = false,\r\n options = {},\r\n autoRaf = true,\r\n rafPriority = 0,\r\n className,\r\n props,\r\n }: LenisProps,\r\n ref\r\n ) => {\r\n const wrapperRef = useRef<HTMLDivElement | null>(null)\r\n const contentRef = useRef<HTMLDivElement | null>(null)\r\n\r\n const [lenis, setLenis] = useState<Lenis | undefined>(undefined)\r\n\r\n // Setup ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n wrapper: wrapperRef.current,\r\n content: contentRef.current,\r\n lenis,\r\n }),\r\n [lenis]\r\n )\r\n\r\n // Setup lenis instance\r\n useEffect(() => {\r\n const lenis = new Lenis({\r\n ...options,\r\n ...(!root && {\r\n wrapper: wrapperRef.current!,\r\n content: contentRef.current!,\r\n }),\r\n })\r\n\r\n setLenis(lenis)\r\n\r\n return () => {\r\n lenis.destroy()\r\n setLenis(undefined)\r\n }\r\n }, [root, JSON.stringify(options)])\r\n\r\n // Setup raf\r\n useEffect(() => {\r\n if (!lenis || !autoRaf) return\r\n\r\n return Tempus.add((time: number) => lenis.raf(time), rafPriority)\r\n }, [lenis, autoRaf, rafPriority])\r\n\r\n // Handle callbacks\r\n const callbacksRefs = useRef<\r\n {\r\n callback: ScrollCallback\r\n priority: number\r\n }[]\r\n >([])\r\n\r\n const addCallback: LenisContextValue['addCallback'] = useCallback(\r\n (callback, priority) => {\r\n callbacksRefs.current.push({ callback, priority })\r\n callbacksRefs.current.sort((a, b) => a.priority - b.priority)\r\n },\r\n []\r\n )\r\n\r\n const removeCallback: LenisContextValue['removeCallback'] = useCallback(\r\n (callback) => {\r\n callbacksRefs.current = callbacksRefs.current.filter(\r\n (cb) => cb.callback !== callback\r\n )\r\n },\r\n []\r\n )\r\n\r\n // This makes sure to set the global context if the root is true\r\n useEffect(() => {\r\n if (root && lenis) {\r\n rootLenisContextStore.set({ lenis, addCallback, removeCallback })\r\n\r\n return () => rootLenisContextStore.set(null)\r\n }\r\n }, [root, lenis, addCallback, removeCallback])\r\n\r\n // Setup callback listeners\r\n useEffect(() => {\r\n if (!lenis) return\r\n\r\n const onScroll: ScrollCallback = (data) => {\r\n for (let i = 0; i < callbacksRefs.current.length; i++) {\r\n callbacksRefs.current[i].callback(data)\r\n }\r\n }\r\n\r\n lenis.on('scroll', onScroll)\r\n\r\n return () => {\r\n lenis.off('scroll', onScroll)\r\n }\r\n }, [lenis])\r\n\r\n return (\r\n <LenisContext.Provider\r\n value={{ lenis: lenis!, addCallback, removeCallback }}\r\n >\r\n {root ? (\r\n children\r\n ) : (\r\n <div ref={wrapperRef} className={className} {...props}>\r\n <div ref={contentRef}>{children}</div>\r\n </div>\r\n )}\r\n </LenisContext.Provider>\r\n )\r\n }\r\n)\r\n\r\nexport * from './types'\r\nexport { ReactLenis as Lenis, ReactLenis }\r\nexport default ReactLenis\r\n","import { useEffect, useState } from 'react'\r\n\r\ntype Listener<S> = (state: S) => void\r\n\r\nexport class Store<S> {\r\n private listeners: Listener<S>[] = []\r\n\r\n constructor(private state: S) {}\r\n\r\n set(state: S) {\r\n this.state = state\r\n\r\n for (let listener of this.listeners) {\r\n listener(this.state)\r\n }\r\n }\r\n\r\n subscribe(listener: Listener<S>) {\r\n this.listeners = [...this.listeners, listener]\r\n return () => {\r\n this.listeners = this.listeners.filter((l) => l !== listener)\r\n }\r\n }\r\n\r\n get() {\r\n return this.state\r\n }\r\n}\r\n\r\nexport function useStore<S>(store: Store<S>) {\r\n const [state, setState] = useState(store.get())\r\n\r\n useEffect(() => {\r\n return store.subscribe((state) => setState(state))\r\n }, [store])\r\n\r\n return state\r\n}\r\n"],"names":["LenisContext","createContext","rootLenisContextStore","Store","constructor","state","this","listeners","set","listener","subscribe","filter","l","get","fallbackContext","useLenis","callback","deps","priority","localContext","useContext","rootContext","useStore","store","setState","useState","useEffect","currentContext","_a","lenis","addCallback","removeCallback","ReactLenis","forwardRef","children","root","options","autoRaf","rafPriority","className","props","ref","wrapperRef","useRef","contentRef","setLenis","undefined","useImperativeHandle","wrapper","current","content","Lenis","Object","assign","destroy","JSON","stringify","Tempus","add","time","raf","callbacksRefs","useCallback","push","sort","a","b","cb","onScroll","data","i","length","on","off","_jsx","Provider","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../packages/react/src/provider.tsx","../packages/react/src/store.ts","../packages/react/src/use-lenis.ts"],"sourcesContent":["import Tempus from '@darkroom.engineering/tempus'\r\nimport Lenis, { type ScrollCallback } from 'lenis'\r\nimport {\r\n createContext,\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useImperativeHandle,\r\n useRef,\r\n useState,\r\n} from 'react'\r\nimport { Store } from './store'\r\nimport type { LenisContextValue, LenisProps, LenisRef } from './types'\r\n\r\nexport const LenisContext = createContext<LenisContextValue | null>(null)\r\n\r\n/**\r\n * The root store for the lenis context\r\n *\r\n * This store serves as a fallback for the context if it is not available\r\n * and allows us to use the global lenis instance above a provider\r\n */\r\nexport const rootLenisContextStore = new Store<LenisContextValue | null>(null)\r\n\r\n/**\r\n * React component to setup a Lenis instance\r\n */\r\nexport const ReactLenis = forwardRef<LenisRef, LenisProps>(\r\n (\r\n {\r\n children,\r\n root = false,\r\n options = {},\r\n autoRaf = true,\r\n rafPriority = 0,\r\n className,\r\n props,\r\n }: LenisProps,\r\n ref\r\n ) => {\r\n const wrapperRef = useRef<HTMLDivElement | null>(null)\r\n const contentRef = useRef<HTMLDivElement | null>(null)\r\n\r\n const [lenis, setLenis] = useState<Lenis | undefined>(undefined)\r\n\r\n // Setup ref\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n wrapper: wrapperRef.current,\r\n content: contentRef.current,\r\n lenis,\r\n }),\r\n [lenis]\r\n )\r\n\r\n // Setup lenis instance\r\n useEffect(() => {\r\n const lenis = new Lenis({\r\n ...options,\r\n ...(!root && {\r\n wrapper: wrapperRef.current!,\r\n content: contentRef.current!,\r\n }),\r\n })\r\n\r\n setLenis(lenis)\r\n\r\n return () => {\r\n lenis.destroy()\r\n setLenis(undefined)\r\n }\r\n }, [root, JSON.stringify(options)])\r\n\r\n // Setup raf\r\n useEffect(() => {\r\n if (!lenis || !autoRaf) return\r\n\r\n return Tempus.add((time: number) => lenis.raf(time), rafPriority)\r\n }, [lenis, autoRaf, rafPriority])\r\n\r\n // Handle callbacks\r\n const callbacksRefs = useRef<\r\n {\r\n callback: ScrollCallback\r\n priority: number\r\n }[]\r\n >([])\r\n\r\n const addCallback: LenisContextValue['addCallback'] = useCallback(\r\n (callback, priority) => {\r\n callbacksRefs.current.push({ callback, priority })\r\n callbacksRefs.current.sort((a, b) => a.priority - b.priority)\r\n },\r\n []\r\n )\r\n\r\n const removeCallback: LenisContextValue['removeCallback'] = useCallback(\r\n (callback) => {\r\n callbacksRefs.current = callbacksRefs.current.filter(\r\n (cb) => cb.callback !== callback\r\n )\r\n },\r\n []\r\n )\r\n\r\n // This makes sure to set the global context if the root is true\r\n useEffect(() => {\r\n if (root && lenis) {\r\n rootLenisContextStore.set({ lenis, addCallback, removeCallback })\r\n\r\n return () => rootLenisContextStore.set(null)\r\n }\r\n }, [root, lenis, addCallback, removeCallback])\r\n\r\n // Setup callback listeners\r\n useEffect(() => {\r\n if (!lenis) return\r\n\r\n const onScroll: ScrollCallback = (data) => {\r\n for (let i = 0; i < callbacksRefs.current.length; i++) {\r\n callbacksRefs.current[i]?.callback(data)\r\n }\r\n }\r\n\r\n lenis.on('scroll', onScroll)\r\n\r\n return () => {\r\n lenis.off('scroll', onScroll)\r\n }\r\n }, [lenis])\r\n\r\n return (\r\n <LenisContext.Provider\r\n value={{ lenis: lenis!, addCallback, removeCallback }}\r\n >\r\n {root ? (\r\n children\r\n ) : (\r\n <div ref={wrapperRef} className={className} {...props}>\r\n <div ref={contentRef}>{children}</div>\r\n </div>\r\n )}\r\n </LenisContext.Provider>\r\n )\r\n }\r\n)\r\n","import { useEffect, useState } from 'react'\r\n\r\ntype Listener<S> = (state: S) => void\r\n\r\nexport class Store<S> {\r\n private listeners: Listener<S>[] = []\r\n\r\n constructor(private state: S) {}\r\n\r\n set(state: S) {\r\n this.state = state\r\n\r\n for (let listener of this.listeners) {\r\n listener(this.state)\r\n }\r\n }\r\n\r\n subscribe(listener: Listener<S>) {\r\n this.listeners = [...this.listeners, listener]\r\n return () => {\r\n this.listeners = this.listeners.filter((l) => l !== listener)\r\n }\r\n }\r\n\r\n get() {\r\n return this.state\r\n }\r\n}\r\n\r\nexport function useStore<S>(store: Store<S>) {\r\n const [state, setState] = useState(store.get())\r\n\r\n useEffect(() => {\r\n return store.subscribe((state) => setState(state))\r\n }, [store])\r\n\r\n return state\r\n}\r\n","import type { ScrollCallback } from 'lenis'\r\nimport { useContext, useEffect } from 'react'\r\nimport { LenisContext, rootLenisContextStore } from './provider'\r\nimport { useStore } from './store'\r\nimport type { LenisContextValue } from './types'\r\n\r\n// Fall back to an empty object if both context and store are not available\r\nconst fallbackContext: Partial<LenisContextValue> = {}\r\n\r\n/**\r\n * Hook to access the Lenis instance and its methods\r\n *\r\n * @example <caption>Scroll callback</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...')\r\n * }\r\n *\r\n * if (lenis.progress === 1) {\r\n * console.log('At the end!')\r\n * }\r\n * })\r\n *\r\n * @example <caption>Scroll callback with dependencies</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...', someDependency)\r\n * }\r\n * }, [someDependency])\r\n * @example <caption>Scroll callback with priority</caption>\r\n * useLenis((lenis) => {\r\n * if (lenis.isScrolling) {\r\n * console.log('Scrolling...')\r\n * }\r\n * }, [], 1)\r\n * @example <caption>Instance access</caption>\r\n * const lenis = useLenis()\r\n *\r\n * handleClick() {\r\n * lenis.scrollTo(100, {\r\n * lerp: 0.1,\r\n * duration: 1,\r\n * easing: (t) => t,\r\n * onComplete: () => {\r\n * console.log('Complete!')\r\n * }\r\n * })\r\n * }\r\n */\r\nexport function useLenis(\r\n callback?: ScrollCallback,\r\n deps: any[] = [],\r\n priority = 0\r\n) {\r\n // Try to get the lenis instance from the context first\r\n const localContext = useContext(LenisContext)\r\n // Fall back to the root store if the context is not available\r\n const rootContext = useStore(rootLenisContextStore)\r\n // Fall back to the fallback context if all else fails\r\n const currentContext = localContext ?? rootContext ?? fallbackContext\r\n\r\n const { lenis, addCallback, removeCallback } = currentContext\r\n\r\n useEffect(() => {\r\n if (!callback || !addCallback || !removeCallback || !lenis) return\r\n\r\n addCallback(callback, priority)\r\n callback(lenis)\r\n\r\n return () => {\r\n removeCallback(callback)\r\n }\r\n }, [lenis, addCallback, removeCallback, priority, ...deps])\r\n\r\n return lenis\r\n}\r\n"],"mappings":"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","names":["useEffect","useState","state","useState","useEffect","lenis","useEffect","useEffect"]}
|