use-scroller 1.1.0 → 1.2.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 +100 -58
- package/dist/cjs/hooks/use-scroll.d.ts +10 -6
- package/dist/cjs/hooks/use-scroll.js +38 -48
- package/dist/cjs/hooks/use-window-scroll.d.ts +1 -1
- package/dist/cjs/hooks/use-window-scroll.js +29 -27
- package/dist/cjs/scroller.d.ts +5 -5
- package/dist/cjs/scroller.js +48 -51
- package/dist/cjs/utils.d.ts +17 -4
- package/dist/cjs/utils.js +35 -22
- package/dist/esm/hooks/use-scroll.d.ts +10 -6
- package/dist/esm/hooks/use-scroll.js +40 -50
- package/dist/esm/hooks/use-window-scroll.d.ts +1 -1
- package/dist/esm/hooks/use-window-scroll.js +30 -28
- package/dist/esm/scroller.d.ts +5 -5
- package/dist/esm/scroller.js +46 -49
- package/dist/esm/utils.d.ts +17 -4
- package/dist/esm/utils.js +35 -22
- package/package.json +2 -3
- package/src/hooks/use-scroll.ts +47 -58
- package/src/hooks/use-window-scroll.ts +55 -42
- package/src/scroller.ts +50 -53
- package/src/utils.ts +37 -24
package/dist/cjs/utils.js
CHANGED
|
@@ -1,42 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getEasing = exports.easingMap = exports.getElement = exports.validateElement = exports.resolveScrollValues = exports.defaultScrollOptions = exports.isServer = void 0;
|
|
4
|
+
// Check if the code is running on the server-side.
|
|
4
5
|
exports.isServer = typeof window === 'undefined' || typeof document === 'undefined';
|
|
6
|
+
// Default scroll options used if no options are provided.
|
|
5
7
|
exports.defaultScrollOptions = {
|
|
6
8
|
direction: 'vertical',
|
|
7
9
|
duration: 300,
|
|
8
10
|
easingOption: 'ease-in-out',
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
|
-
* Resolves scroll values based on the type of
|
|
12
|
-
* @param {HTMLElement | Window} element
|
|
13
|
+
* Resolves scroll values based on the type of element.
|
|
14
|
+
* @param {HTMLElement | Window} element - The element to retrieve scroll values from.
|
|
15
|
+
* @returns {object} - An object containing scroll-related properties.
|
|
13
16
|
*/
|
|
14
17
|
var resolveScrollValues = function (element) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
scrollHeight: document.body.scrollHeight || document.documentElement.scrollHeight,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
18
|
+
var isWindow = element instanceof Window;
|
|
19
|
+
var docElement = document.documentElement;
|
|
20
|
+
var docBody = document.body;
|
|
21
|
+
var scrollLeftMax = isWindow
|
|
22
|
+
? Math.max(docBody.scrollLeft, docElement.scrollLeft)
|
|
23
|
+
: element.scrollWidth - element.clientWidth;
|
|
24
|
+
var scrollTopMax = isWindow
|
|
25
|
+
? Math.max(docBody.scrollTop, docElement.scrollTop)
|
|
26
|
+
: element.scrollHeight - element.clientHeight;
|
|
27
27
|
return {
|
|
28
|
-
scrollLeft: element.scrollLeft,
|
|
29
|
-
scrollTop: element.scrollTop,
|
|
30
|
-
scrollWidth: element.scrollWidth,
|
|
31
|
-
clientWidth: element.clientWidth,
|
|
32
|
-
clientHeight: element.clientHeight,
|
|
33
|
-
scrollHeight: element.scrollHeight,
|
|
28
|
+
scrollLeft: isWindow ? docBody.scrollLeft || docElement.scrollLeft : element.scrollLeft,
|
|
29
|
+
scrollTop: isWindow ? docBody.scrollTop || docElement.scrollTop : element.scrollTop,
|
|
30
|
+
scrollWidth: isWindow ? docBody.scrollWidth || docElement.scrollWidth : element.scrollWidth,
|
|
31
|
+
clientWidth: isWindow ? docBody.clientWidth || docElement.clientWidth : element.clientWidth,
|
|
32
|
+
clientHeight: isWindow ? docBody.clientHeight || docElement.clientHeight : element.clientHeight,
|
|
33
|
+
scrollHeight: isWindow ? docBody.scrollHeight || docElement.scrollHeight : element.scrollHeight,
|
|
34
|
+
scrollLeftMax: scrollLeftMax,
|
|
35
|
+
scrollTopMax: scrollTopMax,
|
|
34
36
|
};
|
|
35
37
|
};
|
|
36
38
|
exports.resolveScrollValues = resolveScrollValues;
|
|
37
39
|
/**
|
|
38
|
-
* Validate if element passed to the function is valid.
|
|
39
|
-
* @param {HTMLElement | Window} element
|
|
40
|
+
* Validate if the element passed to the function is valid.
|
|
41
|
+
* @param {HTMLElement | Window} element - The element to validate.
|
|
40
42
|
*/
|
|
41
43
|
function validateElement(element) {
|
|
42
44
|
if (element === undefined) {
|
|
@@ -47,6 +49,11 @@ function validateElement(element) {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
exports.validateElement = validateElement;
|
|
52
|
+
/**
|
|
53
|
+
* Get the DOM element from a React ref object.
|
|
54
|
+
* @param {RefObject<HTMLElement>} ref - The React ref object.
|
|
55
|
+
* @returns {HTMLElement} - The DOM element.
|
|
56
|
+
*/
|
|
50
57
|
var getElement = function (ref) {
|
|
51
58
|
if (!ref.current) {
|
|
52
59
|
throw new Error("Could not resolve ref object: ".concat(ref.current));
|
|
@@ -54,6 +61,7 @@ var getElement = function (ref) {
|
|
|
54
61
|
return ref.current;
|
|
55
62
|
};
|
|
56
63
|
exports.getElement = getElement;
|
|
64
|
+
// Map of easing functions for scroll animations.
|
|
57
65
|
exports.easingMap = {
|
|
58
66
|
linear: function (t) {
|
|
59
67
|
return t;
|
|
@@ -68,6 +76,11 @@ exports.easingMap = {
|
|
|
68
76
|
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
69
77
|
},
|
|
70
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Get an easing function based on the provided easing option or the default option.
|
|
81
|
+
* @param {EasingOptions} easing - The easing option.
|
|
82
|
+
* @returns {EasingFunction} - The easing function.
|
|
83
|
+
*/
|
|
71
84
|
var getEasing = function (easing) {
|
|
72
85
|
var easeFunc = exports.easingMap[easing || exports.defaultScrollOptions.easingOption];
|
|
73
86
|
if (!easeFunc) {
|
|
@@ -10,11 +10,15 @@ export declare function useScroll<T extends HTMLElement>(props?: Partial<ScrollO
|
|
|
10
10
|
isScrolledRight: boolean;
|
|
11
11
|
isScrolledTop: boolean;
|
|
12
12
|
isScrolledBottom: boolean;
|
|
13
|
+
maxScrollLeft: number;
|
|
14
|
+
maxScrollTop: number;
|
|
15
|
+
scrollPercentageX: number;
|
|
16
|
+
scrollPercentageY: number;
|
|
13
17
|
};
|
|
14
|
-
scrollLeft: (offset?: number) => void;
|
|
15
|
-
scrollRight: (offset?: number) => void;
|
|
16
|
-
scrollBottom: (offset?: number) => void;
|
|
17
|
-
scrollTop: (offset?: number) => void;
|
|
18
|
-
scrollCenter: () => void;
|
|
19
|
-
|
|
18
|
+
scrollLeft: ((offset?: number | undefined) => void) | undefined;
|
|
19
|
+
scrollRight: ((offset?: number | undefined) => void) | undefined;
|
|
20
|
+
scrollBottom: ((offset?: number | undefined) => void) | undefined;
|
|
21
|
+
scrollTop: ((offset?: number | undefined) => void) | undefined;
|
|
22
|
+
scrollCenter: (() => void) | undefined;
|
|
23
|
+
scrollTo: ((to: number) => void) | undefined;
|
|
20
24
|
};
|
|
@@ -9,78 +9,68 @@ var __assign = (this && this.__assign) || function () {
|
|
|
9
9
|
};
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { useRef, useState } from 'react';
|
|
13
|
+
import { createScroller } from '../scroller';
|
|
14
14
|
import { defaultScrollOptions, getElement } from '../utils';
|
|
15
15
|
import { useIsoMorphicEffect } from './use-iso-morphic-effect';
|
|
16
|
+
var initialState = {
|
|
17
|
+
left: 0,
|
|
18
|
+
top: 0,
|
|
19
|
+
isScrollable: false,
|
|
20
|
+
isScrolledLeft: true,
|
|
21
|
+
isScrolledRight: false,
|
|
22
|
+
isScrolledTop: true,
|
|
23
|
+
isScrolledBottom: false,
|
|
24
|
+
maxScrollLeft: 0,
|
|
25
|
+
maxScrollTop: 0,
|
|
26
|
+
scrollPercentageX: 0,
|
|
27
|
+
scrollPercentageY: 0, // Percentage of vertical scroll covered
|
|
28
|
+
};
|
|
16
29
|
export function useScroll(props) {
|
|
30
|
+
var _a, _b, _c, _d, _e, _f;
|
|
17
31
|
var ref = useRef(null);
|
|
18
|
-
var _a = useState(function () { return ({
|
|
19
|
-
left: 0,
|
|
20
|
-
top: 0,
|
|
21
|
-
isScrollable: false,
|
|
22
|
-
isScrolledLeft: false,
|
|
23
|
-
isScrolledRight: false,
|
|
24
|
-
isScrolledTop: false,
|
|
25
|
-
isScrolledBottom: false,
|
|
26
|
-
}); }), state = _a[0], setState = _a[1];
|
|
27
32
|
var scrollOpt = __assign(__assign({}, defaultScrollOptions), props);
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
31
|
-
scrollContainer.scrollTo(from, to);
|
|
32
|
-
}, []);
|
|
33
|
-
var scrollCenter = useCallback(function () {
|
|
34
|
-
var container = getElement(ref);
|
|
35
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
36
|
-
scrollContainer.scrollToCenter();
|
|
37
|
-
}, []);
|
|
38
|
-
var scrollTop = useCallback(function (offset) {
|
|
39
|
-
var container = getElement(ref);
|
|
40
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
41
|
-
scrollContainer.scrollToTop(offset);
|
|
42
|
-
}, []);
|
|
43
|
-
var scrollBottom = useCallback(function (offset) {
|
|
44
|
-
var container = getElement(ref);
|
|
45
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
46
|
-
scrollContainer.scrollToBottom(offset);
|
|
47
|
-
}, []);
|
|
48
|
-
var scrollRight = useCallback(function (offset) {
|
|
49
|
-
var container = getElement(ref);
|
|
50
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
51
|
-
scrollContainer.scrollToRight(offset);
|
|
52
|
-
}, []);
|
|
53
|
-
var scrollLeft = useCallback(function (offset) {
|
|
54
|
-
var container = getElement(ref);
|
|
55
|
-
var scrollContainer = scroller({ container: container, options: scrollOpt });
|
|
56
|
-
scrollContainer.scrollToLeft(offset);
|
|
57
|
-
}, []);
|
|
33
|
+
var scrollerRef = useRef(null);
|
|
34
|
+
var _g = useState(function () { return initialState; }), state = _g[0], setState = _g[1];
|
|
58
35
|
useIsoMorphicEffect(function () {
|
|
59
36
|
var scrollContainer = ref.current;
|
|
60
37
|
if (!scrollContainer)
|
|
61
38
|
return;
|
|
39
|
+
// Create the scroller instance only once inside the effect
|
|
40
|
+
if (!scrollerRef.current) {
|
|
41
|
+
var container = getElement(ref);
|
|
42
|
+
scrollerRef.current = createScroller(container, scrollOpt);
|
|
43
|
+
}
|
|
62
44
|
var scrollWidth = scrollContainer.scrollWidth, clientWidth = scrollContainer.clientWidth, clientHeight = scrollContainer.clientHeight, scrollHeight = scrollContainer.scrollHeight;
|
|
63
45
|
var isScrollable = clientWidth !== scrollWidth || clientHeight !== scrollHeight;
|
|
64
46
|
setState(function (prev) { return (__assign(__assign({}, prev), { isScrollable: isScrollable })); });
|
|
65
47
|
var handleScroll = function () {
|
|
66
48
|
if (scrollContainer) {
|
|
67
|
-
var
|
|
68
|
-
var
|
|
49
|
+
var scrollLeft = scrollContainer.scrollLeft, scrollTop = scrollContainer.scrollTop;
|
|
50
|
+
var isAtLeftBoundary = scrollLeft === 0;
|
|
51
|
+
var isAtRightBoundary = scrollLeft >= scrollWidth - clientWidth;
|
|
52
|
+
var isAtTopBoundary = scrollTop === 0;
|
|
53
|
+
var isAtBottomBoundary = scrollTop >= scrollHeight - clientHeight;
|
|
54
|
+
var scrollState = __assign(__assign({}, state), { isScrolledLeft: isAtLeftBoundary, isScrolledRight: isAtRightBoundary, isScrolledTop: isAtTopBoundary, isScrolledBottom: isAtBottomBoundary, left: scrollLeft, top: scrollTop, maxScrollLeft: scrollWidth - clientWidth, maxScrollTop: scrollHeight - clientHeight, scrollPercentageX: isAtLeftBoundary
|
|
55
|
+
? 0
|
|
56
|
+
: (scrollLeft / (scrollWidth - clientWidth)) * 100, scrollPercentageY: isAtTopBoundary
|
|
57
|
+
? 0
|
|
58
|
+
: (scrollTop / (scrollHeight - clientHeight)) * 100 });
|
|
69
59
|
setState(scrollState);
|
|
70
60
|
}
|
|
71
61
|
};
|
|
72
62
|
handleScroll();
|
|
73
63
|
scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.addEventListener('scroll', handleScroll);
|
|
74
64
|
return function () { return scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.removeEventListener('scroll', handleScroll); };
|
|
75
|
-
}, []);
|
|
65
|
+
}, [state]);
|
|
76
66
|
return {
|
|
77
67
|
ref: ref,
|
|
78
68
|
state: state,
|
|
79
|
-
scrollLeft:
|
|
80
|
-
scrollRight:
|
|
81
|
-
scrollBottom:
|
|
82
|
-
scrollTop:
|
|
83
|
-
scrollCenter:
|
|
84
|
-
|
|
69
|
+
scrollLeft: (_a = scrollerRef.current) === null || _a === void 0 ? void 0 : _a.scrollToLeft,
|
|
70
|
+
scrollRight: (_b = scrollerRef.current) === null || _b === void 0 ? void 0 : _b.scrollToRight,
|
|
71
|
+
scrollBottom: (_c = scrollerRef.current) === null || _c === void 0 ? void 0 : _c.scrollToBottom,
|
|
72
|
+
scrollTop: (_d = scrollerRef.current) === null || _d === void 0 ? void 0 : _d.scrollToTop,
|
|
73
|
+
scrollCenter: (_e = scrollerRef.current) === null || _e === void 0 ? void 0 : _e.scrollToCenter,
|
|
74
|
+
scrollTo: (_f = scrollerRef.current) === null || _f === void 0 ? void 0 : _f.scrollTo,
|
|
85
75
|
};
|
|
86
76
|
}
|
|
@@ -9,5 +9,5 @@ export declare function useWindowScroll(props?: Partial<Omit<ScrollOptions, 'dir
|
|
|
9
9
|
scrollTop: (offset?: number | undefined) => void;
|
|
10
10
|
scrollBottom: (offset?: number | undefined) => void;
|
|
11
11
|
scrollToTarget: (currentTarget: HTMLElement) => void;
|
|
12
|
-
|
|
12
|
+
scrollTo: (position: number) => void;
|
|
13
13
|
};
|
|
@@ -10,7 +10,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { useCallback, useState } from 'react';
|
|
13
|
-
import {
|
|
13
|
+
import { createScroller } from '../scroller';
|
|
14
14
|
import { useIsoMorphicEffect } from './use-iso-morphic-effect';
|
|
15
15
|
import { defaultScrollOptions, resolveScrollValues } from '../utils';
|
|
16
16
|
export function useWindowScroll(props) {
|
|
@@ -20,37 +20,39 @@ export function useWindowScroll(props) {
|
|
|
20
20
|
isScrolledTop: false,
|
|
21
21
|
isScrolledBottom: false,
|
|
22
22
|
}); }), state = _a[0], setState = _a[1];
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
var container = window;
|
|
24
|
+
var scrollOptions = __assign(__assign({}, defaultScrollOptions), props);
|
|
25
|
+
var scrollContainer = createScroller(container, scrollOptions);
|
|
26
|
+
var handleScroll = useCallback(function () {
|
|
27
|
+
var _a = resolveScrollValues(container), scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop, clientHeight = _a.clientHeight, scrollHeight = _a.scrollHeight;
|
|
28
|
+
var isAtTopBoundary = scrollTop === 0;
|
|
29
|
+
var isAtBottomBoundary = scrollTop >= scrollHeight - clientHeight;
|
|
30
|
+
var scrollState = {
|
|
31
|
+
left: scrollLeft,
|
|
32
|
+
top: scrollTop,
|
|
33
|
+
isScrolledTop: isAtTopBoundary,
|
|
34
|
+
isScrolledBottom: isAtBottomBoundary,
|
|
35
|
+
};
|
|
36
|
+
setState(scrollState);
|
|
37
|
+
}, [container]);
|
|
38
|
+
useIsoMorphicEffect(function () {
|
|
39
|
+
handleScroll();
|
|
40
|
+
container.addEventListener('scroll', handleScroll);
|
|
41
|
+
return function () {
|
|
42
|
+
container.removeEventListener('scroll', handleScroll);
|
|
43
|
+
};
|
|
44
|
+
}, [handleScroll]);
|
|
45
|
+
var scrollTo = useCallback(function (position) {
|
|
46
|
+
scrollContainer.scrollTo(position);
|
|
47
|
+
}, [scrollContainer]);
|
|
31
48
|
var scrollToTarget = useCallback(function (currentTarget) {
|
|
32
|
-
var scrollContainer = scroller(scrollArgs);
|
|
33
49
|
scrollContainer.scrollToTarget(currentTarget);
|
|
34
|
-
}, []);
|
|
50
|
+
}, [scrollContainer]);
|
|
35
51
|
var scrollTop = useCallback(function (offset) {
|
|
36
|
-
var scrollContainer = scroller(scrollArgs);
|
|
37
52
|
scrollContainer.scrollToTop(offset);
|
|
38
|
-
}, []);
|
|
53
|
+
}, [scrollContainer]);
|
|
39
54
|
var scrollBottom = useCallback(function (offset) {
|
|
40
|
-
var scrollContainer = scroller(scrollArgs);
|
|
41
55
|
scrollContainer.scrollToBottom(offset);
|
|
42
|
-
}, []);
|
|
43
|
-
|
|
44
|
-
var handleScroll = function () {
|
|
45
|
-
if (window) {
|
|
46
|
-
var _a = resolveScrollValues(window), scrollLeft = _a.scrollLeft, scrollTop_1 = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;
|
|
47
|
-
var scrollState = __assign(__assign({}, state), { isScrolledTop: scrollTop_1 === 0, isScrolledBottom: scrollTop_1 >= scrollHeight - clientHeight, left: scrollLeft, top: scrollTop_1 });
|
|
48
|
-
setState(scrollState);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
handleScroll();
|
|
52
|
-
window === null || window === void 0 ? void 0 : window.addEventListener('scroll', handleScroll);
|
|
53
|
-
return function () { return window === null || window === void 0 ? void 0 : window.removeEventListener('scroll', handleScroll); };
|
|
54
|
-
}, []);
|
|
55
|
-
return { state: state, scrollTop: scrollTop, scrollBottom: scrollBottom, scrollToTarget: scrollToTarget, scroll: scroll };
|
|
56
|
+
}, [scrollContainer]);
|
|
57
|
+
return { state: state, scrollTop: scrollTop, scrollBottom: scrollBottom, scrollToTarget: scrollToTarget, scrollTo: scrollTo };
|
|
56
58
|
}
|
package/dist/esm/scroller.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
1
|
+
import { ScrollOptions } from './types';
|
|
2
|
+
export declare function createScroller(container: HTMLElement | Window, options?: ScrollOptions): {
|
|
3
|
+
scrollTo: (to: number) => void;
|
|
4
|
+
scrollToCenter: () => void;
|
|
5
|
+
scrollToTarget: (target: HTMLElement, offset?: number) => void;
|
|
3
6
|
scrollToLeft: (offset?: number) => void;
|
|
4
7
|
scrollToRight: (offset?: number) => void;
|
|
5
8
|
scrollToTop: (offset?: number) => void;
|
|
6
9
|
scrollToBottom: (offset?: number) => void;
|
|
7
|
-
scrollToTarget: (target: HTMLElement) => void;
|
|
8
|
-
scrollToCenter: () => void;
|
|
9
|
-
scrollTo: (from: number, to: number, layout?: 'horizontal' | 'vertical') => void;
|
|
10
10
|
};
|
package/dist/esm/scroller.js
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
import { defaultScrollOptions, getEasing, resolveScrollValues, validateElement } from './utils';
|
|
2
|
-
export function
|
|
3
|
-
|
|
2
|
+
export function createScroller(container, options) {
|
|
3
|
+
if (options === void 0) { options = defaultScrollOptions; }
|
|
4
4
|
validateElement(container);
|
|
5
5
|
var duration = options.duration, easingOption = options.easingOption, direction = options.direction;
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
* Scroll the Element or Window to the given
|
|
9
|
-
* position.
|
|
10
|
-
*
|
|
11
|
-
* @param {number} from the current scroll position.
|
|
12
|
-
* @param {number} to the new position to scroll.
|
|
13
|
-
* @param {string} layout the scroll direction.
|
|
14
|
-
*/
|
|
15
|
-
function scrollTo(from, to, layout) {
|
|
6
|
+
var _a = resolveScrollValues(container), scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop, clientWidth = _a.clientWidth, clientHeight = _a.clientHeight, scrollWidth = _a.scrollWidth, scrollHeight = _a.scrollHeight;
|
|
7
|
+
function scroll(from, to, layout) {
|
|
16
8
|
if (layout === void 0) { layout = direction; }
|
|
17
9
|
var startTime = null;
|
|
18
10
|
var requestId = 0;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
startTime = currentTime;
|
|
22
|
-
var time = Math.min((currentTime - startTime) / duration, 1);
|
|
11
|
+
var distance = Math.abs(to - from);
|
|
12
|
+
function calculateCurrentPosition(timeFraction) {
|
|
23
13
|
var easingFunc = getEasing(easingOption);
|
|
24
|
-
|
|
14
|
+
return easingFunc(timeFraction) * distance + from;
|
|
15
|
+
}
|
|
16
|
+
function updateScrollPosition(currentPosition) {
|
|
25
17
|
container.scrollTo({
|
|
26
|
-
left: layout === 'horizontal' ?
|
|
27
|
-
top: layout === 'vertical' ?
|
|
18
|
+
left: layout === 'horizontal' ? currentPosition : undefined,
|
|
19
|
+
top: layout === 'vertical' ? currentPosition : undefined,
|
|
28
20
|
});
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
}
|
|
22
|
+
function animateScroll(currentTime) {
|
|
23
|
+
if (!startTime)
|
|
24
|
+
startTime = currentTime;
|
|
25
|
+
var elapsedTime = currentTime - startTime;
|
|
26
|
+
var timeFraction = elapsedTime / duration;
|
|
27
|
+
var currentPosition = calculateCurrentPosition(timeFraction);
|
|
28
|
+
updateScrollPosition(currentPosition);
|
|
29
|
+
if (timeFraction < 1) {
|
|
30
|
+
requestId = requestAnimationFrame(animateScroll);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
cancelAnimationFrame(requestId);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
requestId = requestAnimationFrame(
|
|
36
|
+
requestId = requestAnimationFrame(animateScroll);
|
|
37
|
+
}
|
|
38
|
+
function scrollTo(to) {
|
|
39
|
+
var from = direction === 'vertical' ? scrollTop : scrollLeft;
|
|
40
|
+
scroll(from, to);
|
|
37
41
|
}
|
|
38
42
|
function scrollToCenter() {
|
|
39
43
|
var from = 0;
|
|
@@ -48,46 +52,39 @@ export function scroller(_a) {
|
|
|
48
52
|
from = scrollLeft;
|
|
49
53
|
to = scrollXCenterPosition;
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
scroll(from, to, direction);
|
|
52
56
|
}
|
|
53
|
-
function scrollToTarget(target) {
|
|
57
|
+
function scrollToTarget(target, offset) {
|
|
58
|
+
if (offset === void 0) { offset = 0; }
|
|
54
59
|
validateElement(target);
|
|
55
60
|
var offsetTop = target.offsetTop, offsetLeft = target.offsetLeft;
|
|
56
61
|
var from = 0;
|
|
57
62
|
var to = 0;
|
|
58
63
|
if (direction === 'vertical') {
|
|
59
64
|
from = scrollTop;
|
|
60
|
-
to = offsetTop;
|
|
65
|
+
to = offsetTop - offset;
|
|
61
66
|
}
|
|
62
67
|
if (direction === 'horizontal') {
|
|
63
68
|
from = scrollLeft;
|
|
64
|
-
to = offsetLeft;
|
|
69
|
+
to = offsetLeft - offset;
|
|
65
70
|
}
|
|
66
|
-
|
|
71
|
+
scroll(from, to, direction);
|
|
67
72
|
}
|
|
68
|
-
var scrollToLeft = function (offset) {
|
|
69
|
-
var scrollPosition = offset || scrollLeft - clientWidth;
|
|
70
|
-
scrollTo(scrollLeft, scrollPosition, 'horizontal');
|
|
71
|
-
};
|
|
72
|
-
var scrollToRight = function (offset) {
|
|
73
|
-
var scrollPosition = offset || scrollLeft + clientWidth;
|
|
74
|
-
scrollTo(scrollLeft, scrollPosition, 'horizontal');
|
|
75
|
-
};
|
|
76
|
-
var scrollToTop = function (offset) {
|
|
77
|
-
var scrollPosition = offset || scrollTop - clientHeight;
|
|
78
|
-
scrollTo(scrollTop, scrollPosition, 'vertical');
|
|
79
|
-
};
|
|
80
|
-
var scrollToBottom = function (offset) {
|
|
81
|
-
var scrollPosition = offset || scrollTop + clientHeight;
|
|
82
|
-
scrollTo(scrollTop, scrollPosition, 'vertical');
|
|
83
|
-
};
|
|
84
73
|
return {
|
|
85
|
-
scrollToLeft: scrollToLeft,
|
|
86
|
-
scrollToRight: scrollToRight,
|
|
87
|
-
scrollToTop: scrollToTop,
|
|
88
|
-
scrollToBottom: scrollToBottom,
|
|
89
|
-
scrollToTarget: scrollToTarget,
|
|
90
|
-
scrollToCenter: scrollToCenter,
|
|
91
74
|
scrollTo: scrollTo,
|
|
75
|
+
scrollToCenter: scrollToCenter,
|
|
76
|
+
scrollToTarget: scrollToTarget,
|
|
77
|
+
scrollToLeft: function (offset) {
|
|
78
|
+
scroll(scrollLeft, offset || scrollLeft - clientWidth, 'horizontal');
|
|
79
|
+
},
|
|
80
|
+
scrollToRight: function (offset) {
|
|
81
|
+
scroll(scrollLeft, offset || scrollLeft + clientWidth, 'horizontal');
|
|
82
|
+
},
|
|
83
|
+
scrollToTop: function (offset) {
|
|
84
|
+
scroll(scrollTop, offset || scrollTop - clientHeight, 'vertical');
|
|
85
|
+
},
|
|
86
|
+
scrollToBottom: function (offset) {
|
|
87
|
+
scroll(scrollTop, offset || scrollTop + clientHeight, 'vertical');
|
|
88
|
+
},
|
|
92
89
|
};
|
|
93
90
|
}
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -3,8 +3,9 @@ import { EasingFunction, EasingFunctions, EasingOptions, ScrollOptions } from '.
|
|
|
3
3
|
export declare const isServer: boolean;
|
|
4
4
|
export declare const defaultScrollOptions: ScrollOptions;
|
|
5
5
|
/**
|
|
6
|
-
* Resolves scroll values based on the type of
|
|
7
|
-
* @param {HTMLElement | Window} element
|
|
6
|
+
* Resolves scroll values based on the type of element.
|
|
7
|
+
* @param {HTMLElement | Window} element - The element to retrieve scroll values from.
|
|
8
|
+
* @returns {object} - An object containing scroll-related properties.
|
|
8
9
|
*/
|
|
9
10
|
export declare const resolveScrollValues: (element: HTMLElement | Window) => {
|
|
10
11
|
scrollLeft: number;
|
|
@@ -13,12 +14,24 @@ export declare const resolveScrollValues: (element: HTMLElement | Window) => {
|
|
|
13
14
|
clientWidth: number;
|
|
14
15
|
clientHeight: number;
|
|
15
16
|
scrollHeight: number;
|
|
17
|
+
scrollLeftMax: number;
|
|
18
|
+
scrollTopMax: number;
|
|
16
19
|
};
|
|
17
20
|
/**
|
|
18
|
-
* Validate if element passed to the function is valid.
|
|
19
|
-
* @param {HTMLElement | Window} element
|
|
21
|
+
* Validate if the element passed to the function is valid.
|
|
22
|
+
* @param {HTMLElement | Window} element - The element to validate.
|
|
20
23
|
*/
|
|
21
24
|
export declare function validateElement(element?: HTMLElement | Window): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get the DOM element from a React ref object.
|
|
27
|
+
* @param {RefObject<HTMLElement>} ref - The React ref object.
|
|
28
|
+
* @returns {HTMLElement} - The DOM element.
|
|
29
|
+
*/
|
|
22
30
|
export declare const getElement: (ref: RefObject<HTMLElement>) => HTMLElement;
|
|
23
31
|
export declare const easingMap: EasingFunctions;
|
|
32
|
+
/**
|
|
33
|
+
* Get an easing function based on the provided easing option or the default option.
|
|
34
|
+
* @param {EasingOptions} easing - The easing option.
|
|
35
|
+
* @returns {EasingFunction} - The easing function.
|
|
36
|
+
*/
|
|
24
37
|
export declare const getEasing: (easing?: EasingOptions) => EasingFunction;
|
package/dist/esm/utils.js
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
|
+
// Check if the code is running on the server-side.
|
|
1
2
|
export var isServer = typeof window === 'undefined' || typeof document === 'undefined';
|
|
3
|
+
// Default scroll options used if no options are provided.
|
|
2
4
|
export var defaultScrollOptions = {
|
|
3
5
|
direction: 'vertical',
|
|
4
6
|
duration: 300,
|
|
5
7
|
easingOption: 'ease-in-out',
|
|
6
8
|
};
|
|
7
9
|
/**
|
|
8
|
-
* Resolves scroll values based on the type of
|
|
9
|
-
* @param {HTMLElement | Window} element
|
|
10
|
+
* Resolves scroll values based on the type of element.
|
|
11
|
+
* @param {HTMLElement | Window} element - The element to retrieve scroll values from.
|
|
12
|
+
* @returns {object} - An object containing scroll-related properties.
|
|
10
13
|
*/
|
|
11
14
|
export var resolveScrollValues = function (element) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
scrollHeight: document.body.scrollHeight || document.documentElement.scrollHeight,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
15
|
+
var isWindow = element instanceof Window;
|
|
16
|
+
var docElement = document.documentElement;
|
|
17
|
+
var docBody = document.body;
|
|
18
|
+
var scrollLeftMax = isWindow
|
|
19
|
+
? Math.max(docBody.scrollLeft, docElement.scrollLeft)
|
|
20
|
+
: element.scrollWidth - element.clientWidth;
|
|
21
|
+
var scrollTopMax = isWindow
|
|
22
|
+
? Math.max(docBody.scrollTop, docElement.scrollTop)
|
|
23
|
+
: element.scrollHeight - element.clientHeight;
|
|
24
24
|
return {
|
|
25
|
-
scrollLeft: element.scrollLeft,
|
|
26
|
-
scrollTop: element.scrollTop,
|
|
27
|
-
scrollWidth: element.scrollWidth,
|
|
28
|
-
clientWidth: element.clientWidth,
|
|
29
|
-
clientHeight: element.clientHeight,
|
|
30
|
-
scrollHeight: element.scrollHeight,
|
|
25
|
+
scrollLeft: isWindow ? docBody.scrollLeft || docElement.scrollLeft : element.scrollLeft,
|
|
26
|
+
scrollTop: isWindow ? docBody.scrollTop || docElement.scrollTop : element.scrollTop,
|
|
27
|
+
scrollWidth: isWindow ? docBody.scrollWidth || docElement.scrollWidth : element.scrollWidth,
|
|
28
|
+
clientWidth: isWindow ? docBody.clientWidth || docElement.clientWidth : element.clientWidth,
|
|
29
|
+
clientHeight: isWindow ? docBody.clientHeight || docElement.clientHeight : element.clientHeight,
|
|
30
|
+
scrollHeight: isWindow ? docBody.scrollHeight || docElement.scrollHeight : element.scrollHeight,
|
|
31
|
+
scrollLeftMax: scrollLeftMax,
|
|
32
|
+
scrollTopMax: scrollTopMax,
|
|
31
33
|
};
|
|
32
34
|
};
|
|
33
35
|
/**
|
|
34
|
-
* Validate if element passed to the function is valid.
|
|
35
|
-
* @param {HTMLElement | Window} element
|
|
36
|
+
* Validate if the element passed to the function is valid.
|
|
37
|
+
* @param {HTMLElement | Window} element - The element to validate.
|
|
36
38
|
*/
|
|
37
39
|
export function validateElement(element) {
|
|
38
40
|
if (element === undefined) {
|
|
@@ -42,12 +44,18 @@ export function validateElement(element) {
|
|
|
42
44
|
throw new TypeError("\n The element passed to scroller() must be a valid element. \n You passed ".concat(element, ".\n "));
|
|
43
45
|
}
|
|
44
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the DOM element from a React ref object.
|
|
49
|
+
* @param {RefObject<HTMLElement>} ref - The React ref object.
|
|
50
|
+
* @returns {HTMLElement} - The DOM element.
|
|
51
|
+
*/
|
|
45
52
|
export var getElement = function (ref) {
|
|
46
53
|
if (!ref.current) {
|
|
47
54
|
throw new Error("Could not resolve ref object: ".concat(ref.current));
|
|
48
55
|
}
|
|
49
56
|
return ref.current;
|
|
50
57
|
};
|
|
58
|
+
// Map of easing functions for scroll animations.
|
|
51
59
|
export var easingMap = {
|
|
52
60
|
linear: function (t) {
|
|
53
61
|
return t;
|
|
@@ -62,6 +70,11 @@ export var easingMap = {
|
|
|
62
70
|
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
63
71
|
},
|
|
64
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* Get an easing function based on the provided easing option or the default option.
|
|
75
|
+
* @param {EasingOptions} easing - The easing option.
|
|
76
|
+
* @returns {EasingFunction} - The easing function.
|
|
77
|
+
*/
|
|
65
78
|
export var getEasing = function (easing) {
|
|
66
79
|
var easeFunc = easingMap[easing || defaultScrollOptions.easingOption];
|
|
67
80
|
if (!easeFunc) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "use-scroller",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"author": "silvi lila",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -27,8 +27,7 @@
|
|
|
27
27
|
"clean": "rm -rf ./dist",
|
|
28
28
|
"test": "jest",
|
|
29
29
|
"lint": "lint ./src/*",
|
|
30
|
-
"
|
|
31
|
-
"release": "yarn build && changeset publish",
|
|
30
|
+
"release": "yarn build && yarn changeset version && yarn changeset publish",
|
|
32
31
|
"changeset": "changeset"
|
|
33
32
|
},
|
|
34
33
|
"prettier": {
|