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 🙏

© 2025 – Pkg Stats / Ryan Hefner

dnd-kit-solid

v0.1.0

Published

Bringing the power of dnd-kit to SolidJS applications. A modern, lightweight, performant, accessible and extensible drag & drop toolkit.

Readme

dnd-kit-solid

Bringing the power of dnd-kit to SolidJS applications. A modern, lightweight, performant, accessible and extensible drag & drop toolkit with the same great API and features.

Install

npm i dnd-kit-solid @dnd-kit/dom

Usage

DragDropProvider

The DragDropProvider component creates a context that enables drag and drop interactions for its children. It manages the drag and drop state and coordinates between draggable and droppable elements.

Basic Usage

Wrap your application or a section with DragDropProvider:

import { DragDropProvider } from "dnd-kit-solid";

function App() {
  return (
    <DragDropProvider>
      <YourDraggableContent />
    </DragDropProvider>
  );
}

Event Handling

Listen to drag and drop events to respond to user interactions:

function App() {
  return (
    <DragDropProvider
      onBeforeDragStart={({ source, event }) => {
        // Optionally prevent dragging
        if (shouldPreventDrag(source)) {
          event.preventDefault();
        }
      }}
      onDragStart={({ source }) => {
        console.log("Started dragging", source.id);
      }}
      onDragMove={({ operation }) => {
        const { position } = operation;
        console.log("Current position:", position);
      }}
      onDragOver={({ source, target }) => {
        console.log(`${source.id} is over ${target.id}`);
      }}
      onDragEnd={({ source, target }) => {
        if (target) {
          console.log(`Dropped ${source.id} onto ${target.id}`);
        }
      }}
    >
      <YourDraggableContent />
    </DragDropProvider>
  );
}

Multiple Contexts

You can create multiple independent drag and drop contexts:

function App() {
  return (
    <div>
      <DragDropProvider>
        <FileList /> {/* Files can only be dropped in this context */}
      </DragDropProvider>

      <DragDropProvider>
        <TaskList /> {/* Tasks can only be dropped in this context */}
      </DragDropProvider>
    </div>
  );
}

Configuration

Customize behavior with plugins, sensors, and modifiers:

import {
  DragDropProvider,
  PointerSensor,
  KeyboardSensor,
  RestrictToWindow,
} from "dnd-kit-solid";

function App() {
  return (
    <DragDropProvider
      // Custom input detection
      sensors={[PointerSensor, KeyboardSensor]}
      // Extend functionality
      plugins={[AutoScroller, Accessibility]}
      // Modify drag behavior
      modifiers={[RestrictToWindow]}
    >
      <YourDraggableContent />
    </DragDropProvider>
  );
}

useDraggable

Use the useDraggable hook to make elements draggable that can be dropped over droppable targets.

The useDraggable hook requires an id and accepts all the same options as the Draggable class.

The hook must be used within a DragDropProvider or provided with a manager instance.

Basic Usage

import { useDraggable } from "dnd-kit-solid";

function Draggable(props) {
  const { ref } = useDraggable({
    id: props.id,
    // Optional: provide a manager if not using DragDropProvider
    // manager: props.manager,
  });

  return <div ref={ref}>Draggable</div>;
}

Specifying a Drag Handle

To specify a drag handle, use the handleRef returned by the hook:

function Draggable(props) {
  const { ref, handleRef } = useDraggable({
    id: props.id,
  });

  return (
    <div ref={ref}>
      Draggable
      <button ref={handleRef}>Drag handle</button>
    </div>
  );
}

When you connect a drag handle element, only the element that is connected to the handleRef will initiate the drag operation.

Restricting Dragging Using Modifiers

Use modifiers to modify or restrict the behavior of draggable elements:

import { useDraggable } from "dnd-kit-solid";
import { RestrictToHorizontalAxis } from "@dnd-kit/abstract/modifiers";

function Draggable({ id }) {
  const { ref } = useDraggable({
    id,
    modifiers: [RestrictToHorizontalAxis],
  });

  return <div ref={ref}>Draggable</div>;
}

API Reference

The useDraggable hook is a thin wrapper around the Draggable class that makes it easier to create draggable elements in SolidJS. It therefore accepts all of the same input arguments.

