react-dragdrop-kit 1.0.0 → 1.2.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.
Files changed (38) hide show
  1. package/README.md +223 -82
  2. package/dist/index.esm.js +1 -1
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/jest.setup.d.ts +1 -0
  7. package/dist/kanban.esm.js +2 -0
  8. package/dist/kanban.esm.js.map +1 -0
  9. package/dist/kanban.js +2 -0
  10. package/dist/kanban.js.map +1 -0
  11. package/dist/{components → src/components}/DragDropList.d.ts +1 -2
  12. package/dist/{components → src/components}/DraggableItemWrapper.d.ts +1 -2
  13. package/dist/{hooks → src/hooks}/useDragDropMonitor.d.ts +0 -1
  14. package/dist/{index.d.ts → src/index.d.ts} +0 -1
  15. package/dist/src/kanban/a11y/Announcer.d.ts +37 -0
  16. package/dist/src/kanban/a11y/useLiveRegion.d.ts +17 -0
  17. package/dist/src/kanban/components/KanbanBoard.d.ts +8 -0
  18. package/dist/src/kanban/components/KanbanCardView.d.ts +8 -0
  19. package/dist/src/kanban/components/KanbanColumnView.d.ts +8 -0
  20. package/dist/src/kanban/context.d.ts +13 -0
  21. package/dist/src/kanban/hooks/useAutoscroll.d.ts +10 -0
  22. package/dist/src/kanban/hooks/useKanbanDnd.d.ts +16 -0
  23. package/dist/src/kanban/index.d.ts +15 -0
  24. package/dist/src/kanban/types.d.ts +185 -0
  25. package/dist/src/kanban/utils/dndMath.d.ts +61 -0
  26. package/dist/src/kanban/utils/dom.d.ts +62 -0
  27. package/dist/src/kanban/utils/reorder.d.ts +32 -0
  28. package/dist/{styles → src/styles}/defaultStyles.d.ts +0 -1
  29. package/dist/{types → src/types}/index.d.ts +2 -1
  30. package/dist/{utils → src/utils}/order.d.ts +0 -1
  31. package/package.json +15 -5
  32. package/dist/components/DragDropList.d.ts.map +0 -1
  33. package/dist/components/DraggableItemWrapper.d.ts.map +0 -1
  34. package/dist/hooks/useDragDropMonitor.d.ts.map +0 -1
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/styles/defaultStyles.d.ts.map +0 -1
  37. package/dist/types/index.d.ts.map +0 -1
  38. package/dist/utils/order.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # react-dragdrop-kit
2
2
 
3
- A flexible and lightweight **drag-and-drop toolkit for React**. Build **sortable lists, grids, and boards** with a simple, fully-controlled API and customizable previews. Powered by Atlassians pragmatic drag-and-drop under the hood.
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
4
 
5
5
  <p>
6
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>
@@ -12,12 +12,25 @@ A flexible and lightweight **drag-and-drop toolkit for React**. Build **sortable
12
12
 
13
13
  ## ✨ Features
14
14
 
15
- - 🔁 **Sortable** (vertical / horizontal)
15
+ ### Drag & Drop Lists
16
+ - 🔁 **Sortable** lists (vertical / horizontal)
16
17
  - 🎯 **Controlled**: you own the array, update on `onReorder`
17
18
  - 🧩 **Custom render** per item (cards, compact, detailed… anything)
18
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
19
30
  - 🧪 **TypeScript** types included
20
- - ⚡ Ships tiny bundles (only `dist/` published)
31
+ - ⚡ **Tiny bundles** (~5KB main, ~9KB Kanban)
32
+ - 🎨 **Framework agnostic styling** - Works with Tailwind, MUI, Chakra, etc.
33
+ - 📚 **Comprehensive documentation**
21
34
 
22
35
  ---
23
36
 
@@ -29,54 +42,32 @@ npm i react-dragdrop-kit
29
42
  yarn add react-dragdrop-kit
30
43
  # or
31
44
  pnpm add react-dragdrop-kit
32
- ````
33
-
34
-
35
- ## 🚀 Quick Start (Basic Example)
36
-
37
- ```tsx
38
- // examples/basic-example.tsx
45
+ ```
39
46
 
40
- import * as React from "react";
41
- import { DragDropList, type DraggableItem, type OrderUpdate } from "react-dragdrop-kit";
47
+ ---
42
48
 
43
- interface TodoItem extends DraggableItem {
44
- title: string;
45
- completed: boolean;
46
- }
49
+ ## 🚀 Quick Start
47
50
 
48
- const initial: TodoItem[] = [
49
- { id: "1", position: 0, title: "Learn React", completed: false },
50
- { id: "2", position: 1, title: "Build awesome app", completed: false },
51
- { id: "3", position: 2, title: "Deploy to production", completed: false },
52
- ];
51
+ ### Sortable List
53
52
 
