use-scroll-into-view

Scroll given node into view
Import

Usage

use-scroll-into-view handles scroll behavior for any scrollable element. Basic usage works the same way as element.scrollIntoView(). Hook adjusts scrolling animation with respect to the reduced-motion user preference.

Hello there
import { useScrollIntoView } from '@mantine/hooks';
import { Button, Text } from '@mantine/core';
function Demo() {
const navbarHeight = 60;
const { scrollIntoView, targetRef } = useScrollIntoView({ offset: navbarHeight });
return (
<>
<Button onClick={() => scrollIntoView({ alignment: 'center' })}>
Scroll to target
</Button>
<div style={{ height: '50vh'}} />
<Text ref={targetRef}>Hello there</Text>
</>
);
}

API

Hook is configured with settings object:

  • onScrollFinish – function that will be called after scroll animation
  • easing – custom math easing function
  • duration - duration of scroll animation in milliseconds
  • axis - axis of scroll
  • cancelable - indicator if animation may be interrupted by user scrolling
  • offset - additional distance between nearest edge and element
  • isList - indicator that prevents content jumping in scrolling lists with multiple targets eg. Select, Carousel

Hook returns an object with:

  • scrollIntoView – function that starts scroll animation
  • cancel – function that stops scroll animation
  • targetRef - ref of target HTML node
  • scrollableRef - ref of scrollable parent HTML element, if not used document element will be used

Returned scrollIntoView function accepts single optional argument alignment - optional target element alignment relatively to parent based on current axis.

scrollIntoView({ alignment: 'center' });

Easing

Hook accept custom easing math function to control the flow of animation. It takes t argument which is a number between 0 and 1.

Default easing is easeInOutQuad - more info here. You can find other popular examples on easings.net

useScrollIntoView({
target: someDomElement,
easing: (t) => (t < 0.5 ? 16 * Math.pow(t, 5) : 1 - Math.pow(-2 * x + 2, 5) / 2), // easeInOutQuint
});

Examples

Parent node

Scroll me into view
import { useScrollIntoView } from '@mantine/hooks';
import { Button, Paper } from '@mantine/core';
function Demo() {
const { scrollIntoView, targetRef, scrollableRef } = useScrollIntoView();
return (
<>
<Paper ref={scrollableRef} style={{ overflowY: 'scroll', height: 300, flex: 1 }}>
<Paper ref={targetRef}>Scroll me into view<</Paper>
</Paper>
<Button onClick={() => scrollIntoView()}>Scroll to target</Button>
</>
);
}

Scroll X axis

Scroll me into view
import { useScrollIntoView } from '@mantine/hooks';
import { Button, Paper } from '@mantine/core';
function Demo() {
const { scrollIntoView, targetRef, scrollableRef } = useScrollIntoView({
axis: 'x',
});
return (
<>
<Paper ref={scrollableRef} style={{ overflowX: 'scroll', height: 150, width: 300 }}>
<Paper ref={targetRef}>Scroll me into view</Paper>
</Paper>
<Button onClick={() => scrollIntoView()}>Scroll to target</Button>
</>
);
}

Definition

function useScrollIntoView<
Target extends HTMLElement,
Parent extends HTMLElement | null = null
>({
onScrollFinish?: () => void;
duration?: number;
axis?: 'x' | 'y';
easing?: (t: number) => number;
offset?: number;
cancelable?: boolean;
isList?: boolean;
}): {
targetRef: MutableRefObject<Target>;
scrollableRef: MutableRefObject<Parent>;
scrollIntoView: ({
alignment?: 'start' | 'end' | 'center';
}) => void;
cancel: () => void;
};
Build fully functional accessible web applications faster than ever
Feedback
Your feedback is most valuable contribution to the project, please share how you use Mantine, what features are missing and what is done good
Leave feedback