playbook_ui 15.6.0.pre.alpha.draggableask12898 → 15.6.0.pre.alpha.play2552collapsibleiconrefactor12903
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +2 -2
- data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleIcon.tsx +10 -8
- data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_icons.jsx +0 -1
- data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_state.jsx +0 -3
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +15 -313
- data/app/pb_kits/playbook/tokens/_colors.scss +2 -1
- data/dist/chunks/_typeahead-DHGyRtix.js +6 -0
- data/dist/chunks/{lib-CgpqUb6l.js → lib-BxonsVJa.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +3 -3
- data/dist/chunks/_typeahead-319r1pyq.js +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b56117c9b815041948a7dc894ebad0caebf095ff1da7801e06ed7fec18da7eeb
|
|
4
|
+
data.tar.gz: 8e9f82470ea23ae8863567c8df94451dd927cdcbbaa7cf9d174a5fcd2ee627b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 58c7104cca8322ba83b49875a68bc2a0a49ed6334337bf4a0e00bfa6d8c062bc45b8aadbe2644592a9dc358348cd972b47fef79efb89fbf32135c2f345f6bbd0
|
|
7
|
+
data.tar.gz: 1c1933805f799e9aeca540a29d3ac0861de4c8c8900ecfb62c7e1ea5eb1800e0df5d7dd4164afffb92788d84d19ed486921d7a572afcf4cf5823c5eeb64d5784
|
|
@@ -25,11 +25,11 @@ exports[`html structure is correct 1`] = `
|
|
|
25
25
|
>
|
|
26
26
|
<div
|
|
27
27
|
class="icon_wrapper"
|
|
28
|
-
style="vertical-align: middle;
|
|
28
|
+
style="vertical-align: middle;"
|
|
29
29
|
>
|
|
30
30
|
<svg
|
|
31
31
|
aria-label="chevron-down icon"
|
|
32
|
-
class="pb_custom_icon svg-inline--fa svg_lg svg_fw"
|
|
32
|
+
class="pb_custom_icon svg-inline--fa color_text_lt_lighter svg_lg svg_fw"
|
|
33
33
|
color="currentColor"
|
|
34
34
|
fill="none"
|
|
35
35
|
height="auto"
|
|
@@ -27,12 +27,12 @@ type colorMap = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const colorMap = {
|
|
30
|
-
default:
|
|
31
|
-
light: "
|
|
32
|
-
lighter: "
|
|
33
|
-
link: "
|
|
34
|
-
error: "
|
|
35
|
-
success: "
|
|
30
|
+
default:"text_lt_default",
|
|
31
|
+
light: "text_lt_light",
|
|
32
|
+
lighter: "text_lt_lighter",
|
|
33
|
+
link: "primary",
|
|
34
|
+
error: "error",
|
|
35
|
+
success: "text_dk_success_sm",
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
const CollapsibleIcon = ({
|
|
@@ -68,9 +68,10 @@ const CollapsibleIcon = ({
|
|
|
68
68
|
className="icon_wrapper"
|
|
69
69
|
key={icon ? showIcon(icon)[0] : "chevron-down"}
|
|
70
70
|
onClick={(e) => handleIconClick(e)}
|
|
71
|
-
style={{ verticalAlign: "middle"
|
|
71
|
+
style={{ verticalAlign: "middle"}}
|
|
72
72
|
>
|
|
73
73
|
<Icon
|
|
74
|
+
color={color}
|
|
74
75
|
icon={icon ? showIcon(icon)[0] : "chevron-down"}
|
|
75
76
|
size={iconSize}
|
|
76
77
|
/>
|
|
@@ -80,9 +81,10 @@ const CollapsibleIcon = ({
|
|
|
80
81
|
className="icon_wrapper"
|
|
81
82
|
key={icon ? showIcon(icon)[1] : "chevron-up"}
|
|
82
83
|
onClick={(e) => handleIconClick(e)}
|
|
83
|
-
style={{ verticalAlign: "middle"
|
|
84
|
+
style={{ verticalAlign: "middle" }}
|
|
84
85
|
>
|
|
85
86
|
<Icon
|
|
87
|
+
color={color}
|
|
86
88
|
icon={icon ? showIcon(icon)[1] : "chevron-up"}
|
|
87
89
|
size={iconSize}
|
|
88
90
|
/>
|
|
@@ -22,7 +22,6 @@ const CollapsibleState = (props) => {
|
|
|
22
22
|
<Collapsible
|
|
23
23
|
collapsed={isCollapsed}
|
|
24
24
|
icon={["plus", "minus"]}
|
|
25
|
-
iconColor='white'
|
|
26
25
|
padding="none"
|
|
27
26
|
>
|
|
28
27
|
<Collapsible.Main padding="sm"
|
|
@@ -41,7 +40,6 @@ const CollapsibleState = (props) => {
|
|
|
41
40
|
<Collapsible
|
|
42
41
|
collapsed={isCollapsed}
|
|
43
42
|
icon={["plus", "minus"]}
|
|
44
|
-
iconColor='white'
|
|
45
43
|
padding="none"
|
|
46
44
|
>
|
|
47
45
|
<Collapsible.Main padding="sm"
|
|
@@ -60,7 +58,6 @@ const CollapsibleState = (props) => {
|
|
|
60
58
|
<Collapsible
|
|
61
59
|
collapsed={isCollapsed}
|
|
62
60
|
icon={["plus", "minus"]}
|
|
63
|
-
iconColor='white'
|
|
64
61
|
padding="none"
|
|
65
62
|
>
|
|
66
63
|
<Collapsible.Main padding="sm"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { createContext, useReducer, useContext, useEffect, useMemo
|
|
1
|
+
import React, { createContext, useReducer, useContext, useEffect, useMemo } from "react";
|
|
2
2
|
import { InitialStateType, ActionType, DraggableProviderType } from "./types";
|
|
3
3
|
|
|
4
4
|
const initialState: InitialStateType = {
|
|
@@ -92,19 +92,6 @@ const reducer = (state: InitialStateType, action: ActionType) => {
|
|
|
92
92
|
return { ...state, items: newItems };
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// Reset item back to its original container (e.g., when drag ends without valid drop)
|
|
96
|
-
case "RESET_DRAG_CONTAINER": {
|
|
97
|
-
const { itemId, originalContainer } = action.payload;
|
|
98
|
-
return {
|
|
99
|
-
...state,
|
|
100
|
-
items: state.items.map(item =>
|
|
101
|
-
item.id === itemId
|
|
102
|
-
? { ...item, container: originalContainer }
|
|
103
|
-
: item
|
|
104
|
-
)
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
95
|
default:
|
|
109
96
|
return state;
|
|
110
97
|
}
|
|
@@ -132,27 +119,6 @@ export const DraggableProvider = ({
|
|
|
132
119
|
enableCrossContainerPreview = false,
|
|
133
120
|
}: DraggableProviderType) => {
|
|
134
121
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
135
|
-
|
|
136
|
-
// Track drag state for global listener
|
|
137
|
-
const dragStateRef = useRef<{
|
|
138
|
-
isDragging: boolean;
|
|
139
|
-
draggedItemId: string;
|
|
140
|
-
originalContainer: string;
|
|
141
|
-
currentContainer: string;
|
|
142
|
-
dropOccurred: boolean;
|
|
143
|
-
}>({
|
|
144
|
-
isDragging: false,
|
|
145
|
-
draggedItemId: '',
|
|
146
|
-
originalContainer: '',
|
|
147
|
-
currentContainer: '',
|
|
148
|
-
dropOccurred: false,
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// Track current state for use in gated event listeners (avoid stale closures)
|
|
152
|
-
const stateRef = useRef(state);
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
stateRef.current = state;
|
|
155
|
-
}, [state]);
|
|
156
122
|
|
|
157
123
|
// Parse dropZone prop - handle both string format (backward compatibility) and object format
|
|
158
124
|
let dropZoneType = 'ghost';
|
|
@@ -182,224 +148,7 @@ export const DraggableProvider = ({
|
|
|
182
148
|
onReorder(state.items);
|
|
183
149
|
}, [state.items]);
|
|
184
150
|
|
|
185
|
-
// Monitor for failed drops by detecting mouse/pointer release during drag (this is needed for cross container preview)
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
if (!enableCrossContainerPreview) return;
|
|
188
|
-
|
|
189
|
-
// Allow drops anywhere on the document by preventing default dragover
|
|
190
|
-
const handleGlobalDragOver = (e: DragEvent) => {
|
|
191
|
-
if (dragStateRef.current.isDragging) {
|
|
192
|
-
e.preventDefault();
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// Handle drops anywhere on the document (including non-container areas)
|
|
197
|
-
const handleGlobalDrop = (e: DragEvent) => {
|
|
198
|
-
if (!dragStateRef.current.isDragging) return;
|
|
199
|
-
|
|
200
|
-
// If a container already handled the drop, don't process again
|
|
201
|
-
if (dragStateRef.current.dropOccurred) return;
|
|
202
|
-
|
|
203
|
-
e.preventDefault();
|
|
204
|
-
|
|
205
|
-
const currentContainer = dragStateRef.current.currentContainer;
|
|
206
|
-
|
|
207
|
-
// If item is in a different container than original, treat it as a successful drop
|
|
208
|
-
if (currentContainer && currentContainer !== dragStateRef.current.originalContainer) {
|
|
209
|
-
|
|
210
|
-
// Mark as dropped so other handlers know
|
|
211
|
-
dragStateRef.current.dropOccurred = true;
|
|
212
|
-
|
|
213
|
-
// Trigger onDrop callback with the current container
|
|
214
|
-
if (onDrop) {
|
|
215
|
-
const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
216
|
-
const updatedItem = draggedItem ? { ...draggedItem, container: currentContainer } : null;
|
|
217
|
-
const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
|
|
218
|
-
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
219
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
220
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
221
|
-
|
|
222
|
-
onDrop(
|
|
223
|
-
dragStateRef.current.draggedItemId,
|
|
224
|
-
currentContainer,
|
|
225
|
-
dragStateRef.current.originalContainer,
|
|
226
|
-
updatedItem,
|
|
227
|
-
itemAbove,
|
|
228
|
-
itemBelow
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Trigger onDragEnd callback
|
|
233
|
-
if (onDragEnd) {
|
|
234
|
-
const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
|
|
235
|
-
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
236
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
237
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
238
|
-
|
|
239
|
-
onDragEnd(
|
|
240
|
-
dragStateRef.current.draggedItemId,
|
|
241
|
-
currentContainer,
|
|
242
|
-
dragStateRef.current.originalContainer,
|
|
243
|
-
itemAbove,
|
|
244
|
-
itemBelow
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
249
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
250
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
251
|
-
} else {
|
|
252
|
-
// Reset to original container (item didn't move or dropped in invalid zone)
|
|
253
|
-
const originalContainer = dragStateRef.current.originalContainer;
|
|
254
|
-
|
|
255
|
-
dispatch({
|
|
256
|
-
type: 'RESET_DRAG_CONTAINER',
|
|
257
|
-
payload: {
|
|
258
|
-
itemId: dragStateRef.current.draggedItemId,
|
|
259
|
-
originalContainer: originalContainer,
|
|
260
|
-
},
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// Call onDrop with original container info
|
|
264
|
-
if (onDrop) {
|
|
265
|
-
const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
266
|
-
const updatedItem = draggedItem ? { ...draggedItem, container: originalContainer } : null;
|
|
267
|
-
const itemsInContainer = stateRef.current.items.filter(item => item && item.container === originalContainer);
|
|
268
|
-
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
269
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
270
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
271
|
-
|
|
272
|
-
onDrop(
|
|
273
|
-
dragStateRef.current.draggedItemId,
|
|
274
|
-
originalContainer,
|
|
275
|
-
originalContainer,
|
|
276
|
-
updatedItem,
|
|
277
|
-
itemAbove,
|
|
278
|
-
itemBelow
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
283
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
284
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const handleGlobalMouseUp = () => {
|
|
289
|
-
// If we're dragging and mouse is released, wait a bit to see if drop occurs
|
|
290
|
-
if (dragStateRef.current.isDragging) {
|
|
291
|
-
setTimeout(() => {
|
|
292
|
-
const currentContainer = dragStateRef.current.currentContainer;
|
|
293
|
-
|
|
294
|
-
// If drop still hasn't occurred, check if item is in a different container
|
|
295
|
-
if (dragStateRef.current.isDragging && !dragStateRef.current.dropOccurred) {
|
|
296
|
-
// If item is in a different container than original, treat it as a successful drop
|
|
297
|
-
if (currentContainer && currentContainer !== dragStateRef.current.originalContainer) {
|
|
298
|
-
// Trigger onDrop callback with the current container
|
|
299
|
-
if (onDrop) {
|
|
300
|
-
const draggedItem = stateRef.current.items.find(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
301
|
-
const updatedItem = draggedItem ? { ...draggedItem, container: currentContainer } : null;
|
|
302
|
-
const itemsInContainer = stateRef.current.items.filter(item => item && item.container === currentContainer);
|
|
303
|
-
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === dragStateRef.current.draggedItemId);
|
|
304
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
305
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
306
|
-
|
|
307
|
-
onDrop(
|
|
308
|
-
dragStateRef.current.draggedItemId,
|
|
309
|
-
currentContainer,
|
|
310
|
-
dragStateRef.current.originalContainer,
|
|
311
|
-
updatedItem,
|
|
312
|
-
itemAbove,
|
|
313
|
-
itemBelow
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
} else {
|
|
317
|
-
dispatch({
|
|
318
|
-
type: 'RESET_DRAG_CONTAINER',
|
|
319
|
-
payload: {
|
|
320
|
-
itemId: dragStateRef.current.draggedItemId,
|
|
321
|
-
originalContainer: dragStateRef.current.originalContainer,
|
|
322
|
-
},
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
326
|
-
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
327
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
328
|
-
|
|
329
|
-
// Clear drag state
|
|
330
|
-
dragStateRef.current = {
|
|
331
|
-
isDragging: false,
|
|
332
|
-
draggedItemId: '',
|
|
333
|
-
originalContainer: '',
|
|
334
|
-
currentContainer: '',
|
|
335
|
-
dropOccurred: false,
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
}, 50); // Small delay to let drop event fire if it's going to
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
document.addEventListener('dragover', handleGlobalDragOver);
|
|
343
|
-
document.addEventListener('drop', handleGlobalDrop);
|
|
344
|
-
document.addEventListener('mouseup', handleGlobalMouseUp);
|
|
345
|
-
document.addEventListener('pointerup', handleGlobalMouseUp);
|
|
346
|
-
|
|
347
|
-
return () => {
|
|
348
|
-
document.removeEventListener('dragover', handleGlobalDragOver);
|
|
349
|
-
document.removeEventListener('drop', handleGlobalDrop);
|
|
350
|
-
document.removeEventListener('mouseup', handleGlobalMouseUp);
|
|
351
|
-
document.removeEventListener('pointerup', handleGlobalMouseUp);
|
|
352
|
-
};
|
|
353
|
-
}, [enableCrossContainerPreview]);
|
|
354
|
-
|
|
355
|
-
// Detect when dragging stops (isDragging goes from truthy to empty)
|
|
356
|
-
const prevIsDraggingRef = useRef(state.isDragging);
|
|
357
|
-
|
|
358
|
-
useEffect(() => {
|
|
359
|
-
if (!enableCrossContainerPreview) return;
|
|
360
|
-
|
|
361
|
-
const wasDragging = prevIsDraggingRef.current;
|
|
362
|
-
const isNowDragging = state.isDragging;
|
|
363
|
-
|
|
364
|
-
// Drag just ended (was dragging, now not)
|
|
365
|
-
if (wasDragging && !isNowDragging) {
|
|
366
|
-
|
|
367
|
-
// If drop didn't occur, reset to original container
|
|
368
|
-
if (!dragStateRef.current.dropOccurred && dragStateRef.current.draggedItemId) {
|
|
369
|
-
dispatch({
|
|
370
|
-
type: 'RESET_DRAG_CONTAINER',
|
|
371
|
-
payload: {
|
|
372
|
-
itemId: dragStateRef.current.draggedItemId,
|
|
373
|
-
originalContainer: dragStateRef.current.originalContainer,
|
|
374
|
-
},
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Clear drag state
|
|
379
|
-
dragStateRef.current = {
|
|
380
|
-
isDragging: false,
|
|
381
|
-
draggedItemId: '',
|
|
382
|
-
originalContainer: '',
|
|
383
|
-
currentContainer: '',
|
|
384
|
-
dropOccurred: false,
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
prevIsDraggingRef.current = isNowDragging;
|
|
389
|
-
}, [state.isDragging, enableCrossContainerPreview]);
|
|
390
|
-
|
|
391
151
|
const handleDragStart = (id: string, container: string) => {
|
|
392
|
-
// Track drag in ref for global listener
|
|
393
|
-
if (enableCrossContainerPreview) {
|
|
394
|
-
dragStateRef.current = {
|
|
395
|
-
isDragging: true,
|
|
396
|
-
draggedItemId: id,
|
|
397
|
-
originalContainer: container,
|
|
398
|
-
currentContainer: container,
|
|
399
|
-
dropOccurred: false,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
|
|
403
152
|
dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container, originId: providerId } });
|
|
404
153
|
dispatch({ type: 'SET_IS_DRAGGING', payload: id });
|
|
405
154
|
if (onDragStart) onDragStart(id, container);
|
|
@@ -432,10 +181,6 @@ export const DraggableProvider = ({
|
|
|
432
181
|
newContainer: container,
|
|
433
182
|
},
|
|
434
183
|
});
|
|
435
|
-
// Update current container in ref
|
|
436
|
-
if (enableCrossContainerPreview) {
|
|
437
|
-
dragStateRef.current.currentContainer = container;
|
|
438
|
-
}
|
|
439
184
|
} else {
|
|
440
185
|
// Same container: keep original behavior
|
|
441
186
|
dispatch({
|
|
@@ -448,10 +193,7 @@ export const DraggableProvider = ({
|
|
|
448
193
|
dispatch({type: "REORDER_ITEMS", payload: { dragId: state.dragData.id, targetId: id }});
|
|
449
194
|
}
|
|
450
195
|
|
|
451
|
-
|
|
452
|
-
// Otherwise, update it to track the current container
|
|
453
|
-
const newInitialGroup = enableCrossContainerPreview ? state.dragData.initialGroup : container;
|
|
454
|
-
dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: newInitialGroup, originId: providerId}});
|
|
196
|
+
dispatch({type: "SET_DRAG_DATA",payload: {id: state.dragData.id, initialGroup: container, originId: providerId}});
|
|
455
197
|
}
|
|
456
198
|
if (onDragEnter) onDragEnter(id, container);
|
|
457
199
|
};
|
|
@@ -460,29 +202,17 @@ export const DraggableProvider = ({
|
|
|
460
202
|
const draggedItemId = state.dragData.id;
|
|
461
203
|
const originalContainer = state.dragData.initialGroup;
|
|
462
204
|
|
|
463
|
-
// If enableCrossContainerPreview is true and no drop occurred, reset item to original container
|
|
464
|
-
if (enableCrossContainerPreview && !dragStateRef.current.dropOccurred && draggedItemId && originalContainer) {
|
|
465
|
-
dispatch({ type: 'RESET_DRAG_CONTAINER', payload: { itemId: draggedItemId, originalContainer } });
|
|
466
|
-
}
|
|
467
|
-
|
|
468
205
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
469
206
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
470
207
|
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
471
|
-
|
|
472
|
-
// Only call onDragEnd if drop didn't already occur (for enableCrossContainerPreview)
|
|
473
|
-
// If drop occurred, handleDrop or global drop handler already called onDragEnd
|
|
474
|
-
if (enableCrossContainerPreview && dragStateRef.current.dropOccurred) {
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
208
|
if (onDragEnd) {
|
|
479
209
|
if (!enableCrossContainerPreview) {
|
|
480
210
|
onDragEnd();
|
|
481
211
|
} else {
|
|
482
|
-
const draggedItem =
|
|
212
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
483
213
|
const finalContainer = draggedItem ? draggedItem.container : originalContainer;
|
|
484
214
|
|
|
485
|
-
const itemsInContainer =
|
|
215
|
+
const itemsInContainer = state.items.filter(item => item && item.container === finalContainer);
|
|
486
216
|
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
487
217
|
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
488
218
|
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
@@ -507,58 +237,32 @@ export const DraggableProvider = ({
|
|
|
507
237
|
|
|
508
238
|
const draggedItemId = state.dragData.id;
|
|
509
239
|
const originalContainer = state.dragData.initialGroup;
|
|
510
|
-
|
|
511
|
-
// Mark drop as successful in ref for global listener
|
|
512
|
-
if (enableCrossContainerPreview) {
|
|
513
|
-
dragStateRef.current.dropOccurred = true;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// Gather data for callbacks BEFORE clearing state
|
|
517
|
-
const isCrossContainer = container !== originalContainer;
|
|
518
|
-
let callbackData = null;
|
|
519
|
-
|
|
520
|
-
if (enableCrossContainerPreview) {
|
|
521
|
-
const draggedItem = stateRef.current.items.find(item => item && item.id === draggedItemId);
|
|
522
|
-
const updatedItem = draggedItem ? { ...draggedItem, container } : null;
|
|
523
|
-
const itemsInContainer = stateRef.current.items.filter(item => item && item.container === container);
|
|
524
|
-
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
525
|
-
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
526
|
-
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
527
|
-
|
|
528
|
-
callbackData = { updatedItem, itemAbove, itemBelow };
|
|
529
|
-
}
|
|
530
240
|
|
|
531
241
|
dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
|
|
532
242
|
dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
|
|
533
|
-
dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
|
|
534
243
|
changeCategory(state.dragData.id, container);
|
|
535
|
-
|
|
536
244
|
if (onDrop) {
|
|
537
245
|
if (!enableCrossContainerPreview) {
|
|
538
246
|
onDrop(container);
|
|
539
247
|
} else {
|
|
248
|
+
const draggedItem = state.items.find(item => item && item.id === draggedItemId);
|
|
249
|
+
const updatedItem = draggedItem ? { ...draggedItem, container } : null;
|
|
250
|
+
|
|
251
|
+
const itemsInContainer = state.items.filter(item => item && item.container === container);
|
|
252
|
+
const indexInContainer = itemsInContainer.findIndex(item => item && item.id === draggedItemId);
|
|
253
|
+
const itemAbove = indexInContainer > 0 ? itemsInContainer[indexInContainer - 1] : null;
|
|
254
|
+
const itemBelow = indexInContainer < itemsInContainer.length - 1 ? itemsInContainer[indexInContainer + 1] : null;
|
|
255
|
+
|
|
540
256
|
onDrop(
|
|
541
257
|
draggedItemId,
|
|
542
258
|
container,
|
|
543
259
|
originalContainer,
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
260
|
+
updatedItem,
|
|
261
|
+
itemAbove,
|
|
262
|
+
itemBelow
|
|
547
263
|
);
|
|
548
264
|
}
|
|
549
265
|
}
|
|
550
|
-
|
|
551
|
-
// Trigger onDragEnd ONLY for cross-container drops (dragend doesn't fire reliably in that case)
|
|
552
|
-
// For same-container drops, handleDragEnd will be called normally
|
|
553
|
-
if (enableCrossContainerPreview && isCrossContainer && onDragEnd && callbackData) {
|
|
554
|
-
onDragEnd(
|
|
555
|
-
draggedItemId,
|
|
556
|
-
container,
|
|
557
|
-
originalContainer,
|
|
558
|
-
callbackData.itemAbove,
|
|
559
|
-
callbackData.itemBelow
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
266
|
};
|
|
563
267
|
|
|
564
268
|
const handleDragOver = (e: Event, container: string) => {
|
|
@@ -577,8 +281,6 @@ export const DraggableProvider = ({
|
|
|
577
281
|
type: "MOVE_TO_CONTAINER_END",
|
|
578
282
|
payload: { dragId: state.dragData.id, newContainer: container },
|
|
579
283
|
});
|
|
580
|
-
// Update current container in ref
|
|
581
|
-
dragStateRef.current.currentContainer = container;
|
|
582
284
|
}
|
|
583
285
|
}
|
|
584
286
|
|
|
@@ -139,7 +139,8 @@ $text_colors: (
|
|
|
139
139
|
text_lt_lighter: $text_lt_lighter,
|
|
140
140
|
text_dk_default: $text_dk_default,
|
|
141
141
|
text_dk_light: $text_dk_light,
|
|
142
|
-
text_dk_lighter: $text_dk_lighter
|
|
142
|
+
text_dk_lighter: $text_dk_lighter,
|
|
143
|
+
text_dk_success_sm: $text_dk_success_sm
|
|
143
144
|
);
|
|
144
145
|
|
|
145
146
|
/* Data colors ------------------------*/
|