Drag & Drop

Sortable lists and tables with drag-and-drop functionality. Supports touch, mouse, and keyboard interactions with smooth animations.

Simple Drag & Drop List

Click and drag any item to reorder. Works with mouse, touch, and keyboard.

Design landing page
done
Implement authentication
in-progress
Write documentation
pending
Deploy to production
pending

Code

import { DragDropList, Badge } from '@thesage/ui';

const [tasks, setTasks] = useState([
  { id: '1', name: 'Design landing page', status: 'done' },
  { id: '2', name: 'Implement authentication', status: 'in-progress' },
  { id: '3', name: 'Write documentation', status: 'pending' },
]);

<DragDropList
  items={tasks}
  onReorder={setTasks}
  renderItem={(item, isDragging) => (
    <div className={`
      p-4 bg-surface border rounded-lg cursor-grab
      ${isDragging ? 'shadow-lg ring-2 ring-primary' : 'hover:shadow-md'}
    `}>
      <div className="flex items-center justify-between">
        <span>{item.name}</span>
        <Badge>{item.status}</Badge>
      </div>
    </div>
  )}
/>

Drag Handle

Only the handle area triggers dragging. Click elsewhere to interact with item content.

Design landing page
done
Implement authentication
in-progress
Write documentation
pending
Deploy to production
pending

Code

import { DragDropList, DragDropHandle } from '@thesage/ui';

<DragDropList
  items={tasks}
  onReorder={setTasks}
  withHandle={true}
  renderItem={(item) => (
    <div className="flex items-center gap-3 p-4 bg-surface border rounded-lg">
      {/* Drag Handle - only this triggers dragging */}
      <DragDropHandle />

      {/* Item Content */}
      <div className="flex-1">
        <span>{item.name}</span>
      </div>

      {/* Interactive Button (won't trigger drag) */}
      <button onClick={() => deleteItem(item.id)}>
        Delete
      </button>
    </div>
  )}
/>

Sortable Table

Reorder table rows by dragging the handle in the first column.

NameEmailRole
Alice Johnsonalice@example.com
Designer
Bob Smithbob@example.com
Developer
Carol Whitecarol@example.com
Product Manager
David Browndavid@example.com
Engineer

Code

import { DragDropTable, Badge } from '@thesage/ui';

const [people, setPeople] = useState([
  { id: '1', name: 'Alice Johnson', email: 'alice@example.com', role: 'Designer' },
  { id: '2', name: 'Bob Smith', email: 'bob@example.com', role: 'Developer' },
]);

<DragDropTable
  items={people}
  onReorder={setPeople}
  columns={[
    { key: 'name', header: 'Name' },
    { key: 'email', header: 'Email' },
    {
      key: 'role',
      header: 'Role',
      render: (item) => <Badge>{item.role}</Badge>,
    },
  ]}
/>

API Reference

DragDropList Props

items

Array of items to display. Each item must have an id string property.

onReorder

Callback fired when items are reordered. Receives the new array.

renderItem

Function to render each item. Receives (item, isDragging) parameters.

withHandle (optional)

Enable drag handle mode. Default: false

DragDropTable Props

columns

Array of column configurations with key, header, and optional render function.

Features

  • Touch Support: Works on mobile devices with swipe gestures
  • Keyboard Accessible: Use arrow keys and Space to reorder
  • Smooth Animations: Built-in transition effects during drag
  • Drag Overlay: Visual feedback shows dragged item