All hooks / Elements
useElementScroll
The scroll position of a scrollable element, and whether it is at each edge. Returns a callback ref for the element.
Updates on scroll, and also when the element or its content changes size with no scroll event (rows added, text streamed in), so atBottom never goes stale. Before the element is measured, and on the server, it is at 0, 0 with every edge true.
Re-renders as x and y change, about once a frame while scrolling. If an expensive component only needs the edge flags, call the hook in a small child component instead.
Import
import { useElementScroll } from '@vincent.ri/react-tils'
// or only this hook
import { useElementScroll } from '@vincent.ri/react-tils/useElementScroll'Usage
const [ref, { atTop, atBottom }] = useElementScroll<HTMLDivElement>()
return (
<div ref={ref} style={{ overflow: 'auto', maxHeight: 400 }}
className={[!atTop && 'shadow-top', !atBottom && 'shadow-bottom'].filter(Boolean).join(' ')}>
<Rows />
</div>
)Live demo
Scroll the list: shadows show where there is more.
When to use it
Fade shadows at the edges of a scrolling table or list, a "scroll to top" button inside a panel, or "you've read to the end" in a container.
When not to
The page itself scrolls; use useWindowScroll. For a chat that follows new messages, use useStickToBottom. Shadows alone can be done with CSS scroll-driven animations where supported.
API
function useElementScroll<T extends Element = HTMLElement>(): [(element: T | null) => void, ElementScroll]Returns [ref, scroll]. Pass ref to the scrollable element.
Types
export type ElementScroll = {
/** `scrollLeft`: 0 or negative in right-to-left content, as in the DOM. */
x: number;
/** `scrollTop`. */
y: number;
atTop: boolean;
atBottom: boolean;
atLeft: boolean;
atRight: boolean;
};Browser support
| Uses | Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS |
|---|---|---|---|---|---|---|
| ResizeObserverWidely available | 64+ | 79+ | 69+ | 13.1+ | 64+ | 13.4+ |
| MutationObserverWidely available | 26+ | 12+ | 14+ | 7+ | 26+ | 7+ |
First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).
Coming from another library?
Other libraries call this useScroll.