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

@dragger/core

v1.0.9

Published

A simple, performant drag and drop library for React

Downloads

31

Readme

@dragger/core

Overview

  • Simple Architecture - there are only two components for you to worry about: <Draggable /> and <Droppable />. Use them anywhere, no context provider needed.
  • Unobtrusive - dragger automatically renders dragged components outside the normal document flow. No need to worry about transforms and z-index fighting, and no need to rewrite all your components in a seperate drag layer - it sorts everything out for you
  • Performance - animations are performed outside of the React render loop to ensure everything runs smoothly
  • Customisable - use your own collision algorithms or modify our ones. Each <Draggable /> can have a different collision algorithm, and a different response to a dropped item
  • Typescript Support - everything is typed straight out of the box. You can define your own type for data, which will apply to the whole instance

Getting Started

First, create a dragger instance

The instance returns <Draggable /> and <Droppable /> components, which can be used anywhere you want.

import dragger from "@dragger/core";

const { Draggable, Droppable } = dragger();

Create a draggable component

When a draggable is dragged, it's children will be rendered twice - on a seperate layer as an overlay, and in the normal document flow as a placeholder. The <Draggable /> tells its children which one of these it is.

It also passes two additional props: drag and handle. drag should be attached to the component you want to move with the drag, and handle should be used on the component you want to activate the drag. They can be attached to the same component.

function Item() {
  return (
    <Draggable>
      {({ drag, handle, overlay, placeholder }) => (
        <div
          {...drag}
          {...handle}
          style={{
            opacity: overlay ? 0.2 : 1,
            boxShadow: placeholder
              ? "0px 15px 15px 0 rgba(34, 33, 81, 0.25)"
              : undefined,
          }}
        >
          <p>draggable</p>
        </div>
      )}
    </Draggable>
  );
}

Create a droppable component

<Droppable /> components accept an onDrop callback. They also accept an id, which must be unique and will be automatically generated if not given, and a collision callback - see the "Collision Algorithms" section below.

The <Droppable /> also gives props to it's children. The drop prop should be attached to the component you want to act as the droppable container. The over prop tells them if an item is currently being dragged over it.

function Item() {
  return (
    <Droppable onDrop={() => console.log("dropped!")}>
      {({ drop, over }) => (
        <div {...drop} style={{ backgroundColor: over ? "#f9f9f9" : "#ffffff" }} />
      )}
    </Draggable>
  );
}

Draggable Data

Each <Draggable /> component can be given a data attribute that can be used by onDrop callbacks and collision algorithms.

When using TypeScript, all draggable data should be expressed in a single type. You can use a union type if you want there to be multiple types.

The Draggable Data type should be given to dragger() when creating the instance.

import dragger from "@dragger/core";

interface Data {
  name: string;
}

const { Draggable, Droppable } = dragger<Data>();

The <Draggable /> component returned by the instance will require data of this type as a prop.

<Draggable data={{ name: string }}>

Collision Algorithms

The default collision algorithm chooses the smallest droppable that the mouse is currently over. You can use different collision algorithms on each <Droppable />, including your own custom ones.

Collision algorithms accept the active element and the droppable rect as parameters, and should return either true to definitely choose the current droppable, false to skip the current droppable, or a numerical score (e.g distance) if it should be considered for comparison. If no collision algorithms return true, the one with the lowest score will be chosen.

type CollisionAlgorithm<Data> = (
  active: {
    data: Data;
    rect: Rect;
    mousePosition: Position;
  },
  rect: Rect
) => boolean | number;