react-dragdrop-kit 1.2.0 → 1.3.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 CHANGED
@@ -1,337 +1,289 @@
1
- # react-dragdrop-kit
2
-
3
- A flexible and lightweight **drag-and-drop toolkit for React**. Build **sortable lists, grids, and Kanban boards** with a simple, fully-controlled API and customizable previews. Powered by Atlassian's pragmatic drag-and-drop under the hood.
4
-
5
- <p>
6
- <a href="https://www.npmjs.com/package/react-dragdrop-kit"><img alt="npm" src="https://img.shields.io/npm/v/react-dragdrop-kit.svg?label=react-dragdrop-kit"></a>
7
- <a href="https://www.npmjs.com/package/react-dragdrop-kit"><img alt="downloads" src="https://img.shields.io/npm/dm/react-dragdrop-kit.svg"></a>
8
- <a href="https://github.com/Yourstruggle11/react-dragdrop-kit"><img alt="license" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
9
- </p>
10
-
11
- ---
12
-
13
- ## ✨ Features
14
-
15
- ### Drag & Drop Lists
16
- - 🔁 **Sortable** lists (vertical / horizontal)
17
- - 🎯 **Controlled**: you own the array, update on `onReorder`
18
- - 🧩 **Custom render** per item (cards, compact, detailed… anything)
19
- - 🧲 **Drop indicator** + optional **custom drag preview**
20
-
21
- ### 🆕 Kanban Boards (v1.2.0+)
22
- - 📋 **Full-featured Kanban board** with column and card management
23
- - 🔄 **Cross-column dragging** - Move cards between columns seamlessly
24
- - 🎨 **Headless architecture** - Complete styling control
25
- - ♿ **Accessible** - Screen reader announcements and keyboard support
26
- - 📱 **Touch-friendly** - Works on mobile devices
27
- - 🎯 **TypeScript-first** - Full type safety
28
-
29
- ### 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
-
35
- ---
36
-
37
- ## 📦 Install
38
-
39
- ```bash
40
- npm i react-dragdrop-kit
41
- # or
42
- yarn add react-dragdrop-kit
43
- # or
44
- pnpm add react-dragdrop-kit
45
- ```
46
-
47
- ---
48
-
49
- ## 🚀 Quick Start
50
-
51
- ### Sortable List
52
-
53
- ```tsx
54
- import { useState } from "react";
55
- import { DragDropList } from "react-dragdrop-kit";
56
-
57
- function App() {
58
- const [items, setItems] = useState([
59
- { id: "1", position: 0, title: "Learn React" },
60
- { id: "2", position: 1, title: "Build awesome app" },
61
- { id: "3", position: 2, title: "Deploy to production" },
62
- ]);
63
-
64
- return (
65
- <DragDropList
66
- items={items}
67
- onReorder={(next) => setItems(next.map((it, i) => ({ ...it, position: i })))}
68
- renderItem={(item) => (
69
- <div style={{ padding: 12, border: "1px solid #e5e7eb", borderRadius: 8 }}>
70
- {item.title}
71
- </div>
72
- )}
73
- showDropIndicator
74
- gap={8}
75
- />
76
- );
77
- }
78
- ```
79
-
80
- ### Kanban Board
81
-
82
- ```tsx
83
- import { useState } from 'react';
84
- import {
85
- KanbanBoard,
86
- applyDragResult,
87
- AnnouncerProvider,
88
- } from 'react-dragdrop-kit/kanban';
89
-
90
- function App() {
91
- const [state, setState] = useState({
92
- columns: [
93
- { id: 'todo', title: 'To Do', cardIds: ['task-1', 'task-2'] },
94
- { id: 'done', title: 'Done', cardIds: [] },
95
- ],
96
- cards: {
97
- 'task-1': { id: 'task-1', title: 'Design landing page' },
98
- 'task-2': { id: 'task-2', title: 'Implement auth' },
99
- },
100
- });
101
-
102
- const handleDragEnd = (result) => {
103
- if (!result.destination) return;
104
- setState(applyDragResult(state, result));
105
- };
106
-
107
- return (
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>
120
- );
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
-
140
- return (
141
- <DragDropList
142
- items={items}
143
- onReorder={(next) => setItems(next.map((it, i) => ({ ...it, position: i })))}
144
- containerClassName="bg-gray-50 rounded-xl p-6 space-y-2"
145
- itemClassName="bg-white rounded-lg shadow-sm hover:shadow-lg transition-all duration-200 cursor-move"
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
- )}
154
- />
155
- );
156
- }
157
- ```
158
-
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.
240
-
241
- 🎮 **Live Demo**: Check out our [interactive demo app](https://react-dragdrop-kit.netlify.app/) with full Kanban showcase!
242
-
243
- ---
244
-
245
- ## 🧠 Advanced Usage
246
-
247
- ### TypeScript
248
-
249
- ```tsx
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
- }
264
- ```
265
-
266
- ### React Strict Mode (React 19)
267
-
268
- In dev, React Strict Mode **double-mounts** to surface side effects. If you see duplicate `onReorder` calls in development, ensure your event listeners clean up correctly and keep callback identities stable with `useCallback`. Production builds call once.
269
-
270
- ---
271
-
272
- ## 📊 Bundle Size
273
-
274
- | Module | Size (Minified) |
275
- |--------|-----------------|
276
- | `react-dragdrop-kit` (Main) | ~5KB |
277
- | `react-dragdrop-kit/kanban` | ~9KB |
278
-
279
- Tree-shakeable exports mean you only pay for what you use!
280
-
281
- ---
282
-
283
- ## 🔄 Migration Guides
284
-
285
- ### From react-beautiful-dnd
286
-
287
- See our comprehensive [Kanban migration guide](./docs/kanban.md#migration-from-react-beautiful-dnd) for step-by-step instructions on migrating from `react-beautiful-dnd`.
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
298
-
299
- Contributions are welcome! Please feel free to submit a Pull Request.
300
-
301
- ---
302
-
303
- ## 📝 License
304
-
305
- MIT © [Yourstruggle11](https://github.com/Yourstruggle11)
306
-
307
- ---
308
-
309
- ## 🙏 Credits
310
-
311
- Built with:
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
315
-
316
- ---
317
-
318
- ## 📖 Documentation
319
-
320
- - [Kanban Board Guide](./docs/kanban.md)
321
- - [CHANGELOG](./CHANGELOG.md)
322
- - [Examples](./examples/)
323
- - [Demo Application](https://react-dragdrop-kit.netlify.app/)
324
-
325
- ---
326
-
327
- ## 💬 Support
328
-
329
- - 🐛 [Report Issues](https://github.com/Yourstruggle11/react-dragdrop-kit/issues)
330
- - 💡 [Request Features](https://github.com/Yourstruggle11/react-dragdrop-kit/issues/new)
331
- - ⭐ [Star on GitHub](https://github.com/Yourstruggle11/react-dragdrop-kit)
332
-
333
- ---
334
-
335
- <div align="center">
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>
1
+ # react-dragdrop-kit
2
+
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.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/react-dragdrop-kit.svg)](https://www.npmjs.com/package/react-dragdrop-kit)
7
+ [![npm downloads](https://img.shields.io/npm/dm/react-dragdrop-kit.svg)](https://www.npmjs.com/package/react-dragdrop-kit)
8
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/react-dragdrop-kit)](https://bundlephobia.com/package/react-dragdrop-kit)
9
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Yourstruggle11/react-dragdrop-kit)
10
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Yourstruggle11/react-dragdrop-kit)
11
+
12
+ ## Why this library
13
+
14
+ `react-dragdrop-kit` is designed around a controlled data model:
15
+
16
+ - You own state.
17
+ - The library reports drag intent and reorder results.
18
+ - You decide what to persist and render.
19
+
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
+
33
+ ### Kanban module
34
+
35
+ - Card reorder within columns
36
+ - Card movement across columns
37
+ - Column reordering
38
+ - Headless rendering (`renderColumn`, `renderCard`)
39
+ - Accessibility helpers (`AnnouncerProvider`, `useAnnouncer`, `announcements`)
40
+ - Keyboard drag-reorder is planned, not fully shipped yet
41
+
42
+ ### General
43
+
44
+ - TypeScript-first API
45
+ - Lightweight runtime and tree-shakeable exports
46
+ - Built on `@atlaskit/pragmatic-drag-and-drop`
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ npm install react-dragdrop-kit
52
+ # or
53
+ pnpm add react-dragdrop-kit
54
+ # or
55
+ yarn add react-dragdrop-kit
56
+ ```
57
+
58
+ ## Package entry points
59
+
60
+ ```ts
61
+ import { DragDropList } from "react-dragdrop-kit";
62
+ ```
63
+
64
+ ```ts
65
+ import { KanbanBoard, applyDragResult } from "react-dragdrop-kit/kanban";
66
+ ```
67
+
68
+ ## Quick start: sortable list
69
+
70
+ ```tsx
71
+ import { useState } from "react";
72
+ import { DragDropList } from "react-dragdrop-kit";
73
+
74
+ interface Todo {
75
+ id: string;
76
+ position: number;
77
+ title: string;
78
+ }
79
+
80
+ export default function TodoList() {
81
+ const [items, setItems] = useState<Todo[]>([
82
+ { id: "1", position: 0, title: "Design" },
83
+ { id: "2", position: 1, title: "Build" },
84
+ { id: "3", position: 2, title: "Ship" },
85
+ ]);
86
+
87
+ return (
88
+ <DragDropList
89
+ items={items}
90
+ onReorder={(next) =>
91
+ setItems(next.map((item, index) => ({ ...item, position: index })))
92
+ }
93
+ renderItem={(item) => (
94
+ <div style={{ padding: 12, border: "1px solid #e5e7eb", borderRadius: 8 }}>
95
+ {item.title}
96
+ </div>
97
+ )}
98
+ showDropIndicator
99
+ gap={8}
100
+ />
101
+ );
102
+ }
103
+ ```
104
+
105
+ ## Quick start: drag handle and multi-drag
106
+
107
+ ```tsx
108
+ <DragDropList
109
+ items={items}
110
+ onReorder={handleReorder}
111
+ renderItem={renderItem}
112
+ dragHandle="[data-drag-handle]"
113
+ selectedIds={selectedIds}
114
+ multiDragEnabled
115
+ />
116
+ ```
117
+
118
+ Behavior notes:
119
+
120
+ - `dragHandle` is optional. If provided, drag starts only from matching descendants.
121
+ - `multiDragEnabled` is opt-in. Without it, behavior remains single-item drag.
122
+ - `selectedIds` is consumed only when multi-drag is enabled.
123
+
124
+ ## Quick start: Kanban board
125
+
126
+ ```tsx
127
+ import { useCallback, useState } from "react";
128
+ import {
129
+ KanbanBoard,
130
+ applyDragResult,
131
+ type DropResult,
132
+ type KanbanBoardState,
133
+ } from "react-dragdrop-kit/kanban";
134
+
135
+ export default function Board() {
136
+ const [state, setState] = useState<KanbanBoardState>({
137
+ columns: [
138
+ { id: "todo", title: "To Do", cardIds: ["task-1", "task-2"] },
139
+ { id: "done", title: "Done", cardIds: [] },
140
+ ],
141
+ cards: {
142
+ "task-1": { id: "task-1", title: "Design landing page" },
143
+ "task-2": { id: "task-2", title: "Implement auth" },
144
+ },
145
+ });
146
+
147
+ const handleDragEnd = useCallback(
148
+ (result: DropResult, stateBefore: KanbanBoardState) => {
149
+ if (!result.destination) return;
150
+ setState(applyDragResult(stateBefore, result));
151
+ },
152
+ []
153
+ );
154
+
155
+ return (
156
+ <KanbanBoard
157
+ state={state}
158
+ onDragEnd={handleDragEnd}
159
+ renderColumn={(column) => <div style={{ padding: 12 }}>{column.title}</div>}
160
+ renderCard={(card) => <div style={{ padding: 12 }}>{card.title}</div>}
161
+ />
162
+ );
163
+ }
164
+ ```
165
+
166
+ ## API reference: list module
167
+
168
+ ### Core types
169
+
170
+ ```ts
171
+ type DraggableItem = {
172
+ id: string;
173
+ position: number;
174
+ [key: string]: any;
175
+ };
176
+
177
+ type OrderUpdate = {
178
+ id: string;
179
+ newPosition: number;
180
+ moved?: boolean;
181
+ };
182
+ ```
183
+
184
+ ### DragDropList props
185
+
186
+ | Prop | Type | Default | Description |
187
+ | --- | --- | --- | --- |
188
+ | `items` | `T[]` | Required | Controlled items. Each item must include `id` and `position`. |
189
+ | `onReorder` | `(newItems: T[], orderUpdates: OrderUpdate[]) => void` | Required | Fired after successful drop/reorder. |
190
+ | `renderItem` | `(item: T, index: number) => ReactNode` | Required | Item renderer. |
191
+ | `containerClassName` | `string` | `""` | Class name for container. |
192
+ | `containerStyle` | `React.CSSProperties` | `{}` | Inline style for container. |
193
+ | `itemClassName` | `string` | `""` | Class for each draggable wrapper. |
194
+ | `itemStyle` | `React.CSSProperties` | `{}` | Style for each draggable wrapper. |
195
+ | `dragPreviewClassName` | `string` | `""` | Class for generated drag preview. |
196
+ | `dragPreviewStyle` | `React.CSSProperties` | `{}` | Style for generated drag preview. |
197
+ | `onDragStart` | `(item: T, index: number) => void` | `undefined` | Callback on item drag start. |
198
+ | `onDragEnd` | `(item: T, index: number) => void` | `undefined` | Callback on item drag end. |
199
+ | `disabled` | `boolean` | `false` | Disables list drag/drop. |
200
+ | `gap` | `number \| string` | `undefined` | Gap applied to container. |
201
+ | `direction` | `"vertical" \| "horizontal"` | `"vertical"` | Layout and closest-edge interpretation. |
202
+ | `showDropIndicator` | `boolean` | `false` | Enables drop indicator line. |
203
+ | `dropIndicatorClassName` | `string` | `""` | Class for drop indicator. |
204
+ | `dropIndicatorStyle` | `React.CSSProperties` | `{}` | Style for drop indicator. |
205
+ | `dropIndicatorPosition` | `"top" \| "bottom"` | `"bottom"` | Indicator position for hovered target item. |
206
+ | `dragHandle` | `string` | `undefined` | CSS selector for handle-only dragging. |
207
+ | `selectedIds` | `string[]` | `[]` | Selected IDs used by multi-drag. |
208
+ | `multiDragEnabled` | `boolean` | `false` | Enables grouped drag behavior. |
209
+
210
+ ## API reference: Kanban module
211
+
212
+ The full Kanban API is documented in [docs/kanban.md](./docs/kanban.md).
213
+
214
+ Exports:
215
+
216
+ - Components: `KanbanBoard`, `KanbanColumnView`, `KanbanCardView`
217
+ - Hooks: `useKanbanDnd`, `useAutoscroll`
218
+ - A11y: `AnnouncerProvider`, `useAnnouncer`, `announcements`
219
+ - Utils: `applyDragResult`, `reorderArray`
220
+ - Types: `KanbanBoardState`, `DropResult`, `KanbanCard`, `KanbanColumn`, and more
221
+
222
+ ## Examples
223
+
224
+ ### Repository examples
225
+
226
+ - `examples/basic-example.tsx`
227
+ - `examples/advanced-features.tsx`
228
+ - `examples/material-ui-example.tsx`
229
+ - `examples/tailwind-example.tsx`
230
+ - `examples/kanban/basic-kanban.tsx`
231
+ - `examples/kanban/rich-cards-kanban.tsx`
232
+ - `examples/kanban/themed-kanban.tsx`
233
+ - `examples/kanban/accessible-kanban.tsx`
234
+
235
+ ### Demo examples
236
+
237
+ - List/grid examples under `apps/demo/src/examples/*`
238
+ - Kanban demos:
239
+ - `apps/demo/src/examples/BasicKanban/index.tsx`
240
+ - `apps/demo/src/examples/RichKanban/index.tsx`
241
+ - `apps/demo/src/examples/SwimlanesKanban/index.tsx`
242
+ - `apps/demo/src/examples/WipLimitsKanban/index.tsx`
243
+
244
+ ## Migration notes
245
+
246
+ ### From react-beautiful-dnd
247
+
248
+ High-level mapping for Kanban use cases:
249
+
250
+ - `DragDropContext` -> `KanbanBoard`
251
+ - `Droppable` -> `KanbanColumnView`
252
+ - `Draggable` -> `KanbanCardView`
253
+
254
+ Important differences:
255
+
256
+ 1. State is normalized (`columns` + `cards`) instead of nested.
257
+ 2. IDs are explicit and owned by your app.
258
+ 3. Rendering is done via render functions (`renderColumn`, `renderCard`).
259
+
260
+ ## Development notes
261
+
262
+ ### React Strict Mode
263
+
264
+ In development, React Strict Mode can mount effects twice.
265
+ Ensure listener setup and cleanup are idempotent when integrating custom logic.
266
+
267
+ ## Bundle size
268
+
269
+ Approximate minified sizes:
270
+
271
+ - `react-dragdrop-kit`: about 5KB
272
+ - `react-dragdrop-kit/kanban`: about 9KB
273
+
274
+ ## Documentation and links
275
+
276
+ - [Kanban guide](./docs/kanban.md)
277
+ - [Known issues](./KNOWN_ISSUES.md)
278
+ - [Changelog](./packages/react-dragdrop-kit/CHANGELOG.md)
279
+ - [Examples folder](./examples)
280
+ - [Demo app](https://react-dragdrop-kit.netlify.app/)
281
+
282
+ ## Support
283
+
284
+ - [Report issues](https://github.com/Yourstruggle11/react-dragdrop-kit/issues)
285
+ - [Request features](https://github.com/Yourstruggle11/react-dragdrop-kit/issues/new)
286
+
287
+ ## License
288
+
289
+ MIT