Input

The useDraggable hook accepts the following arguments:

  • id (required): The identifier of the draggable element. Should be unique within the same drag and drop context.
  • type: Optionally supply a type to only allow this draggable element to be dropped over droppable targets that accept this type.
  • element: If you already have a reference to the element, you can pass it instead of using the ref.
  • handle: If you already have a reference to the drag handle element, you can pass it instead of using the handleRef.
  • disabled: Set to true to prevent the draggable element from being draggable.
  • feedback: The type of feedback that should be displayed when the element is being dragged ('default' | 'clone' | 'move' | 'none').
  • modifiers: An array of modifiers that can be used to modify or restrict the behavior of the draggable element.
  • sensors: An array of sensors that can be bound to the draggable element to detect drag interactions.
  • data: Additional data about the draggable element that can be accessed in event handlers, modifiers, sensors or custom plugins.
Output

The useDraggable hook returns an object containing:

  • ref: A ref callback function that can be attached to the element you want to make draggable.
  • handleRef: A ref callback function that can be attached to an element to create a drag handle.
  • isDragging: A boolean signal that indicates whether the draggable is currently being dragged.
  • isDropping: A boolean signal that indicates whether the draggable is being dropped.
  • isDragSource: A boolean signal that indicates whether the draggable is the source of the drag operation.
  • draggable: The draggable instance that is created by the hook.

useDroppable

Use the useDroppable hook to create droppable targets for draggable elements.

The useDroppable hook requires an id and accepts all the same options as the Droppable class.

The hook must be used within a DragDropProvider or provided with a manager instance.

Basic Usage

import { useDroppable } from "dnd-kit-solid";

function Droppable(props) {
  const { isDropTarget, ref } = useDroppable({
    id: props.id,
    // Optional: provide a manager if not using DragDropProvider
    // manager: props.manager,
  });

  return (
    <div ref={ref}>
      {isDropTarget()
        ? "Draggable element is over me"
        : "Drag something over me"}
    </div>
  );
}

Accepting Specific Types

You can restrict which draggable elements can be dropped by specifying the accept property:

function Droppable(props) {
  const { isDropTarget, ref } = useDroppable({
    id: props.id,
    accept: "item", // Only draggable elements with type "item" can be dropped here
  });

  return (
    <div ref={ref}>
      {isDropTarget() ? "Item is over me" : "Drag an item over me"}
    </div>
  );
}

Custom Collision Detection

You can provide a custom collision detector function:

function Droppable(props) {
  const { isDropTarget, ref } = useDroppable({
    id: props.id,
    collisionDetector: (input) => {
      // Custom collision detection logic
      return {
        id: props.id,
        data: input.draggable.data,
      };
    },
  });

  return <div ref={ref}>Drop zone</div>;
}

API Reference

The useDroppable hook is a thin wrapper around the Droppable class that makes it easier to create droppable targets in SolidJS. It therefore accepts all of the same input arguments.

Input

The useDroppable hook accepts the following arguments:

  • id (required): The identifier of the droppable element. Should be unique within the same drag and drop context.
  • element: If you already have a reference to the element, you can pass it instead of using the ref.
  • accept: Optionally supply a type of draggable element to only allow it to be dropped over certain droppable targets that accept this type.
  • collisionDetector: Optionally supply a collision detector function to detect collisions between the droppable element and draggable elements.
  • collisionPriority: Optionally supply a number to set the collision priority of the droppable element. Higher numbers have higher priority when detecting collisions.
  • disabled: Set to true to prevent the droppable element from being a drop target.
  • data: Additional data about the droppable element that can be accessed in event handlers, modifiers, sensors or custom plugins.
  • effects: Advanced feature for setting up reactive effects that are automatically cleaned up when the component is unmounted.
Output

The useDroppable hook returns an object containing:

  • ref: A ref callback function that can be attached to the element you want to use as a droppable target.
  • isDropTarget: A boolean signal that indicates whether the element is currently being dragged over.
  • droppable: The droppable instance that is created by the hook.

useSortable

Use the useSortable hook to reorder elements in a list or across multiple lists.

The useSortable hook requires an id and an index. It accepts all the same options as the Sortable class.

