react-dragdrop-kit 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -253
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/kanban.esm.js +1 -1
- package/dist/kanban.esm.js.map +1 -1
- package/dist/kanban.js +1 -1
- package/dist/kanban.js.map +1 -1
- package/dist/src/components/DragDropList.d.ts +1 -1
- package/dist/src/components/DraggableItemWrapper.d.ts +1 -1
- package/dist/src/hooks/useDragDropMonitor.d.ts +7 -2
- package/dist/src/hooks/useDragDropMonitor.logic.d.ts +39 -0
- package/dist/src/kanban/types.d.ts +3 -1
- package/dist/src/kanban/utils/reorder.d.ts +6 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/utils/order.d.ts +7 -0
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -1,70 +1,97 @@
|
|
|
1
1
|
# react-dragdrop-kit
|
|
2
2
|
|
|
3
|
-
A flexible
|
|
3
|
+
A flexible, lightweight drag-and-drop toolkit for React.
|
|
4
|
+
Build sortable lists, grids, and Kanban boards with a controlled API and minimal overhead.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
[](https://www.npmjs.com/package/react-dragdrop-kit)
|
|
7
|
+
[](https://www.npmjs.com/package/react-dragdrop-kit)
|
|
8
|
+
[](https://www.npmjs.com/package/react-dragdrop-kit)
|
|
9
|
+
[](https://github.com/Yourstruggle11/react-dragdrop-kit)
|
|
10
|
+
[](https://deepwiki.com/Yourstruggle11/react-dragdrop-kit)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## Why this library
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
`react-dragdrop-kit` is designed around a controlled data model:
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- 🧩 **Custom render** per item (cards, compact, detailed… anything)
|
|
19
|
-
- 🧲 **Drop indicator** + optional **custom drag preview**
|
|
16
|
+
- You own state.
|
|
17
|
+
- The library reports drag intent and reorder results.
|
|
18
|
+
- You decide what to persist and render.
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
20
|
+
This keeps behavior predictable and easy to integrate with app-specific rules.
|
|
21
|
+
|
|
22
|
+
## Feature overview
|
|
23
|
+
|
|
24
|
+
### List and grid drag-and-drop
|
|
25
|
+
|
|
26
|
+
- Vertical and horizontal list support
|
|
27
|
+
- Controlled reorder callback: `onReorder(newItems, orderUpdates)`
|
|
28
|
+
- Optional visual drop indicator
|
|
29
|
+
- Optional custom drag preview style/class
|
|
30
|
+
- Optional handle-only dragging via `dragHandle`
|
|
31
|
+
- Optional multi-item drag with `selectedIds` + `multiDragEnabled`
|
|
32
|
+
- Optional live list reordering during drag-over via `liveReorder`
|
|
33
|
+
|
|
34
|
+
### Kanban module
|
|
35
|
+
|
|
36
|
+
- Card reorder within columns
|
|
37
|
+
- Card movement across columns
|
|
38
|
+
- Column reordering
|
|
39
|
+
- Headless rendering (`renderColumn`, `renderCard`)
|
|
40
|
+
- Accessibility helpers (`AnnouncerProvider`, `useAnnouncer`, `announcements`)
|
|
41
|
+
- Keyboard drag-reorder is planned, not fully shipped yet
|
|
42
|
+
- Live-reorder preview for Kanban is not shipped yet (drop-commit only)
|
|
28
43
|
|
|
29
44
|
### General
|
|
30
|
-
- 🧪 **TypeScript** types included
|
|
31
|
-
- ⚡ **Tiny bundles** (~5KB main, ~9KB Kanban)
|
|
32
|
-
- 🎨 **Framework agnostic styling** - Works with Tailwind, MUI, Chakra, etc.
|
|
33
|
-
- 📚 **Comprehensive documentation**
|
|
34
45
|
|
|
35
|
-
|
|
46
|
+
- TypeScript-first API
|
|
47
|
+
- Lightweight runtime and tree-shakeable exports
|
|
48
|
+
- Built on `@atlaskit/pragmatic-drag-and-drop`
|
|
36
49
|
|
|
37
|
-
##
|
|
50
|
+
## Installation
|
|
38
51
|
|
|
39
52
|
```bash
|
|
40
|
-
npm
|
|
41
|
-
# or
|
|
42
|
-
yarn add react-dragdrop-kit
|
|
53
|
+
npm install react-dragdrop-kit
|
|
43
54
|
# or
|
|
44
55
|
pnpm add react-dragdrop-kit
|
|
56
|
+
# or
|
|
57
|
+
yarn add react-dragdrop-kit
|
|
45
58
|
```
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
## Package entry points
|
|
48
61
|
|
|
49
|
-
|
|
62
|
+
```ts
|
|
63
|
+
import { DragDropList } from "react-dragdrop-kit";
|
|
64
|
+
```
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
```ts
|
|
67
|
+
import { KanbanBoard, applyDragResult } from "react-dragdrop-kit/kanban";
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Quick start: sortable list
|
|
52
71
|
|
|
53
72
|
```tsx
|
|
54
73
|
import { useState } from "react";
|
|
55
74
|
import { DragDropList } from "react-dragdrop-kit";
|
|
56
75
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
interface Todo {
|
|
77
|
+
id: string;
|
|
78
|
+
position: number;
|
|
79
|
+
title: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default function TodoList() {
|
|
83
|
+
const [items, setItems] = useState<Todo[]>([
|
|
84
|
+
{ id: "1", position: 0, title: "Design" },
|
|
85
|
+
{ id: "2", position: 1, title: "Build" },
|
|
86
|
+
{ id: "3", position: 2, title: "Ship" },
|
|
62
87
|
]);
|
|
63
88
|
|
|
64
89
|
return (
|
|
65
90
|
<DragDropList
|
|
66
91
|
items={items}
|
|
67
|
-
onReorder={(next) =>
|
|
92
|
+
onReorder={(next) =>
|
|
93
|
+
setItems(next.map((item, index) => ({ ...item, position: index })))
|
|
94
|
+
}
|
|
68
95
|
renderItem={(item) => (
|
|
69
96
|
<div style={{ padding: 12, border: "1px solid #e5e7eb", borderRadius: 8 }}>
|
|
70
97
|
{item.title}
|
|
@@ -77,261 +104,191 @@ function App() {
|
|
|
77
104
|
}
|
|
78
105
|
```
|
|
79
106
|
|
|
80
|
-
|
|
107
|
+
## Quick start: drag handle and multi-drag
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
<DragDropList
|
|
111
|
+
items={items}
|
|
112
|
+
onReorder={handleReorder}
|
|
113
|
+
renderItem={renderItem}
|
|
114
|
+
dragHandle="[data-drag-handle]"
|
|
115
|
+
selectedIds={selectedIds}
|
|
116
|
+
multiDragEnabled
|
|
117
|
+
liveReorder
|
|
118
|
+
/>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Behavior notes:
|
|
122
|
+
|
|
123
|
+
- `dragHandle` is optional. If provided, drag starts only from matching descendants.
|
|
124
|
+
- `multiDragEnabled` is opt-in. Without it, behavior remains single-item drag.
|
|
125
|
+
- `selectedIds` is consumed only when multi-drag is enabled.
|
|
126
|
+
- `liveReorder` is opt-in. Without it, reorder commits on drop (existing behavior).
|
|
127
|
+
|
|
128
|
+
## Quick start: Kanban board
|
|
81
129
|
|
|
82
130
|
```tsx
|
|
83
|
-
import { useState } from
|
|
131
|
+
import { useCallback, useState } from "react";
|
|
84
132
|
import {
|
|
85
133
|
KanbanBoard,
|
|
86
134
|
applyDragResult,
|
|
87
|
-
|
|
88
|
-
|
|
135
|
+
type DropResult,
|
|
136
|
+
type KanbanBoardState,
|
|
137
|
+
} from "react-dragdrop-kit/kanban";
|
|
89
138
|
|
|
90
|
-
function
|
|
91
|
-
const [state, setState] = useState({
|
|
139
|
+
export default function Board() {
|
|
140
|
+
const [state, setState] = useState<KanbanBoardState>({
|
|
92
141
|
columns: [
|
|
93
|
-
{ id:
|
|
94
|
-
{ id:
|
|
142
|
+
{ id: "todo", title: "To Do", cardIds: ["task-1", "task-2"] },
|
|
143
|
+
{ id: "done", title: "Done", cardIds: [] },
|
|
95
144
|
],
|
|
96
145
|
cards: {
|
|
97
|
-
|
|
98
|
-
|
|
146
|
+
"task-1": { id: "task-1", title: "Design landing page" },
|
|
147
|
+
"task-2": { id: "task-2", title: "Implement auth" },
|
|
99
148
|
},
|
|
100
149
|
});
|
|
101
150
|
|
|
102
|
-
const handleDragEnd = (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<AnnouncerProvider>
|
|
109
|
-
<KanbanBoard
|
|
110
|
-
state={state}
|
|
111
|
-
onDragEnd={handleDragEnd}
|
|
112
|
-
renderColumn={(col) => <div style={{ padding: 16 }}>{col.title}</div>}
|
|
113
|
-
renderCard={(card) => (
|
|
114
|
-
<div style={{ padding: 12, background: '#fff', borderRadius: 8 }}>
|
|
115
|
-
{card.title}
|
|
116
|
-
</div>
|
|
117
|
-
)}
|
|
118
|
-
/>
|
|
119
|
-
</AnnouncerProvider>
|
|
151
|
+
const handleDragEnd = useCallback(
|
|
152
|
+
(result: DropResult, stateBefore: KanbanBoardState) => {
|
|
153
|
+
if (!result.destination) return;
|
|
154
|
+
setState(applyDragResult(stateBefore, result));
|
|
155
|
+
},
|
|
156
|
+
[]
|
|
120
157
|
);
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## 🎨 Styled Examples
|
|
127
|
-
|
|
128
|
-
### With Tailwind CSS
|
|
129
|
-
|
|
130
|
-
```tsx
|
|
131
|
-
import { DragDropList } from "react-dragdrop-kit";
|
|
132
|
-
|
|
133
|
-
export default function TailwindExample() {
|
|
134
|
-
const [items, setItems] = useState([
|
|
135
|
-
{ id: "1", position: 0, name: "Dashboard", icon: "📊" },
|
|
136
|
-
{ id: "2", position: 1, name: "Projects", icon: "📁" },
|
|
137
|
-
{ id: "3", position: 2, name: "Team", icon: "👥" },
|
|
138
|
-
]);
|
|
139
158
|
|
|
140
159
|
return (
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
showDropIndicator
|
|
147
|
-
dropIndicatorClassName="bg-blue-500"
|
|
148
|
-
renderItem={(item) => (
|
|
149
|
-
<div className="flex items-center p-4 space-x-3">
|
|
150
|
-
<span className="text-2xl">{item.icon}</span>
|
|
151
|
-
<span className="font-medium text-gray-700">{item.name}</span>
|
|
152
|
-
</div>
|
|
153
|
-
)}
|
|
160
|
+
<KanbanBoard
|
|
161
|
+
state={state}
|
|
162
|
+
onDragEnd={handleDragEnd}
|
|
163
|
+
renderColumn={(column) => <div style={{ padding: 12 }}>{column.title}</div>}
|
|
164
|
+
renderCard={(card) => <div style={{ padding: 12 }}>{card.title}</div>}
|
|
154
165
|
/>
|
|
155
166
|
);
|
|
156
167
|
}
|
|
157
168
|
```
|
|
158
169
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
## 📚 API Reference
|
|
162
|
-
|
|
163
|
-
### DragDropList Component
|
|
164
|
-
|
|
165
|
-
| Prop | Type | Default | Description |
|
|
166
|
-
| ------------------------ | --------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------ |
|
|
167
|
-
| `items` | `Array<DraggableItem & T>` | — | Items to render. Must include `{ id: string; position: number }`. |
|
|
168
|
-
| `onReorder` | `(next: T[], updates: OrderUpdate[]) => void` | — | Called after drop. `next` is the new array; `updates` has id + newPosition. |
|
|
169
|
-
| `renderItem` | `(item: T) => React.ReactNode` | — | Custom renderer for each item. |
|
|
170
|
-
| `direction` | `"vertical" \| "horizontal"` | `"vertical"` | Drag axis + layout. |
|
|
171
|
-
| `gap` | `number` | `0` | Gap (px) between items. |
|
|
172
|
-
| `disabled` | `boolean` | `false` | Disable dragging. |
|
|
173
|
-
| `showDropIndicator` | `boolean` | `false` | Show a drop indicator while dragging. |
|
|
174
|
-
| `dropIndicatorPosition` | `"top" \| "bottom"` | `"bottom"` | Position of drop indicator relative to target item. |
|
|
175
|
-
| `dropIndicatorClassName` | `string` | — | CSS class applied to the drop indicator element. |
|
|
176
|
-
| `dragPreviewStyle` | `React.CSSProperties` | — | Inline styles for custom drag preview. |
|
|
177
|
-
| `containerClassName` | `string` | — | Class applied to the container. |
|
|
178
|
-
| `itemClassName` | `string` | — | Class applied to each item wrapper. |
|
|
179
|
-
|
|
180
|
-
### Kanban Components
|
|
181
|
-
|
|
182
|
-
See the [Kanban Documentation](./docs/kanban.md) for complete API reference, including:
|
|
183
|
-
- `KanbanBoard` - High-level component
|
|
184
|
-
- `KanbanColumnView` - Headless column component
|
|
185
|
-
- `KanbanCardView` - Headless card component
|
|
186
|
-
- `AnnouncerProvider` - Accessibility provider
|
|
187
|
-
- Helper utilities and types
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## 🗂️ Kanban Board Features
|
|
192
|
-
|
|
193
|
-
### Core Functionality
|
|
194
|
-
- ✅ **Drag cards** within and between columns
|
|
195
|
-
- ✅ **Reorder columns** by dragging headers
|
|
196
|
-
- ✅ **Empty column support** - Drop into columns with no cards
|
|
197
|
-
- ✅ **Cancel drag** - Drop outside board to cancel
|
|
198
|
-
- ✅ **Normalized state** - Efficient data structure
|
|
199
|
-
|
|
200
|
-
### Accessibility (a11y)
|
|
201
|
-
- ♿ **Screen reader support** with live announcements
|
|
202
|
-
- 🎹 **Keyboard navigation** (infrastructure ready)
|
|
203
|
-
- 🏷️ **Proper ARIA attributes**
|
|
204
|
-
- 📢 **Context-aware messages**
|
|
205
|
-
|
|
206
|
-
### Developer Experience
|
|
207
|
-
- 📘 **Full TypeScript support**
|
|
208
|
-
- 🎨 **Headless architecture** - Style with any framework
|
|
209
|
-
- 🔧 **Helper utilities** - `applyDragResult`, reorder functions
|
|
210
|
-
- 📖 **Migration guide** from react-beautiful-dnd
|
|
211
|
-
|
|
212
|
-
### Customization
|
|
213
|
-
The Kanban board is completely headless, giving you full control:
|
|
214
|
-
- Custom card designs
|
|
215
|
-
- Custom column headers
|
|
216
|
-
- Theme support
|
|
217
|
-
- Animation styles
|
|
218
|
-
- Responsive layouts
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## 📂 Examples
|
|
223
|
-
|
|
224
|
-
This repo includes comprehensive examples:
|
|
225
|
-
|
|
226
|
-
### Drag & Drop Lists
|
|
227
|
-
* [Basic Example](./examples/basic-example.tsx)
|
|
228
|
-
* [Tailwind Example](./examples/tailwind-example.tsx)
|
|
229
|
-
* [Material UI Example](./examples/material-ui-example.tsx)
|
|
230
|
-
* [Advanced Features](./examples/advanced-features.tsx)
|
|
231
|
-
* [Styled Components](./examples/styled-components-example.tsx)
|
|
232
|
-
|
|
233
|
-
### Kanban Boards
|
|
234
|
-
* [Basic Kanban](./examples/kanban/basic-kanban.tsx)
|
|
235
|
-
* [Rich Cards with Tags & Avatars](./examples/kanban/rich-cards-kanban.tsx)
|
|
236
|
-
* [Multi-theme Kanban](./examples/kanban/themed-kanban.tsx)
|
|
237
|
-
* [Kanban with Accessibility](./examples/kanban/accessible-kanban.tsx)
|
|
238
|
-
|
|
239
|
-
👉 Explore the [`examples/`](./examples) folder for the complete code.
|
|
170
|
+
## API reference: list module
|
|
240
171
|
|
|
241
|
-
|
|
172
|
+
### Core types
|
|
242
173
|
|
|
243
|
-
|
|
174
|
+
```ts
|
|
175
|
+
type DraggableItem = {
|
|
176
|
+
id: string;
|
|
177
|
+
position: number;
|
|
178
|
+
[key: string]: any;
|
|
179
|
+
};
|
|
244
180
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
import type { DraggableItem, OrderUpdate, KanbanBoardState, DropResult } from 'react-dragdrop-kit';
|
|
251
|
-
import type { KanbanCard, KanbanColumn } from 'react-dragdrop-kit/kanban';
|
|
252
|
-
|
|
253
|
-
// Extend with custom fields
|
|
254
|
-
interface TodoItem extends DraggableItem {
|
|
255
|
-
title: string;
|
|
256
|
-
completed: boolean;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
interface ProjectCard extends KanbanCard {
|
|
260
|
-
priority: 'low' | 'medium' | 'high';
|
|
261
|
-
assignee: string;
|
|
262
|
-
tags: string[];
|
|
263
|
-
}
|
|
181
|
+
type OrderUpdate = {
|
|
182
|
+
id: string;
|
|
183
|
+
newPosition: number;
|
|
184
|
+
moved?: boolean;
|
|
185
|
+
};
|
|
264
186
|
```
|
|
265
187
|
|
|
266
|
-
###
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
|
275
|
-
|
|
276
|
-
| `
|
|
277
|
-
| `
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
188
|
+
### DragDropList props
|
|
189
|
+
|
|
190
|
+
| Prop | Type | Default | Description |
|
|
191
|
+
| --- | --- | --- | --- |
|
|
192
|
+
| `items` | `T[]` | Required | Controlled items. Each item must include `id` and `position`. |
|
|
193
|
+
| `onReorder` | `(newItems: T[], orderUpdates: OrderUpdate[]) => void` | Required | Fired after successful drop/reorder. |
|
|
194
|
+
| `renderItem` | `(item: T, index: number) => ReactNode` | Required | Item renderer. |
|
|
195
|
+
| `containerClassName` | `string` | `""` | Class name for container. |
|
|
196
|
+
| `containerStyle` | `React.CSSProperties` | `{}` | Inline style for container. |
|
|
197
|
+
| `itemClassName` | `string` | `""` | Class for each draggable wrapper. |
|
|
198
|
+
| `itemStyle` | `React.CSSProperties` | `{}` | Style for each draggable wrapper. |
|
|
199
|
+
| `dragPreviewClassName` | `string` | `""` | Class for generated drag preview. |
|
|
200
|
+
| `dragPreviewStyle` | `React.CSSProperties` | `{}` | Style for generated drag preview. |
|
|
201
|
+
| `onDragStart` | `(item: T, index: number) => void` | `undefined` | Callback on item drag start. |
|
|
202
|
+
| `onDragEnd` | `(item: T, index: number) => void` | `undefined` | Callback on item drag end. |
|
|
203
|
+
| `disabled` | `boolean` | `false` | Disables list drag/drop. |
|
|
204
|
+
| `gap` | `number \| string` | `undefined` | Gap applied to container. |
|
|
205
|
+
| `direction` | `"vertical" \| "horizontal"` | `"vertical"` | Layout and closest-edge interpretation. |
|
|
206
|
+
| `showDropIndicator` | `boolean` | `false` | Enables drop indicator line. |
|
|
207
|
+
| `dropIndicatorClassName` | `string` | `""` | Class for drop indicator. |
|
|
208
|
+
| `dropIndicatorStyle` | `React.CSSProperties` | `{}` | Style for drop indicator. |
|
|
209
|
+
| `dropIndicatorPosition` | `"top" \| "bottom"` | `"bottom"` | Indicator position for hovered target item. |
|
|
210
|
+
| `dragHandle` | `string` | `undefined` | CSS selector for handle-only dragging. |
|
|
211
|
+
| `selectedIds` | `string[]` | `[]` | Selected IDs used by multi-drag. |
|
|
212
|
+
| `multiDragEnabled` | `boolean` | `false` | Enables grouped drag behavior. |
|
|
213
|
+
| `liveReorder` | `boolean` | `false` | Reorders list in real time during drag-over. |
|
|
214
|
+
|
|
215
|
+
## API reference: Kanban module
|
|
216
|
+
|
|
217
|
+
The full Kanban API is documented in [docs/kanban.md](./docs/kanban.md).
|
|
218
|
+
|
|
219
|
+
Exports:
|
|
220
|
+
|
|
221
|
+
- Components: `KanbanBoard`, `KanbanColumnView`, `KanbanCardView`
|
|
222
|
+
- Hooks: `useKanbanDnd`, `useAutoscroll`
|
|
223
|
+
- A11y: `AnnouncerProvider`, `useAnnouncer`, `announcements`
|
|
224
|
+
- Utils: `applyDragResult`, `reorderArray`
|
|
225
|
+
- Types: `KanbanBoardState`, `DropResult`, `KanbanCard`, `KanbanColumn`, and more
|
|
226
|
+
|
|
227
|
+
## Examples
|
|
228
|
+
|
|
229
|
+
### Repository examples
|
|
230
|
+
|
|
231
|
+
- `examples/basic-example.tsx`
|
|
232
|
+
- `examples/advanced-features.tsx`
|
|
233
|
+
- `examples/material-ui-example.tsx`
|
|
234
|
+
- `examples/tailwind-example.tsx`
|
|
235
|
+
- `examples/kanban/basic-kanban.tsx`
|
|
236
|
+
- `examples/kanban/rich-cards-kanban.tsx`
|
|
237
|
+
- `examples/kanban/themed-kanban.tsx`
|
|
238
|
+
- `examples/kanban/accessible-kanban.tsx`
|
|
239
|
+
|
|
240
|
+
### Demo examples
|
|
241
|
+
|
|
242
|
+
- List/grid examples under `apps/demo/src/examples/*`
|
|
243
|
+
- Kanban demos:
|
|
244
|
+
- `apps/demo/src/examples/BasicKanban/index.tsx`
|
|
245
|
+
- `apps/demo/src/examples/RichKanban/index.tsx`
|
|
246
|
+
- `apps/demo/src/examples/SwimlanesKanban/index.tsx`
|
|
247
|
+
- `apps/demo/src/examples/WipLimitsKanban/index.tsx`
|
|
248
|
+
|
|
249
|
+
## Migration notes
|
|
284
250
|
|
|
285
251
|
### From react-beautiful-dnd
|
|
286
252
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
Key differences:
|
|
290
|
-
- Normalized state structure
|
|
291
|
-
- No auto-generated IDs
|
|
292
|
-
- Render props instead of children
|
|
293
|
-
- Better TypeScript support
|
|
294
|
-
|
|
295
|
-
---
|
|
296
|
-
|
|
297
|
-
## 🤝 Contributing
|
|
253
|
+
High-level mapping for Kanban use cases:
|
|
298
254
|
|
|
299
|
-
|
|
255
|
+
- `DragDropContext` -> `KanbanBoard`
|
|
256
|
+
- `Droppable` -> `KanbanColumnView`
|
|
257
|
+
- `Draggable` -> `KanbanCardView`
|
|
300
258
|
|
|
301
|
-
|
|
259
|
+
Important differences:
|
|
302
260
|
|
|
303
|
-
|
|
261
|
+
1. State is normalized (`columns` + `cards`) instead of nested.
|
|
262
|
+
2. IDs are explicit and owned by your app.
|
|
263
|
+
3. Rendering is done via render functions (`renderColumn`, `renderCard`).
|
|
304
264
|
|
|
305
|
-
|
|
265
|
+
## Development notes
|
|
306
266
|
|
|
307
|
-
|
|
267
|
+
### React Strict Mode
|
|
308
268
|
|
|
309
|
-
|
|
269
|
+
In development, React Strict Mode can mount effects twice.
|
|
270
|
+
Ensure listener setup and cleanup are idempotent when integrating custom logic.
|
|
310
271
|
|
|
311
|
-
|
|
312
|
-
- [`@atlaskit/pragmatic-drag-and-drop`](https://atlassian.design/components/pragmatic-drag-and-drop) - Performance-focused drag and drop
|
|
313
|
-
- Inspired by `react-beautiful-dnd` API design
|
|
314
|
-
- Community feedback and contributions
|
|
272
|
+
## Bundle size
|
|
315
273
|
|
|
316
|
-
|
|
274
|
+
Approximate minified sizes:
|
|
317
275
|
|
|
318
|
-
|
|
276
|
+
- `react-dragdrop-kit`: about 5KB
|
|
277
|
+
- `react-dragdrop-kit/kanban`: about 9KB
|
|
319
278
|
|
|
320
|
-
|
|
321
|
-
- [CHANGELOG](./CHANGELOG.md)
|
|
322
|
-
- [Examples](./examples/)
|
|
323
|
-
- [Demo Application](https://react-dragdrop-kit.netlify.app/)
|
|
279
|
+
## Documentation and links
|
|
324
280
|
|
|
325
|
-
|
|
281
|
+
- [Kanban guide](./docs/kanban.md)
|
|
282
|
+
- [Known issues](./KNOWN_ISSUES.md)
|
|
283
|
+
- [Changelog](./packages/react-dragdrop-kit/CHANGELOG.md)
|
|
284
|
+
- [Examples folder](./examples)
|
|
285
|
+
- [Demo app](https://react-dragdrop-kit.netlify.app/)
|
|
326
286
|
|
|
327
|
-
##
|
|
287
|
+
## Support
|
|
328
288
|
|
|
329
|
-
-
|
|
330
|
-
-
|
|
331
|
-
- ⭐ [Star on GitHub](https://github.com/Yourstruggle11/react-dragdrop-kit)
|
|
289
|
+
- [Report issues](https://github.com/Yourstruggle11/react-dragdrop-kit/issues)
|
|
290
|
+
- [Request features](https://github.com/Yourstruggle11/react-dragdrop-kit/issues/new)
|
|
332
291
|
|
|
333
|
-
|
|
292
|
+
## License
|
|
334
293
|
|
|
335
|
-
|
|
336
|
-
<strong>Made with ❤️ by <a href="https://github.com/Yourstruggle11" target="_blank" rel="noopener noreferrer">Yourstruggle11</a> for the React community</strong>
|
|
337
|
-
</div>
|
|
294
|
+
MIT
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e,{useRef as t,useState as a,useCallback as r,useEffect as o}from"react";import{combine as i}from"@atlaskit/pragmatic-drag-and-drop/combine";import{draggable as n,dropTargetForElements as d,monitorForElements as s}from"@atlaskit/pragmatic-drag-and-drop/element/adapter";import{extractClosestEdge as l}from"@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";const c={container:{default:{minHeight:"200px",transition:"all 0.2s ease",borderRadius:"8px",border:"1px solid #e2e8f0",backgroundColor:"#ffffff",display:"flex",flexDirection:"column",gap:"16px",padding:"16px"},dragging:{backgroundColor:"rgba(66, 153, 225, 0.05)",borderColor:"#3182ce"},horizontal:{flexDirection:"row",flexWrap:"wrap"}},item:{default:{transition:"all 0.2s ease",cursor:"grab",userSelect:"none",position:"relative"},dragging:{opacity:.5,cursor:"grabbing"},hover:{transform:"scale(1.02)",boxShadow:"0 4px 6px rgba(0, 0, 0, 0.1)"},disabled:{cursor:"not-allowed",opacity:.6}},preview:{position:"fixed",pointerEvents:"none",zIndex:9999,opacity:.8,transform:"rotate(2deg)",boxShadow:"0 10px 20px rgba(0, 0, 0, 0.15)"},dropIndicator:{position:"absolute",height:"2px",backgroundColor:"#3182ce",left:0,right:0,zIndex:10,transition:"all 0.2s ease"}},g="draggable-item";function p({item:s,index:l,children:p,className:m="",style:u={},dragPreviewClassName:b="",dragPreviewStyle:v={},onDragStart:f,onDragEnd:x,disabled:y=!1,showDropIndicator:D=!1,dropIndicatorClassName:h="",dropIndicatorStyle:I={},dropIndicatorPosition:j="bottom"}){const O=t(null),[w,S]=a(!1),[N,C]=a(!1),[E,P]=a(null),k=r(e=>y?()=>{}:n({element:e,getInitialData:()=>({type:g,id:s.id,index:l}),onGenerateDragPreview:({nativeSetDragImage:t})=>{const a=e.cloneNode(!0),r=Object.assign(Object.assign({},c.preview),v);b&&(a.className=b),Object.assign(a.style,r,{width:`${(null==e?void 0:e.offsetWidth)||100}px`,height:`${(null==e?void 0:e.offsetHeight)||50}px`}),document.body.appendChild(a),t&&t(a,20,20),requestAnimationFrame(()=>a.remove())},onDragStart:()=>{S(!0),null==f||f(s,l)},onDrop:()=>{S(!1),null==x||x(s,l)}}),[s,l,b,v,f,x,y]),z=r(e=>y?()=>{}:d({element:e,getData:()=>({type:g,id:s.id,index:l}),canDrop:e=>{var t;return(null===(t=e.source.data)||void 0===t?void 0:t.type)===g},getIsSticky:()=>!0,onDragEnter:({source:e,self:t})=>{var a,r;(null===(a=e.data)||void 0===a?void 0:a.id)!==(null===(r=t.data)||void 0===r?void 0:r.id)&&(C(!0),D&&P(j))},onDragLeave:()=>{C(!1),P(null)},onDrop:()=>{C(!1),P(null)}}),[s.id,l,y,D,j]);return o(()=>{const e=O.current;if(e)return e.setAttribute("data-index",l.toString()),y?()=>{}:i(k(e),z(e))},[l,k,z,y]),e.createElement("div",{ref:O,className:m,style:(()=>{const e=Object.assign({},c.item.default);return y?Object.assign(e,c.item.disabled):w?Object.assign(e,c.item.dragging):N&&Object.assign(e,c.item.hover),Object.assign(Object.assign({},e),u)})()},D&&"top"===E&&e.createElement("div",{className:h,style:Object.assign(Object.assign(Object.assign({},c.dropIndicator),I),{top:-1})}),p,D&&"bottom"===E&&e.createElement("div",{className:h,style:Object.assign(Object.assign(Object.assign({},c.dropIndicator),I),{bottom:-1})}))}function m({items:e,onReorder:t,disabled:a=!1}){if(a)return()=>{};return s({onDrop:({location:a,source:r})=>{var o;const i=null===(o=r.data)||void 0===o?void 0:o.index;if(void 0===i)return;const{dropTargets:n}=a.current,d=n.find(e=>{var t,a,o;return"draggable-item"===(null===(t=e.data)||void 0===t?void 0:t.type)&&(null===(a=e.data)||void 0===a?void 0:a.id)!==(null===(o=r.data)||void 0===o?void 0:o.id)});if(!d)return;const s=l(d),c=Number(d.element.getAttribute("data-index")),g="bottom"===s?c+1:c;if(i!==g){const a=[...e],r=function(e,t,a){const r=Array.from(e),[o]=r.splice(t,1);return r.splice(a,0,o),r}(e,i,g),o=function(e,t){const a=t.filter((t,a)=>{var r;return t.id!==(null===(r=e[a])||void 0===r?void 0:r.id)}),r=a.slice().sort((e,t)=>e.position-t.position).map(e=>e.position);return a.map((e,t)=>({id:e.id,newPosition:r[t]}))}(a,r);t(r,o)}}})}function u({items:n,onReorder:s,renderItem:l,containerClassName:g="",containerStyle:u={},itemClassName:b="",itemStyle:v={},dragPreviewClassName:f="",dragPreviewStyle:x={},onDragStart:y,onDragEnd:D,disabled:h=!1,gap:I,direction:j="vertical",showDropIndicator:O=!1,dropIndicatorClassName:w="",dropIndicatorStyle:S={},dropIndicatorPosition:N="bottom"}){const C=t(null),E=m({items:n,onReorder:s,disabled:h}),[P,k]=a(!1),z=r(e=>h?()=>{}:d({element:e,getData:()=>({type:"container"}),onDragEnter:()=>k(!0),onDragLeave:()=>k(!1),onDrop:()=>k(!1)}),[h]);return o(()=>{const e=C.current;if(e&&!h)return i(z(e),E)},[z,E,h]),e.createElement("div",{ref:C,className:g,style:(()=>{const e=Object.assign({},c.container.default);return"horizontal"===j&&Object.assign(e,c.container.horizontal),P&&Object.assign(e,c.container.dragging),void 0!==I&&(e.gap="number"==typeof I?`${I}px`:I),Object.assign(Object.assign({},e),u)})()},n.map((t,a)=>e.createElement(p,{key:t.id,item:t,index:a,className:b,style:v,dragPreviewClassName:f,dragPreviewStyle:x,onDragStart:y,onDragEnd:D,disabled:h,showDropIndicator:O,dropIndicatorClassName:w,dropIndicatorStyle:S,dropIndicatorPosition:N},l(t,a))))}export{u as DragDropList,p as DraggableItemWrapper,c as defaultStyles,m as useDragDropMonitor};
|
|
1
|
+
import e,{useRef as t,useState as n,useCallback as r,useEffect as i}from"react";import{draggable as o,dropTargetForElements as a,monitorForElements as d}from"@atlaskit/pragmatic-drag-and-drop/element/adapter";import{combine as l}from"@atlaskit/pragmatic-drag-and-drop/combine";import{attachClosestEdge as s,extractClosestEdge as c}from"@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";const u={container:{default:{minHeight:"200px",transition:"all 0.2s ease",borderRadius:"8px",border:"1px solid #e2e8f0",backgroundColor:"#ffffff",display:"flex",flexDirection:"column",gap:"16px",padding:"16px"},dragging:{backgroundColor:"rgba(66, 153, 225, 0.05)",borderColor:"#3182ce"},horizontal:{flexDirection:"row",flexWrap:"wrap"}},item:{default:{transition:"all 0.2s ease",cursor:"grab",userSelect:"none",position:"relative"},dragging:{opacity:.5,cursor:"grabbing"},hover:{transform:"scale(1.02)",boxShadow:"0 4px 6px rgba(0, 0, 0, 0.1)"},disabled:{cursor:"not-allowed",opacity:.6}},preview:{position:"fixed",pointerEvents:"none",zIndex:9999,opacity:.8,transform:"rotate(2deg)",boxShadow:"0 10px 20px rgba(0, 0, 0, 0.15)"},dropIndicator:{position:"absolute",height:"2px",backgroundColor:"#3182ce",left:0,right:0,zIndex:10,transition:"all 0.2s ease"}},g="draggable-item";function m({item:d,index:c,children:m,className:p="",style:v={},dragPreviewClassName:f="",dragPreviewStyle:I={},onDragStart:b,onDragEnd:h,disabled:x=!1,showDropIndicator:w=!1,dropIndicatorClassName:D="",dropIndicatorStyle:y={},dropIndicatorPosition:S="bottom",direction:E="vertical",dragHandle:O}){const R=t(null),[j,C]=n(!1),[N,P]=n(!1),[M,z]=n(null),K=r(e=>{if(x)return()=>{};const t=O?e.querySelector(O):void 0;return o({element:e,dragHandle:null!=t?t:void 0,canDrag:()=>!O||Boolean(t),getInitialData:()=>({type:g,id:d.id,index:c}),onGenerateDragPreview:({nativeSetDragImage:t})=>{const n=e.cloneNode(!0),r=Object.assign(Object.assign({},u.preview),I);f&&(n.className=f),Object.assign(n.style,r,{width:`${(null==e?void 0:e.offsetWidth)||100}px`,height:`${(null==e?void 0:e.offsetHeight)||50}px`}),document.body.appendChild(n),t&&t(n,20,20),requestAnimationFrame(()=>n.remove())},onDragStart:()=>{C(!0),null==b||b(d,c)},onDrop:()=>{C(!1),null==h||h(d,c)}})},[d,c,O,f,I,b,h,x]),k=r(e=>x?()=>{}:a({element:e,getData:({input:e,element:t})=>{const n={type:g,id:d.id,index:c};return s(n,{input:e,element:t,allowedEdges:[..."horizontal"===E?["left","right"]:["top","bottom"]]})},canDrop:({source:e})=>{var t,n;return(null===(t=e.data)||void 0===t?void 0:t.type)===g&&(null===(n=e.data)||void 0===n?void 0:n.id)!==d.id},onDragEnter:({source:e,self:t})=>{var n,r;(null===(n=e.data)||void 0===n?void 0:n.id)!==(null===(r=t.data)||void 0===r?void 0:r.id)&&(P(!0),w&&z(S))},onDragLeave:()=>{P(!1),z(null)},onDrop:()=>{P(!1),z(null)}}),[d.id,c,E,x,w,S]);return i(()=>{const e=R.current;if(e)return x?()=>{}:l(K(e),k(e))},[c,K,k,x]),e.createElement("div",{ref:R,"data-index":c,"data-rdk-item-id":d.id,className:p,style:(()=>{const e=Object.assign({},u.item.default);return x?Object.assign(e,u.item.disabled):j?Object.assign(e,u.item.dragging):N&&Object.assign(e,u.item.hover),Object.assign(Object.assign({},e),v)})()},w&&"top"===M&&e.createElement("div",{className:D,style:Object.assign(Object.assign(Object.assign({},u.dropIndicator),y),{top:-1})}),m,w&&"bottom"===M&&e.createElement("div",{className:D,style:Object.assign(Object.assign(Object.assign({},u.dropIndicator),y),{bottom:-1})}))}function p(e,t){const n=new Map(e.map((e,t)=>[e.id,t]));return t.flatMap((e,t)=>{const r=n.get(e.id);return void 0===r||r===t?[]:[{id:e.id,newPosition:t,moved:!0}]})}function v(e,t){const n=e.element.getBoundingClientRect(),r=n.left+n.width/2,i=n.top+n.height/2;return Math.pow(t.clientX-r,2)+Math.pow(t.clientY-i,2)}function f(e,t){return e.length!==t.length||t.some((t,n)=>{var r;return t.id!==(null===(r=e[n])||void 0===r?void 0:r.id)})}function I(e){const{items:t,sourceId:n,selectedIds:r,multiDragEnabled:i}=e;if(!i)return new Set([n]);const o=new Set(t.map(e=>e.id)),a=new Set(r.filter(e=>o.has(e)));return a.has(n)?a:new Set([n])}function b(e){const{items:t,sourceId:n,sourceIndex:r,rawDestinationIndex:i,selectedIds:o,multiDragEnabled:a}=e;if(a){const e=new Set(o);e.has(n)||e.clear(),e.add(n);const r=t.map((t,n)=>e.has(t.id)?n:-1).filter(e=>-1!==e);if(r.length>1)return function(e,t,n){const r=Array.from(new Set(t.filter(t=>t>=0&&t<e.length))).sort((e,t)=>e-t);if(0===r.length)return e;const i=new Set(r),o=r.map(t=>e[t]),a=e.filter((e,t)=>!i.has(t)),d=Math.max(0,Math.min(n,e.length)),l=r.filter(e=>e<d).length,s=Math.max(0,Math.min(d-l,a.length)),c=[...a];return c.splice(s,0,...o),c}(t,r,i)}const d=function(e){const{itemCount:t,sourceIndex:n,rawDestinationIndex:r,isSameList:i}=e;if(t<=0)return 0;const o=t,a=Math.max(0,Math.min(r,o)),d=i&&n<a?a-1:a,l=i?t-1:t;return Math.max(0,Math.min(d,l))}({itemCount:t.length,sourceIndex:r,rawDestinationIndex:i,isSameList:!0});return function(e,t,n){const r=Array.from(e),[i]=r.splice(t,1);return r.splice(n,0,i),r}(t,r,d)}function h(e){var t,n;const{location:r,sourceId:i,sourceIndex:o,direction:a,items:d,excludedIds:l}=e,{dropTargets:s,input:u}=r,g=function(e){const{dropTargets:t,input:n,sourceId:r,excludedIds:i}=e,o=t.filter(e=>{var t,n,o;if("draggable-item"!==(null===(t=e.data)||void 0===t?void 0:t.type))return!1;const a=String(null!==(o=null===(n=e.data)||void 0===n?void 0:n.id)&&void 0!==o?o:"");return!(!a||a===r||i.has(a))});return 0===o.length?null:1===o.length?o[0]:o.reduce((e,t)=>v(t,n)<v(e,n)?t:e)}({dropTargets:s,input:u,sourceId:i,excludedIds:l}),m=s.find(e=>{var t;return"container"===(null===(t=e.data)||void 0===t?void 0:t.type)});if(!g&&!m)return null;if(!g){if(!m)return null;const e=function(e){const{containerElement:t,input:n,direction:r,items:i,excludedIds:o}=e,a=new Map(i.map((e,t)=>[e.id,t])),d=Array.from(t.querySelectorAll("[data-rdk-item-id]"));if(0===d.length)return 0;const l="horizontal"===r?n.clientX:n.clientY,s=d.map(e=>{const t=e.getAttribute("data-rdk-item-id");if(!t||o.has(t))return null;const i=a.get(t);if(void 0===i)return null;const d=e.getBoundingClientRect(),l=d.left+d.width/2,s=d.top+d.height/2;return{index:i,distance:Math.pow(n.clientX-l,2)+Math.pow(n.clientY-s,2),centerOnAxis:"horizontal"===r?l:s}}).filter(e=>null!==e);if(0===s.length)return null;const c=s.reduce((e,t)=>t.distance<e.distance?t:e);return l>=c.centerOnAxis?c.index+1:c.index}({containerElement:m.element,input:u,direction:a,items:d,excludedIds:l}),t=null!=e?e:d.length;return{rawDestinationIndex:t,previewKey:`container:${t}`}}const p=String(null!==(n=null===(t=g.data)||void 0===t?void 0:t.id)&&void 0!==n?n:"");if(!p)return null;const f=d.findIndex(e=>e.id===p);if(-1===f)return null;const I=c(g.data);let b;if(o<f)b=!0;else if(o>f)b=!1;else if(null===I){const e=g.element.getBoundingClientRect(),t="horizontal"===a?e.left+e.width/2:e.top+e.height/2;b=("horizontal"===a?u.clientX:u.clientY)>=t}else b="bottom"===I||"horizontal"===a&&"right"===I;return{rawDestinationIndex:b?f+1:f,previewKey:`item:${p}:${b?"after":"before"}`}}function x({items:e,onReorder:n,disabled:o=!1,direction:a="vertical",selectedIds:l=[],multiDragEnabled:s=!1,liveReorder:c=!1}){const u=t(e),g=t(n),m=t({direction:a,selectedIds:l,multiDragEnabled:s,liveReorder:c}),v=t({sourceId:null,movingIds:null,originalItems:null,didLiveReorder:!1,lastPreviewKey:null});i(()=>{u.current=e,g.current=n,m.current={direction:a,selectedIds:l,multiDragEnabled:s,liveReorder:c}},[e,n,a,l,s,c]);const x=r(()=>{v.current={sourceId:null,movingIds:null,originalItems:null,didLiveReorder:!1,lastPreviewKey:null}},[]),w=r((e,t)=>{const n=u.current.findIndex(t=>t.id===e);if(-1!==n)return n;const r=Number(t);return Number.isFinite(r)?r:-1},[]),D=r(e=>{const t=u.current,{selectedIds:n,multiDragEnabled:r}=m.current;return I({items:t,sourceId:e,selectedIds:n,multiDragEnabled:r})},[]),y=r(e=>{const t=v.current.movingIds;return t?new Set(t):D(e)},[D]),S=r(({sourceId:e,sourceIndex:t,rawDestinationIndex:n})=>{const r=[...u.current],{selectedIds:i,multiDragEnabled:o}=m.current,a=b({items:r,sourceId:e,sourceIndex:t,rawDestinationIndex:n,selectedIds:i,multiDragEnabled:o});if(!f(r,a))return!1;const d=p(r,a);return u.current=a,g.current(a,d),!0},[]),E=r(({source:e})=>{var t,n;if("draggable-item"!==(null===(t=e.data)||void 0===t?void 0:t.type))return;const r=null===(n=e.data)||void 0===n?void 0:n.id;if(!r)return;const i=u.current,{selectedIds:o,multiDragEnabled:a}=m.current,d=I({items:i,sourceId:r,selectedIds:o,multiDragEnabled:a});v.current={sourceId:r,movingIds:d,originalItems:m.current.liveReorder?[...i]:null,didLiveReorder:!1,lastPreviewKey:null}},[]),O=r(({location:e,source:t})=>{var n,r,i;if("draggable-item"!==(null===(n=t.data)||void 0===n?void 0:n.type))return;const{direction:o,liveReorder:a}=m.current;if(!a)return;const d=null===(r=t.data)||void 0===r?void 0:r.id;if(!d)return;const l=w(d,null===(i=t.data)||void 0===i?void 0:i.index);if(l<0)return;const s=u.current,c=y(d),g=h({location:e.current,sourceId:d,sourceIndex:l,direction:o,items:s,excludedIds:c});if(!g)return;if(v.current.lastPreviewKey===g.previewKey)return;const p=S({sourceId:d,sourceIndex:l,rawDestinationIndex:g.rawDestinationIndex});v.current.lastPreviewKey=g.previewKey,p&&(v.current.didLiveReorder=!0)},[w,y,S]),R=r(({location:e,source:t})=>{var n,r,i;if("draggable-item"!==(null===(n=t.data)||void 0===n?void 0:n.type))return void x();const o=null===(r=t.data)||void 0===r?void 0:r.id;if(!o)return void x();const{direction:a,liveReorder:d}=m.current,l=u.current,s=y(o),c=w(o,null===(i=t.data)||void 0===i?void 0:i.index);if(c<0)return void x();const I=h({location:e.current,sourceId:o,sourceIndex:c,direction:a,items:l,excludedIds:s});if(!I){const{originalItems:e,didLiveReorder:t}=v.current;if(d&&t&&e){const t=[...u.current];if(f(t,e)){const n=p(t,e);u.current=e,g.current(e,n)}}return void x()}const{didLiveReorder:b,lastPreviewKey:D}=v.current;d&&b&&D===I.previewKey||S({sourceId:o,sourceIndex:c,rawDestinationIndex:I.rawDestinationIndex}),x()},[y,w,S,x]);return i(()=>{if(!o)return d({onDragStart:E,onDropTargetChange:O,onDrop:R})},[o,E,O,R]),r(()=>{},[])}function w({items:o,onReorder:d,renderItem:l,containerClassName:s="",containerStyle:c={},itemClassName:g="",itemStyle:p={},dragPreviewClassName:v="",dragPreviewStyle:f={},onDragStart:I,onDragEnd:b,disabled:h=!1,gap:w,direction:D="vertical",showDropIndicator:y=!1,dropIndicatorClassName:S="",dropIndicatorStyle:E={},dropIndicatorPosition:O="bottom",dragHandle:R,selectedIds:j=[],multiDragEnabled:C=!1,liveReorder:N=!1}){const P=t(null);x({items:o,onReorder:d,disabled:h,direction:D,selectedIds:j,multiDragEnabled:C,liveReorder:N});const[M,z]=n(!1),K=r(e=>h?()=>{}:a({element:e,getData:()=>({type:"container"}),onDragEnter:()=>z(!0),onDragLeave:()=>z(!1),onDrop:()=>z(!1)}),[h]);return i(()=>{const e=P.current;if(e&&!h)return K(e)},[K,h]),e.createElement("div",{ref:P,className:s,style:(()=>{const e=Object.assign({},u.container.default);return"horizontal"===D&&Object.assign(e,u.container.horizontal),M&&Object.assign(e,u.container.dragging),void 0!==w&&(e.gap="number"==typeof w?`${w}px`:w),Object.assign(Object.assign({},e),c)})()},o.map((t,n)=>e.createElement(m,{key:t.id,item:t,index:n,className:g,style:p,dragPreviewClassName:v,dragPreviewStyle:f,onDragStart:I,onDragEnd:b,disabled:h,showDropIndicator:y,dropIndicatorClassName:S,dropIndicatorStyle:E,dropIndicatorPosition:O,direction:D,dragHandle:R},l(t,n))))}export{w as DragDropList,m as DraggableItemWrapper,u as defaultStyles,x as useDragDropMonitor};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|