Skip to content

Commit a08c78e

Browse files
committed
fix(target): flaws on SSR and bottom, right position
Also, extract types from `index.ts` to `types.ts`
1 parent 2d044a0 commit a08c78e

File tree

5 files changed

+150
-129
lines changed

5 files changed

+150
-129
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@
3030
"react-hooks/rules-of-hooks": "error",
3131
"react-hooks/exhaustive-deps": "warn",
3232
"object-shorthand": "error",
33-
"no-console": "warn"
33+
"no-console": ["warn", { "allow": ["warn", "error", "info"] }]
3434
}
3535
}

Readme.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ To use a custom scrollable element as a target rather than the default window:
8080
```js
8181
const customElementRef = useRef<HTMLDivElement>(null);
8282
const [customElement, setCustomElement] = useState<HTMLDivElement>();
83-
useEffect(() => {
84-
if(customElementRef.current) {
85-
setHomepageElement(customElementRef.current);
86-
}
87-
}, [customElementRef])
88-
const scrollDir = useDetectScroll({target: customElement});
89-
console.log(scrollDir);
83+
84+
const scrollDir = useDetectScroll({target: customElement});
85+
86+
useEffect(() => {
87+
if(customElementRef.current) {
88+
setHomepageElement(customElementRef.current);
89+
}
90+
}, [customElementRef])
9091
```
9192

9293
## Contributing

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,5 @@
8080
},
8181
"type": "module",
8282
"types": "./dist/index.d.ts",
83-
"version": "4.2.0"
83+
"version": "4.2.0-beta.0"
8484
}

src/index.ts

Lines changed: 46 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,11 @@
11
import { useState, useEffect, useCallback, useRef } from 'react';
2-
3-
/** Enumeration for axis values */
4-
export enum Axis {
5-
/**
6-
* The x-axis represents the horizontal direction.
7-
*/
8-
X = 'x',
9-
/**
10-
* The y-axis represents the vertical direction.
11-
*/
12-
Y = 'y'
13-
}
14-
15-
/** Enumeration for direction values */
16-
export enum Direction {
17-
/**
18-
* The up direction represents the scroll direction moving towards the top.
19-
*/
20-
Up = 'up',
21-
/**
22-
* The down direction represents the scroll direction moving towards the bottom.
23-
*/
24-
Down = 'down',
25-
/**
26-
* The left direction represents the scroll direction moving towards the left.
27-
*/
28-
Left = 'left',
29-
/**
30-
* The right direction represents the scroll direction moving towards the right.
31-
*/
32-
Right = 'right',
33-
/**
34-
* The still direction represents the scroll direction when the user is not scrolling.
35-
*/
36-
Still = 'still'
37-
}
38-
39-
type ScrollPosition = {
40-
/**
41-
* The top position represents the distance from the top edge of the page.
42-
*/
43-
top: number;
44-
/**
45-
* The bottom position represents the distance from the bottom edge of the page.
46-
*/
47-
bottom: number;
48-
/**
49-
* The left position represents the distance from the left edge of the page.
50-
*/
51-
left: number;
52-
/**
53-
* The right position represents the distance from the right edge of the page.
54-
*/
55-
right: number;
56-
};
57-
58-
/** Type declaration for the returned scroll information */
59-
type ScrollInfo = {
60-
/**
61-
* The scrollDir represents the current scroll direction.
62-
*/
63-
scrollDir: Direction;
64-
/**
65-
* The scrollPosition represents the current scroll position.
66-
*/
67-
scrollPosition: ScrollPosition;
68-
};
69-
70-
/** Type declaration for scroll properties */
71-
type ScrollProps = {
72-
/**
73-
* The target represents the scrollable element to check for scroll detection.
74-
*/
75-
target?: HTMLDivElement | Window;
76-
/**
77-
* The thr represents the threshold value for scroll detection.
78-
*/
79-
thr?: number;
80-
/**
81-
* The axis represents the scroll axis (x or y).
82-
*/
83-
axis?: Axis;
84-
/**
85-
* The scrollUp represents the scroll direction when moving up.
86-
*/
87-
scrollUp?: Direction;
88-
/**
89-
* The scrollDown represents the scroll direction when moving down.
90-
*/
91-
scrollDown?: Direction;
92-
/**
93-
* The still represents the scroll direction when the user is not scrolling.
94-
*/
95-
still?: Direction;
96-
};
2+
import {
3+
Axis,
4+
Direction,
5+
ScrollInfo,
6+
ScrollPosition,
7+
ScrollProps
8+
} from './types';
979

