Appearance
Drag and Drop Components
Purpose
These components provide consistent UI for drag and drop interactions:
- DraggableItem — Wrapper for sortable items
- DragHandle — Accessible drag trigger
- DroppableZone — Drop target with visual feedback
- SortableList — Container for sortable items
- EmptyDropZone — Placeholder for empty drop areas
Built on @dnd-kit for accessible, performant drag and drop.
When to use
Use these components with the useDragAndDrop hooks for:
- Sortable lists and tables
- Kanban boards
- Reorderable navigation items
- File organization interfaces
DraggableItem
Wrapper that makes an element draggable and sortable.
tsx
import { DraggableItem } from '@/shared/ui/components/DragAndDrop'
<DraggableItem id={item.id}>
<div className="p-4 border rounded">
{item.title}
</div>
</DraggableItem>Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | UniqueIdentifier | Required | Unique item ID |
children | ReactNode | Required | Item content |
data | Record<string, unknown> | - | Additional drag data |
disabled | boolean | false | Disable dragging |
isOverlay | boolean | false | Render as drag overlay |
DragHandle
A dedicated drag trigger when only part of an item should be draggable.
tsx
import { DragHandle } from '@/shared/ui/components/DragAndDrop'
import { GripVertical } from 'lucide-react'
<DragHandle listeners={listeners} attributes={attributes}>
<GripVertical className="h-4 w-4" />
</DragHandle>Props
| Prop | Type | Description |
|---|---|---|
listeners | SortableListeners | From useSortable |
attributes | SortableAttributes | From useSortable |
disabled | boolean | Disable the handle |
DroppableZone
A container that accepts dropped items with visual feedback.
tsx
import { DroppableZone } from '@/shared/ui/components/DragAndDrop'
<DroppableZone id="column-1" isOver={isOverColumn1}>
{items.map(item => <DraggableItem key={item.id} id={item.id} />)}
</DroppableZone>Props
| Prop | Type | Description |
|---|---|---|
id | UniqueIdentifier | Zone identifier |
isOver | boolean | Whether being dragged over |
children | ReactNode | Zone content |
SortableList
A generic container for sortable items.
tsx
import { SortableList } from '@/shared/ui/components/DragAndDrop'
<SortableList
items={tasks}
getItemId={(task) => task.id}
renderItem={(task) => <TaskCard task={task} />}
direction="vertical"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | Required | Items array |
getItemId | (item: T) => UniqueIdentifier | Required | ID extractor |
renderItem | (item: T, index: number) => ReactNode | Required | Item renderer |
direction | 'vertical' | 'horizontal' | 'vertical' | List direction |
EmptyDropZone
Placeholder for empty droppable areas.
tsx
import { EmptyDropZone } from '@/shared/ui/components/DragAndDrop'
<EmptyDropZone message="Drop tasks here" isOver={isOver} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
message | string | 'Drop items here' | Placeholder text |
isOver | boolean | false | Highlight when dragged over |
Related
- useDragAndDrop — Hooks for drag and drop state