lenis 1.3.18-dev.0 → 1.3.18-dev.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/README.md +21 -15
- package/dist/lenis-react.d.ts +6 -0
- package/dist/lenis-react.mjs +10 -1
- package/dist/lenis-react.mjs.map +1 -1
- package/dist/lenis.css +1 -1
- package/dist/lenis.d.ts +1 -1
- package/dist/lenis.js +37 -35
- package/dist/lenis.js.map +1 -1
- package/dist/lenis.min.js +1 -1
- package/dist/lenis.min.js.map +1 -1
- package/dist/lenis.mjs +37 -35
- package/dist/lenis.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -192,7 +192,7 @@ gsap.ticker.lagSmoothing(0);
|
|
|
192
192
|
| `autoRaf` | `boolean` | `false` | Whether or not to automatically run `requestAnimationFrame` loop. |
|
|
193
193
|
| `anchors` | `boolean, ScrollToOptions` | `false` | Scroll to anchor links when clicked. If `true` is passed, it will enable anchor links with default options. If `ScrollToOptions` is passed, it will enable anchor links with the given options. |
|
|
194
194
|
| `autoToggle` | `boolean` | `false` | Automatically start or stop the lenis instance based on the wrapper's overflow property, ⚠️ this requires Lenis recommended CSS. Safari > 17.3, Chrome > 116 and Firefox > 128 ([https://caniuse.com/?search=transition-behavior](https://caniuse.com/?search=transition-behavior)). |
|
|
195
|
-
| `allowNestedScroll` | `boolean` | `false` |
|
|
195
|
+
| `allowNestedScroll` | `boolean` | `false` | Automatically allow nested scrollable elements to scroll natively. This is the simplest way to handle nested scroll. ⚠️ Can create performance issues since it checks the DOM tree on every scroll event. If that's a concern, use `data-lenis-prevent` attributes instead. |
|
|
196
196
|
| `naiveDimensions` | `boolean` | `false` | If `true`, Lenis will use naive dimensions calculation. ⚠️ Be careful, this has a performance impact. |
|
|
197
197
|
| `stopInertiaOnNavigate` | `boolean` | `false` | If `true`, Lenis will stop inertia when an internal link is clicked. |
|
|
198
198
|
<br/>
|
|
@@ -266,21 +266,17 @@ gsap.ticker.lagSmoothing(0);
|
|
|
266
266
|
|
|
267
267
|
### Nested scroll
|
|
268
268
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
```html
|
|
272
|
-
<div id="modal">scrollable content</div>
|
|
273
|
-
```
|
|
269
|
+
The simplest and most reliable way to handle nested scrollable elements is to use the `allowNestedScroll` option:
|
|
274
270
|
|
|
275
271
|
```js
|
|
276
272
|
const lenis = new Lenis({
|
|
277
|
-
|
|
273
|
+
allowNestedScroll: true,
|
|
278
274
|
})
|
|
279
275
|
```
|
|
280
276
|
|
|
281
|
-
|
|
277
|
+
This automatically detects nested scrollable elements and lets them scroll natively. However, this can create performance issues since Lenis needs to check the DOM tree on every scroll event. If you experience performance problems, use `data-lenis-prevent` instead.
|
|
282
278
|
|
|
283
|
-
#### Using HTML
|
|
279
|
+
#### Using HTML attributes
|
|
284
280
|
|
|
285
281
|
```html
|
|
286
282
|
<div data-lenis-prevent>scrollable content</div>
|
|
@@ -288,18 +284,28 @@ const lenis = new Lenis({
|
|
|
288
284
|
|
|
289
285
|
[See example](https://codepen.io/ClementRoche/pen/PoLdjpw)
|
|
290
286
|
|
|
291
|
-
|
|
287
|
+
| Attribute | Description |
|
|
288
|
+
|---------------------------------|--------------------------------------|
|
|
289
|
+
| `data-lenis-prevent` | Prevent all smooth scroll events |
|
|
290
|
+
| `data-lenis-prevent-wheel` | Prevent wheel events only |
|
|
291
|
+
| `data-lenis-prevent-touch` | Prevent touch events only |
|
|
292
|
+
| `data-lenis-prevent-vertical` | Prevent vertical scroll events only |
|
|
293
|
+
| `data-lenis-prevent-horizontal` | Prevent horizontal scroll events only|
|
|
294
|
+
|
|
295
|
+
#### Using Javascript
|
|
292
296
|
|
|
293
297
|
```html
|
|
294
|
-
<div
|
|
298
|
+
<div id="modal">scrollable content</div>
|
|
295
299
|
```
|
|
296
300
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
+
```js
|
|
302
|
+
const lenis = new Lenis({
|
|
303
|
+
prevent: (node) => node.id === 'modal',
|
|
304
|
+
})
|
|
301
305
|
```
|
|
302
306
|
|
|
307
|
+
[See example](https://codepen.io/ClementRoche/pen/emONGYN)
|
|
308
|
+
|
|
303
309
|
|
|
304
310
|
|
|
305
311
|
### Anchor links
|
package/dist/lenis-react.d.ts
CHANGED
|
@@ -29,6 +29,11 @@ type LenisProps = ComponentPropsWithoutRef<'div'> & {
|
|
|
29
29
|
* Children
|
|
30
30
|
*/
|
|
31
31
|
children?: ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Class name to be applied to the wrapper div
|
|
34
|
+
* @default ''
|
|
35
|
+
*/
|
|
36
|
+
className?: string | undefined;
|
|
32
37
|
};
|
|
33
38
|
type LenisRef = {
|
|
34
39
|
/**
|
|
@@ -58,6 +63,7 @@ declare const ReactLenis: react.ForwardRefExoticComponent<Omit<react.DetailedHTM
|
|
|
58
63
|
options?: Lenis.LenisOptions;
|
|
59
64
|
autoRaf?: boolean;
|
|
60
65
|
children?: react.ReactNode;
|
|
66
|
+
className?: string | undefined;
|
|
61
67
|
} & react.RefAttributes<LenisRef>>;
|
|
62
68
|
|
|
63
69
|
/**
|
package/dist/lenis-react.mjs
CHANGED
|
@@ -53,6 +53,7 @@ var ReactLenis = forwardRef(
|
|
|
53
53
|
root = false,
|
|
54
54
|
options = {},
|
|
55
55
|
autoRaf = true,
|
|
56
|
+
className = "",
|
|
56
57
|
...props
|
|
57
58
|
}, ref) => {
|
|
58
59
|
const wrapperRef = useRef(null);
|
|
@@ -122,7 +123,15 @@ var ReactLenis = forwardRef(
|
|
|
122
123
|
LenisContext.Provider,
|
|
123
124
|
{
|
|
124
125
|
value: { lenis, addCallback, removeCallback },
|
|
125
|
-
children: root && root !== "asChild" ? children : /* @__PURE__ */ jsx(
|
|
126
|
+
children: root && root !== "asChild" ? children : /* @__PURE__ */ jsx(
|
|
127
|
+
"div",
|
|
128
|
+
{
|
|
129
|
+
ref: wrapperRef,
|
|
130
|
+
className: `${className} ${lenis?.className ?? ""}`.trim(),
|
|
131
|
+
...props,
|
|
132
|
+
children: /* @__PURE__ */ jsx("div", { ref: contentRef, children })
|
|
133
|
+
}
|
|
134
|
+
)
|
|
126
135
|
}
|
|
127
136
|
);
|
|
128
137
|
}
|
package/dist/lenis-react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/react/src/provider.tsx","../packages/react/src/store.ts","../packages/react/src/use-lenis.ts"],"sourcesContent":["import Lenis, { type ScrollCallback } from 'lenis'\nimport {\n createContext,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\nimport { Store } from './store'\nimport type { LenisContextValue, LenisProps, LenisRef } from './types'\n\nexport const LenisContext = createContext<LenisContextValue | null>(null)\n\n/**\n * The root store for the lenis context\n *\n * This store serves as a fallback for the context if it is not available\n * and allows us to use the global lenis instance above a provider\n */\nexport const rootLenisContextStore = new Store<LenisContextValue | null>(null)\n\n/**\n * React component to setup a Lenis instance\n */\nexport const ReactLenis = forwardRef<LenisRef, LenisProps>(\n (\n {\n children,\n root = false,\n options = {},\n autoRaf = true,\n ...props\n }: LenisProps,\n ref\n ) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n\n const [lenis, setLenis] = useState<Lenis | undefined>(undefined)\n\n // Setup ref\n useImperativeHandle(\n ref,\n () => ({\n wrapper: wrapperRef.current,\n content: contentRef.current,\n lenis,\n }),\n [lenis]\n )\n\n // Setup lenis instance\n useEffect(() => {\n const lenis = new Lenis({\n ...options,\n ...(wrapperRef.current &&\n contentRef.current && {\n wrapper: wrapperRef.current!,\n content: contentRef.current!,\n }),\n autoRaf: options?.autoRaf ?? autoRaf, // this is to avoid breaking the autoRaf prop if it's still used (require breaking change)\n })\n\n setLenis(lenis)\n\n return () => {\n lenis.destroy()\n setLenis(undefined)\n }\n }, [autoRaf, JSON.stringify({ ...options, wrapper: null, content: null })])\n\n // Handle callbacks\n const callbacksRefs = useRef<\n {\n callback: ScrollCallback\n priority: number\n }[]\n >([])\n\n const addCallback: LenisContextValue['addCallback'] = useCallback(\n (callback, priority) => {\n callbacksRefs.current.push({ callback, priority })\n callbacksRefs.current.sort((a, b) => a.priority - b.priority)\n },\n []\n )\n\n const removeCallback: LenisContextValue['removeCallback'] = useCallback(\n (callback) => {\n callbacksRefs.current = callbacksRefs.current.filter(\n (cb) => cb.callback !== callback\n )\n },\n []\n )\n\n // This makes sure to set the global context if the root is true\n useEffect(() => {\n if (root && lenis) {\n rootLenisContextStore.set({ lenis, addCallback, removeCallback })\n\n return () => rootLenisContextStore.set(null)\n }\n }, [root, lenis, addCallback, removeCallback])\n\n // Setup callback listeners\n useEffect(() => {\n if (!lenis) return\n\n const onScroll: ScrollCallback = (data) => {\n for (const { callback } of callbacksRefs.current) {\n callback(data)\n }\n }\n\n lenis.on('scroll', onScroll)\n\n return () => {\n lenis.off('scroll', onScroll)\n }\n }, [lenis])\n\n if (!children) return null\n\n return (\n <LenisContext.Provider\n value={{ lenis: lenis!, addCallback, removeCallback }}\n >\n {root && root !== 'asChild' ? (\n children\n ) : (\n <div ref={wrapperRef} {...props}>\n <div ref={contentRef}>{children}</div>\n </div>\n )}\n </LenisContext.Provider>\n )\n }\n)\n","import { useEffect, useState } from 'react'\n\ntype Listener<S> = (state: S) => void\n\nexport class Store<S> {\n private listeners: Listener<S>[] = []\n\n constructor(private state: S) {}\n\n set(state: S) {\n this.state = state\n\n for (const listener of this.listeners) {\n listener(this.state)\n }\n }\n\n subscribe(listener: Listener<S>) {\n this.listeners = [...this.listeners, listener]\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n get() {\n return this.state\n }\n}\n\nexport function useStore<S>(store: Store<S>) {\n const [state, setState] = useState(store.get())\n\n useEffect(() => {\n return store.subscribe((state) => setState(state))\n }, [store])\n\n return state\n}\n","import type { ScrollCallback } from 'lenis'\nimport { useContext, useEffect } from 'react'\nimport { LenisContext, rootLenisContextStore } from './provider'\nimport { useStore } from './store'\nimport type { LenisContextValue } from './types'\n\n// Fall back to an empty object if both context and store are not available\nconst fallbackContext: Partial<LenisContextValue> = {}\n\n/**\n * Hook to access the Lenis instance and its methods\n *\n * @example <caption>Scroll callback</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...')\n * }\n *\n * if (lenis.progress === 1) {\n * console.log('At the end!')\n * }\n * })\n *\n * @example <caption>Scroll callback with dependencies</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...', someDependency)\n * }\n * }, [someDependency])\n * @example <caption>Scroll callback with priority</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...')\n * }\n * }, [], 1)\n * @example <caption>Instance access</caption>\n * const lenis = useLenis()\n *\n * handleClick() {\n * lenis.scrollTo(100, {\n * lerp: 0.1,\n * duration: 1,\n * easing: (t) => t,\n * onComplete: () => {\n * console.log('Complete!')\n * }\n * })\n * }\n */\nexport function useLenis(\n callback?: ScrollCallback,\n deps: unknown[] = [],\n priority = 0\n) {\n // Try to get the lenis instance from the context first\n const localContext = useContext(LenisContext)\n // Fall back to the root store if the context is not available\n const rootContext = useStore(rootLenisContextStore)\n // Fall back to the fallback context if all else fails\n const currentContext = localContext ?? rootContext ?? fallbackContext\n\n const { lenis, addCallback, removeCallback } = currentContext\n\n useEffect(() => {\n if (!(callback && addCallback && removeCallback && lenis)) return\n\n addCallback(callback, priority)\n callback(lenis)\n\n return () => {\n removeCallback(callback)\n }\n }, [lenis, addCallback, removeCallback, priority, ...deps, callback])\n\n return lenis\n}\n"],"mappings":"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","names":["useEffect","useState","state","useState","useEffect","lenis","useEffect","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../packages/react/src/provider.tsx","../packages/react/src/store.ts","../packages/react/src/use-lenis.ts"],"sourcesContent":["import Lenis, { type ScrollCallback } from 'lenis'\nimport {\n createContext,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\nimport { Store } from './store'\nimport type { LenisContextValue, LenisProps, LenisRef } from './types'\n\nexport const LenisContext = createContext<LenisContextValue | null>(null)\n\n/**\n * The root store for the lenis context\n *\n * This store serves as a fallback for the context if it is not available\n * and allows us to use the global lenis instance above a provider\n */\nexport const rootLenisContextStore = new Store<LenisContextValue | null>(null)\n\n/**\n * React component to setup a Lenis instance\n */\nexport const ReactLenis = forwardRef<LenisRef, LenisProps>(\n (\n {\n children,\n root = false,\n options = {},\n autoRaf = true,\n className = '',\n ...props\n }: LenisProps,\n ref\n ) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n\n const [lenis, setLenis] = useState<Lenis | undefined>(undefined)\n\n // Setup ref\n useImperativeHandle(\n ref,\n () => ({\n wrapper: wrapperRef.current,\n content: contentRef.current,\n lenis,\n }),\n [lenis]\n )\n\n // Setup lenis instance\n useEffect(() => {\n const lenis = new Lenis({\n ...options,\n ...(wrapperRef.current &&\n contentRef.current && {\n wrapper: wrapperRef.current!,\n content: contentRef.current!,\n }),\n autoRaf: options?.autoRaf ?? autoRaf, // this is to avoid breaking the autoRaf prop if it's still used (require breaking change)\n })\n\n setLenis(lenis)\n\n return () => {\n lenis.destroy()\n setLenis(undefined)\n }\n }, [autoRaf, JSON.stringify({ ...options, wrapper: null, content: null })])\n\n // Handle callbacks\n const callbacksRefs = useRef<\n {\n callback: ScrollCallback\n priority: number\n }[]\n >([])\n\n const addCallback: LenisContextValue['addCallback'] = useCallback(\n (callback, priority) => {\n callbacksRefs.current.push({ callback, priority })\n callbacksRefs.current.sort((a, b) => a.priority - b.priority)\n },\n []\n )\n\n const removeCallback: LenisContextValue['removeCallback'] = useCallback(\n (callback) => {\n callbacksRefs.current = callbacksRefs.current.filter(\n (cb) => cb.callback !== callback\n )\n },\n []\n )\n\n // This makes sure to set the global context if the root is true\n useEffect(() => {\n if (root && lenis) {\n rootLenisContextStore.set({ lenis, addCallback, removeCallback })\n\n return () => rootLenisContextStore.set(null)\n }\n }, [root, lenis, addCallback, removeCallback])\n\n // Setup callback listeners\n useEffect(() => {\n if (!lenis) return\n\n const onScroll: ScrollCallback = (data) => {\n for (const { callback } of callbacksRefs.current) {\n callback(data)\n }\n }\n\n lenis.on('scroll', onScroll)\n\n return () => {\n lenis.off('scroll', onScroll)\n }\n }, [lenis])\n\n if (!children) return null\n\n return (\n <LenisContext.Provider\n value={{ lenis: lenis!, addCallback, removeCallback }}\n >\n {root && root !== 'asChild' ? (\n children\n ) : (\n <div\n ref={wrapperRef}\n className={`${className} ${lenis?.className ?? ''}`.trim()}\n {...props}\n >\n <div ref={contentRef}>{children}</div>\n </div>\n )}\n </LenisContext.Provider>\n )\n }\n)\n","import { useEffect, useState } from 'react'\n\ntype Listener<S> = (state: S) => void\n\nexport class Store<S> {\n private listeners: Listener<S>[] = []\n\n constructor(private state: S) {}\n\n set(state: S) {\n this.state = state\n\n for (const listener of this.listeners) {\n listener(this.state)\n }\n }\n\n subscribe(listener: Listener<S>) {\n this.listeners = [...this.listeners, listener]\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n get() {\n return this.state\n }\n}\n\nexport function useStore<S>(store: Store<S>) {\n const [state, setState] = useState(store.get())\n\n useEffect(() => {\n return store.subscribe((state) => setState(state))\n }, [store])\n\n return state\n}\n","import type { ScrollCallback } from 'lenis'\nimport { useContext, useEffect } from 'react'\nimport { LenisContext, rootLenisContextStore } from './provider'\nimport { useStore } from './store'\nimport type { LenisContextValue } from './types'\n\n// Fall back to an empty object if both context and store are not available\nconst fallbackContext: Partial<LenisContextValue> = {}\n\n/**\n * Hook to access the Lenis instance and its methods\n *\n * @example <caption>Scroll callback</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...')\n * }\n *\n * if (lenis.progress === 1) {\n * console.log('At the end!')\n * }\n * })\n *\n * @example <caption>Scroll callback with dependencies</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...', someDependency)\n * }\n * }, [someDependency])\n * @example <caption>Scroll callback with priority</caption>\n * useLenis((lenis) => {\n * if (lenis.isScrolling) {\n * console.log('Scrolling...')\n * }\n * }, [], 1)\n * @example <caption>Instance access</caption>\n * const lenis = useLenis()\n *\n * handleClick() {\n * lenis.scrollTo(100, {\n * lerp: 0.1,\n * duration: 1,\n * easing: (t) => t,\n * onComplete: () => {\n * console.log('Complete!')\n * }\n * })\n * }\n */\nexport function useLenis(\n callback?: ScrollCallback,\n deps: unknown[] = [],\n priority = 0\n) {\n // Try to get the lenis instance from the context first\n const localContext = useContext(LenisContext)\n // Fall back to the root store if the context is not available\n const rootContext = useStore(rootLenisContextStore)\n // Fall back to the fallback context if all else fails\n const currentContext = localContext ?? rootContext ?? fallbackContext\n\n const { lenis, addCallback, removeCallback } = currentContext\n\n useEffect(() => {\n if (!(callback && addCallback && removeCallback && lenis)) return\n\n addCallback(callback, priority)\n callback(lenis)\n\n return () => {\n removeCallback(callback)\n }\n }, [lenis, addCallback, removeCallback, priority, ...deps, callback])\n\n return lenis\n}\n"],"mappings":"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","names":["useEffect","useState","state","useState","useEffect","lenis","useEffect","useEffect"]}
|
package/dist/lenis.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent-touch]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-property:overflow;transition-duration:1ms;transition-behavior:allow-discrete}
|
|
1
|
+
html.lenis,html.lenis body{height:auto}.lenis:not(.lenis-autoToggle).lenis-stopped{overflow:clip}.lenis [data-lenis-prevent],.lenis [data-lenis-prevent-wheel],.lenis [data-lenis-prevent-touch],.lenis [data-lenis-prevent-vertical],.lenis [data-lenis-prevent-horizontal]{overscroll-behavior:contain}.lenis.lenis-smooth iframe{pointer-events:none}.lenis.lenis-autoToggle{transition-property:overflow;transition-duration:1ms;transition-behavior:allow-discrete}
|
package/dist/lenis.d.ts
CHANGED
|
@@ -395,7 +395,7 @@ declare class Lenis {
|
|
|
395
395
|
lerp, duration, easing, onStart, onComplete, force, // scroll even if stopped
|
|
396
396
|
userData, }?: ScrollToOptions): void;
|
|
397
397
|
private preventNextNativeScrollEvent;
|
|
398
|
-
private
|
|
398
|
+
private hasNestedScroll;
|
|
399
399
|
/**
|
|
400
400
|
* The root element on which lenis is instanced
|
|
401
401
|
*/
|
package/dist/lenis.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "1.3.18-dev.
|
|
2
|
+
var version = "1.3.18-dev.1";
|
|
3
3
|
|
|
4
4
|
// packages/core/src/maths.ts
|
|
5
5
|
function clamp(min, input, max) {
|
|
@@ -632,8 +632,12 @@ var Lenis = class {
|
|
|
632
632
|
let composedPath = event.composedPath();
|
|
633
633
|
composedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement));
|
|
634
634
|
const prevent = this.options.prevent;
|
|
635
|
+
const gestureOrientation = Math.abs(deltaX) >= Math.abs(deltaY) ? "horizontal" : "vertical";
|
|
635
636
|
if (composedPath.find(
|
|
636
|
-
(node) => node instanceof HTMLElement && (typeof prevent === "function" && prevent?.(node) || node.hasAttribute?.("data-lenis-prevent") || isTouch && node.hasAttribute?.("data-lenis-prevent-touch") || isWheel && node.hasAttribute?.("data-lenis-prevent-wheel") || this.options.allowNestedScroll && this.
|
|
637
|
+
(node) => node instanceof HTMLElement && (typeof prevent === "function" && prevent?.(node) || node.hasAttribute?.("data-lenis-prevent") || gestureOrientation === "vertical" && node.hasAttribute?.("data-lenis-prevent-vertical") || gestureOrientation === "horizontal" && node.hasAttribute?.("data-lenis-prevent-horizontal") || isTouch && node.hasAttribute?.("data-lenis-prevent-touch") || isWheel && node.hasAttribute?.("data-lenis-prevent-wheel") || this.options.allowNestedScroll && this.hasNestedScroll(node, {
|
|
638
|
+
deltaX,
|
|
639
|
+
deltaY
|
|
640
|
+
}))
|
|
637
641
|
))
|
|
638
642
|
return;
|
|
639
643
|
if (this.isStopped || this.isLocked) {
|
|
@@ -921,7 +925,7 @@ var Lenis = class {
|
|
|
921
925
|
this._preventNextNativeScrollEvent = false;
|
|
922
926
|
});
|
|
923
927
|
}
|
|
924
|
-
|
|
928
|
+
hasNestedScroll(node, { deltaX, deltaY }) {
|
|
925
929
|
const time = Date.now();
|
|
926
930
|
if (!node._lenis) node._lenis = {};
|
|
927
931
|
const cache = node._lenis;
|
|
@@ -929,24 +933,31 @@ var Lenis = class {
|
|
|
929
933
|
let hasOverflowY;
|
|
930
934
|
let isScrollableX;
|
|
931
935
|
let isScrollableY;
|
|
936
|
+
let hasOverscrollBehaviorX;
|
|
937
|
+
let hasOverscrollBehaviorY;
|
|
932
938
|
let scrollWidth;
|
|
933
939
|
let scrollHeight;
|
|
934
940
|
let clientWidth;
|
|
935
941
|
let clientHeight;
|
|
936
|
-
const gestureOrientation = this.options.gestureOrientation;
|
|
937
942
|
if (time - (cache.time ?? 0) > 2e3) {
|
|
938
943
|
cache.time = Date.now();
|
|
939
944
|
const computedStyle = window.getComputedStyle(node);
|
|
940
945
|
cache.computedStyle = computedStyle;
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
hasOverflowY = ["auto", "overlay", "scroll"].includes(
|
|
946
|
+
hasOverflowX = ["auto", "overlay", "scroll"].includes(
|
|
947
|
+
computedStyle.overflowX
|
|
948
|
+
);
|
|
949
|
+
hasOverflowY = ["auto", "overlay", "scroll"].includes(
|
|
950
|
+
computedStyle.overflowY
|
|
951
|
+
);
|
|
952
|
+
hasOverscrollBehaviorX = ["auto"].includes(
|
|
953
|
+
computedStyle.overscrollBehaviorX
|
|
954
|
+
);
|
|
955
|
+
hasOverscrollBehaviorY = ["auto"].includes(
|
|
956
|
+
computedStyle.overscrollBehaviorY
|
|
957
|
+
);
|
|
945
958
|
cache.hasOverflowX = hasOverflowX;
|
|
946
959
|
cache.hasOverflowY = hasOverflowY;
|
|
947
960
|
if (!(hasOverflowX || hasOverflowY)) return false;
|
|
948
|
-
if (gestureOrientation === "vertical" && !hasOverflowY) return false;
|
|
949
|
-
if (gestureOrientation === "horizontal" && !hasOverflowX) return false;
|
|
950
961
|
scrollWidth = node.scrollWidth;
|
|
951
962
|
scrollHeight = node.scrollHeight;
|
|
952
963
|
clientWidth = node.clientWidth;
|
|
@@ -959,6 +970,8 @@ var Lenis = class {
|
|
|
959
970
|
cache.scrollHeight = scrollHeight;
|
|
960
971
|
cache.clientWidth = clientWidth;
|
|
961
972
|
cache.clientHeight = clientHeight;
|
|
973
|
+
cache.hasOverscrollBehaviorX = hasOverscrollBehaviorX;
|
|
974
|
+
cache.hasOverscrollBehaviorY = hasOverscrollBehaviorY;
|
|
962
975
|
} else {
|
|
963
976
|
isScrollableX = cache.isScrollableX;
|
|
964
977
|
isScrollableY = cache.isScrollableY;
|
|
@@ -968,50 +981,39 @@ var Lenis = class {
|
|
|
968
981
|
scrollHeight = cache.scrollHeight;
|
|
969
982
|
clientWidth = cache.clientWidth;
|
|
970
983
|
clientHeight = cache.clientHeight;
|
|
984
|
+
hasOverscrollBehaviorX = cache.hasOverscrollBehaviorX;
|
|
985
|
+
hasOverscrollBehaviorY = cache.hasOverscrollBehaviorY;
|
|
971
986
|
}
|
|
972
|
-
if (!(
|
|
987
|
+
if (!(hasOverflowX && isScrollableX || hasOverflowY && isScrollableY)) {
|
|
973
988
|
return false;
|
|
974
989
|
}
|
|
975
|
-
|
|
976
|
-
return false;
|
|
977
|
-
if (gestureOrientation === "horizontal" && !(hasOverflowX && isScrollableX))
|
|
978
|
-
return false;
|
|
979
|
-
let orientation;
|
|
980
|
-
if (gestureOrientation === "horizontal") {
|
|
981
|
-
orientation = "x";
|
|
982
|
-
} else if (gestureOrientation === "vertical") {
|
|
983
|
-
orientation = "y";
|
|
984
|
-
} else {
|
|
985
|
-
const isScrollingX = deltaX !== 0;
|
|
986
|
-
const isScrollingY = deltaY !== 0;
|
|
987
|
-
if (isScrollingX && hasOverflowX && isScrollableX) {
|
|
988
|
-
orientation = "x";
|
|
989
|
-
}
|
|
990
|
-
if (isScrollingY && hasOverflowY && isScrollableY) {
|
|
991
|
-
orientation = "y";
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
if (!orientation) return false;
|
|
990
|
+
const orientation = Math.abs(deltaX) >= Math.abs(deltaY) ? "horizontal" : "vertical";
|
|
995
991
|
let scroll;
|
|
996
992
|
let maxScroll;
|
|
997
993
|
let delta;
|
|
998
994
|
let hasOverflow;
|
|
999
995
|
let isScrollable;
|
|
1000
|
-
|
|
1001
|
-
|
|
996
|
+
let hasOverscrollBehavior;
|
|
997
|
+
if (orientation === "horizontal") {
|
|
998
|
+
scroll = Math.round(node.scrollLeft);
|
|
1002
999
|
maxScroll = scrollWidth - clientWidth;
|
|
1003
1000
|
delta = deltaX;
|
|
1004
1001
|
hasOverflow = hasOverflowX;
|
|
1005
1002
|
isScrollable = isScrollableX;
|
|
1006
|
-
|
|
1007
|
-
|
|
1003
|
+
hasOverscrollBehavior = hasOverscrollBehaviorX;
|
|
1004
|
+
} else if (orientation === "vertical") {
|
|
1005
|
+
scroll = Math.round(node.scrollTop);
|
|
1008
1006
|
maxScroll = scrollHeight - clientHeight;
|
|
1009
1007
|
delta = deltaY;
|
|
1010
1008
|
hasOverflow = hasOverflowY;
|
|
1011
1009
|
isScrollable = isScrollableY;
|
|
1010
|
+
hasOverscrollBehavior = hasOverscrollBehaviorY;
|
|
1012
1011
|
} else {
|
|
1013
1012
|
return false;
|
|
1014
1013
|
}
|
|
1014
|
+
if (!hasOverscrollBehavior && (scroll === maxScroll || scroll === 0)) {
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1015
1017
|
const willScroll = delta > 0 ? scroll < maxScroll : scroll > 0;
|
|
1016
1018
|
return willScroll && hasOverflow && isScrollable;
|
|
1017
1019
|
}
|