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

@arcturus3/react-drag-drop

v1.0.1

Published

Simple, flexible components and hooks for drag and drop in React.

Downloads

10

Readme

React Drag and Drop

Simple, flexible components and hooks for drag and drop in React.

Installation

npm i @arcturus3/react-drag-drop

Examples

This library provides both components and hooks for drag and drop. The components encapsulate some common functionality and may be useful in simple cases or in addition to the hooks. If you need more control over drag and drop it should be fairly simple to implement this functionality yourself using the hooks. Following are two similar examples using each.

Components

import React from 'react';
import {Drag, Drop, DragView} from '@arcturus3/react-drag-drop';

export const Components = () => <>
    <DragView onDrop={() => alert('dropped')} />
    <Drag previewChildren>drag</Drag>
    <br />
    <Drop>drop</Drop>
</>;

Hooks

import React from 'react';
import {useDrag, useDrop, useDragDrop} from '@arcturus3/react-drag-drop';

export const Hooks = () => {
    const dragRef = useDrag();
    const dropRef = useDrop();
    const state = useDragDrop({
        onDrop: () => alert('dropped')
    });

    const dragStyle = {
        display: 'inline-block',
        transform: state.dragging
            ? `translate(
                ${state.displacement!.x}px,
                ${state.displacement!.y}px
            )`
            : undefined
    };

    return <>
        <span ref={dragRef} style={dragStyle}>drag</span>
        <br />
        <span ref={dropRef}>drop</span>
    </>;
};

Alternatives

React DnD

I think React DnD is based on some good ideas, but I wasn't a fan of its API, and the default HTML5 "backend" for mouse drag and drop comes with some of the limitations of native HTML5 drag and drop. I experienced performance issues with the only third party backend I could find. On the other hand, you may want to use React DnD if you need to support drag and drop with external types like files, links, and selected text.

React UseGesture

React UseGesture does not support drag and drop, but you may want to use it if you only need to support dragging elements and not interacting with drop elements. You could also use it for animating dragging while using this library to handle the drag and drop state.

Documentation

<Drag />

import {Drag} from '@arcturus3/react-drag-drop';

A component that wraps its children with a drag element and prevents browser touch actions from interfering with dragging. Use with <DragView /> to display a drag preview and set the cursor style when hovering. It accepts the following props in addition to children.

  • previewChildren?: boolean (default: false): Whether to use children as the drag preview for <DragView />. Setting to true modifies payload such that the value passed to the payload prop is stored in payload.data and the children are stored in payload.preview for use by <DragView />.
  • payload?: any (default: undefined): See DragConfig.
  • disabled?: boolean (default: false): See DragConfig.
  • deps?: DependencyList (default: []): See DragConfig.

<Drop />

import {Drop} from '@arcturus3/react-drag-drop';

A component that wraps its children with a drop element. It accepts the following props in addition to children.

  • payload?: any (default: undefined): See DropConfig.
  • disabled?: boolean (default: false): See DropConfig.
  • deps?: DependencyList (default: []): See DropConfig.

<DragView />

import {DragView} from '@arcturus3/react-drag-drop';

A component that displays a preview of the element being dragged based on its payload and disables text selection while dragging. It's recommended to render this at the top of the component hierarchy so that it is always mounted. It accepts the following props.

  • preview?: (payload: any) => ReactNode (default: uses payload.preview if defined, which is set automatically if previewChildren={true} on <Drag /> components): Takes a drag payload and returns the preview to render. The preview could be calculated from the payload data or stored directly in the payload.
  • hoverCursor?: string (default: ''): The cursor style to use while hovering over a <Drag /> component before dragging starts.
  • dragCursor?: string (default: ''): The cursor style to use while dragging.
  • onDragStart?: Handler: See DragDropConfig.
  • onDragMove?: Handler: See DragDropConfig.
  • onDragEnd?: Handler: See DragDropConfig.
  • onHoverStart?: Handler: See DragDropConfig.
  • onHoverEnd?: Handler: See DragDropConfig.
  • onDrop?: Handler: See DragDropConfig.
  • onAny?: Handler: See DragDropConfig.
  • deps?: DependencyList (default: []): See DragDropConfig.

useDrag<T extends HTMLElement>(config)

import {useDrag} from '@arcturus3/react-drag-drop';

