An open API service indexing awesome lists of open source software.

https://github.com/obsfx/react-optimized-dnd

A React package for building performant drag-and-drop interfaces.
https://github.com/obsfx/react-optimized-dnd

board component context dnd drag-and-drop draggable droppable hooks kanban library performant react react-dnd trello typescript

Last synced: 6 months ago
JSON representation

A React package for building performant drag-and-drop interfaces.

Awesome Lists containing this project

README

          

# react-optimized-dnd

A React package for building performant drag-and-drop interfaces. Provides context provider, hooks, and type definitions for flexible, optimized DnD in React apps.

## Features

- Simple API: Provider and hooks for drag-and-drop
- Optimized for React performance
- TypeScript support
- No external dependencies

## Installation

```
npm install react-optimized-dnd
```

or

```
yarn add react-optimized-dnd
```

## Usage Example

Below is a minimal Trello-like board with draggable cards and droppable columns.

```tsx
import { useState } from 'react';
import { ReactOptimizedDndProvider, useDraggable, useDroppable } from 'react-optimized-dnd';

const columnsData = [
[
{ title: 'Card 1', description: 'Desc 1', color: '#60a5fa' },
{ title: 'Card 2', description: 'Desc 2', color: '#f59e42' },
],
[{ title: 'Card 3', description: 'Desc 3', color: '#10b981' }],
[{ title: 'Card 4', description: 'Desc 4', color: '#f43f5e' }],
];

function Card({ index, columnIndex, title, description, color }) {
const { droppableRef, isOver } = useDroppable({ data: { index, columnIndex, type: 'card' } });
const { handleRef, deltaPos, isDragging } = useDraggable({
data: { index, columnIndex, type: 'card' },
});
return (





{title.charAt(0)}


{title}

{description}





);
}

function Column({ children, index }) {
const { droppableRef, isOver } = useDroppable({ data: { index, type: 'column' } });
return (


{children}
{isOver && (

)}

);
}

export default function Example() {
const [columns, setColumns] = useState(columnsData);
return (


{}}
onDragEnd={(state) => {
const dragging = state.draggingElement.data;
const over = state.overElement.data;
if (!dragging || !over) return;
if (over.type === 'card') {
const newColumns = [...columns];
const targetCol = over.columnIndex;
const targetIdx = over.index;
const dragCol = dragging.columnIndex;
const dragIdx = dragging.index;
const item = newColumns[dragCol][dragIdx];
newColumns[dragCol] = newColumns[dragCol].filter((_, i) => i !== dragIdx);
newColumns[targetCol].splice(targetIdx, 0, item);
setColumns(newColumns);
return;
}
if (over.type === 'column') {
const newColumns = [...columns];
const targetCol = over.index;
const dragCol = dragging.columnIndex;
const dragIdx = dragging.index;
const item = newColumns[dragCol][dragIdx];
newColumns[dragCol] = newColumns[dragCol].filter((_, i) => i !== dragIdx);
newColumns[targetCol] = [...newColumns[targetCol], item];
setColumns(newColumns);
return;
}
}}
onDragOver={() => {}}
>
{columns.map((column, columnIndex) => (

{column.map((item, cardIndex) => (

))}

))}


);
}
```

## API

### `ReactOptimizedDndProvider`

Wrap your app or a subtree to enable drag-and-drop. Accepts optional callbacks:

- `onDragStart: (state) => void`
- `onDragEnd: (state) => void`
- `onDragOver: (state) => void`

### `useDraggable`

Hook to make an element draggable.

- `data`: Any object to identify the draggable (required)
- Returns: `{ handleRef, deltaPos, isDragging }`

### `useDroppable`

Hook to make an element a drop target.

- `data`: Any object to identify the droppable (required)
- Returns: `{ droppableRef, isOver }`

## License

MIT