9810
/**
9911
* useDetectScroll hook.
@@ -107,14 +19,24 @@ type ScrollProps = {
10719
* import useDetectScroll, { Axis, Direction } from '@smakss/react-scroll-direction';
10820
*
10921
* function App() {
22+
* const customElementRef = useRef<HTMLDivElement>(null);
23+
* const [customElement, setCustomElement] = useState<HTMLDivElement>();
24+
*
11025
* const { scrollDir, scrollPosition } = useDetectScroll({
26+
* target: customElement,
11127
* thr: 100,
11228
* axis: Axis.Y,
11329
* scrollUp: Direction.Up,
11430
* scrollDown: Direction.Down,
11531
* still: Direction.Still
11632
* });
11733
*
34+
* useEffect(() => {
35+
* if (customElementRef.current) {
36+
* setCustomElement(customElementRef.current);
37+
* }
38+
* }, [customElementRef]);
39+
*
11840
* return (
11941
* <div>
12042
* <p>Current scroll direction: {scrollDir}</p>
@@ -129,7 +51,7 @@ type ScrollProps = {
12951
*/
13052
function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
13153
const {
132-
target = window,
54+
target = typeof window !== 'undefined' ? window : undefined,
13355
thr = 0,
13456
axis = Axis.Y,
13557
scrollUp = axis === Axis.Y ? Direction.Up : Direction.Left,
@@ -151,14 +73,13 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
15173

15274
/** Function to update scroll direction */
15375
const updateScrollDir = useCallback(() => {
76+
if (!target) return;
77+
15478
let scroll: number;
15579
if (target instanceof Window) {
15680
scroll = axis === Axis.Y ? target.scrollY : target.scrollX;
15781
} else {
158-
scroll =
159-
axis === Axis.Y
160-
? (target as HTMLDivElement).scrollTop
161-
: (target as HTMLDivElement).scrollLeft;
82+
scroll = axis === Axis.Y ? target.scrollTop : target.scrollLeft;
16283
}
16384

16485
if (Math.abs(scroll - lastScroll.current) >= threshold) {
@@ -169,33 +90,33 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
16990
}, [target, axis, threshold, scrollDown, scrollUp]);
17091

17192
useEffect(() => {
93+
if (!target) {
94+
console.warn(
95+
'useDetectScroll: target is not set. Falling back to window.'
96+
);
97+
return;
98+
}
99+
172100
/** Function to update scroll position */
173101
const updateScrollPosition = () => {
174-
const top =
175-
target instanceof Window
176-
? target.scrollY
177-
: (target as HTMLDivElement).scrollTop;
102+
if (!target) return;
103+
104+
const top = target instanceof Window ? target.scrollY : target.scrollTop;
178105
const left =
179-
target instanceof Window
180-
? target.scrollX
181-
: (target as HTMLDivElement).scrollLeft;
106+
target instanceof Window ? target.scrollX : target.scrollLeft;
107+
182108
const bottom =
183-
document.documentElement.scrollHeight -
184109
(target instanceof Window
185-
? target.innerHeight
186-
: (target as HTMLDivElement).scrollHeight) -
187-
top;
110+
? document.documentElement.scrollHeight - target.innerHeight
111+
: target.scrollHeight - target.clientHeight) - top;
188112
const right =
189-
document.documentElement.scrollWidth -
190113
(target instanceof Window
191-
? target.innerWidth
192-
: (target as HTMLDivElement).scrollWidth) -
193-
left;
114+
? document.documentElement.scrollWidth - target.innerWidth
115+
: target.scrollWidth - target.clientWidth) - left;
194116

195117
setScrollPosition({ top, bottom, left, right });
196118
};
197119

198-
/** Call the update function when the component mounts */
199120
updateScrollPosition();
200121

201122
const targetElement = target as EventTarget;
@@ -207,16 +128,20 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
207128
}, [target]);
208129

