@smakss/react-scroll-direction 4.2.0 → 4.3.0-develop.2
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 +45 -24
- package/dist/index.d.ts +1 -1
- package/dist/index.js +85 -161
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +53 -30
- package/package.json +46 -27
package/Readme.md
CHANGED
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
# React Scroll Direction Hook
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
`@smakss/react-scroll-direction` is a versatile, lightweight React hook that not
|
|
9
|
+
only detects the scroll direction but also provides the scroll position in your
|
|
10
|
+
application with ease. This enhanced functionality includes detecting distances
|
|
11
|
+
from the top, bottom, left, and right edges of the viewport, making it an ideal
|
|
12
|
+
solution for advanced scroll-based interactions in your React applications.
|
|
13
|
+
|
|
14
|
+
Originally inspired by a
|
|
15
|
+
[popular StackOverflow response](https://stackoverflow.com/a/62497293/11908502),
|
|
16
|
+
this package has evolved into a comprehensive tool for managing scroll detection
|
|
17
|
+
in React applications.
|
|
8
18
|
|
|
9
19
|
## Demo
|
|
10
20
|
|
|
11
|
-
Experience the extended capabilities of `@smakss/react-scroll-direction` on
|
|
21
|
+
Experience the extended capabilities of `@smakss/react-scroll-direction` on
|
|
22
|
+
CodeSandbox:
|
|
12
23
|
|
|
13
24
|
[](https://codesandbox.io/s/react-scroll-direction-tclwvp?fontsize=14&hidenavigation=1&theme=dark)
|
|
14
25
|
|
|
15
26
|
## Installation
|
|
16
27
|
|
|
17
|
-
Install `@smakss/react-scroll-direction` via npm or
|
|
28
|
+
Install `@smakss/react-scroll-direction` via npm, yarn, or pnpm:
|
|
18
29
|
|
|
19
30
|
```bash
|
|
20
31
|
npm install @smakss/react-scroll-direction
|
|
21
32
|
# or
|
|
22
33
|
yarn add @smakss/react-scroll-direction
|
|
34
|
+
# or
|
|
35
|
+
pnpm add @smakss/react-scroll-direction
|
|
23
36
|
```
|
|
24
37
|
|
|
25
38
|
Then, import it into your project:
|
|
@@ -27,40 +40,45 @@ Then, import it into your project:
|
|
|
27
40
|
ES Module:
|
|
28
41
|
|
|
29
42
|
```js
|
|
30
|
-
import useDetectScroll from '@smakss/react-scroll-direction'
|
|
43
|
+
import useDetectScroll from '@smakss/react-scroll-direction'
|
|
31
44
|
```
|
|
32
45
|
|
|
33
46
|
For TypeScript projects, import the hook and its types:
|
|
34
47
|
|
|
35
48
|
```ts
|
|
36
|
-
import useDetectScroll, {
|
|
37
|
-
Axis,
|
|
38
|
-
Direction
|
|
39
|
-
} from '@smakss/react-scroll-direction';
|
|
49
|
+
import useDetectScroll, {Axis, Direction} from '@smakss/react-scroll-direction'
|
|
40
50
|
```
|
|
41
51
|
|
|
42
52
|
## Usage
|
|
43
53
|
|
|
44
|
-
The `useDetectScroll` hook takes an options object with the following
|
|
54
|
+
The `useDetectScroll` hook takes an options object with the following
|
|
55
|
+
properties:
|
|
45
56
|
|
|
46
|
-
- `target`: The target scrollable element from which to detect scroll direction
|
|
47
|
-
|
|
57
|
+
- `target`: The target scrollable element from which to detect scroll direction
|
|
58
|
+
and position (default: `window`, must be an `HTMLDivElement`).
|
|
59
|
+
- `thr`: Threshold for scroll direction change detection (default: `0`, accepts
|
|
60
|
+
only positive values).
|
|
48
61
|
- `axis`: Defines the scroll axis (`"y"` or `"x"`, default: `"y"`).
|
|
49
|
-
- `scrollUp`: Value returned when scrolling up (y-axis) or left (x-axis)
|
|
50
|
-
|
|
51
|
-
- `
|
|
62
|
+
- `scrollUp`: Value returned when scrolling up (y-axis) or left (x-axis)
|
|
63
|
+
(default: `"up"` for y-axis, `"left"` for x-axis).
|
|
64
|
+
- `scrollDown`: Value returned when scrolling down (y-axis) or right (x-axis)
|
|
65
|
+
(default: `"down"` for y-axis, `"right"` for x-axis).
|
|
66
|
+
- `still`: Value returned when there's no scrolling activity (default:
|
|
67
|
+
`"still"`).
|
|
52
68
|
|
|
53
69
|
The hook returns an object with two properties:
|
|
54
70
|
|
|
55
|
-
- `scrollDir`: Indicates the scroll direction (`"up"`, `"down"`, `"left"`,
|
|
56
|
-
|
|
71
|
+
- `scrollDir`: Indicates the scroll direction (`"up"`, `"down"`, `"left"`,
|
|
72
|
+
`"right"`, or `"still"`).
|
|
73
|
+
- `scrollPosition`: An object containing distances from the top, bottom, left,
|
|
74
|
+
and right edges of the viewport.
|
|
57
75
|
|
|
58
76
|
## Examples
|
|
59
77
|
|
|
60
78
|
To detect both scroll direction and position:
|
|
61
79
|
|
|
62
80
|
```js
|
|
63
|
-
const {
|
|
81
|
+
const {scrollDir, scrollPosition} = useDetectScroll()
|
|
64
82
|
|
|
65
83
|
// scrollDir: "up", "down", "left", "right", or "still"
|
|
66
84
|
// scrollPosition: { top, bottom, left, right }
|
|
@@ -69,7 +87,7 @@ const { scrollDir, scrollPosition } = useDetectScroll();
|
|
|
69
87
|
To customize for horizontal scroll:
|
|
70
88
|
|
|
71
89
|
```js
|
|
72
|
-
const {
|
|
90
|
+
const {scrollDir, scrollPosition} = useDetectScroll({axis: Axis.X})
|
|
73
91
|
|
|
74
92
|
// scrollDir: "left", "right", or "still"
|
|
75
93
|
// scrollPosition: { top, bottom, left, right }
|
|
@@ -92,8 +110,11 @@ useEffect(() => {
|
|
|
92
110
|
|
|
93
111
|
## Contributing
|
|
94
112
|
|
|
95
|
-
Interested in making contributions to this project? Please see
|
|
113
|
+
Interested in making contributions to this project? Please see
|
|
114
|
+
[CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines and details.
|
|
96
115
|
|
|
97
116
|
## Code of Conduct
|
|
98
117
|
|
|
99
|
-
We value and prioritize the well-being of all our contributors and users. To
|
|
118
|
+
We value and prioritize the well-being of all our contributors and users. To
|
|
119
|
+
ensure that this project remains a welcoming space for everyone, please refer to
|
|
120
|
+
our [Code of Conduct](./CODE_OF_CONDUCT.md).
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,163 +1,87 @@
|
|
|
1
|
-
import { useState, useRef, useCallback, useEffect } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
*/
|
|
82
|
-
function useDetectScroll(props = {}) {
|
|
83
|
-
const { target = typeof window !== 'undefined' ? window : undefined, thr = 0, axis = Axis.Y, scrollUp = axis === Axis.Y ? Direction.Up : Direction.Left, scrollDown = axis === Axis.Y ? Direction.Down : Direction.Right, still = Direction.Still } = props;
|
|
84
|
-
const [scrollDir, setScrollDir] = useState(still);
|
|
85
|
-
const [scrollPosition, setScrollPosition] = useState({
|
|
86
|
-
top: 0,
|
|
87
|
-
bottom: 0,
|
|
88
|
-
left: 0,
|
|
89
|
-
right: 0
|
|
90
|
-
});
|
|
91
|
-
const threshold = Math.max(0, thr);
|
|
92
|
-
const ticking = useRef(false);
|
|
93
|
-
const lastScroll = useRef(0);
|
|
94
|
-
/** Function to update scroll direction */
|
|
95
|
-
const updateScrollDir = useCallback(() => {
|
|
96
|
-
if (!target)
|
|
97
|
-
return;
|
|
98
|
-
let scroll;
|
|
99
|
-
if (target instanceof Window) {
|
|
100
|
-
scroll = axis === Axis.Y ? target.scrollY : target.scrollX;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
scroll = axis === Axis.Y ? target.scrollTop : target.scrollLeft;
|
|
104
|
-
}
|
|
105
|
-
if (Math.abs(scroll - lastScroll.current) >= threshold) {
|
|
106
|
-
setScrollDir(scroll > lastScroll.current ? scrollDown : scrollUp);
|
|
107
|
-
lastScroll.current = Math.max(0, scroll);
|
|
108
|
-
}
|
|
109
|
-
ticking.current = false;
|
|
110
|
-
}, [target, axis, threshold, scrollDown, scrollUp]);
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
if (!target) {
|
|
113
|
-
console.warn('useDetectScroll: target is not set. Falling back to window.');
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
/** Function to update scroll position */
|
|
117
|
-
const updateScrollPosition = () => {
|
|
118
|
-
if (!target)
|
|
119
|
-
return;
|
|
120
|
-
const top = target instanceof Window ? target.scrollY : target.scrollTop;
|
|
121
|
-
const left = target instanceof Window ? target.scrollX : target.scrollLeft;
|
|
122
|
-
const bottom = (target instanceof Window
|
|
123
|
-
? document.documentElement.scrollHeight - target.innerHeight
|
|
124
|
-
: target.scrollHeight - target.clientHeight) - top;
|
|
125
|
-
const right = (target instanceof Window
|
|
126
|
-
? document.documentElement.scrollWidth - target.innerWidth
|
|
127
|
-
: target.scrollWidth - target.clientWidth) - left;
|
|
128
|
-
setScrollPosition({ top, bottom, left, right });
|
|
129
|
-
};
|
|
130
|
-
updateScrollPosition();
|
|
131
|
-
const targetElement = target;
|
|
132
|
-
targetElement.addEventListener('scroll', updateScrollPosition);
|
|
133
|
-
return () => {
|
|
134
|
-
targetElement.removeEventListener('scroll', updateScrollPosition);
|
|
135
|
-
};
|
|
136
|
-
}, [target]);
|
|
137
|
-
useEffect(() => {
|
|
138
|
-
if (!target) {
|
|
139
|
-
console.warn('useDetectScroll: target is not set. Falling back to window.');
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
if (target instanceof Window) {
|
|
143
|
-
lastScroll.current = axis === Axis.Y ? target.scrollY : target.scrollX;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
lastScroll.current =
|
|
147
|
-
axis === Axis.Y ? target.scrollTop : target.scrollLeft;
|
|
148
|
-
}
|
|
149
|
-
const onScroll = () => {
|
|
150
|
-
if (!ticking.current) {
|
|
151
|
-
window.requestAnimationFrame(updateScrollDir);
|
|
152
|
-
ticking.current = true;
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
const targetElement = target;
|
|
156
|
-
targetElement.addEventListener('scroll', onScroll);
|
|
157
|
-
return () => targetElement.removeEventListener('scroll', onScroll);
|
|
158
|
-
}, [target, axis, updateScrollDir]);
|
|
159
|
-
return { scrollDir, scrollPosition };
|
|
1
|
+
import { useState as h, useRef as m, useCallback as x, useEffect as g } from "react";
|
|
2
|
+
const l = {
|
|
3
|
+
/**
|
|
4
|
+
* Horizontal axis.
|
|
5
|
+
*/
|
|
6
|
+
X: "x",
|
|
7
|
+
/**
|
|
8
|
+
* Vertical axis.
|
|
9
|
+
*/
|
|
10
|
+
Y: "y"
|
|
11
|
+
}, c = {
|
|
12
|
+
/**
|
|
13
|
+
* Scroll direction toward the top.
|
|
14
|
+
*/
|
|
15
|
+
Up: "up",
|
|
16
|
+
/**
|
|
17
|
+
* Scroll direction toward the bottom.
|
|
18
|
+
*/
|
|
19
|
+
Down: "down",
|
|
20
|
+
/**
|
|
21
|
+
* Scroll direction toward the left.
|
|
22
|
+
*/
|
|
23
|
+
Left: "left",
|
|
24
|
+
/**
|
|
25
|
+
* Scroll direction toward the right.
|
|
26
|
+
*/
|
|
27
|
+
Right: "right",
|
|
28
|
+
/**
|
|
29
|
+
* No scrolling detected.
|
|
30
|
+
*/
|
|
31
|
+
Still: "still"
|
|
32
|
+
};
|
|
33
|
+
function H(p = {}) {
|
|
34
|
+
const {
|
|
35
|
+
target: t = typeof window < "u" ? window : void 0,
|
|
36
|
+
thr: S = 0,
|
|
37
|
+
axis: o = l.Y,
|
|
38
|
+
scrollUp: i = o === l.Y ? c.Up : c.Left,
|
|
39
|
+
scrollDown: a = o === l.Y ? c.Down : c.Right,
|
|
40
|
+
still: Y = c.Still
|
|
41
|
+
} = p, [D, W] = h(Y), [E, L] = h({
|
|
42
|
+
top: 0,
|
|
43
|
+
bottom: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
right: 0
|
|
46
|
+
}), u = Math.max(0, S), s = m(!1), n = m(0), f = x(() => {
|
|
47
|
+
if (!t) return;
|
|
48
|
+
let e;
|
|
49
|
+
t instanceof Window ? e = o === l.Y ? t.scrollY : t.scrollX : e = o === l.Y ? t.scrollTop : t.scrollLeft, Math.abs(e - n.current) >= u && (W(e > n.current ? a : i), n.current = Math.max(0, e)), s.current = !1;
|
|
50
|
+
}, [t, o, u, a, i]);
|
|
51
|
+
return g(() => {
|
|
52
|
+
if (!t) {
|
|
53
|
+
console.warn(
|
|
54
|
+
"useDetectScroll: target is not set. Falling back to window."
|
|
55
|
+
);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const e = () => {
|
|
59
|
+
if (!t) return;
|
|
60
|
+
const d = t instanceof Window ? t.scrollY : t.scrollTop, w = t instanceof Window ? t.scrollX : t.scrollLeft, v = (t instanceof Window ? document.documentElement.scrollHeight - t.innerHeight : t.scrollHeight - t.clientHeight) - d, b = (t instanceof Window ? document.documentElement.scrollWidth - t.innerWidth : t.scrollWidth - t.clientWidth) - w;
|
|
61
|
+
L({ top: d, bottom: v, left: w, right: b });
|
|
62
|
+
};
|
|
63
|
+
e();
|
|
64
|
+
const r = t;
|
|
65
|
+
return r.addEventListener("scroll", e), () => {
|
|
66
|
+
r.removeEventListener("scroll", e);
|
|
67
|
+
};
|
|
68
|
+
}, [t]), g(() => {
|
|
69
|
+
if (!t) {
|
|
70
|
+
console.warn(
|
|
71
|
+
"useDetectScroll: target is not set. Falling back to window."
|
|
72
|
+
);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
t instanceof Window ? n.current = o === l.Y ? t.scrollY : t.scrollX : n.current = o === l.Y ? t.scrollTop : t.scrollLeft;
|
|
76
|
+
const e = () => {
|
|
77
|
+
s.current || (window.requestAnimationFrame(f), s.current = !0);
|
|
78
|
+
}, r = t;
|
|
79
|
+
return r.addEventListener("scroll", e), () => r.removeEventListener("scroll", e);
|
|
80
|
+
}, [t, o, f]), { scrollDir: D, scrollPosition: E };
|
|
160
81
|
}
|
|
161
|
-
|
|
162
|
-
|
|
82
|
+
export {
|
|
83
|
+
l as Axis,
|
|
84
|
+
c as Direction,
|
|
85
|
+
H as default
|
|
86
|
+
};
|
|
163
87
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/useDetectScroll.ts"],"sourcesContent":["// Enumeration for axis values\nexport enum Axis {\n /**\n * The x-axis represents the horizontal direction.\n */\n X = 'x',\n /**\n * The y-axis represents the vertical direction.\n */\n Y = 'y'\n}\n\n// Enumeration for direction values\nexport enum Direction {\n /**\n * The up direction represents the scroll direction moving towards the top.\n */\n Up = 'up',\n /**\n * The down direction represents the scroll direction moving towards the bottom.\n */\n Down = 'down',\n /**\n * The left direction represents the scroll direction moving towards the left.\n */\n Left = 'left',\n /**\n * The right direction represents the scroll direction moving towards the right.\n */\n Right = 'right',\n /**\n * The still direction represents the scroll direction when the user is not scrolling.\n */\n Still = 'still'\n}\n\n// Type declaration for scroll position\nexport type ScrollPosition = {\n /**\n * The top position represents the distance from the top edge of the page.\n */\n top: number;\n /**\n * The bottom position represents the distance from the bottom edge of the page.\n */\n bottom: number;\n /**\n * The left position represents the distance from the left edge of the page.\n */\n left: number;\n /**\n * The right position represents the distance from the right edge of the page.\n */\n right: number;\n};\n\n// Type declaration for the returned scroll information\nexport type ScrollInfo = {\n /**\n * The scrollDir represents the current scroll direction.\n */\n scrollDir: Direction;\n /**\n * The scrollPosition represents the current scroll position.\n */\n scrollPosition: ScrollPosition;\n};\n\n// Type declaration for scroll properties\nexport type ScrollProps = {\n /**\n * The target represents the scrollable element to check for scroll detection.\n */\n target?: HTMLDivElement | Window;\n /**\n * The thr represents the threshold value for scroll detection.\n */\n thr?: number;\n /**\n * The axis represents the scroll axis (x or y).\n */\n axis?: Axis;\n /**\n * The scrollUp represents the scroll direction when moving up.\n */\n scrollUp?: Direction;\n /**\n * The scrollDown represents the scroll direction when moving down.\n */\n scrollDown?: Direction;\n /**\n * The still represents the scroll direction when the user is not scrolling.\n */\n still?: Direction;\n};\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport {\n Axis,\n Direction,\n ScrollInfo,\n ScrollPosition,\n ScrollProps\n} from './types';\n\n/**\n * useDetectScroll hook.\n *\n * This hook provides a mechanism to detect the scroll direction and position.\n * It will return the scroll direction as a string (up, down, left, right, or still) based on user scrolling,\n * as well as the scroll position from the top, bottom, left, and right edges of the page.\n *\n * @example\n *\n * import useDetectScroll, { Axis, Direction } from '@smakss/react-scroll-direction';\n *\n * function App() {\n * const customElementRef = useRef<HTMLDivElement>(null);\n * const [customElement, setCustomElement] = useState<HTMLDivElement>();\n *\n * const { scrollDir, scrollPosition } = useDetectScroll({\n * target: customElement,\n * thr: 100,\n * axis: Axis.Y,\n * scrollUp: Direction.Up,\n * scrollDown: Direction.Down,\n * still: Direction.Still\n * });\n *\n * useEffect(() => {\n * if (customElementRef.current) {\n * setCustomElement(customElementRef.current);\n * }\n * }, [customElementRef]);\n *\n * return (\n * <div>\n * <p>Current scroll direction: {scrollDir}</p>\n * <p>Scroll position - Top: {scrollPosition.top}, Bottom: {scrollPosition.bottom},\n * Left: {scrollPosition.left}, Right: {scrollPosition.right}</p>\n * </div>\n * );\n * }\n *\n * @param {ScrollProps} props - The properties related to scrolling.\n * @returns {ScrollInfo} - The current direction and position of scrolling.\n */\nfunction useDetectScroll(props: ScrollProps = {}): ScrollInfo {\n const {\n target = typeof window !== 'undefined' ? window : undefined,\n thr = 0,\n axis = Axis.Y,\n scrollUp = axis === Axis.Y ? Direction.Up : Direction.Left,\n scrollDown = axis === Axis.Y ? Direction.Down : Direction.Right,\n still = Direction.Still\n } = props;\n\n const [scrollDir, setScrollDir] = useState<Direction>(still);\n const [scrollPosition, setScrollPosition] = useState<ScrollPosition>({\n top: 0,\n bottom: 0,\n left: 0,\n right: 0\n });\n\n const threshold = Math.max(0, thr);\n const ticking = useRef(false);\n const lastScroll = useRef(0);\n\n /** Function to update scroll direction */\n const updateScrollDir = useCallback(() => {\n if (!target) return;\n\n let scroll: number;\n if (target instanceof Window) {\n scroll = axis === Axis.Y ? target.scrollY : target.scrollX;\n } else {\n scroll = axis === Axis.Y ? target.scrollTop : target.scrollLeft;\n }\n\n if (Math.abs(scroll - lastScroll.current) >= threshold) {\n setScrollDir(scroll > lastScroll.current ? scrollDown : scrollUp);\n lastScroll.current = Math.max(0, scroll);\n }\n ticking.current = false;\n }, [target, axis, threshold, scrollDown, scrollUp]);\n\n useEffect(() => {\n if (!target) {\n console.warn(\n 'useDetectScroll: target is not set. Falling back to window.'\n );\n return;\n }\n\n /** Function to update scroll position */\n const updateScrollPosition = () => {\n if (!target) return;\n\n const top = target instanceof Window ? target.scrollY : target.scrollTop;\n const left =\n target instanceof Window ? target.scrollX : target.scrollLeft;\n\n const bottom =\n (target instanceof Window\n ? document.documentElement.scrollHeight - target.innerHeight\n : target.scrollHeight - target.clientHeight) - top;\n const right =\n (target instanceof Window\n ? document.documentElement.scrollWidth - target.innerWidth\n : target.scrollWidth - target.clientWidth) - left;\n\n setScrollPosition({ top, bottom, left, right });\n };\n\n updateScrollPosition();\n\n const targetElement = target as EventTarget;\n targetElement.addEventListener('scroll', updateScrollPosition);\n\n return () => {\n targetElement.removeEventListener('scroll', updateScrollPosition);\n };\n }, [target]);\n\n useEffect(() => {\n if (!target) {\n console.warn(\n 'useDetectScroll: target is not set. Falling back to window.'\n );\n return;\n }\n\n if (target instanceof Window) {\n lastScroll.current = axis === Axis.Y ? target.scrollY : target.scrollX;\n } else {\n lastScroll.current =\n axis === Axis.Y ? target.scrollTop : target.scrollLeft;\n }\n\n const onScroll = () => {\n if (!ticking.current) {\n window.requestAnimationFrame(updateScrollDir);\n ticking.current = true;\n }\n };\n\n const targetElement = target as EventTarget;\n targetElement.addEventListener('scroll', onScroll);\n\n return () => targetElement.removeEventListener('scroll', onScroll);\n }, [target, axis, updateScrollDir]);\n\n return { scrollDir, scrollPosition };\n}\n\nexport default useDetectScroll;\n"],"names":[],"mappings":";;AAAA;IACY,KASX;AATD,CAAA,UAAY,IAAI,EAAA;AACd;;AAEG;AACH,IAAA,IAAA,CAAA,GAAA,CAAA,GAAA,GAAO,CAAA;AACP;;AAEG;AACH,IAAA,IAAA,CAAA,GAAA,CAAA,GAAA,GAAO,CAAA;AACT,CAAC,EATW,IAAI,KAAJ,IAAI,GASf,EAAA,CAAA,CAAA,CAAA;AAED;IACY,UAqBX;AArBD,CAAA,UAAY,SAAS,EAAA;AACnB;;AAEG;AACH,IAAA,SAAA,CAAA,IAAA,CAAA,GAAA,IAAS,CAAA;AACT;;AAEG;AACH,IAAA,SAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb;;AAEG;AACH,IAAA,SAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb;;AAEG;AACH,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf;;AAEG;AACH,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EArBW,SAAS,KAAT,SAAS,GAqBpB,EAAA,CAAA,CAAA;;ACzBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCG;AACH,SAAS,eAAe,CAAC,KAAA,GAAqB,EAAE,EAAA;AAC9C,IAAA,MAAM,EACJ,MAAM,GAAG,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,GAAG,SAAS,EAC3D,GAAG,GAAG,CAAC,EACP,IAAI,GAAG,IAAI,CAAC,CAAC,EACb,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,EAC1D,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,EAC/D,KAAK,GAAG,SAAS,CAAC,KAAK,EACxB,GAAG,KAAK,CAAC;IAEV,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,KAAK,CAAC,CAAC;AAC7D,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAiB;AACnE,QAAA,GAAG,EAAE,CAAC;AACN,QAAA,MAAM,EAAE,CAAC;AACT,QAAA,IAAI,EAAE,CAAC;AACP,QAAA,KAAK,EAAE,CAAC;AACT,KAAA,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9B,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;AAG7B,IAAA,MAAM,eAAe,GAAG,WAAW,CAAC,MAAK;AACvC,QAAA,IAAI,CAAC,MAAM;YAAE,OAAO;AAEpB,QAAA,IAAI,MAAc,CAAC;AACnB,QAAA,IAAI,MAAM,YAAY,MAAM,EAAE;AAC5B,YAAA,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;SAC5D;aAAM;AACL,YAAA,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;SACjE;AAED,QAAA,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE;AACtD,YAAA,YAAY,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC;YAClE,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;SAC1C;AACD,QAAA,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;AAC1B,KAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEpD,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,CAAC,IAAI,CACV,6DAA6D,CAC9D,CAAC;YACF,OAAO;SACR;;QAGD,MAAM,oBAAoB,GAAG,MAAK;AAChC,YAAA,IAAI,CAAC,MAAM;gBAAE,OAAO;AAEpB,YAAA,MAAM,GAAG,GAAG,MAAM,YAAY,MAAM,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;AACzE,YAAA,MAAM,IAAI,GACR,MAAM,YAAY,MAAM,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhE,YAAA,MAAM,MAAM,GACV,CAAC,MAAM,YAAY,MAAM;kBACrB,QAAQ,CAAC,eAAe,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW;kBAC1D,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC;AACvD,YAAA,MAAM,KAAK,GACT,CAAC,MAAM,YAAY,MAAM;kBACrB,QAAQ,CAAC,eAAe,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU;kBACxD,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;YAEtD,iBAAiB,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAClD,SAAC,CAAC;AAEF,QAAA,oBAAoB,EAAE,CAAC;QAEvB,MAAM,aAAa,GAAG,MAAqB,CAAC;AAC5C,QAAA,aAAa,CAAC,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;AAE/D,QAAA,OAAO,MAAK;AACV,YAAA,aAAa,CAAC,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;AACpE,SAAC,CAAC;AACJ,KAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,CAAC,IAAI,CACV,6DAA6D,CAC9D,CAAC;YACF,OAAO;SACR;AAED,QAAA,IAAI,MAAM,YAAY,MAAM,EAAE;YAC5B,UAAU,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;SACxE;aAAM;AACL,YAAA,UAAU,CAAC,OAAO;AAChB,gBAAA,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;SAC1D;QAED,MAAM,QAAQ,GAAG,MAAK;AACpB,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;AACpB,gBAAA,MAAM,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;AAC9C,gBAAA,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;aACxB;AACH,SAAC,CAAC;QAEF,MAAM,aAAa,GAAG,MAAqB,CAAC;AAC5C,QAAA,aAAa,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEnD,OAAO,MAAM,aAAa,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;KACpE,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;AAEpC,IAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACvC;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/useDetectScroll.ts"],"sourcesContent":["/**\n * Axis values (const + type)\n */\nexport const Axis = {\n /**\n * Horizontal axis.\n */\n X: 'x',\n /**\n * Vertical axis.\n */\n Y: 'y',\n} as const\n\n/**\n * Union of allowed axis values.\n */\nexport type Axis = (typeof Axis)[keyof typeof Axis]\n\n/**\n * Direction values (const + type)\n */\nexport const Direction = {\n /**\n * Scroll direction toward the top.\n */\n Up: 'up',\n /**\n * Scroll direction toward the bottom.\n */\n Down: 'down',\n /**\n * Scroll direction toward the left.\n */\n Left: 'left',\n /**\n * Scroll direction toward the right.\n */\n Right: 'right',\n /**\n * No scrolling detected.\n */\n Still: 'still',\n} as const\n\n/**\n * Union of allowed direction values.\n */\nexport type Direction = (typeof Direction)[keyof typeof Direction]\n\n/**\n * Scroll position values\n */\nexport type ScrollPosition = {\n /**\n * Distance from the top edge.\n */\n top: number\n /**\n * Distance from the bottom edge.\n */\n bottom: number\n /**\n * Distance from the left edge.\n */\n left: number\n /**\n * Distance from the right edge.\n */\n right: number\n}\n\n/**\n * Scroll info returned by the hook\n */\nexport type ScrollInfo = {\n /**\n * Current scroll direction.\n */\n scrollDir: Direction\n /**\n * Current scroll position.\n */\n scrollPosition: ScrollPosition\n}\n\n/**\n * Options accepted by the hook\n */\nexport type ScrollProps = {\n /**\n * Scroll target element (defaults to window).\n */\n target?: HTMLDivElement | Window\n /**\n * Threshold for scroll direction changes.\n */\n thr?: number\n /**\n * Axis to observe.\n */\n axis?: Axis\n /**\n * Value returned when scrolling up (y) or left (x).\n */\n scrollUp?: Direction\n /**\n * Value returned when scrolling down (y) or right (x).\n */\n scrollDown?: Direction\n /**\n * Value returned when no scrolling is detected.\n */\n still?: Direction\n}\n","import {useCallback, useEffect, useRef, useState} from 'react'\nimport {Axis, Direction, ScrollInfo, ScrollPosition, ScrollProps} from './types'\n\n/**\n * useDetectScroll hook.\n *\n * This hook provides a mechanism to detect the scroll direction and position.\n * It will return the scroll direction as a string (up, down, left, right, or still) based on user scrolling,\n * as well as the scroll position from the top, bottom, left, and right edges of the page.\n *\n * @example\n *\n * import useDetectScroll, { Axis, Direction } from '@smakss/react-scroll-direction';\n *\n * function App() {\n * const customElementRef = useRef<HTMLDivElement>(null);\n * const [customElement, setCustomElement] = useState<HTMLDivElement>();\n *\n * const { scrollDir, scrollPosition } = useDetectScroll({\n * target: customElement,\n * thr: 100,\n * axis: Axis.Y,\n * scrollUp: Direction.Up,\n * scrollDown: Direction.Down,\n * still: Direction.Still\n * });\n *\n * useEffect(() => {\n * if (customElementRef.current) {\n * setCustomElement(customElementRef.current);\n * }\n * }, [customElementRef]);\n *\n * return (\n * <div>\n * <p>Current scroll direction: {scrollDir}</p>\n * <p>Scroll position - Top: {scrollPosition.top}, Bottom: {scrollPosition.bottom},\n * Left: {scrollPosition.left}, Right: {scrollPosition.right}</p>\n * </div>\n * );\n * }\n *\n * @param {ScrollProps} props - The properties related to scrolling.\n * @returns {ScrollInfo} - The current direction and position of scrolling.\n */\nfunction useDetectScroll(props: ScrollProps = {}): ScrollInfo {\n const {\n target = typeof window !== 'undefined' ? window : undefined,\n thr = 0,\n axis = Axis.Y,\n scrollUp = axis === Axis.Y ? Direction.Up : Direction.Left,\n scrollDown = axis === Axis.Y ? Direction.Down : Direction.Right,\n still = Direction.Still,\n } = props\n\n const [scrollDir, setScrollDir] = useState<Direction>(still)\n const [scrollPosition, setScrollPosition] = useState<ScrollPosition>({\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n })\n\n const threshold = Math.max(0, thr)\n const ticking = useRef(false)\n const lastScroll = useRef(0)\n\n /** Function to update scroll direction */\n const updateScrollDir = useCallback(() => {\n if (!target) return\n\n let scroll: number\n if (target instanceof Window) {\n scroll = axis === Axis.Y ? target.scrollY : target.scrollX\n } else {\n scroll = axis === Axis.Y ? target.scrollTop : target.scrollLeft\n }\n\n if (Math.abs(scroll - lastScroll.current) >= threshold) {\n setScrollDir(scroll > lastScroll.current ? scrollDown : scrollUp)\n lastScroll.current = Math.max(0, scroll)\n }\n ticking.current = false\n }, [target, axis, threshold, scrollDown, scrollUp])\n\n useEffect(() => {\n if (!target) {\n console.warn(\n 'useDetectScroll: target is not set. Falling back to window.',\n )\n return\n }\n\n /** Function to update scroll position */\n const updateScrollPosition = () => {\n if (!target) return\n\n const top =\n target instanceof Window ? target.scrollY : target.scrollTop\n const left =\n target instanceof Window ? target.scrollX : target.scrollLeft\n\n const bottom =\n (target instanceof Window\n ? document.documentElement.scrollHeight - target.innerHeight\n : target.scrollHeight - target.clientHeight) - top\n const right =\n (target instanceof Window\n ? document.documentElement.scrollWidth - target.innerWidth\n : target.scrollWidth - target.clientWidth) - left\n\n setScrollPosition({top, bottom, left, right})\n }\n\n updateScrollPosition()\n\n const targetElement = target as EventTarget\n targetElement.addEventListener('scroll', updateScrollPosition)\n\n return () => {\n targetElement.removeEventListener('scroll', updateScrollPosition)\n }\n }, [target])\n\n useEffect(() => {\n if (!target) {\n console.warn(\n 'useDetectScroll: target is not set. Falling back to window.',\n )\n return\n }\n\n if (target instanceof Window) {\n lastScroll.current =\n axis === Axis.Y ? target.scrollY : target.scrollX\n } else {\n lastScroll.current =\n axis === Axis.Y ? target.scrollTop : target.scrollLeft\n }\n\n const onScroll = () => {\n if (!ticking.current) {\n window.requestAnimationFrame(updateScrollDir)\n ticking.current = true\n }\n }\n\n const targetElement = target as EventTarget\n targetElement.addEventListener('scroll', onScroll)\n\n return () => targetElement.removeEventListener('scroll', onScroll)\n }, [target, axis, updateScrollDir])\n\n return {scrollDir, scrollPosition}\n}\n\nexport default useDetectScroll\n"],"names":["Axis","Direction","useDetectScroll","props","target","thr","axis","scrollUp","scrollDown","still","scrollDir","setScrollDir","useState","scrollPosition","setScrollPosition","threshold","ticking","useRef","lastScroll","updateScrollDir","useCallback","scroll","useEffect","updateScrollPosition","top","left","bottom","right","targetElement","onScroll"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,86 +1,109 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Axis values (const + type)
|
|
3
|
+
*/
|
|
4
|
+
export declare const Axis: {
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
6
|
+
* Horizontal axis.
|
|
4
7
|
*/
|
|
5
|
-
X
|
|
8
|
+
readonly X: "x";
|
|
6
9
|
/**
|
|
7
|
-
*
|
|
10
|
+
* Vertical axis.
|
|
8
11
|
*/
|
|
9
|
-
Y
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
+
readonly Y: "y";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Union of allowed axis values.
|
|
16
|
+
*/
|
|
17
|
+
export type Axis = (typeof Axis)[keyof typeof Axis];
|
|
18
|
+
/**
|
|
19
|
+
* Direction values (const + type)
|
|
20
|
+
*/
|
|
21
|
+
export declare const Direction: {
|
|
12
22
|
/**
|
|
13
|
-
*
|
|
23
|
+
* Scroll direction toward the top.
|
|
14
24
|
*/
|
|
15
|
-
Up
|
|
25
|
+
readonly Up: "up";
|
|
16
26
|
/**
|
|
17
|
-
*
|
|
27
|
+
* Scroll direction toward the bottom.
|
|
18
28
|
*/
|
|
19
|
-
Down
|
|
29
|
+
readonly Down: "down";
|
|
20
30
|
/**
|
|
21
|
-
*
|
|
31
|
+
* Scroll direction toward the left.
|
|
22
32
|
*/
|
|
23
|
-
Left
|
|
33
|
+
readonly Left: "left";
|
|
24
34
|
/**
|
|
25
|
-
*
|
|
35
|
+
* Scroll direction toward the right.
|
|
26
36
|
*/
|
|
27
|
-
Right
|
|
37
|
+
readonly Right: "right";
|
|
28
38
|
/**
|
|
29
|
-
*
|
|
39
|
+
* No scrolling detected.
|
|
30
40
|
*/
|
|
31
|
-
Still
|
|
32
|
-
}
|
|
41
|
+
readonly Still: "still";
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Union of allowed direction values.
|
|
45
|
+
*/
|
|
46
|
+
export type Direction = (typeof Direction)[keyof typeof Direction];
|
|
47
|
+
/**
|
|
48
|
+
* Scroll position values
|
|
49
|
+
*/
|
|
33
50
|
export type ScrollPosition = {
|
|
34
51
|
/**
|
|
35
|
-
*
|
|
52
|
+
* Distance from the top edge.
|
|
36
53
|
*/
|
|
37
54
|
top: number;
|
|
38
55
|
/**
|
|
39
|
-
*
|
|
56
|
+
* Distance from the bottom edge.
|
|
40
57
|
*/
|
|
41
58
|
bottom: number;
|
|
42
59
|
/**
|
|
43
|
-
*
|
|
60
|
+
* Distance from the left edge.
|
|
44
61
|
*/
|
|
45
62
|
left: number;
|
|
46
63
|
/**
|
|
47
|
-
*
|
|
64
|
+
* Distance from the right edge.
|
|
48
65
|
*/
|
|
49
66
|
right: number;
|
|
50
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Scroll info returned by the hook
|
|
70
|
+
*/
|
|
51
71
|
export type ScrollInfo = {
|
|
52
72
|
/**
|
|
53
|
-
*
|
|
73
|
+
* Current scroll direction.
|
|
54
74
|
*/
|
|
55
75
|
scrollDir: Direction;
|
|
56
76
|
/**
|
|
57
|
-
*
|
|
77
|
+
* Current scroll position.
|
|
58
78
|
*/
|
|
59
79
|
scrollPosition: ScrollPosition;
|
|
60
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Options accepted by the hook
|
|
83
|
+
*/
|
|
61
84
|
export type ScrollProps = {
|
|
62
85
|
/**
|
|
63
|
-
*
|
|
86
|
+
* Scroll target element (defaults to window).
|
|
64
87
|
*/
|
|
65
88
|
target?: HTMLDivElement | Window;
|
|
66
89
|
/**
|
|
67
|
-
*
|
|
90
|
+
* Threshold for scroll direction changes.
|
|
68
91
|
*/
|
|
69
92
|
thr?: number;
|
|
70
93
|
/**
|
|
71
|
-
*
|
|
94
|
+
* Axis to observe.
|
|
72
95
|
*/
|
|
73
96
|
axis?: Axis;
|
|
74
97
|
/**
|
|
75
|
-
*
|
|
98
|
+
* Value returned when scrolling up (y) or left (x).
|
|
76
99
|
*/
|
|
77
100
|
scrollUp?: Direction;
|
|
78
101
|
/**
|
|
79
|
-
*
|
|
102
|
+
* Value returned when scrolling down (y) or right (x).
|
|
80
103
|
*/
|
|
81
104
|
scrollDown?: Direction;
|
|
82
105
|
/**
|
|
83
|
-
*
|
|
106
|
+
* Value returned when no scrolling is detected.
|
|
84
107
|
*/
|
|
85
108
|
still?: Direction;
|
|
86
109
|
};
|
package/package.json
CHANGED
|
@@ -5,28 +5,38 @@
|
|
|
5
5
|
},
|
|
6
6
|
"description": "Enhance your React apps with advanced scroll detection using @smakss/react-scroll-direction. This powerful hook not only detects scroll direction but also provides scroll position information. Ideal for React, Remix, Next.js, and Gatsby projects, it comes with adjustable sensitivity and supports ES Modules.",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@commitlint/cli": "^
|
|
9
|
-
"@commitlint/config-conventional": "^
|
|
10
|
-
"@
|
|
11
|
-
"@
|
|
12
|
-
"@
|
|
13
|
-
"@
|
|
14
|
-
"@
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"eslint-plugin
|
|
18
|
-
"eslint
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"prettier": "^
|
|
22
|
-
"
|
|
23
|
-
"
|
|
8
|
+
"@commitlint/cli": "^20.4.0",
|
|
9
|
+
"@commitlint/config-conventional": "^20.4.0",
|
|
10
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
11
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
12
|
+
"@semantic-release/git": "^10.0.1",
|
|
13
|
+
"@semantic-release/github": "^12.0.3",
|
|
14
|
+
"@semantic-release/npm": "^13.1.3",
|
|
15
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
16
|
+
"@types/react": "^19.2.10",
|
|
17
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
18
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
19
|
+
"eslint": "^9.39.2",
|
|
20
|
+
"eslint-config-prettier": "^10.1.8",
|
|
21
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
22
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
23
|
+
"husky": "^9.1.7",
|
|
24
|
+
"lint-staged": "^16.2.7",
|
|
25
|
+
"prettier": "^3.8.1",
|
|
26
|
+
"prettier-plugin-organize-imports": "^4.3.0",
|
|
27
|
+
"semantic-release": "^25.0.3",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"vite": "^6.4.1",
|
|
30
|
+
"vite-plugin-dts": "^4.5.4"
|
|
24
31
|
},
|
|
25
32
|
"engines": {
|
|
26
|
-
"node": ">=
|
|
33
|
+
"node": ">=22.14.0"
|
|
27
34
|
},
|
|
28
35
|
"exports": {
|
|
29
|
-
".":
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
}
|
|
30
40
|
},
|
|
31
41
|
"files": [
|
|
32
42
|
"dist"
|
|
@@ -43,7 +53,7 @@
|
|
|
43
53
|
"direction-and-position-detection",
|
|
44
54
|
"scroll-hook",
|
|
45
55
|
"npm",
|
|
46
|
-
"
|
|
56
|
+
"pnpm",
|
|
47
57
|
"react",
|
|
48
58
|
"remix",
|
|
49
59
|
"nextjs",
|
|
@@ -59,7 +69,7 @@
|
|
|
59
69
|
"react scroll direction and position"
|
|
60
70
|
],
|
|
61
71
|
"license": "MIT",
|
|
62
|
-
"main": "dist/
|
|
72
|
+
"main": "dist/index.js",
|
|
63
73
|
"name": "@smakss/react-scroll-direction",
|
|
64
74
|
"peerDependencies": {
|
|
65
75
|
"react": ">=16.8.0"
|
|
@@ -71,14 +81,23 @@
|
|
|
71
81
|
"scripts": {
|
|
72
82
|
"format": "prettier --write \"**/*.+(js|jsx|json|yml|yaml|css|ts|tsx|md|gql|graphql|mdx)\"",
|
|
73
83
|
"format:check": "prettier -l \"**/*.+(js|jsx|json|yml|yaml|css|ts|tsx|md|gql|graphql|mdx)\"",
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
84
|
+
"build": "rm -rf dist && vite build",
|
|
85
|
+
"build:playground": "pnpm -C playground build",
|
|
86
|
+
"generate": "rm -rf dist && vite build",
|
|
87
|
+
"lint:main": "eslint --cache --cache-location ./node_modules/.cache/.eslintcache --max-warnings=0 \"src/**/*.{js,jsx,ts,tsx}\" eslint.config.js vite.config.ts --no-warn-ignored",
|
|
88
|
+
"lint:playground": "pnpm -C playground lint",
|
|
89
|
+
"lint": "pnpm lint:main && pnpm lint:playground",
|
|
90
|
+
"lint:fix:main": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\" eslint.config.js vite.config.ts --no-warn-ignored",
|
|
91
|
+
"lint:fix:playground": "pnpm -C playground eslint --fix . --no-warn-ignored",
|
|
92
|
+
"prepare": "if [ \"$NODE_ENV\" != \"production\" ]; then husky; fi",
|
|
93
|
+
"setup": "pnpm install && husky",
|
|
94
|
+
"release": "semantic-release",
|
|
95
|
+
"typecheck:main": "tsc -b .",
|
|
96
|
+
"typecheck:playground": "pnpm build && pnpm -C playground exec tsc -p tsconfig.json",
|
|
97
|
+
"typecheck": "pnpm typecheck:main && pnpm typecheck:playground",
|
|
98
|
+
"update:deps": "rm -rf node_modules pnpm-lock.yaml && npx npm-check-updates -u && pnpm install"
|
|
80
99
|
},
|
|
81
100
|
"type": "module",
|
|
82
101
|
"types": "./dist/index.d.ts",
|
|
83
|
-
"version": "4.
|
|
102
|
+
"version": "4.3.0-develop.2"
|
|
84
103
|
}
|