54
- export default function BasicExample() {
55
- const [todos, setTodos] = React.useState(initial);
53
+ ```tsx
54
+ import { useState } from "react";
55
+ import { DragDropList } from "react-dragdrop-kit";
56
56
 
57
- const handleReorder = (next: TodoItem[], updates: OrderUpdate[]) => {
58
- // keep positions normalized
59
- setTodos(next.map((it, i) => ({ ...it, position: i })));
60
- // optionally send `updates` to your API
61
- // console.log("order updates", updates);
62
- };
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
63
 
64
64
  return (
65
65
  <DragDropList
66
- items={todos}
67
- onReorder={handleReorder}
66
+ items={items}
67
+ onReorder={(next) => setItems(next.map((it, i) => ({ ...it, position: i })))}
68
68
  renderItem={(item) => (
69
69
  <div style={{ padding: 12, border: "1px solid #e5e7eb", borderRadius: 8 }}>
70
- <input
71
- type="checkbox"
72
- checked={item.completed}
73
- onChange={() =>
74
- setTodos((prev) =>
75
- prev.map((t) => (t.id === item.id ? { ...t, completed: !t.completed } : t))
76
- )
77
- }
78
- />
79
- <span style={{ marginLeft: 8 }}>{item.title}</span>
70
+ {item.title}
80
71
  </div>
81
72
  )}
82
73
  showDropIndicator
@@ -86,22 +77,64 @@ export default function BasicExample() {
86
77
  }
87
78
  ```
88
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
+
89
124
  ---
90
125
 
91
- ## 🎨 Styled Example (Tailwind)
126
+ ## 🎨 Styled Examples
92
127
 
93
- ```tsx
94
- // examples/tailwind-example.tsx
128
+ ### With Tailwind CSS
95
129
 
96
- import * as React from "react";
130
+ ```tsx
97
131
  import { DragDropList } from "react-dragdrop-kit";
98
132
 
99
133
  export default function TailwindExample() {
100
- const [items, setItems] = React.useState([
134
+ const [items, setItems] = useState([
101
135
  { id: "1", position: 0, name: "Dashboard", icon: "📊" },
102
136
  { id: "2", position: 1, name: "Projects", icon: "📁" },
103
137
  { id: "3", position: 2, name: "Team", icon: "👥" },
104
- { id: "4", position: 3, name: "Calendar", icon: "📅" },
105
138
  ]);
106
139
 
107
140
  return (
@@ -110,18 +143,12 @@ export default function TailwindExample() {
110
143
  onReorder={(next) => setItems(next.map((it, i) => ({ ...it, position: i })))}
111
144
  containerClassName="bg-gray-50 rounded-xl p-6 space-y-2"
112
145
  itemClassName="bg-white rounded-lg shadow-sm hover:shadow-lg transition-all duration-200 cursor-move"
113
- dragPreviewClassName="bg-blue-100 rounded-lg shadow-2xl"
114
146
  showDropIndicator
115
147
  dropIndicatorClassName="bg-blue-500"
116
148
  renderItem={(item) => (
117
149
  <div className="flex items-center p-4 space-x-3">
118
150
  <span className="text-2xl">{item.icon}</span>
119
151
  <span className="font-medium text-gray-700">{item.name}</span>
120
- <div className="ml-auto">
121
- <svg className="w-5 h-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
122
- <path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
123
- </svg>
124
- </div>
125
152
  </div>
126
153
  )}
127
154
  />
@@ -131,66 +158,180 @@ export default function TailwindExample() {
131
158
 
132
159
  ---
133
160
 
134
- ## 🧩 API
161
+ ## 📚 API Reference
135
162
 
136
- ### `<DragDropList />`
163
+ ### DragDropList Component
137
164
 
138
165
  | Prop | Type | Default | Description |
139
166
  | ------------------------ | --------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------ |
140
- | `items` | `Array<DraggableItem & T>` | — | Items to render. Must include `{ id: string; position: number }`. You can extend with your own fields. |
167
+ | `items` | `Array<DraggableItem & T>` | — | Items to render. Must include `{ id: string; position: number }`. |
141
168
  | `onReorder` | `(next: T[], updates: OrderUpdate[]) => void` | — | Called after drop. `next` is the new array; `updates` has id + newPosition. |
142
169
  | `renderItem` | `(item: T) => React.ReactNode` | — | Custom renderer for each item. |
143
170
  | `direction` | `"vertical" \| "horizontal"` | `"vertical"` | Drag axis + layout. |
144
171
  | `gap` | `number` | `0` | Gap (px) between items. |
145
172
  | `disabled` | `boolean` | `false` | Disable dragging. |
146
173
  | `showDropIndicator` | `boolean` | `false` | Show a drop indicator while dragging. |
174
+ | `dropIndicatorPosition` | `"top" \| "bottom"` | `"bottom"` | Position of drop indicator relative to target item. |
147
175
  | `dropIndicatorClassName` | `string` | — | CSS class applied to the drop indicator element. |
148
176
  | `dragPreviewStyle` | `React.CSSProperties` | — | Inline styles for custom drag preview. |
149
177
  | `containerClassName` | `string` | — | Class applied to the container. |
150
178
  | `itemClassName` | `string` | — | Class applied to each item wrapper. |
151
- | `containerStyle` | `React.CSSProperties` | — | Inline styles for the container. |
152
- | `itemStyle` | `React.CSSProperties` | — | Inline styles for each item wrapper. |
153
- | `onDragStart` | `(item: T, index: number) => void` | — | Optional callback when drag starts. |
154
- | `onDragEnd` | `(item: T, index: number) => void` | — | Optional callback when drag ends. |
155
-
156
- #### Types
157
-
158
- ```ts
159
- export type DraggableItem = {
160
- id: string;
161
- position: number; // 0-based
162
- };
163
-
164
- export type OrderUpdate = {
165
- id: string;
166
- newPosition: number;
167
- // Extend in your app if you need: { oldPosition, moved }
168
- };
169
- ```
170
179
 
171
- ---
180
+ ### Kanban Components
172
181
 
173
- ## 🧠 Strict Mode (React 19)
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
174
188
 
175
- 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.
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
176
219
 
177
220
  ---
178
221
 
179
- ## 📚 More Examples
222
+ ## 📂 Examples
180
223
 
181
- This repo includes full examples:
224
+ This repo includes comprehensive examples:
182
225
 
226
+ ### Drag & Drop Lists
183
227
  * [Basic Example](./examples/basic-example.tsx)
184
228
  * [Tailwind Example](./examples/tailwind-example.tsx)
185
229
  * [Material UI Example](./examples/material-ui-example.tsx)
186
- * [Horizontal Kanban](./examples/horizontal-kanban.tsx)
187
230
  * [Advanced Features](./examples/advanced-features.tsx)
188
- * [Styled Components Example](./examples/styled-components-example.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)
189
238
 
190
239
  👉 Explore the [`examples/`](./examples) folder for the complete code.
191
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
+
192
301
  ---
193
302
 
194
303
  ## 📝 License
195
304
 
196
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>
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:j={}}){const O=t(null),[w,I]=a(!1),[S,N]=a(!1),[C,E]=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:()=>{I(!0),null==f||f(s,l)},onDrop:()=>{I(!1),null==x||x(s,l)}}),[s,l,b,v,f,x,y]),P=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,location:a})=>{var r,o,i;if((null===(r=e.data)||void 0===r?void 0:r.id)!==(null===(o=t.data)||void 0===o?void 0:o.id)&&(N(!0),D)){const e=null===(i=a.current.dropTargets[0])||void 0===i?void 0:i.edge;E("top"===e?"top":"bottom")}},onDragLeave:()=>{N(!1),E(null)},onDrop:()=>{N(!1),E(null)}}),[s.id,l,y,D]);return o(()=>{const e=O.current;if(e)return e.setAttribute("data-index",l.toString()),y?()=>{}:i(k(e),P(e))},[l,k,P,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):S&&Object.assign(e,c.item.hover),Object.assign(Object.assign({},e),u)})()},D&&"top"===C&&e.createElement("div",{className:h,style:Object.assign(Object.assign(Object.assign({},c.dropIndicator),j),{top:-1})}),p,D&&"bottom"===C&&e.createElement("div",{className:h,style:Object.assign(Object.assign(Object.assign({},c.dropIndicator),j),{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=((e,t,a)=>{const r=Array.from(e),[o]=r.splice(t,1);return r.splice(a,0,o),r})(e,i,g),o=((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:j,direction:O="vertical",showDropIndicator:w=!1,dropIndicatorClassName:I="",dropIndicatorStyle:S={}}){const N=t(null),C=m({items:n,onReorder:s,disabled:h}),[E,k]=a(!1),P=r(e=>h?()=>{}:d({element:e,getData:()=>({type:"container"}),onDragEnter:()=>k(!0),onDragLeave:()=>k(!1),onDrop:()=>k(!1)}),[h]);return o(()=>{const e=N.current;if(e&&!h)return i(P(e),C)},[P,C,h]),e.createElement("div",{ref:N,className:g,style:(()=>{const e=Object.assign({},c.container.default);return"horizontal"===O&&Object.assign(e,c.container.horizontal),E&&Object.assign(e,c.container.dragging),void 0!==j&&(e.gap="number"==typeof j?`${j}px`:j),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:w,dropIndicatorClassName:I,dropIndicatorStyle:S},l(t,a))))}export{u as DragDropList,p as DraggableItemWrapper,c as defaultStyles,m as useDragDropMonitor};
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};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/styles/defaultStyles.ts","../src/components/DraggableItemWrapper.tsx","../src/hooks/useDragDropMonitor.ts","../src/components/DragDropList.tsx"],"sourcesContent":["export const defaultStyles = {\r\n container: {\r\n default: {\r\n minHeight: \"200px\",\r\n transition: \"all 0.2s ease\",\r\n borderRadius: \"8px\",\r\n border: \"1px solid #e2e8f0\",\r\n backgroundColor: \"#ffffff\",\r\n display: \"flex\",\r\n flexDirection: \"column\" as const,\r\n gap: \"16px\",\r\n padding: \"16px\",\r\n },\r\n dragging: {\r\n backgroundColor: \"rgba(66, 153, 225, 0.05)\",\r\n borderColor: \"#3182ce\",\r\n },\r\n horizontal: {\r\n flexDirection: \"row\" as const,\r\n flexWrap: \"wrap\" as const,\r\n },\r\n },\r\n item: {\r\n default: {\r\n transition: \"all 0.2s ease\",\r\n cursor: \"grab\",\r\n userSelect: \"none\" as const,\r\n position: \"relative\" as const,\r\n },\r\n dragging: {\r\n opacity: 0.5,\r\n cursor: \"grabbing\",\r\n },\r\n hover: {\r\n transform: \"scale(1.02)\",\r\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\r\n },\r\n disabled: {\r\n cursor: \"not-allowed\",\r\n opacity: 0.6,\r\n },\r\n },\r\n preview: {\r\n position: \"fixed\" as const,\r\n pointerEvents: \"none\" as const,\r\n zIndex: 9999,\r\n opacity: 0.8,\r\n transform: \"rotate(2deg)\",\r\n boxShadow: \"0 10px 20px rgba(0, 0, 0, 0.15)\",\r\n },\r\n dropIndicator: {\r\n position: \"absolute\" as const,\r\n height: \"2px\",\r\n backgroundColor: \"#3182ce\",\r\n left: 0,\r\n right: 0,\r\n zIndex: 10,\r\n transition: \"all 0.2s ease\",\r\n },\r\n};\r\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\r\nimport { combine } from \"@atlaskit/pragmatic-drag-and-drop/combine\";\r\nimport {\r\n draggable,\r\n dropTargetForElements,\r\n} from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport type { DraggableItemWrapperProps, DraggableItem } from \"../types\";\r\nimport { defaultStyles } from \"../styles/defaultStyles\";\r\n\r\nconst DRAGGABLE_ITEM = \"draggable-item\";\r\n\r\nexport function DraggableItemWrapper<T extends DraggableItem>({\r\n item,\r\n index,\r\n children,\r\n className = \"\",\r\n style = {},\r\n dragPreviewClassName = \"\",\r\n dragPreviewStyle = {},\r\n onDragStart,\r\n onDragEnd,\r\n disabled = false,\r\n showDropIndicator = false,\r\n dropIndicatorClassName = \"\",\r\n dropIndicatorStyle = {},\r\n}: DraggableItemWrapperProps<T>) {\r\n const elementRef = useRef<HTMLDivElement>(null);\r\n const [isDragging, setIsDragging] = useState(false);\r\n const [isHovered, setIsHovered] = useState(false);\r\n const [dropPosition, setDropPosition] = useState<\"top\" | \"bottom\" | null>(\r\n null\r\n );\r\n\r\n const getItemStyles = (): React.CSSProperties => {\r\n const baseStyle = { ...defaultStyles.item.default };\r\n\r\n if (disabled) {\r\n Object.assign(baseStyle, defaultStyles.item.disabled);\r\n } else if (isDragging) {\r\n Object.assign(baseStyle, defaultStyles.item.dragging);\r\n } else if (isHovered) {\r\n Object.assign(baseStyle, defaultStyles.item.hover);\r\n }\r\n\r\n return { ...baseStyle, ...style };\r\n };\r\n\r\n const getPreviewStyles = (): React.CSSProperties => {\r\n return { ...defaultStyles.preview, ...dragPreviewStyle };\r\n };\r\n\r\n const createDraggable = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return draggable({\r\n element,\r\n getInitialData: () => ({\r\n type: DRAGGABLE_ITEM,\r\n id: item.id,\r\n index,\r\n }),\r\n onGenerateDragPreview: ({ nativeSetDragImage }) => {\r\n const previewElement = element.cloneNode(true) as HTMLElement;\r\n const previewStyles = getPreviewStyles();\r\n\r\n // Apply custom preview class if provided\r\n if (dragPreviewClassName) {\r\n previewElement.className = dragPreviewClassName;\r\n }\r\n\r\n Object.assign(previewElement.style, previewStyles, {\r\n width: `${element?.offsetWidth || 100}px`,\r\n height: `${element?.offsetHeight || 50}px`,\r\n });\r\n\r\n document.body.appendChild(previewElement);\r\n if (nativeSetDragImage) {\r\n nativeSetDragImage(previewElement, 20, 20);\r\n }\r\n requestAnimationFrame(() => previewElement.remove());\r\n },\r\n onDragStart: () => {\r\n setIsDragging(true);\r\n onDragStart?.(item, index);\r\n },\r\n onDrop: () => {\r\n setIsDragging(false);\r\n onDragEnd?.(item, index);\r\n },\r\n });\r\n },\r\n [\r\n item,\r\n index,\r\n dragPreviewClassName,\r\n dragPreviewStyle,\r\n onDragStart,\r\n onDragEnd,\r\n disabled,\r\n ]\r\n );\r\n\r\n const createDropTarget = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return dropTargetForElements({\r\n element,\r\n getData: () => ({\r\n type: DRAGGABLE_ITEM,\r\n id: item.id,\r\n index,\r\n }),\r\n canDrop: (args: any) => args.source.data?.type === DRAGGABLE_ITEM,\r\n getIsSticky: () => true,\r\n onDragEnter: ({ source, self, location }: any) => {\r\n if (source.data?.id !== self.data?.id) {\r\n setIsHovered(true);\r\n if (showDropIndicator) {\r\n const edge = location.current.dropTargets[0]?.edge;\r\n setDropPosition(edge === \"top\" ? \"top\" : \"bottom\");\r\n }\r\n }\r\n },\r\n onDragLeave: () => {\r\n setIsHovered(false);\r\n setDropPosition(null);\r\n },\r\n onDrop: () => {\r\n setIsHovered(false);\r\n setDropPosition(null);\r\n },\r\n });\r\n },\r\n [item.id, index, disabled, showDropIndicator]\r\n );\r\n\r\n// useEffect(() => {\r\n// const element = elementRef.current;\r\n// if (!element) return;\r\n\r\n// element.setAttribute(\"data-index\", index.toString());\r\n\r\n// if (!disabled) {\r\n// return combine(createDraggable(element), createDropTarget(element));\r\n// }\r\n// }, [index, createDraggable, createDropTarget, disabled]);\r\n\r\n useEffect(() => {\r\n const element = elementRef.current;\r\n if (!element) return;\r\n\r\n element.setAttribute(\"data-index\", index.toString());\r\n\r\n if (disabled) {\r\n // provide a no-op cleanup to satisfy all code paths\r\n return () => {};\r\n }\r\n\r\n // normal draggable + droptarget setup\r\n return combine(createDraggable(element), createDropTarget(element));\r\n }, [index, createDraggable, createDropTarget, disabled]);\r\n\r\n return (\r\n <div ref={elementRef} className={className} style={getItemStyles()}>\r\n {showDropIndicator && dropPosition === \"top\" && (\r\n <div\r\n className={dropIndicatorClassName}\r\n style={{\r\n ...defaultStyles.dropIndicator,\r\n ...dropIndicatorStyle,\r\n top: -1,\r\n }}\r\n />\r\n )}\r\n {children}\r\n {showDropIndicator && dropPosition === \"bottom\" && (\r\n <div\r\n className={dropIndicatorClassName}\r\n style={{\r\n ...defaultStyles.dropIndicator,\r\n ...dropIndicatorStyle,\r\n bottom: -1,\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { monitorForElements } from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport { extractClosestEdge } from \"@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge\";\r\nimport type { DraggableItem, OrderUpdate } from \"../types\";\r\n\r\nexport function useDragDropMonitor<T extends DraggableItem>({\r\n items,\r\n onReorder,\r\n disabled = false,\r\n}: {\r\n items: T[];\r\n onReorder: (newItems: T[], orderUpdates: OrderUpdate[]) => void;\r\n disabled?: boolean;\r\n}) {\r\n if (disabled) {\r\n return () => {};\r\n }\r\n\r\n const reorder = (list: T[], startIndex: number, endIndex: number) => {\r\n const result = Array.from(list);\r\n const [removed] = result.splice(startIndex, 1);\r\n result.splice(endIndex, 0, removed);\r\n return result;\r\n };\r\n\r\n const calculateOrderUpdates = (\r\n oldItems: T[],\r\n newItems: T[]\r\n ): OrderUpdate[] => {\r\n const affectedItems = newItems.filter(\r\n (item, index) => item.id !== oldItems[index]?.id\r\n );\r\n const orderList = affectedItems\r\n .slice()\r\n .sort((a, b) => a.position - b.position)\r\n .map((item) => item.position);\r\n\r\n return affectedItems.map((item, index) => ({\r\n id: item.id,\r\n newPosition: orderList[index],\r\n }));\r\n };\r\n\r\n const handleDrop = ({ location, source }: any) => {\r\n const sourceIndex = source.data?.index as number;\r\n if (sourceIndex === undefined) return;\r\n\r\n const { dropTargets } = location.current;\r\n const destinationTarget = dropTargets.find(\r\n (target: any) =>\r\n target.data?.type === \"draggable-item\" &&\r\n target.data?.id !== source.data?.id\r\n );\r\n\r\n if (!destinationTarget) return;\r\n\r\n const edge = extractClosestEdge(destinationTarget);\r\n const targetIndex = Number(\r\n destinationTarget.element.getAttribute(\"data-index\")\r\n );\r\n const destinationIndex = edge === \"bottom\" ? targetIndex + 1 : targetIndex;\r\n\r\n if (sourceIndex !== destinationIndex) {\r\n const oldItems = [...items];\r\n const newItems = reorder(items, sourceIndex, destinationIndex);\r\n const orderUpdates = calculateOrderUpdates(oldItems, newItems);\r\n onReorder(newItems, orderUpdates);\r\n }\r\n };\r\n\r\n return monitorForElements({\r\n onDrop: handleDrop,\r\n });\r\n}\r\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\r\nimport { combine } from \"@atlaskit/pragmatic-drag-and-drop/combine\";\r\nimport { dropTargetForElements } from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport { DraggableItemWrapper } from \"./DraggableItemWrapper\";\r\nimport type { DragDropListProps, DraggableItem } from \"../types\";\r\nimport { useDragDropMonitor } from \"../hooks/useDragDropMonitor\";\r\nimport { defaultStyles } from \"../styles/defaultStyles\";\r\n\r\nexport function DragDropList<T extends DraggableItem>({\r\n items,\r\n onReorder,\r\n renderItem,\r\n containerClassName = \"\",\r\n containerStyle = {},\r\n itemClassName = \"\",\r\n itemStyle = {},\r\n dragPreviewClassName = \"\",\r\n dragPreviewStyle = {},\r\n onDragStart,\r\n onDragEnd,\r\n disabled = false,\r\n gap,\r\n direction = \"vertical\",\r\n showDropIndicator = false,\r\n dropIndicatorClassName = \"\",\r\n dropIndicatorStyle = {},\r\n}: DragDropListProps<T>) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const monitor = useDragDropMonitor({ items, onReorder, disabled });\r\n const [isDraggingOver, setIsDraggingOver] = useState(false);\r\n\r\n const getContainerStyles = (): React.CSSProperties => {\r\n const baseStyle = { ...defaultStyles.container.default };\r\n\r\n if (direction === \"horizontal\") {\r\n Object.assign(baseStyle, defaultStyles.container.horizontal);\r\n }\r\n\r\n if (isDraggingOver) {\r\n Object.assign(baseStyle, defaultStyles.container.dragging);\r\n }\r\n\r\n if (gap !== undefined) {\r\n baseStyle.gap = typeof gap === \"number\" ? `${gap}px` : gap;\r\n }\r\n\r\n return { ...baseStyle, ...containerStyle };\r\n };\r\n\r\n const createDropTarget = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return dropTargetForElements({\r\n element,\r\n getData: () => ({ type: \"container\" }),\r\n onDragEnter: () => setIsDraggingOver(true),\r\n onDragLeave: () => setIsDraggingOver(false),\r\n onDrop: () => setIsDraggingOver(false),\r\n });\r\n },\r\n [disabled]\r\n );\r\n\r\n useEffect(() => {\r\n const element = containerRef.current;\r\n if (!element || disabled) return;\r\n\r\n return combine(createDropTarget(element), monitor);\r\n }, [createDropTarget, monitor, disabled]);\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={containerClassName}\r\n style={getContainerStyles()}\r\n >\r\n {items.map((item, index) => (\r\n <DraggableItemWrapper\r\n key={item.id}\r\n item={item}\r\n index={index}\r\n className={itemClassName}\r\n style={itemStyle}\r\n dragPreviewClassName={dragPreviewClassName}\r\n dragPreviewStyle={dragPreviewStyle}\r\n onDragStart={onDragStart}\r\n onDragEnd={onDragEnd}\r\n disabled={disabled}\r\n showDropIndicator={showDropIndicator}\r\n dropIndicatorClassName={dropIndicatorClassName}\r\n dropIndicatorStyle={dropIndicatorStyle}\r\n >\r\n {renderItem(item, index)}\r\n </DraggableItemWrapper>\r\n ))}\r\n </div>\r\n );\r\n}\r\n"],"names":["defaultStyles","container","default","minHeight","transition","borderRadius","border","backgroundColor","display","flexDirection","gap","padding","dragging","borderColor","horizontal","flexWrap","item","cursor","userSelect","position","opacity","hover","transform","boxShadow","disabled","preview","pointerEvents","zIndex","dropIndicator","height","left","right","DRAGGABLE_ITEM","DraggableItemWrapper","index","children","className","style","dragPreviewClassName","dragPreviewStyle","onDragStart","onDragEnd","showDropIndicator","dropIndicatorClassName","dropIndicatorStyle","elementRef","useRef","isDragging","setIsDragging","useState","isHovered","setIsHovered","dropPosition","setDropPosition","createDraggable","useCallback","element","draggable","getInitialData","type","id","onGenerateDragPreview","nativeSetDragImage","previewElement","cloneNode","previewStyles","Object","assign","width","offsetWidth","offsetHeight","document","body","appendChild","requestAnimationFrame","remove","onDrop","createDropTarget","dropTargetForElements","getData","canDrop","args","_a","source","data","getIsSticky","onDragEnter","self","location","_b","edge","_c","current","dropTargets","onDragLeave","useEffect","setAttribute","toString","combine","React","createElement","ref","baseStyle","getItemStyles","top","bottom","useDragDropMonitor","items","onReorder","monitorForElements","sourceIndex","undefined","destinationTarget","find","target","extractClosestEdge","targetIndex","Number","getAttribute","destinationIndex","oldItems","newItems","list","startIndex","endIndex","result","Array","from","removed","splice","reorder","orderUpdates","affectedItems","filter","orderList","slice","sort","a","b","map","newPosition","calculateOrderUpdates","DragDropList","renderItem","containerClassName","containerStyle","itemClassName","itemStyle","direction","containerRef","monitor","isDraggingOver","setIsDraggingOver","getContainerStyles","key"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/styles/defaultStyles.ts","../src/components/DraggableItemWrapper.tsx","../src/hooks/useDragDropMonitor.ts","../src/utils/order.ts","../src/components/DragDropList.tsx"],"sourcesContent":["export const defaultStyles = {\r\n container: {\r\n default: {\r\n minHeight: \"200px\",\r\n transition: \"all 0.2s ease\",\r\n borderRadius: \"8px\",\r\n border: \"1px solid #e2e8f0\",\r\n backgroundColor: \"#ffffff\",\r\n display: \"flex\",\r\n flexDirection: \"column\" as const,\r\n gap: \"16px\",\r\n padding: \"16px\",\r\n },\r\n dragging: {\r\n backgroundColor: \"rgba(66, 153, 225, 0.05)\",\r\n borderColor: \"#3182ce\",\r\n },\r\n horizontal: {\r\n flexDirection: \"row\" as const,\r\n flexWrap: \"wrap\" as const,\r\n },\r\n },\r\n item: {\r\n default: {\r\n transition: \"all 0.2s ease\",\r\n cursor: \"grab\",\r\n userSelect: \"none\" as const,\r\n position: \"relative\" as const,\r\n },\r\n dragging: {\r\n opacity: 0.5,\r\n cursor: \"grabbing\",\r\n },\r\n hover: {\r\n transform: \"scale(1.02)\",\r\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\r\n },\r\n disabled: {\r\n cursor: \"not-allowed\",\r\n opacity: 0.6,\r\n },\r\n },\r\n preview: {\r\n position: \"fixed\" as const,\r\n pointerEvents: \"none\" as const,\r\n zIndex: 9999,\r\n opacity: 0.8,\r\n transform: \"rotate(2deg)\",\r\n boxShadow: \"0 10px 20px rgba(0, 0, 0, 0.15)\",\r\n },\r\n dropIndicator: {\r\n position: \"absolute\" as const,\r\n height: \"2px\",\r\n backgroundColor: \"#3182ce\",\r\n left: 0,\r\n right: 0,\r\n zIndex: 10,\r\n transition: \"all 0.2s ease\",\r\n },\r\n};\r\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\r\nimport { combine } from \"@atlaskit/pragmatic-drag-and-drop/combine\";\r\nimport {\r\n draggable,\r\n dropTargetForElements,\r\n} from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport type { DraggableItemWrapperProps, DraggableItem } from \"../types\";\r\nimport { defaultStyles } from \"../styles/defaultStyles\";\r\n\r\nconst DRAGGABLE_ITEM = \"draggable-item\";\r\n\r\nexport function DraggableItemWrapper<T extends DraggableItem>({\r\n item,\r\n index,\r\n children,\r\n className = \"\",\r\n style = {},\r\n dragPreviewClassName = \"\",\r\n dragPreviewStyle = {},\r\n onDragStart,\r\n onDragEnd,\r\n disabled = false,\r\n showDropIndicator = false,\r\n dropIndicatorClassName = \"\",\r\n dropIndicatorStyle = {},\r\n dropIndicatorPosition = \"bottom\",\r\n}: DraggableItemWrapperProps<T>) {\r\n const elementRef = useRef<HTMLDivElement>(null);\r\n const [isDragging, setIsDragging] = useState(false);\r\n const [isHovered, setIsHovered] = useState(false);\r\n const [dropPosition, setDropPosition] = useState<\"top\" | \"bottom\" | null>(\r\n null\r\n );\r\n\r\n const getItemStyles = (): React.CSSProperties => {\r\n const baseStyle = { ...defaultStyles.item.default };\r\n\r\n if (disabled) {\r\n Object.assign(baseStyle, defaultStyles.item.disabled);\r\n } else if (isDragging) {\r\n Object.assign(baseStyle, defaultStyles.item.dragging);\r\n } else if (isHovered) {\r\n Object.assign(baseStyle, defaultStyles.item.hover);\r\n }\r\n\r\n return { ...baseStyle, ...style };\r\n };\r\n\r\n const getPreviewStyles = (): React.CSSProperties => {\r\n return { ...defaultStyles.preview, ...dragPreviewStyle };\r\n };\r\n\r\n const createDraggable = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return draggable({\r\n element,\r\n getInitialData: () => ({\r\n type: DRAGGABLE_ITEM,\r\n id: item.id,\r\n index,\r\n }),\r\n onGenerateDragPreview: ({ nativeSetDragImage }) => {\r\n const previewElement = element.cloneNode(true) as HTMLElement;\r\n const previewStyles = getPreviewStyles();\r\n\r\n // Apply custom preview class if provided\r\n if (dragPreviewClassName) {\r\n previewElement.className = dragPreviewClassName;\r\n }\r\n\r\n Object.assign(previewElement.style, previewStyles, {\r\n width: `${element?.offsetWidth || 100}px`,\r\n height: `${element?.offsetHeight || 50}px`,\r\n });\r\n\r\n document.body.appendChild(previewElement);\r\n if (nativeSetDragImage) {\r\n nativeSetDragImage(previewElement, 20, 20);\r\n }\r\n requestAnimationFrame(() => previewElement.remove());\r\n },\r\n onDragStart: () => {\r\n setIsDragging(true);\r\n onDragStart?.(item, index);\r\n },\r\n onDrop: () => {\r\n setIsDragging(false);\r\n onDragEnd?.(item, index);\r\n },\r\n });\r\n },\r\n [\r\n item,\r\n index,\r\n dragPreviewClassName,\r\n dragPreviewStyle,\r\n onDragStart,\r\n onDragEnd,\r\n disabled,\r\n ]\r\n );\r\n\r\n const createDropTarget = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return dropTargetForElements({\r\n element,\r\n getData: () => ({\r\n type: DRAGGABLE_ITEM,\r\n id: item.id,\r\n index,\r\n }),\r\n canDrop: (args: any) => args.source.data?.type === DRAGGABLE_ITEM,\r\n getIsSticky: () => true,\r\n onDragEnter: ({ source, self }: any) => {\r\n if (source.data?.id !== self.data?.id) {\r\n setIsHovered(true);\r\n if (showDropIndicator) {\r\n setDropPosition(dropIndicatorPosition);\r\n }\r\n }\r\n },\r\n onDragLeave: () => {\r\n setIsHovered(false);\r\n setDropPosition(null);\r\n },\r\n onDrop: () => {\r\n setIsHovered(false);\r\n setDropPosition(null);\r\n },\r\n });\r\n },\r\n [item.id, index, disabled, showDropIndicator, dropIndicatorPosition]\r\n );\r\n\r\n useEffect(() => {\r\n const element = elementRef.current;\r\n if (!element) return;\r\n\r\n element.setAttribute(\"data-index\", index.toString());\r\n\r\n if (disabled) {\r\n // provide a no-op cleanup to satisfy all code paths\r\n return () => {};\r\n }\r\n\r\n // normal draggable + droptarget setup\r\n return combine(createDraggable(element), createDropTarget(element));\r\n }, [index, createDraggable, createDropTarget, disabled]);\r\n\r\n return (\r\n <div ref={elementRef} className={className} style={getItemStyles()}>\r\n {showDropIndicator && dropPosition === \"top\" && (\r\n <div\r\n className={dropIndicatorClassName}\r\n style={{\r\n ...defaultStyles.dropIndicator,\r\n ...dropIndicatorStyle,\r\n top: -1,\r\n }}\r\n />\r\n )}\r\n {children}\r\n {showDropIndicator && dropPosition === \"bottom\" && (\r\n <div\r\n className={dropIndicatorClassName}\r\n style={{\r\n ...defaultStyles.dropIndicator,\r\n ...dropIndicatorStyle,\r\n bottom: -1,\r\n }}\r\n />\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { monitorForElements } from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport { extractClosestEdge } from \"@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge\";\r\nimport type { DraggableItem, OrderUpdate } from \"../types\";\r\nimport { reorder, calculateOrderUpdates } from \"../utils/order\";\r\n\r\nexport function useDragDropMonitor<T extends DraggableItem>({\r\n items,\r\n onReorder,\r\n disabled = false,\r\n}: {\r\n items: T[];\r\n onReorder: (newItems: T[], orderUpdates: OrderUpdate[]) => void;\r\n disabled?: boolean;\r\n}) {\r\n if (disabled) {\r\n return () => {};\r\n }\r\n\r\n\r\n const handleDrop = ({ location, source }: any) => {\r\n const sourceIndex = source.data?.index as number;\r\n if (sourceIndex === undefined) return;\r\n\r\n const { dropTargets } = location.current;\r\n const destinationTarget = dropTargets.find(\r\n (target: any) =>\r\n target.data?.type === \"draggable-item\" &&\r\n target.data?.id !== source.data?.id\r\n );\r\n\r\n if (!destinationTarget) return;\r\n\r\n const edge = extractClosestEdge(destinationTarget);\r\n const targetIndex = Number(\r\n destinationTarget.element.getAttribute(\"data-index\")\r\n );\r\n const destinationIndex = edge === \"bottom\" ? targetIndex + 1 : targetIndex;\r\n\r\n if (sourceIndex !== destinationIndex) {\r\n const oldItems = [...items];\r\n const newItems = reorder(items, sourceIndex, destinationIndex);\r\n const orderUpdates = calculateOrderUpdates(oldItems, newItems);\r\n onReorder(newItems, orderUpdates);\r\n }\r\n };\r\n\r\n return monitorForElements({\r\n onDrop: handleDrop,\r\n });\r\n}\r\n","import type { DraggableItem, OrderUpdate } from '../types';\r\n\r\nexport function reorder<T>(list: T[], startIndex: number, endIndex: number): T[] {\r\n const result = Array.from(list);\r\n const [removed] = result.splice(startIndex, 1);\r\n result.splice(endIndex, 0, removed);\r\n return result;\r\n}\r\n\r\nexport function calculateOrderUpdates<T extends DraggableItem>(oldItems: T[], newItems: T[]): OrderUpdate[] {\r\n const affected = newItems.filter((item, i) => item.id !== oldItems[i]?.id);\r\n const orderList = affected.slice().sort((a, b) => a.position - b.position).map(i => i.position);\r\n return affected.map((item, i) => ({ id: item.id, newPosition: orderList[i] }));\r\n}\r\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\r\nimport { combine } from \"@atlaskit/pragmatic-drag-and-drop/combine\";\r\nimport { dropTargetForElements } from \"@atlaskit/pragmatic-drag-and-drop/element/adapter\";\r\nimport { DraggableItemWrapper } from \"./DraggableItemWrapper\";\r\nimport type { DragDropListProps, DraggableItem } from \"../types\";\r\nimport { useDragDropMonitor } from \"../hooks/useDragDropMonitor\";\r\nimport { defaultStyles } from \"../styles/defaultStyles\";\r\n\r\nexport function DragDropList<T extends DraggableItem>({\r\n items,\r\n onReorder,\r\n renderItem,\r\n containerClassName = \"\",\r\n containerStyle = {},\r\n itemClassName = \"\",\r\n itemStyle = {},\r\n dragPreviewClassName = \"\",\r\n dragPreviewStyle = {},\r\n onDragStart,\r\n onDragEnd,\r\n disabled = false,\r\n gap,\r\n direction = \"vertical\",\r\n showDropIndicator = false,\r\n dropIndicatorClassName = \"\",\r\n dropIndicatorStyle = {},\r\n dropIndicatorPosition = \"bottom\",\r\n}: DragDropListProps<T>) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const monitor = useDragDropMonitor({ items, onReorder, disabled });\r\n const [isDraggingOver, setIsDraggingOver] = useState(false);\r\n\r\n const getContainerStyles = (): React.CSSProperties => {\r\n const baseStyle = { ...defaultStyles.container.default };\r\n\r\n if (direction === \"horizontal\") {\r\n Object.assign(baseStyle, defaultStyles.container.horizontal);\r\n }\r\n\r\n if (isDraggingOver) {\r\n Object.assign(baseStyle, defaultStyles.container.dragging);\r\n }\r\n\r\n if (gap !== undefined) {\r\n baseStyle.gap = typeof gap === \"number\" ? `${gap}px` : gap;\r\n }\r\n\r\n return { ...baseStyle, ...containerStyle };\r\n };\r\n\r\n const createDropTarget = useCallback(\r\n (element: HTMLElement) => {\r\n if (disabled) return () => {};\r\n\r\n return dropTargetForElements({\r\n element,\r\n getData: () => ({ type: \"container\" }),\r\n onDragEnter: () => setIsDraggingOver(true),\r\n onDragLeave: () => setIsDraggingOver(false),\r\n onDrop: () => setIsDraggingOver(false),\r\n });\r\n },\r\n [disabled]\r\n );\r\n\r\n useEffect(() => {\r\n const element = containerRef.current;\r\n if (!element || disabled) return;\r\n\r\n return combine(createDropTarget(element), monitor);\r\n }, [createDropTarget, monitor, disabled]);\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={containerClassName}\r\n style={getContainerStyles()}\r\n >\r\n {items.map((item, index) => (\r\n <DraggableItemWrapper\r\n key={item.id}\r\n item={item}\r\n index={index}\r\n className={itemClassName}\r\n style={itemStyle}\r\n dragPreviewClassName={dragPreviewClassName}\r\n dragPreviewStyle={dragPreviewStyle}\r\n onDragStart={onDragStart}\r\n onDragEnd={onDragEnd}\r\n disabled={disabled}\r\n showDropIndicator={showDropIndicator}\r\n dropIndicatorClassName={dropIndicatorClassName}\r\n dropIndicatorStyle={dropIndicatorStyle}\r\n dropIndicatorPosition={dropIndicatorPosition}\r\n >\r\n {renderItem(item, index)}\r\n </DraggableItemWrapper>\r\n ))}\r\n </div>\r\n );\r\n}\r\n"],"names":["defaultStyles","container","default","minHeight","transition","borderRadius","border","backgroundColor","display","flexDirection","gap","padding","dragging","borderColor","horizontal","flexWrap","item","cursor","userSelect","position","opacity","hover","transform","boxShadow","disabled","preview","pointerEvents","zIndex","dropIndicator","height","left","right","DRAGGABLE_ITEM","DraggableItemWrapper","index","children","className","style","dragPreviewClassName","dragPreviewStyle","onDragStart","onDragEnd","showDropIndicator","dropIndicatorClassName","dropIndicatorStyle","dropIndicatorPosition","elementRef","useRef","isDragging","setIsDragging","useState","isHovered","setIsHovered","dropPosition","setDropPosition","createDraggable","useCallback","element","draggable","getInitialData","type","id","onGenerateDragPreview","nativeSetDragImage","previewElement","cloneNode","previewStyles","Object","assign","width","offsetWidth","offsetHeight","document","body","appendChild","requestAnimationFrame","remove","onDrop","createDropTarget","dropTargetForElements","getData","canDrop","args","_a","source","data","getIsSticky","onDragEnter","self","_b","onDragLeave","useEffect","current","setAttribute","toString","combine","React","createElement","ref","baseStyle","getItemStyles","top","bottom","useDragDropMonitor","items","onReorder","monitorForElements","location","sourceIndex","undefined","dropTargets","destinationTarget","find","target","_c","edge","extractClosestEdge","targetIndex","Number","getAttribute","destinationIndex","oldItems","newItems","list","startIndex","endIndex","result","Array","from","removed","splice","reorder","orderUpdates","affected","filter","i","orderList","slice","sort","a","b","map","newPosition","calculateOrderUpdates","DragDropList","renderItem","containerClassName","containerStyle","itemClassName","itemStyle","direction","containerRef","monitor","isDraggingOver","setIsDraggingOver","getContainerStyles","key"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react"),t=require("@atlaskit/pragmatic-drag-and-drop/combine"),a=require("@atlaskit/pragmatic-drag-and-drop/element/adapter"),r=require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");const o={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"}},i="draggable-item";function n({item:r,index:n,children:s,className:d="",style:l={},dragPreviewClassName:c="",dragPreviewStyle:g={},onDragStart:p,onDragEnd:u,disabled:m=!1,showDropIndicator:b=!1,dropIndicatorClassName:v="",dropIndicatorStyle:f={}}){const x=e.useRef(null),[D,y]=e.useState(!1),[S,h]=e.useState(!1),[j,O]=e.useState(null),w=e.useCallback(e=>m?()=>{}:a.draggable({element:e,getInitialData:()=>({type:i,id:r.id,index:n}),onGenerateDragPreview:({nativeSetDragImage:t})=>{const a=e.cloneNode(!0),r=Object.assign(Object.assign({},o.preview),g);c&&(a.className=c),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:()=>{y(!0),null==p||p(r,n)},onDrop:()=>{y(!1),null==u||u(r,n)}}),[r,n,c,g,p,u,m]),I=e.useCallback(e=>m?()=>{}:a.dropTargetForElements({element:e,getData:()=>({type:i,id:r.id,index:n}),canDrop:e=>{var t;return(null===(t=e.source.data)||void 0===t?void 0:t.type)===i},getIsSticky:()=>!0,onDragEnter:({source:e,self:t,location:a})=>{var r,o,i;if((null===(r=e.data)||void 0===r?void 0:r.id)!==(null===(o=t.data)||void 0===o?void 0:o.id)&&(h(!0),b)){const e=null===(i=a.current.dropTargets[0])||void 0===i?void 0:i.edge;O("top"===e?"top":"bottom")}},onDragLeave:()=>{h(!1),O(null)},onDrop:()=>{h(!1),O(null)}}),[r.id,n,m,b]);return e.useEffect(()=>{const e=x.current;if(e)return e.setAttribute("data-index",n.toString()),m?()=>{}:t.combine(w(e),I(e))},[n,w,I,m]),e.createElement("div",{ref:x,className:d,style:(()=>{const e=Object.assign({},o.item.default);return m?Object.assign(e,o.item.disabled):D?Object.assign(e,o.item.dragging):S&&Object.assign(e,o.item.hover),Object.assign(Object.assign({},e),l)})()},b&&"top"===j&&e.createElement("div",{className:v,style:Object.assign(Object.assign(Object.assign({},o.dropIndicator),f),{top:-1})}),s,b&&"bottom"===j&&e.createElement("div",{className:v,style:Object.assign(Object.assign(Object.assign({},o.dropIndicator),f),{bottom:-1})}))}function s({items:e,onReorder:t,disabled:o=!1}){if(o)return()=>{};return a.monitorForElements({onDrop:({location:a,source:o})=>{var i;const n=null===(i=o.data)||void 0===i?void 0:i.index;if(void 0===n)return;const{dropTargets:s}=a.current,d=s.find(e=>{var t,a,r;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===(r=o.data)||void 0===r?void 0:r.id)});if(!d)return;const l=r.extractClosestEdge(d),c=Number(d.element.getAttribute("data-index")),g="bottom"===l?c+1:c;if(n!==g){const a=[...e],r=((e,t,a)=>{const r=Array.from(e),[o]=r.splice(t,1);return r.splice(a,0,o),r})(e,n,g),o=((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)}}})}exports.DragDropList=function({items:r,onReorder:i,renderItem:d,containerClassName:l="",containerStyle:c={},itemClassName:g="",itemStyle:p={},dragPreviewClassName:u="",dragPreviewStyle:m={},onDragStart:b,onDragEnd:v,disabled:f=!1,gap:x,direction:D="vertical",showDropIndicator:y=!1,dropIndicatorClassName:S="",dropIndicatorStyle:h={}}){const j=e.useRef(null),O=s({items:r,onReorder:i,disabled:f}),[w,I]=e.useState(!1),C=e.useCallback(e=>f?()=>{}:a.dropTargetForElements({element:e,getData:()=>({type:"container"}),onDragEnter:()=>I(!0),onDragLeave:()=>I(!1),onDrop:()=>I(!1)}),[f]);return e.useEffect(()=>{const e=j.current;if(e&&!f)return t.combine(C(e),O)},[C,O,f]),e.createElement("div",{ref:j,className:l,style:(()=>{const e=Object.assign({},o.container.default);return"horizontal"===D&&Object.assign(e,o.container.horizontal),w&&Object.assign(e,o.container.dragging),void 0!==x&&(e.gap="number"==typeof x?`${x}px`:x),Object.assign(Object.assign({},e),c)})()},r.map((t,a)=>e.createElement(n,{key:t.id,item:t,index:a,className:g,style:p,dragPreviewClassName:u,dragPreviewStyle:m,onDragStart:b,onDragEnd:v,disabled:f,showDropIndicator:y,dropIndicatorClassName:S,dropIndicatorStyle:h},d(t,a))))},exports.DraggableItemWrapper=n,exports.defaultStyles=o,exports.useDragDropMonitor=s;
1
+ "use strict";var e=require("react"),t=require("@atlaskit/pragmatic-drag-and-drop/combine"),r=require("@atlaskit/pragmatic-drag-and-drop/element/adapter"),a=require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");const o={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"}},i="draggable-item";function n({item:a,index:n,children:s,className:d="",style:l={},dragPreviewClassName:c="",dragPreviewStyle:g={},onDragStart:p,onDragEnd:u,disabled:m=!1,showDropIndicator:b=!1,dropIndicatorClassName:f="",dropIndicatorStyle:v={},dropIndicatorPosition:x="bottom"}){const D=e.useRef(null),[y,S]=e.useState(!1),[h,I]=e.useState(!1),[j,O]=e.useState(null),w=e.useCallback(e=>m?()=>{}:r.draggable({element:e,getInitialData:()=>({type:i,id:a.id,index:n}),onGenerateDragPreview:({nativeSetDragImage:t})=>{const r=e.cloneNode(!0),a=Object.assign(Object.assign({},o.preview),g);c&&(r.className=c),Object.assign(r.style,a,{width:`${(null==e?void 0:e.offsetWidth)||100}px`,height:`${(null==e?void 0:e.offsetHeight)||50}px`}),document.body.appendChild(r),t&&t(r,20,20),requestAnimationFrame(()=>r.remove())},onDragStart:()=>{S(!0),null==p||p(a,n)},onDrop:()=>{S(!1),null==u||u(a,n)}}),[a,n,c,g,p,u,m]),C=e.useCallback(e=>m?()=>{}:r.dropTargetForElements({element:e,getData:()=>({type:i,id:a.id,index:n}),canDrop:e=>{var t;return(null===(t=e.source.data)||void 0===t?void 0:t.type)===i},getIsSticky:()=>!0,onDragEnter:({source:e,self:t})=>{var r,a;(null===(r=e.data)||void 0===r?void 0:r.id)!==(null===(a=t.data)||void 0===a?void 0:a.id)&&(I(!0),b&&O(x))},onDragLeave:()=>{I(!1),O(null)},onDrop:()=>{I(!1),O(null)}}),[a.id,n,m,b,x]);return e.useEffect(()=>{const e=D.current;if(e)return e.setAttribute("data-index",n.toString()),m?()=>{}:t.combine(w(e),C(e))},[n,w,C,m]),e.createElement("div",{ref:D,className:d,style:(()=>{const e=Object.assign({},o.item.default);return m?Object.assign(e,o.item.disabled):y?Object.assign(e,o.item.dragging):h&&Object.assign(e,o.item.hover),Object.assign(Object.assign({},e),l)})()},b&&"top"===j&&e.createElement("div",{className:f,style:Object.assign(Object.assign(Object.assign({},o.dropIndicator),v),{top:-1})}),s,b&&"bottom"===j&&e.createElement("div",{className:f,style:Object.assign(Object.assign(Object.assign({},o.dropIndicator),v),{bottom:-1})}))}function s({items:e,onReorder:t,disabled:o=!1}){if(o)return()=>{};return r.monitorForElements({onDrop:({location:r,source:o})=>{var i;const n=null===(i=o.data)||void 0===i?void 0:i.index;if(void 0===n)return;const{dropTargets:s}=r.current,d=s.find(e=>{var t,r,a;return"draggable-item"===(null===(t=e.data)||void 0===t?void 0:t.type)&&(null===(r=e.data)||void 0===r?void 0:r.id)!==(null===(a=o.data)||void 0===a?void 0:a.id)});if(!d)return;const l=a.extractClosestEdge(d),c=Number(d.element.getAttribute("data-index")),g="bottom"===l?c+1:c;if(n!==g){const r=[...e],a=function(e,t,r){const a=Array.from(e),[o]=a.splice(t,1);return a.splice(r,0,o),a}(e,n,g),o=function(e,t){const r=t.filter((t,r)=>{var a;return t.id!==(null===(a=e[r])||void 0===a?void 0:a.id)}),a=r.slice().sort((e,t)=>e.position-t.position).map(e=>e.position);return r.map((e,t)=>({id:e.id,newPosition:a[t]}))}(r,a);t(a,o)}}})}exports.DragDropList=function({items:a,onReorder:i,renderItem:d,containerClassName:l="",containerStyle:c={},itemClassName:g="",itemStyle:p={},dragPreviewClassName:u="",dragPreviewStyle:m={},onDragStart:b,onDragEnd:f,disabled:v=!1,gap:x,direction:D="vertical",showDropIndicator:y=!1,dropIndicatorClassName:S="",dropIndicatorStyle:h={},dropIndicatorPosition:I="bottom"}){const j=e.useRef(null),O=s({items:a,onReorder:i,disabled:v}),[w,C]=e.useState(!1),E=e.useCallback(e=>v?()=>{}:r.dropTargetForElements({element:e,getData:()=>({type:"container"}),onDragEnter:()=>C(!0),onDragLeave:()=>C(!1),onDrop:()=>C(!1)}),[v]);return e.useEffect(()=>{const e=j.current;if(e&&!v)return t.combine(E(e),O)},[E,O,v]),e.createElement("div",{ref:j,className:l,style:(()=>{const e=Object.assign({},o.container.default);return"horizontal"===D&&Object.assign(e,o.container.horizontal),w&&Object.assign(e,o.container.dragging),void 0!==x&&(e.gap="number"==typeof x?`${x}px`:x),Object.assign(Object.assign({},e),c)})()},a.map((t,r)=>e.createElement(n,{key:t.id,item:t,index:r,className:g,style:p,dragPreviewClassName:u,dragPreviewStyle:m,onDragStart:b,onDragEnd:f,disabled:v,showDropIndicator:y,dropIndicatorClassName:S,dropIndicatorStyle:h,dropIndicatorPosition:I},d(t,r))))},exports.DraggableItemWrapper=n,exports.defaultStyles=o,exports.useDragDropMonitor=s;
2
2
  //# sourceMappingURL=index.js.map