209130
useEffect(() => {
131+
if (!target) {
132+
console.warn(
133+
'useDetectScroll: target is not set. Falling back to window.'
134+
);
135+
return;
136+
}
137+
210138
if (target instanceof Window) {
211139
lastScroll.current = axis === Axis.Y ? target.scrollY : target.scrollX;
212140
} else {
213141
lastScroll.current =
214-
axis === Axis.Y
215-
? (target as HTMLDivElement).scrollTop
216-
: (target as HTMLDivElement).scrollLeft;
142+
axis === Axis.Y ? target.scrollTop : target.scrollLeft;
217143
}
218144

219-
/** Function to handle onScroll event */
220145
const onScroll = () => {
221146
if (!ticking.current) {
222147
window.requestAnimationFrame(updateScrollDir);
@@ -233,4 +158,5 @@ function useDetectScroll(props: ScrollProps = {}): ScrollInfo {
233158
return { scrollDir, scrollPosition };
234159
}
235160

161+
export { Axis, Direction };
236162
export default useDetectScroll;

src/types.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/** Enumeration for axis values */
2+
export enum Axis {
3+
/**
4+
* The x-axis represents the horizontal direction.
5+
*/
6+
X = 'x',
7+
/**
8+
* The y-axis represents the vertical direction.
9+
*/
10+
Y = 'y'
11+
}
12+
13+
/** Enumeration for direction values */
14+
export enum Direction {
15+
/**
16+
* The up direction represents the scroll direction moving towards the top.
17+
*/
18+
Up = 'up',
19+
/**
20+
* The down direction represents the scroll direction moving towards the bottom.
21+
*/
22+
Down = 'down',
23+
/**
24+
* The left direction represents the scroll direction moving towards the left.
25+
*/
26+
Left = 'left',
27+
/**
28+
* The right direction represents the scroll direction moving towards the right.
29+
*/
30+
Right = 'right',
31+
/**
32+
* The still direction represents the scroll direction when the user is not scrolling.
33+
*/
34+
Still = 'still'
35+
}
36+
37+
export type ScrollPosition = {
38+
/**
39+
* The top position represents the distance from the top edge of the page.
40+
*/
41+
top: number;
42+
/**
43+
* The bottom position represents the distance from the bottom edge of the page.
44+
*/
45+
bottom: number;
46+
/**
47+
* The left position represents the distance from the left edge of the page.
48+
*/
49+
left: number;
50+
/**
51+
* The right position represents the distance from the right edge of the page.
52+
*/
53+
right: number;
54+
};
55+
56+
/** Type declaration for the returned scroll information */
57+
export type ScrollInfo = {
58+
/**
59+
* The scrollDir represents the current scroll direction.
60+
*/
61+
scrollDir: Direction;
62+
/**
63+
* The scrollPosition represents the current scroll position.
64+
*/
65+
scrollPosition: ScrollPosition;
66+
};
67+
68+
/** Type declaration for scroll properties */
69+
export type ScrollProps = {
70+
/**
71+
* The target represents the scrollable element to check for scroll detection.
72+
*/
73+
target?: HTMLDivElement | Window;
74+
/**
75+
* The thr represents the threshold value for scroll detection.
76+
*/
77+
thr?: number;
78+
/**
79+
* The axis represents the scroll axis (x or y).
80+
*/
81+
axis?: Axis;
82+
/**
83+
* The scrollUp represents the scroll direction when moving up.
84+
*/
85+
scrollUp?: Direction;
86+
/**
87+
* The scrollDown represents the scroll direction when moving down.
88+
*/
89+
scrollDown?: Direction;
90+
/**
91+
* The still represents the scroll direction when the user is not scrolling.
92+
*/
93+
still?: Direction;
94+
};

0 commit comments

Comments
 (0)