The hook must be used within a DragDropProvider or provided with a manager instance.

Basic Usage

import { useSortable } from "dnd-kit-solid";

function SortableItem(props) {
  const { ref, isDragging } = useSortable({
    id: props.id,
    index: props.index,
    // Optional: provide a manager if not using DragDropProvider
    // manager: props.manager,
  });

  return (
    <div
      ref={ref}
      style={{
        opacity: isDragging() ? 0.5 : 1,
      }}
    >
      Item {props.id}
    </div>
  );
}

Using a Drag Handle

You can specify a drag handle to control which part of the element initiates the drag:

function SortableItem(props) {
  const { ref, handleRef, isDragging } = useSortable({
    id: props.id,
    index: props.index,
  });

  return (
    <div ref={ref}>
      <div>Item {props.id}</div>
      <button ref={handleRef}>Drag handle</button>
    </div>
  );
}

Animating Transitions

You can add smooth transitions when items are reordered:

function SortableItem(props) {
  const { ref, isDragging } = useSortable({
    id: props.id,
    index: props.index,
    transition: {
      duration: 200,
      easing: "ease",
      idle: true,
    },
  });

  return (
    <div
      ref={ref}
      style={{
        opacity: isDragging() ? 0.5 : 1,
        transition: "all 200ms ease",
      }}
    >
      Item {props.id}
    </div>
  );
}

API Reference

The useSortable hook is a thin wrapper around the Sortable class that makes it easier to create sortable elements in SolidJS. It combines the functionality of useDraggable and useDroppable hooks.

Input

The useSortable hook accepts all the same arguments as the useDraggable and useDroppable hooks, plus:

  • id (required): The identifier of the sortable element. Should be unique within the same drag and drop context.
  • index (required): The index of the sortable element in the list.
  • transition: Optional configuration for animating the sortable element:
    • duration: The duration of the transition in milliseconds
    • easing: The easing function to use for the transition
    • idle: Whether to animate when the index changes without dragging
  • element: If you already have a reference to the element, you can pass it instead of using the ref.
  • handle: If you already have a reference to the drag handle element, you can pass it instead of using the handleRef.
  • target: If you already have a reference to the droppable target element, you can pass it instead of using the targetRef.
  • source: If you already have a reference to the draggable source element, you can pass it instead of using the sourceRef.
  • accept: Optionally supply a type of draggable element to only allow it to be dropped over certain droppable targets.
  • collisionDetector: Optionally supply a collision detector function.
  • collisionPriority: Optionally supply a number to set the collision priority.
  • disabled: Set to true to prevent the sortable element from being sortable.
  • data: Additional data about the sortable element.
  • effects: Advanced feature for setting up reactive effects.
Output

The useSortable hook returns an object containing:

  • ref: A ref callback function for the main sortable element.
  • targetRef: A ref callback function for the droppable target element.
  • sourceRef: A ref callback function for the draggable source element.
  • handleRef: A ref callback function for the drag handle element.
  • isDropTarget: A boolean signal indicating if the element is a drop target.
  • isDragSource: A boolean signal indicating if the element is the drag source.
  • isDragging: A boolean signal indicating if the element is being dragged.
  • isDropping: A boolean signal indicating if the element is being dropped.
  • sortable: The sortable instance that is created by the hook.

useDragDropMonitor

Monitor drag and drop events in your SolidJS components.

The useDragDropMonitor hook allows you to monitor drag and drop events within a DragDropProvider.

Basic Usage

import { useDragDropMonitor } from "dnd-kit-solid";

function DragMonitor() {
  useDragDropMonitor({
    onBeforeDragStart(event, manager) {
      // Optionally prevent dragging
      if (shouldPreventDrag(event.operation.source)) {
        event.preventDefault();
      }
    },
    onDragStart(event, manager) {
      console.log("Started dragging", event.operation.source);
    },
    onDragMove(event, manager) {
      console.log("Current position:", event.operation.position);
    },
    onDragOver(event, manager) {
      console.log("Over droppable:", event.operation.target);
    },
    onDragEnd(event, manager) {
      const { operation, canceled } = event;

      if (canceled) {
        console.log("Drag cancelled");
        return;
      }

      if (operation.target) {
        console.log(
          `Dropped ${operation.source.id} onto ${operation.target.id}`
        );
      }
    },
    onCollision(event, manager) {
      console.log("Collisions:", event.collisions);
    },
  });

  return null;
}