Make a drag element.

  • config: DragConfig (default: {}): Configuration for the drag element. Note that if config may change when the component using this hook rerenders, config.deps should be specified. Additionally, updates to config will only be reflected in DragDropState once the next drag and drop event occurs.
  • return: RefCallback<T>: A ref to assign to the element that should be draggable.

useDrop<T extends HTMLElement>(config)

import {useDrop} from '@arcturus3/react-drag-drop';

Make a drop element.

  • config: DropConfig (default: {}): Configuration for the drop element. Note that if config may change when the component using this hook rerenders, config.deps should be specified. Additionally, updates to config will only be reflected in DragDropState once the next drag and drop event occurs.
  • return: RefCallback<T>: A ref to assign to the element that should accept drag elements.

useDragDrop(config)

import {useDragDrop} from '@arcturus3/react-drag-drop';

Get the drag and drop state and handle events.

  • config: DragDropConfig (default: {}): Configuration for state and event handlers.
  • return: DragDropState: The drag and drop state, updated according to config.stateProps and requestAnimationFrame.

DragConfig

Configuration object for drag elements with the following properties.

  • payload?: any (default: undefined): Data describing the drag element.
  • disabled?: boolean (default: false): Whether to allow dragging the element. If set to false while dragging the element, this only takes effect once dragging ends normally.
  • deps?: DependencyList (default: []): Array containing the values of any variables that other properties of DragConfig depend upon. Used in the same manner as the useEffect dependency list.

DropConfig

Configuration object for drop elements with the following properties.

  • payload?: any (default: undefined): Data describing the drop element.
  • disabled?: boolean (default: false): Whether to allow dropping and hovering on the element.
  • deps?: DependencyList (default: []): Array containing the values of any variables that other properties of DropConfig depend upon. Used in the same manner as the useEffect dependency list.

DragDropConfig

Configuration object for state and event handlers with the following properties.

  • onDragStart?: Handler: Pointer activates on a drag element.
  • onDragMove?: Handler: Pointer moves after dragging has started.
  • onDragEnd?: Handler: Pointer deactivates after dragging has started.
  • onHoverStart?: Handler: Dragging is in progress and pointer moves over a drop element.
  • onHoverEnd?: Handler: Dragging is in progress and pointer moves off a drop element.
  • onDrop?: Handler: Dragging is in progress and pointer deactivates over a drop element.
  • onAny?: Handler: Called on any of the other events in DragDropConfig.
  • stateProps?: (keyof DragDropState)[] (default: array of all DragDropState properties): Changes to the DragDropState returned by useDragDrop will only cause a component to rerender if one of the properties in this array changes. If set, the array should contain all properties of DragDropState that are used in the component, and serves as a performance optimization by ignoring those that aren't.
  • deps?: DependencyList (default: []): Array containing the values of any variables that other properties of DragDropConfig depend upon. Used in the same manner as the useEffect dependency list.

Handler: (state, prevState) => void

Drag and drop event handler passed to DragDropConfig.

  • state: DragDropState: The drag and drop state after this event occurs. Note that for onDragEnd and onDrop in particular, this will be the initial state where nothing is being dragged, and prevState may be more useful.
  • prevState: DragDropState: The drag and drop state before this event occurred.

DragDropState

Object containing the following properties.

  • dragging: boolean: Whether an element is being dragged.
  • hovering: boolean: Whether the pointer is hovering a droppable element while dragging.
  • dragPayload: any: Payload of the item being dragged or undefined if not dragging.
  • dropPayload: any: Payload of the item being hovered or undefined if not dragging
  • initialPointerPosition: Point | null: pointerPosition when dragging started or null if not dragging.
  • pointerPosition: Point | null: Position of the pointer relative to the viewport or null if not dragging. Add window.scrollX and window.scrollY to get the position relative to the document.
  • initialElementPosition: Point | null: elementPosition when dragging started or null if not dragging.
  • elementPosition: Point | null: initialElementPosition plus displacement or null if not dragging.
  • displacement: Point | null: Displacement between initialPointerPosition and pointerPosition or null if not dragging.

Point

Object containing the following properties.

  • x: number: Horizontal coordinate of a position relative to the viewport.
  • y: number: Vertical coordinate of a position relative to the viewport.