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/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 param.
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
- if (element === document.body ||
16
- element === document.documentElement ||
17
- element instanceof Window) {
18
- return {
19
- scrollLeft: document.body.scrollLeft || document.documentElement.scrollLeft,
20
- scrollTop: document.body.scrollTop || document.documentElement.scrollTop,
21
- scrollWidth: document.body.scrollWidth || document.documentElement.scrollWidth,
22
- clientWidth: document.body.clientWidth || document.documentElement.clientWidth,
23
- clientHeight: document.body.clientHeight || document.documentElement.clientHeight,
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
- scroll: (from: number, to: number) => void;
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 { useCallback, useRef, useState } from 'react';
13
- import { scroller } from '../scroller';
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 scroll = useCallback(function (from, to) {
29
- var container = getElement(ref);
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 scrollLeft_1 = scrollContainer.scrollLeft, scrollTop_1 = scrollContainer.scrollTop;
68
- var scrollState = __assign(__assign({}, state), { isScrolledLeft: scrollLeft_1 === 0, isScrolledRight: scrollLeft_1 >= scrollWidth - clientWidth, isScrolledTop: scrollTop_1 === 0, isScrolledBottom: scrollTop_1 >= scrollHeight - clientHeight, left: scrollLeft_1, top: scrollTop_1 });
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: scrollLeft,
80
- scrollRight: scrollRight,
81
- scrollBottom: scrollBottom,
82
- scrollTop: scrollTop,
83
- scrollCenter: scrollCenter,
84
- scroll: scroll,
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
- scroll: (from: number, to: number) => void;
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 { scroller } from '../scroller';
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 scrollArgs = {
24
- container: window,
25
- options: __assign(__assign({}, defaultScrollOptions), props),
26
- };
27
- var scroll = useCallback(function (from, to) {
28
- var scrollContainer = scroller(scrollArgs);
29
- scrollContainer.scrollTo(from, to);
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
- useIsoMorphicEffect(function () {
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
  }
@@ -1,10 +1,10 @@
1
- import { ScrollerProps } from './types';
2
- export declare function scroller({ container, options }: ScrollerProps): {
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
  };
@@ -1,39 +1,43 @@
1
1
  import { defaultScrollOptions, getEasing, resolveScrollValues, validateElement } from './utils';
2
- export function scroller(_a) {
3
- var container = _a.container, _b = _a.options, options = _b === void 0 ? defaultScrollOptions : _b;
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 _c = resolveScrollValues(container), scrollLeft = _c.scrollLeft, scrollTop = _c.scrollTop, clientWidth = _c.clientWidth, clientHeight = _c.clientHeight, scrollWidth = _c.scrollWidth, scrollHeight = _c.scrollHeight;
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
- function loop(currentTime) {
20
- if (!startTime)
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
- var currentPositionInTime = easingFunc(time) * (to - from) + from;
14
+ return easingFunc(timeFraction) * distance + from;
15
+ }
16
+ function updateScrollPosition(currentPosition) {
25
17
  container.scrollTo({
26
- left: layout === 'horizontal' ? currentPositionInTime : undefined,
27
- top: layout === 'vertical' ? currentPositionInTime : undefined,
18
+ left: layout === 'horizontal' ? currentPosition : undefined,
19
+ top: layout === 'vertical' ? currentPosition : undefined,
28
20
  });
29
- if (time < 1) {
30
- requestId = requestAnimationFrame(loop);
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(loop);
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
- scrollTo(from, to, direction);
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
- scrollTo(from, to, direction);
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
  }
@@ -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 param.
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 param.
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
- if (element === document.body ||
13
- element === document.documentElement ||
14
- element instanceof Window) {
15
- return {
16
- scrollLeft: document.body.scrollLeft || document.documentElement.scrollLeft,
17
- scrollTop: document.body.scrollTop || document.documentElement.scrollTop,
18
- scrollWidth: document.body.scrollWidth || document.documentElement.scrollWidth,
19
- clientWidth: document.body.clientWidth || document.documentElement.clientWidth,
20
- clientHeight: document.body.clientHeight || document.documentElement.clientHeight,
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.1.0",
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
- "bump": "changeset version",
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": {