Make sure to use the useDragDropMonitor hook within a component that is wrapped in a DragDropProvider component.

Events

| Event | Description | Preventable | Data | | --------------- | ---------------------------- | ----------- | -------------------------------- | | beforeDragStart | Fires before drag begins | Yes | operation | | dragStart | Fires when drag starts | No | operation, nativeEvent | | dragMove | Fires during movement | Yes | operation, to, by, nativeEvent | | dragOver | Fires when over a droppable | Yes | operation | | collision | Fires on droppable collision | Yes | collisions | | dragEnd | Fires when drag ends | No | operation, canceled, nativeEvent |

Notes

  • The hook must be used within a DragDropProvider
  • Event handlers receive both the event data and the manager instance
  • Use event.preventDefault() on preventable events to stop their default behavior
  • The dragEnd event includes a canceled property that replaces the old onDragCancel event
  • Event handlers are automatically cleaned up when the component is unmounted

useDragOperation

Access the current drag operation state in your SolidJS components.

The useDragOperation hook provides reactive access to the current drag operation state, including the dragged element, drop target, and position.

Basic Usage

import { useDragOperation } from "dnd-kit-solid";

function DragOperationMonitor() {
  const operation = useDragOperation();

  return (
    <div>
      {operation.source && <div>Dragging: {operation.source.id}</div>}
      {operation.target && <div>Over: {operation.target.id}</div>}
      {operation.position && (
        <div>
          Position: {operation.position.x}, {operation.position.y}
        </div>
      )}
      <div>Status: {operation.status}</div>
      {operation.canceled && <div>Operation was canceled</div>}
    </div>
  );
}

Using with Custom Manager

If you need to use the hook outside of a DragDropProvider, you can pass a manager instance:

function CustomDragMonitor(props) {
  const operation = useDragOperation({
    manager: props.manager,
  });

  return <div>{operation.source?.id}</div>;
}

API Reference

Input

The useDragOperation hook accepts an optional options object:

  • manager: Optional DragDropManager instance. If not provided, the hook will use the manager from the nearest DragDropProvider.
Output

The useDragOperation hook returns a reactive store containing:

  • source: The currently dragged element (or null if no drag is in progress)
  • target: The current drop target (or null if not over a valid target)
  • position: The current drag coordinates (or null if no drag is in progress)
  • status: The current operation status
  • canceled: Whether the operation was canceled

Notes

  • The hook must be used within a DragDropProvider unless a manager is explicitly provided
  • All properties are reactive and will update automatically when the drag operation state changes
  • The store is automatically disposed when the component is unmounted

Development

Setup

# Install dependencies
npm install

Development Mode

Start the development server with the playground:

npm run dev

This will start a development server at http://localhost:3000 where you can see your changes in real-time.

Building

Build the library for production:

npm run build

This generates:

  • CommonJS build in dist/cjs/
  • ES Modules build in dist/esm/
  • TypeScript type definitions in dist/types/

Testing

# Run tests
npm test

# Check code quality
npm run lint

# Fix linting issues
npm run lint:fix

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Clone your fork:
    git clone https://github.com/your-username/sorta.git
    cd sorta
  3. Install dependencies:
    npm install
  4. Create a new branch for your feature:
    git checkout -b feature/your-feature-name
  5. Make your changes and ensure:
    • All tests pass (npm test)
    • Code is properly linted (npm run lint)
    • TypeScript types are correct
    • Documentation is updated
  6. Commit your changes with a descriptive message
  7. Push to your fork
  8. Create a Pull Request

Development Guidelines

  • Follow the existing code style and patterns
  • Write tests for new features
  • Update documentation as needed
  • Keep the bundle size minimal
  • Ensure cross-browser compatibility
  • Use TypeScript for type safety
  • Maintain compatibility with the original dnd-kit API where possible
  • Follow SolidJS best practices

Code of Conduct

Please be respectful and considerate of others when contributing. We follow the Contributor Covenant code of conduct.

License

MIT