When a user drags a <Draggable />
near the edge of a container we automatically scroll the container as we are able to in order make room for the <Draggable />
.
A container is either a
<Droppable />
that is scrollable or has a scroll parent - or thewindow
.
Mouse and touch | Keyboard |
---|---|
It also works in multi list configurations with all input types
Mouse and touch | Keyboard |
---|---|
When the center of a <Draggable />
gets within a small distance from the edge of a container we start auto scrolling. As the user gets closer to the edge of the container we increase the speed of the auto scroll. This acceleration uses an easing function to exponentially increase the rate of acceleration the closer we move towards the edge. We reach a maximum rate of acceleration a small distance from the true edge of a container so that the user does not need to be extremely precise to obtain the maximum scroll speed. This logic applies for any edge that is scrollable.
The distances required for auto scrolling are based on a percentage of the height or width of the container for vertical and horizontal scrolling respectively. By using percentages rather than raw pixel values we are able to have a great experience regardless of the size and shape of your containers.
In addition to auto scrolling we also allow users to scroll the window or a <Droppable />
manually using their mouse wheel or trackpad 👌
If the <Draggable />
is bigger than a container on the axis you are trying to scroll - we will not permit scrolling on that axis. For example, if you have a <Draggable />
that is longer than the height of the window we will not auto scroll vertically. However, we will still permit scrolling to occur horizontally.
When auto scrolling on an iOS browser (webkit) the <Draggable />
noticeably shakes. This is due to a bug with webkit that has no known work around. We tried for a long time to work around the issue! If you are interesting in seeing this improved please engage with the webkit issue.
We also correctly update the scroll position as required when keyboard dragging. In order to move a <Draggable />
into the correct position we can do a combination of a <Droppable />
scroll, window
scroll and manual movements to ensure the <Draggable />
ends up in the correct position in response to user movement instructions. This is boss 🔥.
This is amazing for users with visual impairments as they can correctly move items around in big lists without needing to use mouse positioning.
The <DragDropContext />
accepts a prop
called autoScrollerOptions
, which follows the following interface:
const autoScrollerOptions: PartialAutoScrollerOptions = {
// percentage distance from edge of container at which to start auto scrolling
startFromPercentage?: number;
// percentage distance from edge of container at which max scroll speed is achieved
maxScrollAtPercentage?: number;
// pixels per frame
maxPixelScroll?: number;
// A function used to ease a percentage value for scroll
ease?: (percentage: number) => number;
durationDampening?: {
// ms: how long to dampen the speed of an auto scroll from the start of a drag
stopDampeningAt?: number;
// ms: when to start accelerating the reduction of duration dampening
accelerateAt?: number;
};
// whether or not autoscroll should be turned off entirely
disabled?: boolean;
}
This prop provides developers interested in exerting more control over auto scroll with the tools to do so. Visit the "Custom Auto-Scroll Options" story of the DND Storybook to better understand what each property of this prop controls.