JSPM

  • Created
  • Published
  • Downloads 845
  • Score
    100M100P100Q106199F
  • License MIT

SolidJS library to add dragging to your apps 😉

Package Exports

  • @neodrag/solid
  • @neodrag/solid/package.json

Readme

@neodrag/solid

One draggable to rule em all

A lightweight SolidJS library to make your elements draggable.

Getting Started

Features

  • 🤏 Small in size - ~5KB, plugin architecture enables tree-shaking
  • 🧩 Plugin-based - Mix and match only what you need
  • Performance - Event delegation, pointer capture, optimized for modern browsers
  • 🎯 SolidJS Native - Built for SolidJS with useDraggable hook
  • 🔄 Reactive - createCompartment for reactive plugin updates

Installing

npm install @neodrag/solid@next

Usage

Basic usage

import { useDraggable } from '@neodrag/solid';

export const App: Component = () => {
    const [draggableRef, setDraggableRef] = createSignal<HTMLElement | null>(null);

    useDraggable(draggableRef);

    return <div ref={setDraggableRef}>You can drag me</div>;
};

With plugins

import { useDraggable, axis, grid } from '@neodrag/solid';

export const App: Component = () => {
    const [draggableRef, setDraggableRef] = createSignal<HTMLElement | null>(null);

    useDraggable(draggableRef, [axis('x'), grid([10, 10])]);

    return <div ref={setDraggableRef}>Horizontal grid snapping</div>;
};

Defining plugins elsewhere with TypeScript

import { useDraggable, axis, bounds, BoundsFrom, type Plugin } from '@neodrag/solid';

export const App: Component = () => {
    const [draggableRef, setDraggableRef] = createSignal<HTMLElement | null>(null);

    const plugins: Plugin[] = [axis('y'), bounds(BoundsFrom.parent())];
    useDraggable(draggableRef, plugins);

    return <div ref={setDraggableRef}>Type-safe dragging</div>;
};

Getting drag state

import { useDraggable } from '@neodrag/solid';

export const App: Component = () => {
    const [draggableRef, setDraggableRef] = createSignal<HTMLElement | null>(null);
    const dragState = useDraggable(draggableRef);

    createEffect(() => {
        console.log('Position:', dragState().offset);
        console.log('Is dragging:', dragState().isDragging);
    });

    return <div ref={setDraggableRef}>Check console while dragging</div>;
};

Reactive plugins with createCompartment

import { createSignal } from 'solid-js';
import { useDraggable, axis, createCompartment } from '@neodrag/solid';

export const App: Component = () => {
    const [draggableRef, setDraggableRef] = createSignal<HTMLElement | null>(null);
    const [currentAxis, setCurrentAxis] = createSignal<'x' | 'y'>('x');

    const axisCompartment = createCompartment(() => axis(currentAxis()));

    useDraggable(draggableRef, [axisCompartment]);

    return (
        <div>
            <div ref={setDraggableRef}>Current axis: {currentAxis()}</div>
            <button onClick={() => setCurrentAxis(currentAxis() === 'x' ? 'y' : 'x')}>Switch Axis</button>
        </div>
    );
};

Read the docs

Credits

Inspired by react-draggable, but with a modern plugin architecture and optimized for performance.

License

MIT License © Puru Vijay