Skip to content

Commit 74a0274

Browse files
committed
chore!(utils): useScrollListener no longer accepts an element or options
1 parent 6a95734 commit 74a0274

3 files changed

Lines changed: 47 additions & 64 deletions

File tree

‎packages/documentation/src/components/Demos/AppBar/AnimatingAppBar.tsx‎

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { Avatar } from "@react-md/avatar";
44
import avatarVariables from "@react-md/avatar/dist/scssVariables";
55
import { List, ListItem } from "@react-md/list";
66
import { MenuSVGIcon, MoreVertSVGIcon } from "@react-md/material-icons";
7-
import { useScrollListener } from "@react-md/utils";
87

98
import people from "constants/people";
109
import AppBarTitle from "components/AppBarTitle";
@@ -33,27 +32,6 @@ const SCROLL_MULTIPLIER = 0.314;
3332

3433
export default function AnimatingAppBar(): ReactElement {
3534
const [height, setHeight] = useState(`${HEIGHT}px`);
36-
37-
const [ref, setRef] = useState<HTMLDivElement | null>(null);
38-
useScrollListener({
39-
element: ref,
40-
onScroll: () => {
41-
if (!ref) {
42-
return;
43-
}
44-
45-
const { scrollTop } = ref;
46-
const remaining = Math.min(
47-
Math.max(HEIGHT - scrollTop * SCROLL_MULTIPLIER, 0),
48-
HEIGHT
49-
);
50-
const nextHeight = `${remaining}px`;
51-
if (height !== nextHeight) {
52-
setHeight(nextHeight);
53-
}
54-
},
55-
});
56-
5735
const style: CSSProperties = {
5836
"--offset": height,
5937
};
@@ -74,7 +52,20 @@ export default function AnimatingAppBar(): ReactElement {
7452
<MoreVertSVGIcon />
7553
</AppBarAction>
7654
</AppBar>
77-
<div className={styles.content} ref={setRef}>
55+
<div
56+
className={styles.content}
57+
onScroll={(event) => {
58+
const { scrollTop } = event.currentTarget;
59+
const remaining = Math.min(
60+
Math.max(HEIGHT - scrollTop * SCROLL_MULTIPLIER, 0),
61+
HEIGHT
62+
);
63+
const nextHeight = `${remaining}px`;
64+
if (height !== nextHeight) {
65+
setHeight(nextHeight);
66+
}
67+
}}
68+
>
7869
<List>
7970
{transformedPeople.map(({ id, name, avatar, color }, i) => (
8071
<ListItem

‎packages/utils/src/events/ScrollListener.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { useScrollListener, Options } from "./useScrollListener";
1+
import {
2+
useScrollListener,
3+
ScrollListenerHookOptions,
4+
} from "./useScrollListener";
25

3-
export type ScrollListenerProps = Omit<Options<HTMLElement>, "enabled">;
6+
export type ScrollListenerProps = Omit<ScrollListenerHookOptions, "enabled">;
47

58
/**
69
* This is a simple component wrapper for the `useScrollListener` hook.

‎packages/utils/src/events/useScrollListener.ts‎

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,51 @@ import { useEffect } from "react";
22

33
import { useRefCache } from "../useRefCache";
44
import { delegateEvent } from "./delegateEvent";
5-
import { isSupported } from "./passiveEvents";
65

7-
export interface Options<E extends HTMLElement = HTMLElement> {
6+
/**
7+
* @remarks \@since 5.0.0
8+
*/
9+
export interface ScrollListenerHookOptions extends AddEventListenerOptions {
810
/**
9-
* A function that is called whenever the scroll event is triggered.
11+
* The event handler that will be fired when the page scrolls or if any child
12+
* element scrolls when the {@link capture} option is `true`.
1013
*/
1114
onScroll: EventListener;
1215

13-
/**
14-
* Any event listener options to use when attaching the event.
15-
*/
16-
options?: AddEventListenerOptions | boolean;
17-
18-
/**
19-
* Boolean if the scroll listener should be enabled. You can swap this boolean
20-
* to `true` or `false` to add/remove the event listeners. The event listeners
21-
* will *always* be removed when the parent component is unmounted though.
22-
*/
16+
/** @defaultValue `true` */
2317
enabled?: boolean;
24-
25-
/**
26-
* The element that should gain the focus event. When this is omitted, it will
27-
* default to the entire `window`.
28-
*/
29-
element?: E | null;
3018
}
3119

3220
/**
33-
* This hook will create a performant scroll listener by enabling passive events
34-
* if it's supported by the browser and delegating the event as needed.
21+
*
22+
* @remarks \@since 5.0.0 Moved the `AddEventListenerOptions` to no longer be
23+
* part of an `options` object.
3524
*/
36-
export function useScrollListener<E extends HTMLElement = HTMLElement>({
25+
export function useScrollListener({
26+
once,
27+
passive = true,
28+
signal,
29+
capture,
3730
enabled = true,
3831
onScroll,
39-
element,
40-
options = isSupported ? { passive: true } : false,
41-
}: Options<E>): void {
42-
const callback = useRefCache(onScroll);
43-
32+
}: ScrollListenerHookOptions): void {
33+
const scrollHandlerRef = useRefCache(onScroll);
4434
useEffect(() => {
4535
if (!enabled) {
4636
return;
4737
}
4838

49-
const eventHandler = delegateEvent(
50-
"scroll",
51-
element || window,
52-
true,
53-
options
54-
);
55-
const handler = (event: Event): void => callback.current(event);
56-
eventHandler.add(handler);
39+
const eventHandler = delegateEvent("scroll", window, true, {
40+
once,
41+
passive,
42+
signal,
43+
capture,
44+
});
45+
const scrollHandler = scrollHandlerRef.current;
46+
eventHandler.add(scrollHandler);
47+
5748
return () => {
58-
eventHandler.remove(handler);
49+
eventHandler.remove(scrollHandler);
5950
};
60-
// disabled since useRefCache
61-
// eslint-disable-next-line react-hooks/exhaustive-deps
62-
}, [enabled, element, options]);
51+
}, [capture, enabled, once, passive, scrollHandlerRef, signal]);
6352
}

0 commit comments

Comments
 (0)