npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-use-draggable-scroll

v0.4.7

Published

[![NPM Version](https://img.shields.io/npm/v/react-use-draggable-scroll)](https://www.npmjs.com/package/react-use-draggable-scroll)

Downloads

160,142

Readme

useDraggable Hook

NPM Version

useDraggable is a React hook that allows a wrapping div to have a draggable scroll with an inertial effect. It is completely unstyled and just adds the functionality you are looking for so your application gives the best user experience possible. It works in both x- and y-coordinate directions.

See DEMO.

Why useDraggable?

Differently from other hooks designed for the same purpose, this hook does not rely on any state changes. The functionality is built entirely on event listeners. This means that the wrapping div and its children elements are not re-rendered, resulting in a better performance.

Installation

yarn add react-use-draggable-scroll
npm install react-use-draggable-scroll

How to use

All you have to do is to create a reference to the wrapping div and pass it as parameter to to the useDraggable hook. The hook is totally unstyled. You can use any library of your choice to style the div and the child components as you would normally do. In the example below, we use TailwindCSS to illustrate.

Just recapping some basics of CSS that you will probably use along with this hook: It is important to set overflow-x: scroll; property in the CSS of the wrapping div to create the scroll (same goes for y-direction, if that is your case). To prevent a flex item from growing or shrinking, use the CSS property flex: none;.

In Javascript:

import { useRef } from "react";
import { useDraggable } from "react-use-draggable-scroll";

export default function MyComponent() {
  const ref = useRef(); // We will use React useRef hook to reference the wrapping div:
  const { events } = useDraggable(ref); // Now we pass the reference to the useDraggable hook:

  return (
    <div
      className="flex max-w-xl space-x-3 overflow-x-scroll scrollbar-hide"
      {...events}
      ref={ref} // add reference and events to the wrapping div
    >
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
    </div>
  );
}

In Typescript:

import { useRef } from "react";
import { useDraggable } from "react-use-draggable-scroll";

export default function MyComponent(): JSX.Element {
  // We will use React useRef hook to reference the wrapping div:
  const ref =
    useRef<HTMLDivElement>() as React.MutableRefObject<HTMLInputElement>;
  const { events } = useDraggable(ref); // Now we pass the reference to the useDraggable hook:

  return (
    <div
      className="flex max-w-xl space-x-3 overflow-x-scroll scrollbar-hide"
      {...events}
      ref={ref} // add reference and events to the wrapping div
    >
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
      <div className="flex-none w-52 h-32 bg-red-200" />
    </div>
  );
}

Additional settings:

activeMouseButton: Change which mouse button starts a scroll

By default, holding left mouse button will start a scroll. However, you can also use the middle or right mouse button to start a scroll.

Accepts "Left" | "Right" | "Middle

const { events } = useDraggable(ref, {
    activeMouseButton?: "Middle"; // Sets which mouse button starts a scroll
});

applyRubberBandEffect: Rubber Band Effect

It is possible to toggle a rubber band effect on and off for when the user scrolls past the end of the container. This effect is turned off by default to avoid conflicting CSS style rules in code that uses earlier versions of this hook.

const { events } = useDraggable(ref, {
  applyRubberBandEffect: true, // activate rubber band effect
});

:warning: If you are using rubber band effect: This effect is applied using the transform CSS property. User-defined styles can be overridden when applyRubberBandEffect is true (default value is false).

decayRate: Control the decay rate of the inertial effect

You can also control the decay rate of the inertial effect by using an optional parameter. The default value is 0.95, which means that at the speed will decay 5% of its current value at every 1/60 seconds.

const { events } = useDraggable(ref, {
  decayRate: 0.96, // specify the decay rate
});

safeDisplacement: Control the drag sensitivity

Finally, you can control drag sensitivity by using an optional parameter that states the minimum distance in order to distinguish an intentional drag movement from an unwanted one, which should be instead considered as a click. The default value is 10, which means that when a drag movement travels for 10 pixels or less it is considered unintentional. In this scenario, the drag operation would still be performed, but the closing mouse-up event would still be propagated to the rest of the DOM.

const { events } = useDraggable(ref, {
  safeDisplacement: 11, // specify the drag sensitivity
});

isMounted: Determine if ref is available or not, default true

In some use cases, such as you need to use useImperativeHandle, you will need to wait for the component to be rendered and the Ref to be accessible before using the useDraggable hook. In this case, use isMounted as a controllable switch.

const { events } = useDraggable(ref, {
  isMounted: true, 
});

Contributing

See CONTRIBUTING.md.