@sguisse/react-grid-layout 2.2.3-sguisse.3

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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/css/styles.css +120 -0
  4. package/dist/ResponsiveGridLayout-B_6TXsWM.d.ts +80 -0
  5. package/dist/ResponsiveGridLayout-Bin5MBC3.d.mts +80 -0
  6. package/dist/calculate-CoBSgofg.d.mts +196 -0
  7. package/dist/calculate-K0IBpu53.d.ts +196 -0
  8. package/dist/chunk-7BT7XXIT.js +74 -0
  9. package/dist/chunk-G3PAJYGP.mjs +72 -0
  10. package/dist/chunk-ITLZ7N2R.mjs +456 -0
  11. package/dist/chunk-J4LTYI7L.js +485 -0
  12. package/dist/chunk-KKV4ZCG4.mjs +583 -0
  13. package/dist/chunk-LQOPWRJR.js +623 -0
  14. package/dist/chunk-O3KX3VYW.mjs +1 -0
  15. package/dist/chunk-STBCV65G.js +3159 -0
  16. package/dist/chunk-UZL6BMXQ.mjs +3146 -0
  17. package/dist/chunk-ZJHF4QM5.js +2 -0
  18. package/dist/core.d.mts +160 -0
  19. package/dist/core.d.ts +160 -0
  20. package/dist/core.js +268 -0
  21. package/dist/core.mjs +3 -0
  22. package/dist/extras.d.mts +208 -0
  23. package/dist/extras.d.ts +208 -0
  24. package/dist/extras.js +388 -0
  25. package/dist/extras.mjs +380 -0
  26. package/dist/index.d.mts +7 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.js +152 -0
  29. package/dist/index.mjs +5 -0
  30. package/dist/legacy.d.mts +163 -0
  31. package/dist/legacy.d.ts +163 -0
  32. package/dist/legacy.js +331 -0
  33. package/dist/legacy.mjs +319 -0
  34. package/dist/position-BeP60S5h.d.ts +316 -0
  35. package/dist/position-CeG3Nr4z.d.mts +316 -0
  36. package/dist/react.d.mts +214 -0
  37. package/dist/react.d.ts +214 -0
  38. package/dist/react.js +94 -0
  39. package/dist/react.mjs +5 -0
  40. package/dist/responsive-D4zBXLkH.d.ts +145 -0
  41. package/dist/responsive-DQi_9rBi.d.mts +145 -0
  42. package/dist/types-Dbg8jAWj.d.mts +458 -0
  43. package/dist/types-Dbg8jAWj.d.ts +458 -0
  44. package/index-dev.js +23 -0
  45. package/index.js +8 -0
  46. package/package.json +238 -0
@@ -0,0 +1,3146 @@
1
+ import { defaultConstraints, setTransform, setTopLeft, perc, applyPositionConstraints, resizeItemInDirection, applySizeConstraints, verticalCompactor, defaultPositionStrategy, defaultGridConfig, defaultDragConfig, defaultResizeConfig, defaultDropConfig, getCompactor, sortBreakpoints, getBreakpointFromWidth, getColsFromBreakpoint, findOrGenerateResponsiveLayout, getIndentationValue } from './chunk-KKV4ZCG4.mjs';
2
+ import { calcXYRaw, calcGridItemWHPx, clamp, calcGridColWidth, calcWHRaw, calcGridItemPosition, correctBounds, cloneLayout, getLayoutItem, cloneLayoutItem, moveElement, bottom, getGridPixelSteps, withLayoutItem, getAllCollisions, calcXY, __require } from './chunk-ITLZ7N2R.mjs';
3
+ import React3, { useState, useRef, useMemo, useCallback, useEffect } from 'react';
4
+ import clsx from 'clsx';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+ import { deepEqual } from 'fast-equals';
7
+
8
+ var noopRef = () => {
9
+ };
10
+ function isTestRuntime() {
11
+ return process.env["NODE_ENV"] === "test";
12
+ }
13
+ function isRuntimeDndAvailable() {
14
+ return !isTestRuntime();
15
+ }
16
+ function loadReactDndRuntime() {
17
+ if (!isRuntimeDndAvailable()) {
18
+ return null;
19
+ }
20
+ return __require("@dnd-kit/react");
21
+ }
22
+ function loadSortableRuntime() {
23
+ if (!isRuntimeDndAvailable()) {
24
+ return null;
25
+ }
26
+ return __require("@dnd-kit/react/sortable");
27
+ }
28
+ function loadDomRuntime() {
29
+ if (!isRuntimeDndAvailable()) {
30
+ return null;
31
+ }
32
+ return __require("@dnd-kit/dom");
33
+ }
34
+ function DragDropProvider({
35
+ children,
36
+ ...props
37
+ }) {
38
+ const runtime = loadReactDndRuntime();
39
+ if (!runtime) {
40
+ return /* @__PURE__ */ jsx(Fragment, { children });
41
+ }
42
+ const Component = runtime.DragDropProvider;
43
+ return /* @__PURE__ */ jsx(Component, { ...props, children });
44
+ }
45
+ function DragOverlay({
46
+ children,
47
+ disabled,
48
+ dropAnimation
49
+ }) {
50
+ const runtime = loadReactDndRuntime();
51
+ if (!runtime || disabled) {
52
+ return /* @__PURE__ */ jsx(Fragment, {});
53
+ }
54
+ const Component = runtime.DragOverlay;
55
+ return /* @__PURE__ */ jsx(Component, { disabled, dropAnimation, children });
56
+ }
57
+ function useRuntimeSortable(input) {
58
+ const runtime = loadSortableRuntime();
59
+ if (!runtime) {
60
+ return {
61
+ isDragSource: false,
62
+ ref: noopRef,
63
+ handleRef: noopRef
64
+ };
65
+ }
66
+ return runtime.useSortable(input);
67
+ }
68
+ function useRuntimeDraggable(input) {
69
+ const runtime = loadReactDndRuntime();
70
+ if (!runtime) {
71
+ return {
72
+ isDragSource: false,
73
+ ref: noopRef,
74
+ handleRef: noopRef
75
+ };
76
+ }
77
+ return runtime.useDraggable(input);
78
+ }
79
+ function useRuntimeDragDropMonitor(handlers) {
80
+ const runtime = loadReactDndRuntime();
81
+ if (!runtime) {
82
+ React3.useEffect(() => {
83
+ console.debug("[runtime] useDragDropMonitor: runtime unavailable, handlers not attached", handlers);
84
+ }, [handlers]);
85
+ return;
86
+ }
87
+ const wrappedHandlers = React3.useMemo(() => {
88
+ const wrap = (name, fn) => {
89
+ if (!fn) return void 0;
90
+ return (event, manager) => {
91
+ try {
92
+ console.debug(`[runtime] dnd-monitor ${name}`, event, manager);
93
+ } catch (err) {
94
+ }
95
+ fn(event, manager);
96
+ };
97
+ };
98
+ return {
99
+ onDragStart: wrap("onDragStart", handlers.onDragStart),
100
+ onDragMove: wrap("onDragMove", handlers.onDragMove),
101
+ onDragEnd: wrap("onDragEnd", handlers.onDragEnd)
102
+ };
103
+ }, [handlers]);
104
+ runtime.useDragDropMonitor(wrappedHandlers);
105
+ }
106
+ var PointerSensor = {
107
+ configure(options) {
108
+ const runtime = loadDomRuntime();
109
+ return runtime ? runtime.PointerSensor.configure(options) : options;
110
+ }
111
+ };
112
+ var KeyboardSensor = {
113
+ configure(options) {
114
+ const runtime = loadDomRuntime();
115
+ return runtime ? runtime.KeyboardSensor.configure(options) : options;
116
+ }
117
+ };
118
+ var PointerActivationConstraints = {
119
+ Distance: class Distance {
120
+ constructor(options) {
121
+ const runtime = loadDomRuntime();
122
+ if (runtime && runtime.PointerActivationConstraints && runtime.PointerActivationConstraints.Distance) {
123
+ return new runtime.PointerActivationConstraints.Distance(options);
124
+ }
125
+ this.options = options;
126
+ }
127
+ }
128
+ };
129
+ function describeElementForDebug(node) {
130
+ if (!(node instanceof Element)) {
131
+ return null;
132
+ }
133
+ const className = typeof node.className === "string" ? node.className.trim() : "";
134
+ return className.length > 0 ? `${node.tagName.toLowerCase()}.${className.replace(/\s+/g, ".")}` : node.tagName.toLowerCase();
135
+ }
136
+ function getGridItemResizeData(data) {
137
+ if (!data || typeof data !== "object") {
138
+ return null;
139
+ }
140
+ const itemId = data.itemId;
141
+ const axis = data.axis;
142
+ const kind = data.kind;
143
+ return kind === "resize" && typeof itemId === "string" && typeof axis === "string" ? { kind, itemId, axis } : null;
144
+ }
145
+ function GridResizeHandle({
146
+ axis,
147
+ itemId,
148
+ resizeHandle,
149
+ supportsDndKitResize,
150
+ onPointerDown,
151
+ onMouseDown,
152
+ onTouchStart
153
+ }) {
154
+ const commonClassName = clsx(
155
+ "react-resizable-handle",
156
+ `react-resizable-handle-${axis}`
157
+ );
158
+ const { ref: resizeRef } = useRuntimeDraggable({
159
+ id: `${itemId}:resize:${axis}`,
160
+ data: {
161
+ kind: "resize",
162
+ itemId,
163
+ axis
164
+ },
165
+ disabled: !supportsDndKitResize,
166
+ feedback: "none"
167
+ });
168
+ const commonProps = {
169
+ className: commonClassName,
170
+ onPointerDown,
171
+ onMouseDown,
172
+ onTouchStart,
173
+ ref: supportsDndKitResize ? resizeRef : null,
174
+ style: { touchAction: "none" }
175
+ };
176
+ if (typeof resizeHandle === "function") {
177
+ return React3.cloneElement(
178
+ resizeHandle(axis, supportsDndKitResize ? resizeRef : null),
179
+ commonProps
180
+ );
181
+ }
182
+ if (React3.isValidElement(resizeHandle)) {
183
+ const element = resizeHandle;
184
+ return React3.cloneElement(element, {
185
+ ...commonProps,
186
+ className: clsx(commonClassName, element.props.className)
187
+ });
188
+ }
189
+ return /* @__PURE__ */ jsx("span", { ...commonProps }, axis);
190
+ }
191
+ function getTargetElement(target) {
192
+ return target instanceof HTMLElement ? target : null;
193
+ }
194
+ function isTouchInputEvent(event) {
195
+ return "changedTouches" in event;
196
+ }
197
+ function isMouseLikeInputEvent(event) {
198
+ return !isTouchInputEvent(event);
199
+ }
200
+ function getTrackedTouch(event, touchId) {
201
+ const touchLists = [event.changedTouches, event.touches, event.targetTouches];
202
+ for (const touchList of touchLists) {
203
+ for (let index = 0; index < touchList.length; index += 1) {
204
+ const touch = typeof touchList.item === "function" ? touchList.item(index) : touchList[index];
205
+ if (!touch) {
206
+ continue;
207
+ }
208
+ if (touchId === void 0 || touch.identifier === touchId) {
209
+ return touch;
210
+ }
211
+ }
212
+ }
213
+ return null;
214
+ }
215
+ function getInputCoordinates(event, touchId) {
216
+ if (isTouchInputEvent(event)) {
217
+ const touch = getTrackedTouch(event, touchId);
218
+ return touch ? { clientX: touch.clientX, clientY: touch.clientY } : null;
219
+ }
220
+ return { clientX: event.clientX, clientY: event.clientY };
221
+ }
222
+ function createResizeCandidate(origin, handle, deltaX, deltaY) {
223
+ const next = { ...origin };
224
+ if (handle.includes("e")) {
225
+ next.width = origin.width + deltaX;
226
+ }
227
+ if (handle.includes("s")) {
228
+ next.height = origin.height + deltaY;
229
+ }
230
+ if (handle.includes("w")) {
231
+ next.width = origin.width - deltaX;
232
+ next.left = origin.left + deltaX;
233
+ }
234
+ if (handle.includes("n")) {
235
+ next.height = origin.height - deltaY;
236
+ next.top = origin.top + deltaY;
237
+ }
238
+ return next;
239
+ }
240
+ function isPrimaryInputStart(kind, event) {
241
+ if (kind === "touch") {
242
+ return true;
243
+ }
244
+ return isMouseLikeInputEvent(event) && event.button === 0;
245
+ }
246
+ function getTrackedInputId(kind, event) {
247
+ return kind === "touch" && isTouchInputEvent(event) ? getTrackedTouch(event)?.identifier : void 0;
248
+ }
249
+ function isTrackedInputEvent(kind, startEvent, nextEvent) {
250
+ if (kind === "pointer" && nextEvent instanceof PointerEvent && startEvent instanceof PointerEvent) {
251
+ return nextEvent.pointerId === startEvent.pointerId;
252
+ }
253
+ return true;
254
+ }
255
+ function preventTouchMoveDefault(kind, event) {
256
+ if (kind === "touch" && isTouchInputEvent(event)) {
257
+ event.preventDefault();
258
+ }
259
+ }
260
+ function createNativeInteractionSession(kind, startEvent, node, onMove, onEnd) {
261
+ const ownerDocument = node.ownerDocument ?? document;
262
+ if (kind === "pointer" && startEvent instanceof PointerEvent) {
263
+ const moveListener = (moveEvent) => onMove(moveEvent);
264
+ const endListener = (endEvent) => onEnd(endEvent);
265
+ ownerDocument.addEventListener("pointermove", moveListener);
266
+ ownerDocument.addEventListener("pointerup", endListener);
267
+ ownerDocument.addEventListener("pointercancel", endListener);
268
+ node.setPointerCapture?.(startEvent.pointerId);
269
+ return () => {
270
+ ownerDocument.removeEventListener("pointermove", moveListener);
271
+ ownerDocument.removeEventListener("pointerup", endListener);
272
+ ownerDocument.removeEventListener("pointercancel", endListener);
273
+ if (node.hasPointerCapture?.(startEvent.pointerId)) {
274
+ node.releasePointerCapture(startEvent.pointerId);
275
+ }
276
+ };
277
+ }
278
+ if (kind === "mouse" && startEvent instanceof MouseEvent) {
279
+ const moveListener = (moveEvent) => onMove(moveEvent);
280
+ const endListener = (endEvent) => onEnd(endEvent);
281
+ ownerDocument.addEventListener("mousemove", moveListener);
282
+ ownerDocument.addEventListener("mouseup", endListener);
283
+ return () => {
284
+ ownerDocument.removeEventListener("mousemove", moveListener);
285
+ ownerDocument.removeEventListener("mouseup", endListener);
286
+ };
287
+ }
288
+ if (kind === "touch" && isTouchInputEvent(startEvent)) {
289
+ const moveListener = (moveEvent) => onMove(moveEvent);
290
+ const endListener = (endEvent) => onEnd(endEvent);
291
+ ownerDocument.addEventListener("touchmove", moveListener, {
292
+ passive: false
293
+ });
294
+ ownerDocument.addEventListener("touchend", endListener);
295
+ ownerDocument.addEventListener("touchcancel", endListener);
296
+ return () => {
297
+ ownerDocument.removeEventListener("touchmove", moveListener);
298
+ ownerDocument.removeEventListener("touchend", endListener);
299
+ ownerDocument.removeEventListener("touchcancel", endListener);
300
+ };
301
+ }
302
+ return () => {
303
+ };
304
+ }
305
+ function GridItem(props) {
306
+ const {
307
+ children,
308
+ cols,
309
+ containerWidth,
310
+ margin,
311
+ containerPadding,
312
+ rowHeight,
313
+ maxRows,
314
+ isDraggable,
315
+ isResizable,
316
+ isBounded,
317
+ static: isStatic,
318
+ useCSSTransforms = true,
319
+ usePercentages = false,
320
+ transformScale = 1,
321
+ positionStrategy,
322
+ dragThreshold = 0,
323
+ droppingPosition,
324
+ enableSortable = true,
325
+ className = "",
326
+ style,
327
+ handle = "",
328
+ cancel = "",
329
+ x,
330
+ y,
331
+ w,
332
+ h,
333
+ minW = 1,
334
+ maxW = Infinity,
335
+ minH = 1,
336
+ maxH = Infinity,
337
+ i,
338
+ resizeHandles,
339
+ resizeHandle,
340
+ constraints = defaultConstraints,
341
+ isDndKitDragSource = false,
342
+ layoutItem,
343
+ layout = [],
344
+ onDragStart: onDragStartProp,
345
+ onDrag: onDragProp,
346
+ onDragStop: onDragStopProp,
347
+ onResizeStart: onResizeStartProp,
348
+ onResize: onResizeProp,
349
+ onResizeStop: onResizeStopProp,
350
+ onResizeCancel: onResizeCancelProp
351
+ } = props;
352
+ const [dragging, setDragging] = useState(false);
353
+ const [resizing, setResizing] = useState(false);
354
+ const elementRef = useRef(null);
355
+ const dragPositionRef = useRef({ left: 0, top: 0 });
356
+ const resizePositionRef = useRef({
357
+ top: 0,
358
+ left: 0,
359
+ width: 0,
360
+ height: 0
361
+ });
362
+ const prevDroppingPositionRef = useRef(void 0);
363
+ const layoutRef = useRef(layout);
364
+ const dragSessionRef = useRef(null);
365
+ const resizeSessionRef = useRef(null);
366
+ const dragPendingRef = useRef(false);
367
+ const initialDragClientRef = useRef({ x: 0, y: 0 });
368
+ const thresholdExceededRef = useRef(false);
369
+ const draggingRef = useRef(false);
370
+ const activeDndResizeRef = useRef(null);
371
+ const runtimeDndAvailable = isRuntimeDndAvailable();
372
+ const nativePointerEventsAvailable = typeof window !== "undefined" && "PointerEvent" in window;
373
+ const runtimePointerEventsAvailable = enableSortable && nativePointerEventsAvailable;
374
+ const supportsDndKitRuntime = runtimeDndAvailable && runtimePointerEventsAvailable;
375
+ const supportsDndKitDrag = supportsDndKitRuntime && isDraggable && !isStatic;
376
+ const supportsDndKitResize = supportsDndKitRuntime && isResizable && !isStatic;
377
+ const useNativeDragFallback = !supportsDndKitDrag && isDraggable && !isStatic;
378
+ const useNativeResizeFallback = !supportsDndKitResize && isResizable && !isStatic;
379
+ layoutRef.current = layout;
380
+ const resolvedResizeHandles = useMemo(
381
+ () => [...resizeHandles ?? ["se"]],
382
+ [resizeHandles]
383
+ );
384
+ const sortableIndex = useMemo(
385
+ () => Math.max(0, layout.findIndex((item) => item.i === i)),
386
+ [layout, i]
387
+ );
388
+ const {
389
+ isDragSource: isSortableDragSource,
390
+ ref: sortableRef,
391
+ handleRef: sortableHandleRef
392
+ } = useRuntimeSortable({
393
+ id: i,
394
+ index: sortableIndex,
395
+ group: "react-grid-layout",
396
+ data: { kind: "drag", itemId: i },
397
+ disabled: !supportsDndKitDrag,
398
+ feedback: "none",
399
+ transition: null
400
+ });
401
+ const dragCancelSelector = useMemo(
402
+ () => [".react-resizable-handle", cancel].filter((value) => value.length > 0).join(","),
403
+ [cancel]
404
+ );
405
+ const setElementRef = useCallback(
406
+ (node) => {
407
+ elementRef.current = node;
408
+ console.debug("[GridItem] setElementRef", {
409
+ i,
410
+ node: describeElementForDebug(node),
411
+ connected: node?.isConnected ?? false,
412
+ supportsDndKitDrag,
413
+ handle
414
+ });
415
+ sortableRef(node);
416
+ if (!supportsDndKitDrag) {
417
+ sortableHandleRef(null);
418
+ return;
419
+ }
420
+ const handleElement = handle && node ? node.querySelector(handle) : null;
421
+ console.debug("[GridItem] setElementRef: sortable handle assigned", {
422
+ i,
423
+ handle,
424
+ handleElement: describeElementForDebug(handleElement)
425
+ });
426
+ sortableHandleRef(handleElement instanceof Element ? handleElement : null);
427
+ },
428
+ [handle, i, sortableHandleRef, sortableRef, supportsDndKitDrag]
429
+ );
430
+ const positionParams = useMemo(
431
+ () => ({
432
+ cols,
433
+ containerPadding,
434
+ containerWidth,
435
+ margin,
436
+ maxRows,
437
+ rowHeight
438
+ }),
439
+ [cols, containerPadding, containerWidth, margin, maxRows, rowHeight]
440
+ );
441
+ function createGridItemDndSnapshot(snapshotParams, item, dragPosition, resizePosition) {
442
+ const position = calcGridItemPosition(
443
+ snapshotParams,
444
+ item.x,
445
+ item.y,
446
+ item.w,
447
+ item.h,
448
+ dragPosition ?? null,
449
+ resizePosition ?? null
450
+ );
451
+ const { x: gridX, y: gridY } = calcXYRaw(
452
+ snapshotParams,
453
+ position.top,
454
+ position.left
455
+ );
456
+ return {
457
+ left: position.left,
458
+ top: position.top,
459
+ width: position.width,
460
+ height: position.height,
461
+ gridX,
462
+ gridY
463
+ };
464
+ }
465
+ function getGridItemPixelDelta(previous, next) {
466
+ return {
467
+ deltaX: next.left - previous.left,
468
+ deltaY: next.top - previous.top
469
+ };
470
+ }
471
+ const constraintContext = useMemo(
472
+ () => ({
473
+ cols,
474
+ maxRows,
475
+ containerWidth,
476
+ containerHeight: 0,
477
+ rowHeight,
478
+ margin,
479
+ layout: []
480
+ }),
481
+ [cols, maxRows, containerWidth, rowHeight, margin]
482
+ );
483
+ const getConstraintContext = useCallback(
484
+ () => ({
485
+ ...constraintContext,
486
+ layout: layoutRef.current
487
+ }),
488
+ [constraintContext]
489
+ );
490
+ const getRuntimeInteractionEvent = useCallback(
491
+ (event) => event.nativeEvent ?? event.operation.activatorEvent ?? new Event("drag"),
492
+ []
493
+ );
494
+ const effectiveLayoutItem = useMemo(
495
+ () => layoutItem ?? {
496
+ i,
497
+ x,
498
+ y,
499
+ w,
500
+ h,
501
+ minW,
502
+ maxW,
503
+ minH,
504
+ maxH
505
+ },
506
+ [layoutItem, i, x, y, w, h, minW, maxW, minH, maxH]
507
+ );
508
+ const createStyle = useCallback(
509
+ (pos2) => {
510
+ if (positionStrategy?.calcStyle) {
511
+ return positionStrategy.calcStyle(pos2);
512
+ }
513
+ if (useCSSTransforms) {
514
+ return setTransform(pos2);
515
+ }
516
+ const styleObject = setTopLeft(pos2);
517
+ if (usePercentages) {
518
+ return {
519
+ ...styleObject,
520
+ left: perc(pos2.left / containerWidth),
521
+ width: perc(pos2.width / containerWidth)
522
+ };
523
+ }
524
+ return styleObject;
525
+ },
526
+ [positionStrategy, useCSSTransforms, usePercentages, containerWidth]
527
+ );
528
+ const getDragStartPosition = useCallback(
529
+ (clientX, clientY, node) => {
530
+ const { offsetParent } = node;
531
+ if (!offsetParent) {
532
+ return null;
533
+ }
534
+ const parentRect = offsetParent.getBoundingClientRect();
535
+ const clientRect = node.getBoundingClientRect();
536
+ const cLeft = clientRect.left / transformScale;
537
+ const pLeft = parentRect.left / transformScale;
538
+ const cTop = clientRect.top / transformScale;
539
+ const pTop = parentRect.top / transformScale;
540
+ if (positionStrategy?.calcDragPosition) {
541
+ return positionStrategy.calcDragPosition(
542
+ clientX,
543
+ clientY,
544
+ clientX - clientRect.left,
545
+ clientY - clientRect.top
546
+ );
547
+ }
548
+ return {
549
+ left: cLeft - pLeft + offsetParent.scrollLeft,
550
+ top: cTop - pTop + offsetParent.scrollTop
551
+ };
552
+ },
553
+ [positionStrategy, transformScale]
554
+ );
555
+ const clearDragSession = useCallback(() => {
556
+ const session = dragSessionRef.current;
557
+ if (!session) {
558
+ return;
559
+ }
560
+ session.cleanup();
561
+ dragSessionRef.current = null;
562
+ }, []);
563
+ const clearResizeSession = useCallback(() => {
564
+ const session = resizeSessionRef.current;
565
+ if (!session) {
566
+ return;
567
+ }
568
+ session.cleanup();
569
+ resizeSessionRef.current = null;
570
+ }, []);
571
+ const emitDragStart = useCallback(
572
+ (event, node, newPosition, skipThreshold, clientX, clientY) => {
573
+ console.debug("[GridItem] emitDragStart", { i, skipThreshold, clientX, clientY, newPosition });
574
+ dragPositionRef.current = newPosition;
575
+ if (clientX !== void 0 && clientY !== void 0) {
576
+ initialDragClientRef.current = { x: clientX, y: clientY };
577
+ }
578
+ setDragging(true);
579
+ draggingRef.current = true;
580
+ if (dragThreshold > 0 && !skipThreshold) {
581
+ dragPendingRef.current = true;
582
+ thresholdExceededRef.current = false;
583
+ return;
584
+ }
585
+ dragPendingRef.current = false;
586
+ thresholdExceededRef.current = true;
587
+ if (!onDragStartProp) {
588
+ return;
589
+ }
590
+ const rawPos = calcXYRaw(positionParams, newPosition.top, newPosition.left);
591
+ const { x: newX, y: newY } = applyPositionConstraints(
592
+ constraints,
593
+ effectiveLayoutItem,
594
+ rawPos.x,
595
+ rawPos.y,
596
+ getConstraintContext()
597
+ );
598
+ console.debug("[GridItem] calling onDragStartProp", i, newX, newY);
599
+ onDragStartProp(i, newX, newY, {
600
+ e: event,
601
+ node,
602
+ newPosition
603
+ });
604
+ },
605
+ [
606
+ dragThreshold,
607
+ onDragStartProp,
608
+ positionParams,
609
+ constraints,
610
+ effectiveLayoutItem,
611
+ getConstraintContext,
612
+ i
613
+ ]
614
+ );
615
+ const emitDragMove = useCallback(
616
+ (event, node, deltaX, deltaY, clientX, clientY) => {
617
+ console.debug("[GridItem] emitDragMove", { i, deltaX, deltaY, clientX, clientY });
618
+ if (!draggingRef.current && !dragPendingRef.current) {
619
+ return;
620
+ }
621
+ if (dragPendingRef.current && !thresholdExceededRef.current && clientX !== void 0 && clientY !== void 0) {
622
+ const dx = clientX - initialDragClientRef.current.x;
623
+ const dy = clientY - initialDragClientRef.current.y;
624
+ const distance = Math.hypot(dx, dy);
625
+ if (distance < dragThreshold) {
626
+ return;
627
+ }
628
+ thresholdExceededRef.current = true;
629
+ dragPendingRef.current = false;
630
+ if (onDragStartProp) {
631
+ const rawPos2 = calcXYRaw(
632
+ positionParams,
633
+ dragPositionRef.current.top,
634
+ dragPositionRef.current.left
635
+ );
636
+ const { x: startX, y: startY } = applyPositionConstraints(
637
+ constraints,
638
+ effectiveLayoutItem,
639
+ rawPos2.x,
640
+ rawPos2.y,
641
+ getConstraintContext()
642
+ );
643
+ console.debug("[GridItem] emitting onDragStart from pending state", i, startX, startY);
644
+ onDragStartProp(i, startX, startY, {
645
+ e: event,
646
+ node,
647
+ newPosition: dragPositionRef.current
648
+ });
649
+ }
650
+ }
651
+ let top = dragPositionRef.current.top + deltaY;
652
+ let left = dragPositionRef.current.left + deltaX;
653
+ if (isBounded) {
654
+ const { offsetParent } = node;
655
+ if (offsetParent) {
656
+ const bottomBoundary = offsetParent.clientHeight - calcGridItemWHPx(h, rowHeight, margin[1]);
657
+ top = clamp(top, 0, bottomBoundary);
658
+ const colWidth = calcGridColWidth(positionParams);
659
+ const rightBoundary = containerWidth - calcGridItemWHPx(w, colWidth, margin[0]);
660
+ left = clamp(left, 0, rightBoundary);
661
+ }
662
+ }
663
+ const newPosition = { top, left };
664
+ dragPositionRef.current = newPosition;
665
+ if (!onDragProp) {
666
+ return;
667
+ }
668
+ const rawPos = calcXYRaw(positionParams, top, left);
669
+ const { x: newX, y: newY } = applyPositionConstraints(
670
+ constraints,
671
+ effectiveLayoutItem,
672
+ rawPos.x,
673
+ rawPos.y,
674
+ getConstraintContext()
675
+ );
676
+ console.debug("[GridItem] calling onDragProp", i, newX, newY);
677
+ onDragProp(i, newX, newY, {
678
+ e: event,
679
+ node,
680
+ newPosition
681
+ });
682
+ },
683
+ [
684
+ dragThreshold,
685
+ onDragStartProp,
686
+ positionParams,
687
+ constraints,
688
+ effectiveLayoutItem,
689
+ getConstraintContext,
690
+ i,
691
+ isBounded,
692
+ h,
693
+ rowHeight,
694
+ margin,
695
+ containerWidth,
696
+ w,
697
+ onDragProp
698
+ ]
699
+ );
700
+ const emitDragStop = useCallback(
701
+ (event, node) => {
702
+ console.debug("[GridItem] emitDragStop", { i, eventType: event?.type });
703
+ if (!draggingRef.current && !dragPendingRef.current) {
704
+ return;
705
+ }
706
+ const wasPending = dragPendingRef.current;
707
+ dragPendingRef.current = false;
708
+ thresholdExceededRef.current = false;
709
+ initialDragClientRef.current = { x: 0, y: 0 };
710
+ if (wasPending) {
711
+ setDragging(false);
712
+ draggingRef.current = false;
713
+ dragPositionRef.current = { left: 0, top: 0 };
714
+ return;
715
+ }
716
+ const { left, top } = dragPositionRef.current;
717
+ const newPosition = { top, left };
718
+ setDragging(false);
719
+ draggingRef.current = false;
720
+ dragPositionRef.current = { left: 0, top: 0 };
721
+ if (!onDragStopProp) {
722
+ return;
723
+ }
724
+ const rawPos = calcXYRaw(positionParams, top, left);
725
+ const { x: newX, y: newY } = applyPositionConstraints(
726
+ constraints,
727
+ effectiveLayoutItem,
728
+ rawPos.x,
729
+ rawPos.y,
730
+ getConstraintContext()
731
+ );
732
+ console.debug("[GridItem] calling onDragStopProp", i, newX, newY);
733
+ onDragStopProp(i, newX, newY, {
734
+ e: event,
735
+ node,
736
+ newPosition
737
+ });
738
+ },
739
+ [
740
+ onDragStopProp,
741
+ positionParams,
742
+ constraints,
743
+ effectiveLayoutItem,
744
+ getConstraintContext,
745
+ i
746
+ ]
747
+ );
748
+ const emitResize = useCallback(
749
+ (handlerName, event, data, origin) => {
750
+ console.debug("[GridItem] emitResize", { i, handlerName, data, origin });
751
+ const handler = handlerName === "onResizeStart" ? onResizeStartProp : handlerName === "onResize" ? onResizeProp : onResizeStopProp;
752
+ resizePositionRef.current = data.size;
753
+ if (!handler) {
754
+ console.debug("[GridItem] emitResize: no handler", handlerName);
755
+ return;
756
+ }
757
+ const updatedSize = resizeItemInDirection(
758
+ data.handle,
759
+ origin,
760
+ data.size,
761
+ containerWidth
762
+ );
763
+ resizePositionRef.current = updatedSize;
764
+ const rawSize = calcWHRaw(
765
+ positionParams,
766
+ updatedSize.width,
767
+ updatedSize.height
768
+ );
769
+ const { w: newW, h: newH } = applySizeConstraints(
770
+ constraints,
771
+ effectiveLayoutItem,
772
+ rawSize.w,
773
+ rawSize.h,
774
+ data.handle,
775
+ getConstraintContext()
776
+ );
777
+ console.debug("[GridItem] calling resize handler", { i, handlerName, newW, newH, updatedSize });
778
+ handler(i, newW, newH, {
779
+ e: event,
780
+ node: data.node,
781
+ size: updatedSize,
782
+ handle: data.handle
783
+ });
784
+ },
785
+ [
786
+ onResizeStartProp,
787
+ onResizeProp,
788
+ onResizeStopProp,
789
+ containerWidth,
790
+ positionParams,
791
+ constraints,
792
+ effectiveLayoutItem,
793
+ getConstraintContext,
794
+ i
795
+ ]
796
+ );
797
+ const clearDndResizeState = useCallback(() => {
798
+ activeDndResizeRef.current = null;
799
+ setResizing(false);
800
+ resizePositionRef.current = { top: 0, left: 0, width: 0, height: 0 };
801
+ }, []);
802
+ useRuntimeDragDropMonitor({
803
+ onDragStart: (event) => {
804
+ console.debug("[GridItem] runtime onDragStart", { i, event });
805
+ const resizeData = getGridItemResizeData(event.operation.source?.data);
806
+ if (!supportsDndKitResize || !resizeData || resizeData.itemId !== i) {
807
+ console.debug("[GridItem] runtime onDragStart: ignored", { supportsDndKitResize, resizeData });
808
+ return;
809
+ }
810
+ const node = elementRef.current;
811
+ if (!node) {
812
+ console.debug("[GridItem] runtime onDragStart: no node");
813
+ return;
814
+ }
815
+ const origin = calcGridItemPosition(positionParams, x, y, w, h);
816
+ activeDndResizeRef.current = {
817
+ axis: resizeData.axis,
818
+ node,
819
+ origin,
820
+ initialPointer: (() => {
821
+ const ae = event.operation.activatorEvent;
822
+ return ae ? { x: ae.clientX ?? 0, y: ae.clientY ?? 0 } : { x: 0, y: 0 };
823
+ })()
824
+ };
825
+ setResizing(true);
826
+ emitResize(
827
+ "onResizeStart",
828
+ getRuntimeInteractionEvent(event),
829
+ { node, size: origin, handle: resizeData.axis },
830
+ origin
831
+ );
832
+ },
833
+ onDragMove: (event) => {
834
+ console.debug("[GridItem] runtime onDragMove", { i, event });
835
+ const session = activeDndResizeRef.current;
836
+ const resizeData = getGridItemResizeData(event.operation.source?.data);
837
+ if (!session || !supportsDndKitResize || !resizeData || resizeData.itemId !== i || resizeData.axis !== session.axis) {
838
+ console.debug("[GridItem] runtime onDragMove: ignored", { session, resizeData });
839
+ return;
840
+ }
841
+ const moveTransform = event.to ? {
842
+ x: event.to.x - session.initialPointer.x,
843
+ y: event.to.y - session.initialPointer.y
844
+ } : event.operation.transform;
845
+ const nextCandidate = createResizeCandidate(
846
+ session.origin,
847
+ resizeData.axis,
848
+ moveTransform.x / transformScale,
849
+ moveTransform.y / transformScale
850
+ );
851
+ emitResize(
852
+ "onResize",
853
+ getRuntimeInteractionEvent(event),
854
+ { node: session.node, size: nextCandidate, handle: resizeData.axis },
855
+ session.origin
856
+ );
857
+ },
858
+ onDragEnd: (event) => {
859
+ console.debug("[GridItem] runtime onDragEnd", { i, event });
860
+ const session = activeDndResizeRef.current;
861
+ const resizeData = getGridItemResizeData(event.operation.source?.data);
862
+ if (!session || !supportsDndKitResize || !resizeData || resizeData.itemId !== i || resizeData.axis !== session.axis) {
863
+ console.debug("[GridItem] runtime onDragEnd: ignored", { session, resizeData });
864
+ return;
865
+ }
866
+ const nativeEnd = event.nativeEvent instanceof PointerEvent ? event.nativeEvent : null;
867
+ const endTransform = nativeEnd ? {
868
+ x: nativeEnd.clientX - session.initialPointer.x,
869
+ y: nativeEnd.clientY - session.initialPointer.y
870
+ } : event.operation.transform;
871
+ const nextCandidate = event.canceled ? session.origin : createResizeCandidate(
872
+ session.origin,
873
+ resizeData.axis,
874
+ endTransform.x / transformScale,
875
+ endTransform.y / transformScale
876
+ );
877
+ if (event.canceled) {
878
+ onResizeCancelProp?.(i);
879
+ clearDndResizeState();
880
+ return;
881
+ }
882
+ emitResize(
883
+ "onResizeStop",
884
+ getRuntimeInteractionEvent(event),
885
+ { node: session.node, size: nextCandidate, handle: resizeData.axis },
886
+ session.origin
887
+ );
888
+ clearDndResizeState();
889
+ }
890
+ });
891
+ const startDragSession = useCallback(
892
+ (event, kind) => {
893
+ if (!isDraggable || isStatic || dragSessionRef.current) {
894
+ return;
895
+ }
896
+ if (!isPrimaryInputStart(kind, event)) {
897
+ return;
898
+ }
899
+ const node = elementRef.current;
900
+ const target = getTargetElement(event.target);
901
+ if (!node || !target) {
902
+ return;
903
+ }
904
+ if (dragCancelSelector && target.closest(dragCancelSelector)) {
905
+ return;
906
+ }
907
+ if (handle && !target.closest(handle)) {
908
+ return;
909
+ }
910
+ const touchId = getTrackedInputId(kind, event);
911
+ const startCoords = getInputCoordinates(event, touchId);
912
+ if (!startCoords) {
913
+ return;
914
+ }
915
+ const startPosition = getDragStartPosition(
916
+ startCoords.clientX,
917
+ startCoords.clientY,
918
+ node
919
+ );
920
+ if (!startPosition) {
921
+ return;
922
+ }
923
+ clearDragSession();
924
+ event.preventDefault();
925
+ let lastClientX = startCoords.clientX;
926
+ let lastClientY = startCoords.clientY;
927
+ const handleMove = (moveEvent) => {
928
+ if (!isTrackedInputEvent(kind, event, moveEvent)) {
929
+ return;
930
+ }
931
+ const coords = getInputCoordinates(moveEvent, touchId);
932
+ if (!coords) {
933
+ return;
934
+ }
935
+ preventTouchMoveDefault(kind, moveEvent);
936
+ const deltaX = (coords.clientX - lastClientX) / transformScale;
937
+ const deltaY = (coords.clientY - lastClientY) / transformScale;
938
+ lastClientX = coords.clientX;
939
+ lastClientY = coords.clientY;
940
+ emitDragMove(
941
+ moveEvent,
942
+ node,
943
+ deltaX,
944
+ deltaY,
945
+ coords.clientX,
946
+ coords.clientY
947
+ );
948
+ };
949
+ const handleEnd = (endEvent) => {
950
+ if (!isTrackedInputEvent(kind, event, endEvent)) {
951
+ return;
952
+ }
953
+ clearDragSession();
954
+ emitDragStop(endEvent, node);
955
+ };
956
+ dragSessionRef.current = {
957
+ cleanup: createNativeInteractionSession(
958
+ kind,
959
+ event,
960
+ node,
961
+ handleMove,
962
+ handleEnd
963
+ )
964
+ };
965
+ emitDragStart(
966
+ event,
967
+ node,
968
+ startPosition,
969
+ false,
970
+ startCoords.clientX,
971
+ startCoords.clientY
972
+ );
973
+ },
974
+ [
975
+ isDraggable,
976
+ isStatic,
977
+ dragCancelSelector,
978
+ handle,
979
+ getDragStartPosition,
980
+ clearDragSession,
981
+ transformScale,
982
+ emitDragMove,
983
+ emitDragStop,
984
+ emitDragStart
985
+ ]
986
+ );
987
+ const handleDragPointerDown = useCallback(
988
+ (event) => {
989
+ startDragSession(event, "pointer");
990
+ },
991
+ [startDragSession]
992
+ );
993
+ const handleDragMouseDown = useCallback(
994
+ (event) => {
995
+ startDragSession(event, "mouse");
996
+ },
997
+ [startDragSession]
998
+ );
999
+ const handleDragTouchStart = useCallback(
1000
+ (event) => {
1001
+ startDragSession(event, "touch");
1002
+ },
1003
+ [startDragSession]
1004
+ );
1005
+ const startResizeSession = useCallback(
1006
+ (handleAxis, nativeEvent, kind) => {
1007
+ if (!isResizable || isStatic || resizeSessionRef.current) {
1008
+ return;
1009
+ }
1010
+ if (!isPrimaryInputStart(kind, nativeEvent)) {
1011
+ return;
1012
+ }
1013
+ const node = elementRef.current;
1014
+ if (!node) {
1015
+ return;
1016
+ }
1017
+ const touchId = getTrackedInputId(kind, nativeEvent);
1018
+ const startCoords = getInputCoordinates(nativeEvent, touchId);
1019
+ if (!startCoords) {
1020
+ return;
1021
+ }
1022
+ clearResizeSession();
1023
+ nativeEvent.preventDefault();
1024
+ setResizing(true);
1025
+ const origin = calcGridItemPosition(positionParams, x, y, w, h);
1026
+ emitResize(
1027
+ "onResizeStart",
1028
+ nativeEvent,
1029
+ { node, size: origin, handle: handleAxis },
1030
+ origin
1031
+ );
1032
+ const startClientX = startCoords.clientX;
1033
+ const startClientY = startCoords.clientY;
1034
+ const handleMove = (moveEvent) => {
1035
+ if (!isTrackedInputEvent(kind, nativeEvent, moveEvent)) {
1036
+ return;
1037
+ }
1038
+ const coords = getInputCoordinates(moveEvent, touchId);
1039
+ if (!coords) {
1040
+ return;
1041
+ }
1042
+ preventTouchMoveDefault(kind, moveEvent);
1043
+ const deltaX = (coords.clientX - startClientX) / transformScale;
1044
+ const deltaY = (coords.clientY - startClientY) / transformScale;
1045
+ const nextCandidate = createResizeCandidate(
1046
+ origin,
1047
+ handleAxis,
1048
+ deltaX,
1049
+ deltaY
1050
+ );
1051
+ emitResize(
1052
+ "onResize",
1053
+ moveEvent,
1054
+ { node, size: nextCandidate, handle: handleAxis },
1055
+ origin
1056
+ );
1057
+ };
1058
+ const handleEnd = (endEvent) => {
1059
+ if (!isTrackedInputEvent(kind, nativeEvent, endEvent)) {
1060
+ return;
1061
+ }
1062
+ const coords = getInputCoordinates(endEvent, touchId) ?? startCoords;
1063
+ const deltaX = (coords.clientX - startClientX) / transformScale;
1064
+ const deltaY = (coords.clientY - startClientY) / transformScale;
1065
+ const nextCandidate = createResizeCandidate(
1066
+ origin,
1067
+ handleAxis,
1068
+ deltaX,
1069
+ deltaY
1070
+ );
1071
+ clearResizeSession();
1072
+ emitResize(
1073
+ "onResizeStop",
1074
+ endEvent,
1075
+ { node, size: nextCandidate, handle: handleAxis },
1076
+ origin
1077
+ );
1078
+ setResizing(false);
1079
+ resizePositionRef.current = { top: 0, left: 0, width: 0, height: 0 };
1080
+ };
1081
+ resizeSessionRef.current = {
1082
+ cleanup: createNativeInteractionSession(
1083
+ kind,
1084
+ nativeEvent,
1085
+ node,
1086
+ handleMove,
1087
+ handleEnd
1088
+ )
1089
+ };
1090
+ },
1091
+ [
1092
+ isResizable,
1093
+ isStatic,
1094
+ clearResizeSession,
1095
+ positionParams,
1096
+ x,
1097
+ y,
1098
+ w,
1099
+ h,
1100
+ emitResize,
1101
+ transformScale
1102
+ ]
1103
+ );
1104
+ const handleResizePointerDown = useCallback(
1105
+ (handleAxis, event) => {
1106
+ event.preventDefault();
1107
+ event.stopPropagation();
1108
+ startResizeSession(handleAxis, event.nativeEvent, "pointer");
1109
+ },
1110
+ [startResizeSession]
1111
+ );
1112
+ const handleResizeMouseDown = useCallback(
1113
+ (handleAxis, event) => {
1114
+ event.preventDefault();
1115
+ event.stopPropagation();
1116
+ startResizeSession(handleAxis, event.nativeEvent, "mouse");
1117
+ },
1118
+ [startResizeSession]
1119
+ );
1120
+ const handleResizeTouchStart = useCallback(
1121
+ (handleAxis, event) => {
1122
+ event.preventDefault();
1123
+ event.stopPropagation();
1124
+ startResizeSession(handleAxis, event.nativeEvent, "touch");
1125
+ },
1126
+ [startResizeSession]
1127
+ );
1128
+ useEffect(() => {
1129
+ if (!supportsDndKitDrag) {
1130
+ console.debug("[GridItem] sortable handle effect: disabled", { i });
1131
+ sortableHandleRef(null);
1132
+ return;
1133
+ }
1134
+ const node = elementRef.current;
1135
+ if (!node) {
1136
+ console.debug("[GridItem] sortable handle effect: no node", { i, handle });
1137
+ return;
1138
+ }
1139
+ const handleElement = handle ? node.querySelector(handle) : null;
1140
+ console.debug("[GridItem] sortable handle effect: applied", {
1141
+ i,
1142
+ handle,
1143
+ node: describeElementForDebug(node),
1144
+ handleElement: describeElementForDebug(handleElement)
1145
+ });
1146
+ sortableHandleRef(handleElement instanceof Element ? handleElement : null);
1147
+ return () => {
1148
+ console.debug("[GridItem] sortable handle effect: cleanup", { i });
1149
+ sortableHandleRef(null);
1150
+ };
1151
+ }, [supportsDndKitDrag, handle, i, sortableHandleRef]);
1152
+ useEffect(() => {
1153
+ if (!supportsDndKitDrag || isDndKitDragSource || resizing) {
1154
+ return;
1155
+ }
1156
+ const node = elementRef.current;
1157
+ if (!node) {
1158
+ console.debug("[GridItem] sortable rebind skipped: no node", {
1159
+ i,
1160
+ x,
1161
+ y,
1162
+ w,
1163
+ h,
1164
+ isDndKitDragSource,
1165
+ resizing
1166
+ });
1167
+ return;
1168
+ }
1169
+ const handleElement = handle ? node.querySelector(handle) : null;
1170
+ console.debug("[GridItem] sortable rebind after geometry/state change", {
1171
+ i,
1172
+ x,
1173
+ y,
1174
+ w,
1175
+ h,
1176
+ node: describeElementForDebug(node),
1177
+ handle,
1178
+ handleElement: describeElementForDebug(handleElement),
1179
+ isSortableDragSource,
1180
+ isDndKitDragSource,
1181
+ resizing
1182
+ });
1183
+ sortableHandleRef(null);
1184
+ sortableRef(null);
1185
+ sortableRef(node);
1186
+ sortableHandleRef(handleElement instanceof Element ? handleElement : null);
1187
+ }, [
1188
+ h,
1189
+ handle,
1190
+ i,
1191
+ isDndKitDragSource,
1192
+ isSortableDragSource,
1193
+ resizing,
1194
+ sortableHandleRef,
1195
+ sortableRef,
1196
+ supportsDndKitDrag,
1197
+ w,
1198
+ x,
1199
+ y
1200
+ ]);
1201
+ useEffect(() => {
1202
+ if (!useNativeDragFallback) {
1203
+ return;
1204
+ }
1205
+ const node = elementRef.current;
1206
+ if (!node) {
1207
+ return;
1208
+ }
1209
+ if (nativePointerEventsAvailable) {
1210
+ node.addEventListener("pointerdown", handleDragPointerDown);
1211
+ } else {
1212
+ node.addEventListener("mousedown", handleDragMouseDown);
1213
+ node.addEventListener("touchstart", handleDragTouchStart, {
1214
+ passive: false
1215
+ });
1216
+ }
1217
+ return () => {
1218
+ if (nativePointerEventsAvailable) {
1219
+ node.removeEventListener("pointerdown", handleDragPointerDown);
1220
+ } else {
1221
+ node.removeEventListener("mousedown", handleDragMouseDown);
1222
+ node.removeEventListener("touchstart", handleDragTouchStart);
1223
+ }
1224
+ };
1225
+ }, [
1226
+ handleDragPointerDown,
1227
+ handleDragMouseDown,
1228
+ handleDragTouchStart,
1229
+ nativePointerEventsAvailable,
1230
+ useNativeDragFallback
1231
+ ]);
1232
+ useEffect(() => {
1233
+ return () => {
1234
+ clearDragSession();
1235
+ clearResizeSession();
1236
+ };
1237
+ }, [clearDragSession, clearResizeSession]);
1238
+ useEffect(() => {
1239
+ if (!droppingPosition) {
1240
+ return;
1241
+ }
1242
+ const node = elementRef.current;
1243
+ if (!node) {
1244
+ return;
1245
+ }
1246
+ const prevDroppingPosition = prevDroppingPositionRef.current ?? {
1247
+ left: 0,
1248
+ top: 0,
1249
+ e: droppingPosition.e
1250
+ };
1251
+ const currentSnapshot = createGridItemDndSnapshot(
1252
+ positionParams,
1253
+ { x, y, w, h },
1254
+ droppingPosition,
1255
+ null
1256
+ );
1257
+ const previousSnapshot = createGridItemDndSnapshot(
1258
+ positionParams,
1259
+ { x, y, w, h },
1260
+ prevDroppingPosition,
1261
+ null
1262
+ );
1263
+ const nextPosition = {
1264
+ left: currentSnapshot.left,
1265
+ top: currentSnapshot.top
1266
+ };
1267
+ if (!dragging) {
1268
+ emitDragStart(droppingPosition.e, node, nextPosition, true);
1269
+ } else if (currentSnapshot.left !== previousSnapshot.left || currentSnapshot.top !== previousSnapshot.top) {
1270
+ const { deltaX, deltaY } = getGridItemPixelDelta(
1271
+ dragPositionRef.current,
1272
+ nextPosition
1273
+ );
1274
+ emitDragMove(droppingPosition.e, node, deltaX, deltaY);
1275
+ }
1276
+ prevDroppingPositionRef.current = droppingPosition;
1277
+ }, [droppingPosition, dragging, emitDragMove, emitDragStart, positionParams, x, y, w, h]);
1278
+ const dndSnapshot = createGridItemDndSnapshot(
1279
+ positionParams,
1280
+ { x, y, w, h },
1281
+ dragging ? dragPositionRef.current : null,
1282
+ resizing ? resizePositionRef.current : null
1283
+ );
1284
+ const pos = {
1285
+ left: dndSnapshot.left,
1286
+ top: dndSnapshot.top,
1287
+ width: dndSnapshot.width,
1288
+ height: dndSnapshot.height
1289
+ };
1290
+ const child = React3.Children.only(children);
1291
+ const childProps = child.props;
1292
+ const childClassName = childProps["className"];
1293
+ const childStyle = childProps["style"];
1294
+ const childOnPointerDownCapture = childProps["onPointerDownCapture"];
1295
+ const childOnMouseDownCapture = childProps["onMouseDownCapture"];
1296
+ const childOnClickCapture = childProps["onClickCapture"];
1297
+ const showSortableDragSource = supportsDndKitDrag && isSortableDragSource && isDndKitDragSource;
1298
+ const renderResizeHandle = useCallback(
1299
+ (axis) => {
1300
+ return /* @__PURE__ */ jsx(
1301
+ GridResizeHandle,
1302
+ {
1303
+ axis,
1304
+ itemId: i,
1305
+ resizeHandle,
1306
+ supportsDndKitResize,
1307
+ onPointerDown: useNativeResizeFallback && nativePointerEventsAvailable ? (event) => handleResizePointerDown(axis, event) : void 0,
1308
+ onMouseDown: useNativeResizeFallback && !nativePointerEventsAvailable ? (event) => handleResizeMouseDown(axis, event) : void 0,
1309
+ onTouchStart: useNativeResizeFallback && !nativePointerEventsAvailable ? (event) => handleResizeTouchStart(axis, event) : void 0
1310
+ },
1311
+ axis
1312
+ );
1313
+ },
1314
+ [
1315
+ handleResizePointerDown,
1316
+ handleResizeMouseDown,
1317
+ handleResizeTouchStart,
1318
+ i,
1319
+ nativePointerEventsAvailable,
1320
+ resizeHandle,
1321
+ supportsDndKitResize,
1322
+ useNativeResizeFallback
1323
+ ]
1324
+ );
1325
+ const nextChildren = React3.Children.toArray(
1326
+ childProps["children"]
1327
+ );
1328
+ if (isResizable && !isStatic) {
1329
+ nextChildren.push(...resolvedResizeHandles.map(renderResizeHandle));
1330
+ }
1331
+ return React3.cloneElement(
1332
+ child,
1333
+ {
1334
+ ref: setElementRef,
1335
+ className: clsx("react-grid-item", childClassName, className, {
1336
+ static: isStatic,
1337
+ resizing,
1338
+ "react-draggable": isDraggable,
1339
+ "react-draggable-dragging": dragging || showSortableDragSource,
1340
+ dropping: Boolean(droppingPosition),
1341
+ cssTransforms: useCSSTransforms,
1342
+ "react-resizable-hide": !isResizable
1343
+ }),
1344
+ onPointerDownCapture: (event) => {
1345
+ const node = elementRef.current;
1346
+ console.debug("[GridItem] pointerdown capture", {
1347
+ i,
1348
+ target: describeElementForDebug(event.target),
1349
+ currentTarget: describeElementForDebug(event.currentTarget),
1350
+ node: describeElementForDebug(node),
1351
+ connected: node?.isConnected ?? false,
1352
+ supportsDndKitDrag,
1353
+ isSortableDragSource,
1354
+ isDndKitDragSource,
1355
+ dragging,
1356
+ resizing,
1357
+ handle,
1358
+ cancel,
1359
+ visibility: node && typeof window !== "undefined" ? window.getComputedStyle(node).visibility : void 0,
1360
+ pointerEvents: node && typeof window !== "undefined" ? window.getComputedStyle(node).pointerEvents : void 0
1361
+ });
1362
+ childOnPointerDownCapture?.(event);
1363
+ },
1364
+ onMouseDownCapture: (event) => {
1365
+ console.debug("[GridItem] mousedown capture", {
1366
+ i,
1367
+ target: describeElementForDebug(event.target),
1368
+ currentTarget: describeElementForDebug(event.currentTarget),
1369
+ supportsDndKitDrag,
1370
+ isSortableDragSource,
1371
+ isDndKitDragSource,
1372
+ dragging,
1373
+ resizing
1374
+ });
1375
+ childOnMouseDownCapture?.(event);
1376
+ },
1377
+ onClickCapture: (event) => {
1378
+ console.debug("[GridItem] click capture", {
1379
+ i,
1380
+ target: describeElementForDebug(event.target),
1381
+ currentTarget: describeElementForDebug(event.currentTarget),
1382
+ supportsDndKitDrag,
1383
+ isSortableDragSource,
1384
+ isDndKitDragSource,
1385
+ dragging,
1386
+ resizing
1387
+ });
1388
+ childOnClickCapture?.(event);
1389
+ },
1390
+ style: {
1391
+ ...style,
1392
+ ...childStyle,
1393
+ ...createStyle(pos),
1394
+ visibility: showSortableDragSource ? "hidden" : childStyle?.visibility,
1395
+ touchAction: isDraggable || isResizable ? "none" : childStyle?.touchAction
1396
+ }
1397
+ },
1398
+ ...nextChildren
1399
+ );
1400
+ }
1401
+ function createGridLayoutInteractionSnapshot(dragState, resizeState, dropState) {
1402
+ const isDragging = dragState.activeDrag !== null;
1403
+ const isResizing = resizeState.resizing;
1404
+ const isDropping = dropState.droppingPosition !== null;
1405
+ return {
1406
+ isDragging,
1407
+ isResizing,
1408
+ isDropping,
1409
+ isInteracting: isDragging || isResizing || isDropping,
1410
+ activeDragId: dragState.activeDrag?.i ?? null
1411
+ };
1412
+ }
1413
+ function useGridLayout(options) {
1414
+ const {
1415
+ layout: propsLayout,
1416
+ cols,
1417
+ preventCollision = false,
1418
+ onLayoutChange,
1419
+ compactor = verticalCompactor,
1420
+ droppingItemId = "__dropping-elem__"
1421
+ } = options;
1422
+ const isDraggingRef = useRef(false);
1423
+ const [layout, setLayoutState] = useState(() => {
1424
+ const corrected = correctBounds(cloneLayout(propsLayout), { cols });
1425
+ return compactor.compact(corrected, cols);
1426
+ });
1427
+ const [dragState, setDragState] = useState({
1428
+ activeDrag: null,
1429
+ oldDragItem: null,
1430
+ oldLayout: null
1431
+ });
1432
+ const [resizeState, setResizeState] = useState({
1433
+ resizing: false,
1434
+ oldResizeItem: null,
1435
+ oldLayout: null
1436
+ });
1437
+ const [dropState, setDropState] = useState({
1438
+ droppingDOMNode: null,
1439
+ droppingPosition: null
1440
+ });
1441
+ const prevLayoutRef = useRef(layout);
1442
+ const setLayout = useCallback(
1443
+ (newLayout) => {
1444
+ const corrected = correctBounds(cloneLayout(newLayout), { cols });
1445
+ const compacted = compactor.compact(corrected, cols);
1446
+ setLayoutState(compacted);
1447
+ },
1448
+ [cols, compactor]
1449
+ );
1450
+ useEffect(() => {
1451
+ if (isDraggingRef.current) {
1452
+ return;
1453
+ }
1454
+ if (!deepEqual(propsLayout, prevLayoutRef.current)) {
1455
+ setLayout(propsLayout);
1456
+ }
1457
+ }, [propsLayout, setLayout]);
1458
+ useEffect(() => {
1459
+ if (!deepEqual(layout, prevLayoutRef.current)) {
1460
+ prevLayoutRef.current = layout;
1461
+ if (!layout.some((item) => item.i === droppingItemId)) {
1462
+ onLayoutChange?.(layout);
1463
+ }
1464
+ }
1465
+ }, [layout, onLayoutChange, droppingItemId]);
1466
+ const onDragStart = useCallback(
1467
+ (itemId, x, y) => {
1468
+ const item = getLayoutItem(layout, itemId);
1469
+ if (!item) {
1470
+ return null;
1471
+ }
1472
+ isDraggingRef.current = true;
1473
+ const placeholder = {
1474
+ ...cloneLayoutItem(item),
1475
+ x,
1476
+ y,
1477
+ static: false,
1478
+ moved: false
1479
+ };
1480
+ setDragState({
1481
+ activeDrag: placeholder,
1482
+ oldDragItem: cloneLayoutItem(item),
1483
+ oldLayout: cloneLayout(layout)
1484
+ });
1485
+ return placeholder;
1486
+ },
1487
+ [layout]
1488
+ );
1489
+ const onDrag = useCallback(
1490
+ (itemId, x, y) => {
1491
+ console.debug("[useGridLayout] onDrag received", { itemId, x, y });
1492
+ const item = getLayoutItem(layout, itemId);
1493
+ if (!item) {
1494
+ console.debug("[useGridLayout] onDrag: item not found", itemId);
1495
+ return;
1496
+ }
1497
+ setDragState((prev) => ({
1498
+ ...prev,
1499
+ activeDrag: prev.activeDrag ? { ...prev.activeDrag, x, y } : null
1500
+ }));
1501
+ const newLayout = moveElement(
1502
+ layout,
1503
+ item,
1504
+ x,
1505
+ y,
1506
+ true,
1507
+ preventCollision,
1508
+ compactor.type,
1509
+ cols,
1510
+ compactor.allowOverlap
1511
+ );
1512
+ console.debug("[useGridLayout] onDrag: moveElement computed", { itemId, x, y });
1513
+ const compacted = compactor.compact(newLayout, cols);
1514
+ setLayoutState(compacted);
1515
+ console.debug("[useGridLayout] onDrag: setLayoutState applied", { length: compacted.length });
1516
+ },
1517
+ [layout, cols, compactor, preventCollision]
1518
+ );
1519
+ const onDragStop = useCallback(
1520
+ (itemId, x, y) => {
1521
+ const item = getLayoutItem(layout, itemId);
1522
+ if (!item) {
1523
+ return;
1524
+ }
1525
+ const newLayout = moveElement(
1526
+ layout,
1527
+ item,
1528
+ x,
1529
+ y,
1530
+ true,
1531
+ preventCollision,
1532
+ compactor.type,
1533
+ cols,
1534
+ compactor.allowOverlap
1535
+ );
1536
+ const compacted = compactor.compact(newLayout, cols);
1537
+ isDraggingRef.current = false;
1538
+ setDragState({ activeDrag: null, oldDragItem: null, oldLayout: null });
1539
+ setLayoutState(compacted);
1540
+ },
1541
+ [layout, cols, compactor, preventCollision]
1542
+ );
1543
+ const cancelDrag = useCallback(() => {
1544
+ isDraggingRef.current = false;
1545
+ setDragState((prev) => {
1546
+ if (prev.oldLayout) {
1547
+ const corrected = correctBounds(cloneLayout(prev.oldLayout), { cols });
1548
+ const compacted = compactor.compact(corrected, cols);
1549
+ setLayoutState(compacted);
1550
+ }
1551
+ return { activeDrag: null, oldDragItem: null, oldLayout: null };
1552
+ });
1553
+ }, [cols, compactor]);
1554
+ const onResizeStart = useCallback(
1555
+ (itemId) => {
1556
+ const item = getLayoutItem(layout, itemId);
1557
+ if (!item) {
1558
+ return null;
1559
+ }
1560
+ setResizeState({
1561
+ resizing: true,
1562
+ oldResizeItem: cloneLayoutItem(item),
1563
+ oldLayout: cloneLayout(layout)
1564
+ });
1565
+ return item;
1566
+ },
1567
+ [layout]
1568
+ );
1569
+ const onResize = useCallback(
1570
+ (itemId, w, h, x, y) => {
1571
+ const newLayout = layout.map((item) => {
1572
+ if (item.i !== itemId) {
1573
+ return item;
1574
+ }
1575
+ const updated = {
1576
+ ...item,
1577
+ w,
1578
+ h
1579
+ };
1580
+ if (x !== void 0) {
1581
+ updated.x = x;
1582
+ }
1583
+ if (y !== void 0) {
1584
+ updated.y = y;
1585
+ }
1586
+ return updated;
1587
+ });
1588
+ const corrected = correctBounds(newLayout, { cols });
1589
+ const compacted = compactor.compact(corrected, cols);
1590
+ const activeResizeItem = getLayoutItem(compacted, itemId);
1591
+ setLayoutState(compacted);
1592
+ setDragState((prev) => ({
1593
+ ...prev,
1594
+ activeDrag: activeResizeItem ? cloneLayoutItem(activeResizeItem) : prev.activeDrag
1595
+ }));
1596
+ },
1597
+ [layout, cols, compactor]
1598
+ );
1599
+ const onResizeStop = useCallback(
1600
+ (itemId, w, h, x, y) => {
1601
+ onResize(itemId, w, h, x, y);
1602
+ setResizeState({
1603
+ resizing: false,
1604
+ oldResizeItem: null,
1605
+ oldLayout: null
1606
+ });
1607
+ setDragState({ activeDrag: null, oldDragItem: null, oldLayout: null });
1608
+ },
1609
+ [onResize]
1610
+ );
1611
+ const cancelResize = useCallback(() => {
1612
+ setResizeState((prev) => {
1613
+ if (prev.oldLayout) {
1614
+ const corrected = correctBounds(cloneLayout(prev.oldLayout), { cols });
1615
+ const compacted = compactor.compact(corrected, cols);
1616
+ setLayoutState(compacted);
1617
+ }
1618
+ return {
1619
+ resizing: false,
1620
+ oldResizeItem: null,
1621
+ oldLayout: null
1622
+ };
1623
+ });
1624
+ setDragState({ activeDrag: null, oldDragItem: null, oldLayout: null });
1625
+ }, [cols, compactor]);
1626
+ const onDropDragOver = useCallback(
1627
+ (droppingItem, position) => {
1628
+ const existingItem = getLayoutItem(layout, droppingItem.i);
1629
+ isDraggingRef.current = true;
1630
+ if (!existingItem) {
1631
+ const newLayout = [...layout, droppingItem];
1632
+ const corrected = correctBounds(newLayout, { cols });
1633
+ setLayoutState(corrected);
1634
+ }
1635
+ setDropState({
1636
+ droppingDOMNode: null,
1637
+ droppingPosition: position
1638
+ });
1639
+ },
1640
+ [layout, cols]
1641
+ );
1642
+ const onDropDragLeave = useCallback(() => {
1643
+ const newLayout = layout.filter((item) => item.i !== droppingItemId);
1644
+ setLayout(newLayout);
1645
+ isDraggingRef.current = false;
1646
+ setDragState({ activeDrag: null, oldDragItem: null, oldLayout: null });
1647
+ setResizeState((prev) => ({
1648
+ ...prev,
1649
+ resizing: false
1650
+ }));
1651
+ setDropState({
1652
+ droppingDOMNode: null,
1653
+ droppingPosition: null
1654
+ });
1655
+ }, [layout, droppingItemId, setLayout]);
1656
+ const onDrop = useCallback(
1657
+ (droppingItem) => {
1658
+ const newLayout = layout.map((item) => {
1659
+ if (item.i !== droppingItemId) {
1660
+ return item;
1661
+ }
1662
+ return {
1663
+ ...item,
1664
+ i: droppingItem.i,
1665
+ static: false
1666
+ };
1667
+ });
1668
+ const corrected = correctBounds(newLayout, { cols });
1669
+ const compacted = compactor.compact(corrected, cols);
1670
+ setLayoutState(compacted);
1671
+ isDraggingRef.current = false;
1672
+ setDragState({ activeDrag: null, oldDragItem: null, oldLayout: null });
1673
+ setDropState({
1674
+ droppingDOMNode: null,
1675
+ droppingPosition: null
1676
+ });
1677
+ },
1678
+ [layout, droppingItemId, cols, compactor]
1679
+ );
1680
+ const containerHeight = useMemo(() => bottom(layout), [layout]);
1681
+ const interactionSnapshot = useMemo(
1682
+ () => createGridLayoutInteractionSnapshot(dragState, resizeState, dropState),
1683
+ [dragState, resizeState, dropState]
1684
+ );
1685
+ return {
1686
+ layout,
1687
+ setLayout,
1688
+ dragState,
1689
+ resizeState,
1690
+ dropState,
1691
+ onDragStart,
1692
+ onDrag,
1693
+ onDragStop,
1694
+ cancelDrag,
1695
+ onResizeStart,
1696
+ onResize,
1697
+ onResizeStop,
1698
+ cancelResize,
1699
+ onDropDragOver,
1700
+ onDropDragLeave,
1701
+ onDrop,
1702
+ containerHeight,
1703
+ isInteracting: interactionSnapshot.isInteracting,
1704
+ compactor
1705
+ };
1706
+ }
1707
+ var noop = () => {
1708
+ };
1709
+ var layoutClassName = "react-grid-layout";
1710
+ var isFirefox = false;
1711
+ try {
1712
+ isFirefox = /firefox/i.test(navigator.userAgent);
1713
+ } catch {
1714
+ }
1715
+ function childrenEqual(a, b) {
1716
+ const aArr = React3.Children.toArray(a);
1717
+ const bArr = React3.Children.toArray(b);
1718
+ if (aArr.length !== bArr.length) {
1719
+ return false;
1720
+ }
1721
+ for (let i = 0; i < aArr.length; i++) {
1722
+ const aChild = aArr[i];
1723
+ const bChild = bArr[i];
1724
+ if (aChild?.key !== bChild?.key) {
1725
+ return false;
1726
+ }
1727
+ }
1728
+ return true;
1729
+ }
1730
+ function synchronizeLayoutWithChildren(initialLayout, children, cols, compactor) {
1731
+ const layout = [];
1732
+ const childKeys = /* @__PURE__ */ new Set();
1733
+ React3.Children.forEach(children, (child) => {
1734
+ if (!React3.isValidElement(child) || child.key === null) {
1735
+ return;
1736
+ }
1737
+ const key = String(child.key);
1738
+ childKeys.add(key);
1739
+ const existingItem = initialLayout.find((l) => l.i === key);
1740
+ if (existingItem) {
1741
+ layout.push(cloneLayoutItem(existingItem));
1742
+ return;
1743
+ }
1744
+ const childProps = child.props;
1745
+ const dataGrid = childProps["data-grid"];
1746
+ if (dataGrid) {
1747
+ layout.push({
1748
+ i: key,
1749
+ x: dataGrid.x ?? 0,
1750
+ y: dataGrid.y ?? 0,
1751
+ w: dataGrid.w ?? 1,
1752
+ h: dataGrid.h ?? 1,
1753
+ minW: dataGrid.minW,
1754
+ maxW: dataGrid.maxW,
1755
+ minH: dataGrid.minH,
1756
+ maxH: dataGrid.maxH,
1757
+ static: dataGrid.static,
1758
+ isDraggable: dataGrid.isDraggable,
1759
+ isResizable: dataGrid.isResizable,
1760
+ resizeHandles: dataGrid.resizeHandles,
1761
+ isBounded: dataGrid.isBounded
1762
+ });
1763
+ return;
1764
+ }
1765
+ layout.push({
1766
+ i: key,
1767
+ x: 0,
1768
+ y: bottom(layout),
1769
+ w: 1,
1770
+ h: 1
1771
+ });
1772
+ });
1773
+ const corrected = correctBounds(layout, { cols });
1774
+ return compactor.compact(corrected, cols);
1775
+ }
1776
+ function createGridDropPlaceholder(config) {
1777
+ return config.override ?? {
1778
+ i: "__dropping-elem__",
1779
+ x: 0,
1780
+ y: 0,
1781
+ ...config.defaultItem
1782
+ };
1783
+ }
1784
+ function createGridInteractionState(activeDrag, resizing, droppingPosition) {
1785
+ return {
1786
+ isInteracting: activeDrag !== null || resizing || droppingPosition !== void 0,
1787
+ activeDrag,
1788
+ resizing,
1789
+ droppingPosition
1790
+ };
1791
+ }
1792
+ function getGridItemDragData(value) {
1793
+ if (!value || typeof value !== "object") {
1794
+ return null;
1795
+ }
1796
+ const kind = value.kind;
1797
+ const itemId = value.itemId;
1798
+ return kind === "drag" && typeof itemId === "string" ? { kind: "drag", itemId } : null;
1799
+ }
1800
+ function GridLayout(props) {
1801
+ const {
1802
+ children,
1803
+ width,
1804
+ gridConfig: gridConfigProp,
1805
+ dragConfig: dragConfigProp,
1806
+ resizeConfig: resizeConfigProp,
1807
+ dropConfig: dropConfigProp,
1808
+ positionStrategy = defaultPositionStrategy,
1809
+ compactor: compactorProp,
1810
+ constraints = defaultConstraints,
1811
+ layout: propsLayout = [],
1812
+ droppingItem: droppingItemProp,
1813
+ autoSize = true,
1814
+ className = "",
1815
+ style = {},
1816
+ innerRef,
1817
+ onLayoutChange = noop,
1818
+ onDragStart: onDragStartProp = noop,
1819
+ onDrag: onDragProp = noop,
1820
+ onDragStop: onDragStopProp = noop,
1821
+ onResizeStart: onResizeStartProp = noop,
1822
+ onResize: onResizeProp = noop,
1823
+ onResizeStop: onResizeStopProp = noop,
1824
+ onDrop: onDropProp = noop,
1825
+ onDropDragOver: onDropDragOverProp = noop
1826
+ } = props;
1827
+ const gridConfig = useMemo(
1828
+ () => ({ ...defaultGridConfig, ...gridConfigProp }),
1829
+ [gridConfigProp]
1830
+ );
1831
+ const dragConfig = useMemo(
1832
+ () => ({ ...defaultDragConfig, ...dragConfigProp }),
1833
+ [dragConfigProp]
1834
+ );
1835
+ const resizeConfig = useMemo(
1836
+ () => ({ ...defaultResizeConfig, ...resizeConfigProp }),
1837
+ [resizeConfigProp]
1838
+ );
1839
+ const dropConfig = useMemo(
1840
+ () => ({ ...defaultDropConfig, ...dropConfigProp }),
1841
+ [dropConfigProp]
1842
+ );
1843
+ const { cols, rowHeight, maxRows, margin, containerPadding } = gridConfig;
1844
+ const {
1845
+ enabled: isDraggable,
1846
+ bounded: isBounded,
1847
+ handle: draggableHandle,
1848
+ cancel: draggableCancel,
1849
+ threshold: dragThreshold
1850
+ } = dragConfig;
1851
+ const {
1852
+ enabled: isResizable,
1853
+ handles: resizeHandles,
1854
+ handleComponent: resizeHandle
1855
+ } = resizeConfig;
1856
+ const {
1857
+ enabled: isDroppable,
1858
+ defaultItem: defaultDropItem,
1859
+ onDragOver: dropConfigOnDragOver
1860
+ } = dropConfig;
1861
+ const compactor = compactorProp ?? getCompactor("vertical");
1862
+ const compactType = compactor.type;
1863
+ const allowOverlap = compactor.allowOverlap;
1864
+ const preventCollision = compactor.preventCollision ?? false;
1865
+ const droppingItem = useMemo(
1866
+ () => createGridDropPlaceholder({
1867
+ defaultItem: defaultDropItem,
1868
+ override: droppingItemProp
1869
+ }),
1870
+ [droppingItemProp, defaultDropItem]
1871
+ );
1872
+ const useCSSTransforms = positionStrategy.type === "transform";
1873
+ const transformScale = positionStrategy.scale;
1874
+ const effectiveContainerPadding = containerPadding ?? margin;
1875
+ const positionParams = useMemo(
1876
+ () => ({
1877
+ cols,
1878
+ margin,
1879
+ maxRows,
1880
+ rowHeight,
1881
+ containerWidth: width,
1882
+ containerPadding: effectiveContainerPadding
1883
+ }),
1884
+ [cols, margin, maxRows, rowHeight, width, effectiveContainerPadding]
1885
+ );
1886
+ const { stepX, stepY } = useMemo(
1887
+ () => getGridPixelSteps(positionParams),
1888
+ [positionParams]
1889
+ );
1890
+ const synchronizedLayout = useMemo(
1891
+ () => synchronizeLayoutWithChildren(propsLayout, children, cols, compactor),
1892
+ [propsLayout, children, cols, compactor]
1893
+ );
1894
+ const [mounted, setMounted] = useState(false);
1895
+ const [droppingDOMNode, setDroppingDOMNode] = useState(
1896
+ null
1897
+ );
1898
+ const [dragOverlayId, setDragOverlayId] = useState(null);
1899
+ const containerRef = useRef(null);
1900
+ const activeDndDragRef = useRef(null);
1901
+ const setContainerNode = useCallback(
1902
+ (node) => {
1903
+ containerRef.current = node;
1904
+ if (typeof innerRef === "function") {
1905
+ innerRef(node);
1906
+ return;
1907
+ }
1908
+ if (innerRef && "current" in innerRef) {
1909
+ innerRef.current = node;
1910
+ }
1911
+ },
1912
+ [innerRef]
1913
+ );
1914
+ const dndSensors = useMemo(
1915
+ () => [
1916
+ PointerSensor.configure({
1917
+ activationConstraints: [
1918
+ new PointerActivationConstraints.Distance({
1919
+ value: Math.max(3, dragThreshold)
1920
+ })
1921
+ ],
1922
+ preventActivation: (event, source) => {
1923
+ const sourceData = source?.data;
1924
+ if (sourceData?.kind === "resize") return false;
1925
+ const target = event.target instanceof HTMLElement ? event.target : null;
1926
+ return Boolean(
1927
+ target && target.closest(
1928
+ [".react-resizable-handle", draggableCancel].filter(Boolean).join(",")
1929
+ )
1930
+ );
1931
+ }
1932
+ }),
1933
+ KeyboardSensor.configure({
1934
+ offset: {
1935
+ x: stepX,
1936
+ y: stepY
1937
+ }
1938
+ })
1939
+ ],
1940
+ [dragThreshold, draggableCancel, stepX, stepY]
1941
+ );
1942
+ const {
1943
+ layout,
1944
+ setLayout,
1945
+ dragState,
1946
+ resizeState,
1947
+ dropState,
1948
+ onDragStart: beginDragState,
1949
+ onDrag: updateDragState,
1950
+ onDragStop: stopDragState,
1951
+ cancelDrag: cancelDragState,
1952
+ onResizeStart: beginResizeState,
1953
+ onResize: updateResizeState,
1954
+ onResizeStop: stopResizeState,
1955
+ cancelResize: cancelResizeState,
1956
+ onDropDragOver: updateDropPlaceholder,
1957
+ onDropDragLeave: clearDropPlaceholder
1958
+ } = useGridLayout({
1959
+ layout: synchronizedLayout,
1960
+ cols,
1961
+ preventCollision,
1962
+ compactor,
1963
+ droppingItemId: droppingItem.i
1964
+ });
1965
+ const activeDrag = dragState.activeDrag;
1966
+ const resizing = resizeState.resizing;
1967
+ const droppingPosition = dropState.droppingPosition ?? void 0;
1968
+ const interactionState = useMemo(
1969
+ () => createGridInteractionState(activeDrag, resizing, droppingPosition),
1970
+ [activeDrag, resizing, droppingPosition]
1971
+ );
1972
+ const oldDragItemRef = useRef(null);
1973
+ const oldResizeItemRef = useRef(null);
1974
+ const oldLayoutRef = useRef(null);
1975
+ const dragEnterCounterRef = useRef(0);
1976
+ const prevLayoutRef = useRef(layout);
1977
+ const prevPropsLayoutRef = useRef(propsLayout);
1978
+ const prevChildrenRef = useRef(children);
1979
+ const prevCompactTypeRef = useRef(compactType);
1980
+ const layoutRef = useRef(layout);
1981
+ layoutRef.current = layout;
1982
+ const childMap = useMemo(() => {
1983
+ const next = /* @__PURE__ */ new Map();
1984
+ React3.Children.forEach(children, (child) => {
1985
+ if (!React3.isValidElement(child) || child.key === null) {
1986
+ return;
1987
+ }
1988
+ next.set(String(child.key), child);
1989
+ });
1990
+ return next;
1991
+ }, [children]);
1992
+ const createConstraintContext = useCallback(
1993
+ (currentLayout) => ({
1994
+ cols,
1995
+ maxRows,
1996
+ containerWidth: width,
1997
+ containerHeight: containerRef.current?.clientHeight ?? 0,
1998
+ rowHeight,
1999
+ margin,
2000
+ layout: currentLayout
2001
+ }),
2002
+ [cols, maxRows, width, rowHeight, margin]
2003
+ );
2004
+ const getDragEventNativeEvent = useCallback(
2005
+ (event) => event.nativeEvent ?? event.operation.activatorEvent ?? new Event("drag"),
2006
+ []
2007
+ );
2008
+ const getDragSourceElement = useCallback(
2009
+ (source) => {
2010
+ const element = source?.element;
2011
+ return element instanceof HTMLElement ? element : null;
2012
+ },
2013
+ []
2014
+ );
2015
+ const getDraggedGridPosition = useCallback(
2016
+ (session, currentItem, transform) => {
2017
+ const newPosition = {
2018
+ left: session.origin.left + transform.x / transformScale,
2019
+ top: session.origin.top + transform.y / transformScale
2020
+ };
2021
+ const rawPosition = calcXYRaw(
2022
+ positionParams,
2023
+ newPosition.top,
2024
+ newPosition.left
2025
+ );
2026
+ const constrained = applyPositionConstraints(
2027
+ constraints,
2028
+ currentItem,
2029
+ rawPosition.x,
2030
+ rawPosition.y,
2031
+ createConstraintContext(layoutRef.current)
2032
+ );
2033
+ return {
2034
+ x: constrained.x,
2035
+ y: constrained.y,
2036
+ newPosition
2037
+ };
2038
+ },
2039
+ [constraints, createConstraintContext, positionParams, transformScale]
2040
+ );
2041
+ useEffect(() => {
2042
+ setMounted(true);
2043
+ if (!deepEqual(layout, propsLayout)) {
2044
+ onLayoutChange(layout);
2045
+ }
2046
+ }, []);
2047
+ useEffect(() => {
2048
+ if (activeDrag || droppingDOMNode) {
2049
+ return;
2050
+ }
2051
+ const layoutChanged = !deepEqual(propsLayout, prevPropsLayoutRef.current);
2052
+ const childrenChanged = !childrenEqual(children, prevChildrenRef.current);
2053
+ const compactTypeChanged = compactType !== prevCompactTypeRef.current;
2054
+ if (layoutChanged || childrenChanged || compactTypeChanged) {
2055
+ const baseLayout = layoutChanged ? propsLayout : layoutRef.current;
2056
+ const nextLayout = synchronizeLayoutWithChildren(
2057
+ baseLayout,
2058
+ children,
2059
+ cols,
2060
+ compactor
2061
+ );
2062
+ if (!deepEqual(nextLayout, layoutRef.current)) {
2063
+ setLayout(nextLayout);
2064
+ }
2065
+ }
2066
+ prevPropsLayoutRef.current = propsLayout;
2067
+ prevChildrenRef.current = children;
2068
+ prevCompactTypeRef.current = compactType;
2069
+ }, [
2070
+ propsLayout,
2071
+ children,
2072
+ cols,
2073
+ compactType,
2074
+ compactor,
2075
+ activeDrag,
2076
+ droppingDOMNode
2077
+ // 'layout' intentionally omitted: we access it via layoutRef.current to avoid
2078
+ // re-running on every drag-move. 'setLayout' omitted because it only changes
2079
+ // when cols/compactor change, which are already in the deps.
2080
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2081
+ ]);
2082
+ useEffect(() => {
2083
+ if (!activeDrag && !deepEqual(layout, prevLayoutRef.current)) {
2084
+ prevLayoutRef.current = layout;
2085
+ const publicLayout = layout.filter((l) => l.i !== droppingItem.i);
2086
+ onLayoutChange(publicLayout);
2087
+ }
2088
+ }, [layout, activeDrag, onLayoutChange, droppingItem.i]);
2089
+ const containerHeight = useMemo(() => {
2090
+ if (!autoSize) {
2091
+ return void 0;
2092
+ }
2093
+ const nbRow = bottom(layout);
2094
+ const containerPaddingY = effectiveContainerPadding[1];
2095
+ return nbRow * rowHeight + (nbRow - 1) * margin[1] + containerPaddingY * 2 + "px";
2096
+ }, [autoSize, layout, rowHeight, margin, effectiveContainerPadding]);
2097
+ const onDragStart = useCallback(
2098
+ (i, x, y, data) => {
2099
+ const currentLayout = layoutRef.current;
2100
+ const item = getLayoutItem(currentLayout, i);
2101
+ if (!item) {
2102
+ return;
2103
+ }
2104
+ oldDragItemRef.current = cloneLayoutItem(item);
2105
+ oldLayoutRef.current = currentLayout;
2106
+ beginDragState(i, x, y);
2107
+ onDragStartProp(currentLayout, item, item, null, data.e, data.node);
2108
+ },
2109
+ [beginDragState, onDragStartProp]
2110
+ );
2111
+ const onDrag = useCallback(
2112
+ (i, x, y, data) => {
2113
+ const currentLayout = layoutRef.current;
2114
+ const oldDragItem = oldDragItemRef.current;
2115
+ const item = getLayoutItem(currentLayout, i);
2116
+ if (!item) {
2117
+ return;
2118
+ }
2119
+ const placeholder = {
2120
+ w: item.w,
2121
+ h: item.h,
2122
+ x: item.x,
2123
+ y: item.y,
2124
+ i
2125
+ };
2126
+ const newLayout = moveElement(
2127
+ currentLayout,
2128
+ item,
2129
+ x,
2130
+ y,
2131
+ true,
2132
+ preventCollision,
2133
+ compactType,
2134
+ cols,
2135
+ allowOverlap
2136
+ );
2137
+ onDragProp(newLayout, oldDragItem, item, placeholder, data.e, data.node);
2138
+ updateDragState(i, x, y);
2139
+ },
2140
+ [
2141
+ preventCollision,
2142
+ compactType,
2143
+ cols,
2144
+ allowOverlap,
2145
+ onDragProp,
2146
+ updateDragState
2147
+ ]
2148
+ );
2149
+ const onDragStop = useCallback(
2150
+ (i, x, y, data) => {
2151
+ const currentLayout = layoutRef.current;
2152
+ const oldDragItem = oldDragItemRef.current;
2153
+ const item = getLayoutItem(currentLayout, i);
2154
+ if (!item) {
2155
+ return;
2156
+ }
2157
+ const newLayout = moveElement(
2158
+ currentLayout,
2159
+ item,
2160
+ x,
2161
+ y,
2162
+ true,
2163
+ preventCollision,
2164
+ compactType,
2165
+ cols,
2166
+ allowOverlap
2167
+ );
2168
+ const finalLayout = compactor.compact(newLayout, cols);
2169
+ onDragStopProp(finalLayout, oldDragItem, item, null, data.e, data.node);
2170
+ oldDragItemRef.current = null;
2171
+ oldLayoutRef.current = null;
2172
+ stopDragState(i, x, y);
2173
+ },
2174
+ [
2175
+ preventCollision,
2176
+ compactType,
2177
+ cols,
2178
+ allowOverlap,
2179
+ compactor,
2180
+ onDragStopProp,
2181
+ stopDragState
2182
+ ]
2183
+ );
2184
+ const handleDndKitDragStart = useCallback(
2185
+ (event) => {
2186
+ console.debug("[GridLayout] handleDndKitDragStart", {
2187
+ sourceData: event.operation.source?.data,
2188
+ activatorEvent: event.operation.activatorEvent,
2189
+ nativeEvent: event.nativeEvent
2190
+ });
2191
+ const dragData = getGridItemDragData(event.operation.source?.data);
2192
+ if (!dragData) {
2193
+ console.debug("[GridLayout] handleDndKitDragStart: no dragData");
2194
+ return;
2195
+ }
2196
+ const currentLayout = layoutRef.current;
2197
+ const item = getLayoutItem(currentLayout, dragData.itemId);
2198
+ if (!item) {
2199
+ console.debug("[GridLayout] handleDndKitDragStart: item not found", dragData);
2200
+ return;
2201
+ }
2202
+ const originPosition = calcGridItemPosition(
2203
+ positionParams,
2204
+ item.x,
2205
+ item.y,
2206
+ item.w,
2207
+ item.h
2208
+ );
2209
+ const node = getDragSourceElement(event.operation.source);
2210
+ const activatorEvent = event.operation.activatorEvent;
2211
+ const initialPointer = activatorEvent ? { x: activatorEvent.clientX ?? 0, y: activatorEvent.clientY ?? 0 } : { x: 0, y: 0 };
2212
+ activeDndDragRef.current = {
2213
+ itemId: item.i,
2214
+ node,
2215
+ initialPointer,
2216
+ origin: {
2217
+ left: originPosition.left,
2218
+ top: originPosition.top,
2219
+ x: item.x,
2220
+ y: item.y,
2221
+ w: item.w,
2222
+ h: item.h
2223
+ }
2224
+ };
2225
+ console.debug("[GridLayout] activeDndDragRef set", activeDndDragRef.current);
2226
+ setDragOverlayId(item.i);
2227
+ console.debug("[GridLayout] invoking onDragStart callback", item.i, item.x, item.y);
2228
+ onDragStart(item.i, item.x, item.y, {
2229
+ e: getDragEventNativeEvent(event),
2230
+ node: node ?? containerRef.current ?? document.body,
2231
+ newPosition: {
2232
+ left: originPosition.left,
2233
+ top: originPosition.top
2234
+ }
2235
+ });
2236
+ },
2237
+ [getDragEventNativeEvent, getDragSourceElement, onDragStart, positionParams]
2238
+ );
2239
+ const handleDndKitDragMove = useCallback(
2240
+ (event) => {
2241
+ console.debug("[GridLayout] handleDndKitDragMove", {
2242
+ transform: event.operation.transform,
2243
+ to: event.to,
2244
+ sourceData: event.operation.source?.data
2245
+ });
2246
+ const session = activeDndDragRef.current;
2247
+ const dragData = getGridItemDragData(event.operation.source?.data);
2248
+ if (!session || !dragData || session.itemId !== dragData.itemId) {
2249
+ console.debug("[GridLayout] handleDndKitDragMove: session mismatch", { session, dragData });
2250
+ return;
2251
+ }
2252
+ const currentLayout = layoutRef.current;
2253
+ const item = getLayoutItem(currentLayout, session.itemId);
2254
+ if (!item) {
2255
+ console.debug("[GridLayout] handleDndKitDragMove: item not found", session.itemId);
2256
+ return;
2257
+ }
2258
+ const transform = event.to ? {
2259
+ x: event.to.x - session.initialPointer.x,
2260
+ y: event.to.y - session.initialPointer.y
2261
+ } : event.operation.transform;
2262
+ const { x, y, newPosition } = getDraggedGridPosition(
2263
+ session,
2264
+ item,
2265
+ transform
2266
+ );
2267
+ const node = getDragSourceElement(event.operation.source) ?? session.node;
2268
+ console.debug("[GridLayout] invoking onDrag", session.itemId, { x, y, newPosition });
2269
+ onDrag(session.itemId, x, y, {
2270
+ e: getDragEventNativeEvent(event),
2271
+ node: node ?? containerRef.current ?? document.body,
2272
+ newPosition
2273
+ });
2274
+ },
2275
+ [getDragEventNativeEvent, getDragSourceElement, getDraggedGridPosition, onDrag]
2276
+ );
2277
+ const handleDndKitDragEnd = useCallback(
2278
+ (event) => {
2279
+ console.debug("[GridLayout] handleDndKitDragEnd", {
2280
+ canceled: event.canceled,
2281
+ transform: event.operation.transform,
2282
+ sourceData: event.operation.source?.data
2283
+ });
2284
+ const session = activeDndDragRef.current;
2285
+ const dragData = getGridItemDragData(event.operation.source?.data);
2286
+ activeDndDragRef.current = null;
2287
+ setDragOverlayId(null);
2288
+ if (!session || !dragData || session.itemId !== dragData.itemId) {
2289
+ console.debug("[GridLayout] handleDndKitDragEnd: session or dragData mismatch", { session, dragData });
2290
+ return;
2291
+ }
2292
+ if (event.canceled) {
2293
+ console.debug("[GridLayout] drag canceled for", session.itemId);
2294
+ oldDragItemRef.current = null;
2295
+ oldLayoutRef.current = null;
2296
+ cancelDragState();
2297
+ return;
2298
+ }
2299
+ const currentLayout = layoutRef.current;
2300
+ const item = getLayoutItem(currentLayout, session.itemId);
2301
+ if (!item) {
2302
+ console.debug("[GridLayout] handleDndKitDragEnd: item not found", session.itemId);
2303
+ cancelDragState();
2304
+ return;
2305
+ }
2306
+ const nativePointerEnd = event.nativeEvent instanceof PointerEvent ? event.nativeEvent : null;
2307
+ const endTransform = nativePointerEnd ? {
2308
+ x: nativePointerEnd.clientX - session.initialPointer.x,
2309
+ y: nativePointerEnd.clientY - session.initialPointer.y
2310
+ } : event.operation.transform;
2311
+ const { x, y, newPosition } = getDraggedGridPosition(
2312
+ session,
2313
+ item,
2314
+ endTransform
2315
+ );
2316
+ const node = getDragSourceElement(event.operation.source) ?? session.node;
2317
+ console.debug("[GridLayout] invoking onDragStop", session.itemId, { x, y, newPosition });
2318
+ onDragStop(session.itemId, x, y, {
2319
+ e: getDragEventNativeEvent(event),
2320
+ node: node ?? containerRef.current ?? document.body,
2321
+ newPosition
2322
+ });
2323
+ },
2324
+ [
2325
+ cancelDragState,
2326
+ getDragEventNativeEvent,
2327
+ getDragSourceElement,
2328
+ getDraggedGridPosition,
2329
+ onDragStop
2330
+ ]
2331
+ );
2332
+ const onResizeStart = useCallback(
2333
+ (i, _w, _h, data) => {
2334
+ const currentLayout = layoutRef.current;
2335
+ const item = getLayoutItem(currentLayout, i);
2336
+ if (!item) {
2337
+ return;
2338
+ }
2339
+ oldResizeItemRef.current = cloneLayoutItem(item);
2340
+ oldLayoutRef.current = currentLayout;
2341
+ beginResizeState(i);
2342
+ onResizeStartProp(currentLayout, item, item, null, data.e, data.node);
2343
+ },
2344
+ [beginResizeState, onResizeStartProp]
2345
+ );
2346
+ const onResize = useCallback(
2347
+ (i, w, h, data) => {
2348
+ const currentLayout = layoutRef.current;
2349
+ const oldResizeItem = oldResizeItemRef.current;
2350
+ const { handle } = data;
2351
+ let shouldMoveItem = false;
2352
+ let newX;
2353
+ let newY;
2354
+ const [newLayout, item] = withLayoutItem(currentLayout, i, (layoutItem) => {
2355
+ newX = layoutItem.x;
2356
+ newY = layoutItem.y;
2357
+ if (["sw", "w", "nw", "n", "ne"].includes(handle)) {
2358
+ if (["sw", "nw", "w"].includes(handle)) {
2359
+ newX = layoutItem.x + (layoutItem.w - w);
2360
+ w = layoutItem.x !== newX && newX < 0 ? layoutItem.w : w;
2361
+ newX = newX < 0 ? 0 : newX;
2362
+ }
2363
+ if (["ne", "n", "nw"].includes(handle)) {
2364
+ newY = layoutItem.y + (layoutItem.h - h);
2365
+ h = layoutItem.y !== newY && newY < 0 ? layoutItem.h : h;
2366
+ newY = newY < 0 ? 0 : newY;
2367
+ }
2368
+ shouldMoveItem = true;
2369
+ }
2370
+ if (preventCollision && !allowOverlap) {
2371
+ const collisions = getAllCollisions(currentLayout, {
2372
+ ...layoutItem,
2373
+ w,
2374
+ h,
2375
+ x: newX ?? layoutItem.x,
2376
+ y: newY ?? layoutItem.y
2377
+ }).filter((layoutEntry) => layoutEntry.i !== layoutItem.i);
2378
+ if (collisions.length > 0) {
2379
+ newY = layoutItem.y;
2380
+ h = layoutItem.h;
2381
+ newX = layoutItem.x;
2382
+ w = layoutItem.w;
2383
+ shouldMoveItem = false;
2384
+ }
2385
+ }
2386
+ layoutItem.w = w;
2387
+ layoutItem.h = h;
2388
+ return layoutItem;
2389
+ });
2390
+ if (!item) {
2391
+ return;
2392
+ }
2393
+ let finalLayout = newLayout;
2394
+ if (shouldMoveItem && newX !== void 0 && newY !== void 0) {
2395
+ finalLayout = moveElement(
2396
+ newLayout,
2397
+ item,
2398
+ newX,
2399
+ newY,
2400
+ true,
2401
+ preventCollision,
2402
+ compactType,
2403
+ cols,
2404
+ allowOverlap
2405
+ );
2406
+ }
2407
+ const placeholder = {
2408
+ w: item.w,
2409
+ h: item.h,
2410
+ x: item.x,
2411
+ y: item.y,
2412
+ i,
2413
+ static: true
2414
+ };
2415
+ onResizeProp(
2416
+ finalLayout,
2417
+ oldResizeItem,
2418
+ item,
2419
+ placeholder,
2420
+ data.e,
2421
+ data.node
2422
+ );
2423
+ updateResizeState(i, w, h, newX, newY);
2424
+ },
2425
+ [
2426
+ preventCollision,
2427
+ allowOverlap,
2428
+ compactType,
2429
+ cols,
2430
+ onResizeProp,
2431
+ updateResizeState
2432
+ ]
2433
+ );
2434
+ const onResizeStop = useCallback(
2435
+ (i, w, h, data) => {
2436
+ const currentLayout = layoutRef.current;
2437
+ const oldResizeItem = oldResizeItemRef.current;
2438
+ const item = getLayoutItem(currentLayout, i);
2439
+ const finalLayout = compactor.compact(currentLayout, cols);
2440
+ onResizeStopProp(
2441
+ finalLayout,
2442
+ oldResizeItem,
2443
+ item ?? null,
2444
+ null,
2445
+ data.e,
2446
+ data.node
2447
+ );
2448
+ oldResizeItemRef.current = null;
2449
+ oldLayoutRef.current = null;
2450
+ stopResizeState(
2451
+ i,
2452
+ item?.w ?? w,
2453
+ item?.h ?? h,
2454
+ item?.x,
2455
+ item?.y
2456
+ );
2457
+ },
2458
+ [cols, compactor, onResizeStopProp, stopResizeState]
2459
+ );
2460
+ const onResizeCancel = useCallback(
2461
+ (_i) => {
2462
+ oldResizeItemRef.current = null;
2463
+ oldLayoutRef.current = null;
2464
+ cancelResizeState();
2465
+ },
2466
+ [cancelResizeState]
2467
+ );
2468
+ const removeDroppingPlaceholder = useCallback(() => {
2469
+ clearDropPlaceholder();
2470
+ setDroppingDOMNode(null);
2471
+ }, [clearDropPlaceholder]);
2472
+ const handleDragOver = useCallback(
2473
+ (e) => {
2474
+ e.preventDefault();
2475
+ e.stopPropagation();
2476
+ if (isFirefox && !e.nativeEvent.target?.classList.contains(layoutClassName)) {
2477
+ return false;
2478
+ }
2479
+ const rawResult = dropConfigOnDragOver ? dropConfigOnDragOver(e.nativeEvent) : onDropDragOverProp(e);
2480
+ if (rawResult === false) {
2481
+ if (droppingDOMNode) {
2482
+ removeDroppingPlaceholder();
2483
+ }
2484
+ return false;
2485
+ }
2486
+ const safeDragOverResult = rawResult ?? {};
2487
+ const {
2488
+ dragOffsetX = 0,
2489
+ dragOffsetY = 0,
2490
+ ...onDragOverResult
2491
+ } = safeDragOverResult;
2492
+ const finalDroppingItem = { ...droppingItem, ...onDragOverResult };
2493
+ const gridRect = e.currentTarget.getBoundingClientRect();
2494
+ const positionParams2 = {
2495
+ cols,
2496
+ margin,
2497
+ maxRows,
2498
+ rowHeight,
2499
+ containerWidth: width,
2500
+ containerPadding: effectiveContainerPadding
2501
+ };
2502
+ const actualColWidth = calcGridColWidth(positionParams2);
2503
+ const itemPixelWidth = calcGridItemWHPx(
2504
+ finalDroppingItem.w,
2505
+ actualColWidth,
2506
+ margin[0]
2507
+ );
2508
+ const itemPixelHeight = calcGridItemWHPx(
2509
+ finalDroppingItem.h,
2510
+ rowHeight,
2511
+ margin[1]
2512
+ );
2513
+ const itemCenterOffsetX = itemPixelWidth / 2;
2514
+ const itemCenterOffsetY = itemPixelHeight / 2;
2515
+ const rawGridX = e.clientX - gridRect.left + dragOffsetX - itemCenterOffsetX;
2516
+ const rawGridY = e.clientY - gridRect.top + dragOffsetY - itemCenterOffsetY;
2517
+ const clampedGridX = Math.max(0, rawGridX);
2518
+ const clampedGridY = Math.max(0, rawGridY);
2519
+ const newDroppingPosition = {
2520
+ left: clampedGridX / transformScale,
2521
+ top: clampedGridY / transformScale,
2522
+ e: e.nativeEvent
2523
+ };
2524
+ if (!droppingDOMNode) {
2525
+ const calculatedPosition = calcXY(
2526
+ positionParams2,
2527
+ clampedGridY,
2528
+ clampedGridX,
2529
+ finalDroppingItem.w,
2530
+ finalDroppingItem.h
2531
+ );
2532
+ setDroppingDOMNode(/* @__PURE__ */ jsx("div", {}, finalDroppingItem.i));
2533
+ updateDropPlaceholder(
2534
+ {
2535
+ ...finalDroppingItem,
2536
+ x: calculatedPosition.x,
2537
+ y: calculatedPosition.y,
2538
+ static: false,
2539
+ isDraggable: true
2540
+ },
2541
+ newDroppingPosition
2542
+ );
2543
+ return;
2544
+ }
2545
+ if (!droppingPosition || droppingPosition.left !== newDroppingPosition.left || droppingPosition.top !== newDroppingPosition.top) {
2546
+ updateDropPlaceholder(finalDroppingItem, newDroppingPosition);
2547
+ }
2548
+ },
2549
+ [
2550
+ dropConfigOnDragOver,
2551
+ onDropDragOverProp,
2552
+ droppingDOMNode,
2553
+ removeDroppingPlaceholder,
2554
+ droppingItem,
2555
+ cols,
2556
+ margin,
2557
+ maxRows,
2558
+ rowHeight,
2559
+ width,
2560
+ effectiveContainerPadding,
2561
+ transformScale,
2562
+ droppingPosition,
2563
+ updateDropPlaceholder
2564
+ ]
2565
+ );
2566
+ const handleDragLeave = useCallback(
2567
+ (e) => {
2568
+ e.preventDefault();
2569
+ e.stopPropagation();
2570
+ dragEnterCounterRef.current--;
2571
+ if (dragEnterCounterRef.current < 0) {
2572
+ dragEnterCounterRef.current = 0;
2573
+ }
2574
+ if (dragEnterCounterRef.current === 0) {
2575
+ removeDroppingPlaceholder();
2576
+ }
2577
+ },
2578
+ [removeDroppingPlaceholder]
2579
+ );
2580
+ const handleDragEnter = useCallback((e) => {
2581
+ e.preventDefault();
2582
+ e.stopPropagation();
2583
+ dragEnterCounterRef.current++;
2584
+ }, []);
2585
+ const handleDrop = useCallback(
2586
+ (e) => {
2587
+ e.preventDefault();
2588
+ e.stopPropagation();
2589
+ const currentLayout = layoutRef.current;
2590
+ const item = currentLayout.find((l) => l.i === droppingItem.i);
2591
+ dragEnterCounterRef.current = 0;
2592
+ removeDroppingPlaceholder();
2593
+ onDropProp(currentLayout, item, e.nativeEvent);
2594
+ },
2595
+ [droppingItem.i, removeDroppingPlaceholder, onDropProp]
2596
+ );
2597
+ const processGridItem = useCallback(
2598
+ (child, isDroppingItem) => {
2599
+ if (!child || !child.key) {
2600
+ return null;
2601
+ }
2602
+ const layoutItem = getLayoutItem(layout, String(child.key));
2603
+ if (!layoutItem) {
2604
+ return null;
2605
+ }
2606
+ const draggable = typeof layoutItem.isDraggable === "boolean" ? layoutItem.isDraggable : !layoutItem.static && isDraggable;
2607
+ const resizable = typeof layoutItem.isResizable === "boolean" ? layoutItem.isResizable : !layoutItem.static && isResizable;
2608
+ const resizeHandlesOptions = layoutItem.resizeHandles || [...resizeHandles];
2609
+ const bounded = draggable && isBounded && layoutItem.isBounded !== false;
2610
+ const resizeHandleElement = resizeHandle;
2611
+ return /* @__PURE__ */ jsx(
2612
+ GridItem,
2613
+ {
2614
+ containerWidth: width,
2615
+ cols,
2616
+ margin,
2617
+ containerPadding: effectiveContainerPadding,
2618
+ maxRows,
2619
+ rowHeight,
2620
+ cancel: draggableCancel,
2621
+ handle: draggableHandle,
2622
+ onDragStart: isDroppingItem ? void 0 : onDragStart,
2623
+ onDrag: isDroppingItem ? void 0 : onDrag,
2624
+ onDragStop: isDroppingItem ? void 0 : onDragStop,
2625
+ onResizeStart,
2626
+ onResize,
2627
+ onResizeStop,
2628
+ onResizeCancel,
2629
+ isDraggable: draggable,
2630
+ isResizable: resizable,
2631
+ isBounded: bounded,
2632
+ enableSortable: !isDroppingItem,
2633
+ useCSSTransforms: useCSSTransforms && mounted,
2634
+ usePercentages: !mounted,
2635
+ transformScale,
2636
+ positionStrategy,
2637
+ dragThreshold,
2638
+ w: layoutItem.w,
2639
+ h: layoutItem.h,
2640
+ x: layoutItem.x,
2641
+ y: layoutItem.y,
2642
+ i: layoutItem.i,
2643
+ minH: layoutItem.minH,
2644
+ minW: layoutItem.minW,
2645
+ maxH: layoutItem.maxH,
2646
+ maxW: layoutItem.maxW,
2647
+ static: layoutItem.static,
2648
+ isDndKitDragSource: !isDroppingItem && dragOverlayId === layoutItem.i,
2649
+ droppingPosition: isDroppingItem ? interactionState.droppingPosition : void 0,
2650
+ resizeHandles: resizeHandlesOptions,
2651
+ resizeHandle: resizeHandleElement,
2652
+ constraints,
2653
+ layoutItem,
2654
+ layout,
2655
+ children: child
2656
+ },
2657
+ layoutItem.i
2658
+ );
2659
+ },
2660
+ [
2661
+ layout,
2662
+ width,
2663
+ cols,
2664
+ margin,
2665
+ effectiveContainerPadding,
2666
+ maxRows,
2667
+ rowHeight,
2668
+ draggableCancel,
2669
+ draggableHandle,
2670
+ onDragStart,
2671
+ onDrag,
2672
+ onDragStop,
2673
+ onResizeStart,
2674
+ onResize,
2675
+ onResizeStop,
2676
+ isDraggable,
2677
+ isResizable,
2678
+ isBounded,
2679
+ useCSSTransforms,
2680
+ mounted,
2681
+ transformScale,
2682
+ positionStrategy,
2683
+ dragThreshold,
2684
+ dragOverlayId,
2685
+ interactionState.droppingPosition,
2686
+ resizeHandles,
2687
+ resizeHandle,
2688
+ constraints
2689
+ ]
2690
+ );
2691
+ const renderPlaceholder = () => {
2692
+ if (!interactionState.isInteracting || !interactionState.activeDrag) {
2693
+ return null;
2694
+ }
2695
+ const placeholderId = `__rgl-interaction-placeholder__${interactionState.activeDrag.i}`;
2696
+ return /* @__PURE__ */ jsx(
2697
+ GridItem,
2698
+ {
2699
+ w: interactionState.activeDrag.w,
2700
+ h: interactionState.activeDrag.h,
2701
+ x: interactionState.activeDrag.x,
2702
+ y: interactionState.activeDrag.y,
2703
+ i: placeholderId,
2704
+ className: `react-grid-placeholder ${interactionState.resizing ? "placeholder-resizing" : ""}`,
2705
+ containerWidth: width,
2706
+ cols,
2707
+ margin,
2708
+ containerPadding: effectiveContainerPadding,
2709
+ maxRows,
2710
+ rowHeight,
2711
+ isDraggable: false,
2712
+ isResizable: false,
2713
+ isBounded: false,
2714
+ onResizeCancel,
2715
+ enableSortable: false,
2716
+ useCSSTransforms,
2717
+ transformScale,
2718
+ constraints,
2719
+ layout,
2720
+ children: /* @__PURE__ */ jsx("div", {})
2721
+ },
2722
+ placeholderId
2723
+ );
2724
+ };
2725
+ const renderDragOverlay = useCallback(() => {
2726
+ if (!dragOverlayId) {
2727
+ return null;
2728
+ }
2729
+ const child = childMap.get(dragOverlayId);
2730
+ const session = activeDndDragRef.current;
2731
+ if (!child || !session) {
2732
+ return null;
2733
+ }
2734
+ const childProps = child.props;
2735
+ const childClassName = childProps["className"];
2736
+ const childStyle = childProps["style"];
2737
+ const size = calcGridItemPosition(
2738
+ positionParams,
2739
+ session.origin.x,
2740
+ session.origin.y,
2741
+ session.origin.w,
2742
+ session.origin.h
2743
+ );
2744
+ return React3.cloneElement(child, {
2745
+ className: clsx(
2746
+ "react-grid-item",
2747
+ "react-draggable",
2748
+ "react-draggable-dragging",
2749
+ childClassName
2750
+ ),
2751
+ style: {
2752
+ ...childStyle,
2753
+ width: size.width,
2754
+ height: size.height,
2755
+ touchAction: "none"
2756
+ }
2757
+ });
2758
+ }, [childMap, dragOverlayId, positionParams]);
2759
+ const mergedClassName = clsx(layoutClassName, className);
2760
+ const mergedStyle = {
2761
+ height: containerHeight,
2762
+ ...style
2763
+ };
2764
+ return /* @__PURE__ */ jsxs(
2765
+ DragDropProvider,
2766
+ {
2767
+ sensors: dndSensors,
2768
+ onDragStart: handleDndKitDragStart,
2769
+ onDragMove: handleDndKitDragMove,
2770
+ onDragEnd: handleDndKitDragEnd,
2771
+ children: [
2772
+ /* @__PURE__ */ jsxs(
2773
+ "div",
2774
+ {
2775
+ ref: setContainerNode,
2776
+ className: mergedClassName,
2777
+ style: mergedStyle,
2778
+ onDrop: isDroppable ? handleDrop : void 0,
2779
+ onDragLeave: isDroppable ? handleDragLeave : void 0,
2780
+ onDragEnter: isDroppable ? handleDragEnter : void 0,
2781
+ onDragOver: isDroppable ? handleDragOver : void 0,
2782
+ children: [
2783
+ React3.Children.map(children, (child) => {
2784
+ if (!React3.isValidElement(child)) {
2785
+ return null;
2786
+ }
2787
+ return processGridItem(child);
2788
+ }),
2789
+ isDroppable && droppingDOMNode && processGridItem(droppingDOMNode, true),
2790
+ renderPlaceholder()
2791
+ ]
2792
+ }
2793
+ ),
2794
+ /* @__PURE__ */ jsx(DragOverlay, { disabled: !dragOverlayId, dropAnimation: null, children: renderDragOverlay() })
2795
+ ]
2796
+ }
2797
+ );
2798
+ }
2799
+ var DEFAULT_BREAKPOINTS = {
2800
+ lg: 1200,
2801
+ md: 996,
2802
+ sm: 768,
2803
+ xs: 480,
2804
+ xxs: 0
2805
+ };
2806
+ var DEFAULT_COLS = {
2807
+ lg: 12,
2808
+ md: 10,
2809
+ sm: 6,
2810
+ xs: 4,
2811
+ xxs: 2
2812
+ };
2813
+ function cloneResponsiveLayouts(layouts) {
2814
+ const cloned = {};
2815
+ for (const breakpoint of Object.keys(layouts)) {
2816
+ const layout = layouts[breakpoint];
2817
+ if (layout) {
2818
+ cloned[breakpoint] = cloneLayout(layout);
2819
+ }
2820
+ }
2821
+ return cloned;
2822
+ }
2823
+ function useResponsiveLayout(options) {
2824
+ const {
2825
+ width,
2826
+ breakpoint: breakpointProp,
2827
+ breakpoints = DEFAULT_BREAKPOINTS,
2828
+ cols: colsConfig = DEFAULT_COLS,
2829
+ layouts: propsLayouts = {},
2830
+ compactor = verticalCompactor,
2831
+ onBreakpointChange,
2832
+ onLayoutChange,
2833
+ onWidthChange
2834
+ } = options;
2835
+ const sortedBreakpoints = useMemo(
2836
+ () => sortBreakpoints(breakpoints),
2837
+ [breakpoints]
2838
+ );
2839
+ const initialBreakpoint = useMemo(
2840
+ () => breakpointProp ?? getBreakpointFromWidth(breakpoints, width),
2841
+ []
2842
+ );
2843
+ const [layoutsState, setLayoutsState] = useState(
2844
+ () => cloneResponsiveLayouts(propsLayouts)
2845
+ );
2846
+ const prevWidthRef = useRef(width);
2847
+ const prevBreakpointRef = useRef(initialBreakpoint);
2848
+ const prevBreakpointsRef = useRef(breakpoints);
2849
+ const prevColsRef = useRef(colsConfig);
2850
+ const prevPropsLayoutsRef = useRef(propsLayouts);
2851
+ const prevLayoutsRef = useRef(layoutsState);
2852
+ const layoutsRef = useRef(layoutsState);
2853
+ const currentBreakpoint = breakpointProp ?? getBreakpointFromWidth(breakpoints, width);
2854
+ const currentCols = getColsFromBreakpoint(currentBreakpoint, colsConfig);
2855
+ const propsLayoutsChanged = !deepEqual(propsLayouts, prevPropsLayoutsRef.current);
2856
+ const sourceLayouts = useMemo(
2857
+ () => propsLayoutsChanged ? cloneResponsiveLayouts(propsLayouts) : layoutsState,
2858
+ [propsLayoutsChanged, propsLayouts, layoutsState]
2859
+ );
2860
+ const layout = useMemo(
2861
+ () => findOrGenerateResponsiveLayout(
2862
+ sourceLayouts,
2863
+ breakpoints,
2864
+ currentBreakpoint,
2865
+ prevBreakpointRef.current,
2866
+ currentCols,
2867
+ compactor
2868
+ ),
2869
+ [sourceLayouts, breakpoints, currentBreakpoint, currentCols, compactor]
2870
+ );
2871
+ const effectiveLayouts = useMemo(() => {
2872
+ const currentLayout = sourceLayouts[currentBreakpoint];
2873
+ if (currentLayout && deepEqual(currentLayout, layout)) {
2874
+ return sourceLayouts;
2875
+ }
2876
+ return {
2877
+ ...sourceLayouts,
2878
+ [currentBreakpoint]: cloneLayout(layout)
2879
+ };
2880
+ }, [sourceLayouts, currentBreakpoint, layout]);
2881
+ const setLayoutForBreakpoint = useCallback((breakpoint, layout2) => {
2882
+ setLayoutsState((previousLayouts) => ({
2883
+ ...previousLayouts,
2884
+ [breakpoint]: cloneLayout(layout2)
2885
+ }));
2886
+ }, []);
2887
+ const setLayouts = useCallback((layouts) => {
2888
+ setLayoutsState(cloneResponsiveLayouts(layouts));
2889
+ }, []);
2890
+ useEffect(() => {
2891
+ layoutsRef.current = layoutsState;
2892
+ }, [layoutsState]);
2893
+ useEffect(() => {
2894
+ if (!propsLayoutsChanged) {
2895
+ return;
2896
+ }
2897
+ const nextLayouts = cloneResponsiveLayouts(propsLayouts);
2898
+ setLayoutsState(nextLayouts);
2899
+ layoutsRef.current = nextLayouts;
2900
+ prevPropsLayoutsRef.current = propsLayouts;
2901
+ }, [propsLayoutsChanged, propsLayouts]);
2902
+ useEffect(() => {
2903
+ const widthChanged = width !== prevWidthRef.current;
2904
+ const breakpointChanged = currentBreakpoint !== prevBreakpointRef.current;
2905
+ const breakpointsChanged = !deepEqual(breakpoints, prevBreakpointsRef.current);
2906
+ const colsChanged = !deepEqual(colsConfig, prevColsRef.current);
2907
+ const layoutsChanged = !deepEqual(effectiveLayouts, layoutsRef.current);
2908
+ if (layoutsChanged) {
2909
+ setLayoutsState(effectiveLayouts);
2910
+ layoutsRef.current = effectiveLayouts;
2911
+ }
2912
+ if (widthChanged || breakpointChanged || breakpointsChanged || colsChanged) {
2913
+ onWidthChange?.(width, [10, 10], currentCols, null);
2914
+ if (breakpointChanged || breakpointsChanged || colsChanged) {
2915
+ onBreakpointChange?.(currentBreakpoint, currentCols);
2916
+ }
2917
+ }
2918
+ if (layoutsChanged && !propsLayoutsChanged) {
2919
+ onLayoutChange?.(layout, effectiveLayouts);
2920
+ }
2921
+ prevWidthRef.current = width;
2922
+ prevBreakpointRef.current = currentBreakpoint;
2923
+ prevBreakpointsRef.current = breakpoints;
2924
+ prevColsRef.current = colsConfig;
2925
+ prevLayoutsRef.current = effectiveLayouts;
2926
+ if (!propsLayoutsChanged) {
2927
+ prevPropsLayoutsRef.current = propsLayouts;
2928
+ }
2929
+ }, [
2930
+ width,
2931
+ currentBreakpoint,
2932
+ currentCols,
2933
+ breakpoints,
2934
+ colsConfig,
2935
+ effectiveLayouts,
2936
+ layout,
2937
+ onBreakpointChange,
2938
+ onLayoutChange,
2939
+ onWidthChange,
2940
+ propsLayouts,
2941
+ propsLayoutsChanged
2942
+ ]);
2943
+ return {
2944
+ layout,
2945
+ layouts: effectiveLayouts,
2946
+ breakpoint: currentBreakpoint,
2947
+ cols: currentCols,
2948
+ setLayoutForBreakpoint,
2949
+ setLayouts,
2950
+ sortedBreakpoints
2951
+ };
2952
+ }
2953
+ var noop2 = () => {
2954
+ };
2955
+ function synchronizeLayoutWithChildren2(initialLayout, children, cols, compactor) {
2956
+ const layout = [];
2957
+ React3.Children.forEach(children, (child) => {
2958
+ if (!React3.isValidElement(child) || child.key === null) return;
2959
+ const key = String(child.key);
2960
+ const existingItem = initialLayout.find((l) => l.i === key);
2961
+ if (existingItem) {
2962
+ layout.push({
2963
+ ...existingItem,
2964
+ i: key
2965
+ });
2966
+ return;
2967
+ }
2968
+ const childProps = child.props;
2969
+ const dataGrid = childProps["data-grid"];
2970
+ if (dataGrid) {
2971
+ layout.push({
2972
+ i: key,
2973
+ x: dataGrid.x ?? 0,
2974
+ y: dataGrid.y ?? 0,
2975
+ w: dataGrid.w ?? 1,
2976
+ h: dataGrid.h ?? 1,
2977
+ minW: dataGrid.minW,
2978
+ maxW: dataGrid.maxW,
2979
+ minH: dataGrid.minH,
2980
+ maxH: dataGrid.maxH,
2981
+ static: dataGrid.static,
2982
+ isDraggable: dataGrid.isDraggable,
2983
+ isResizable: dataGrid.isResizable,
2984
+ resizeHandles: dataGrid.resizeHandles,
2985
+ isBounded: dataGrid.isBounded
2986
+ });
2987
+ return;
2988
+ }
2989
+ layout.push({
2990
+ i: key,
2991
+ x: 0,
2992
+ y: bottom(layout),
2993
+ w: 1,
2994
+ h: 1
2995
+ });
2996
+ });
2997
+ const corrected = correctBounds(layout, { cols });
2998
+ return compactor.compact(corrected, cols);
2999
+ }
3000
+ function ResponsiveGridLayout(props) {
3001
+ const {
3002
+ children,
3003
+ width,
3004
+ breakpoint: breakpointProp,
3005
+ breakpoints = DEFAULT_BREAKPOINTS,
3006
+ cols: colsConfig = DEFAULT_COLS,
3007
+ layouts: propsLayouts = {},
3008
+ rowHeight = 150,
3009
+ maxRows = Infinity,
3010
+ margin: marginProp = [10, 10],
3011
+ containerPadding: containerPaddingProp = null,
3012
+ compactor: compactorProp,
3013
+ onBreakpointChange = noop2,
3014
+ onLayoutChange = noop2,
3015
+ onWidthChange = noop2,
3016
+ ...restProps
3017
+ } = props;
3018
+ const compactor = compactorProp ?? getCompactor("vertical");
3019
+ const {
3020
+ layout: responsiveLayout,
3021
+ layouts,
3022
+ breakpoint,
3023
+ cols,
3024
+ setLayouts
3025
+ } = useResponsiveLayout({
3026
+ width,
3027
+ breakpoint: breakpointProp,
3028
+ breakpoints,
3029
+ cols: colsConfig,
3030
+ layouts: propsLayouts,
3031
+ compactor
3032
+ });
3033
+ const prevWidthRef = useRef(width);
3034
+ const prevBreakpointRef = useRef(breakpoint);
3035
+ const prevBreakpointsRef = useRef(breakpoints);
3036
+ const prevColsRef = useRef(colsConfig);
3037
+ const prevCompactTypeRef = useRef(compactor.type);
3038
+ const currentMargin = useMemo(
3039
+ () => getIndentationValue(
3040
+ marginProp,
3041
+ breakpoint
3042
+ ),
3043
+ [marginProp, breakpoint]
3044
+ );
3045
+ const currentContainerPadding = useMemo(() => {
3046
+ if (containerPaddingProp === null) {
3047
+ return null;
3048
+ }
3049
+ return getIndentationValue(
3050
+ containerPaddingProp,
3051
+ breakpoint
3052
+ );
3053
+ }, [containerPaddingProp, breakpoint]);
3054
+ const synchronizedLayout = useMemo(
3055
+ () => synchronizeLayoutWithChildren2(responsiveLayout, children, cols, compactor),
3056
+ [responsiveLayout, children, cols, compactor]
3057
+ );
3058
+ const effectiveLayouts = useMemo(() => {
3059
+ const currentLayout = layouts[breakpoint];
3060
+ if (currentLayout && deepEqual(currentLayout, synchronizedLayout)) {
3061
+ return layouts;
3062
+ }
3063
+ return {
3064
+ ...layouts,
3065
+ [breakpoint]: cloneLayout(synchronizedLayout)
3066
+ };
3067
+ }, [layouts, breakpoint, synchronizedLayout]);
3068
+ useEffect(() => {
3069
+ if (deepEqual(effectiveLayouts, layouts)) {
3070
+ return;
3071
+ }
3072
+ setLayouts(effectiveLayouts);
3073
+ }, [effectiveLayouts, layouts, setLayouts]);
3074
+ useEffect(() => {
3075
+ const widthChanged = width !== prevWidthRef.current;
3076
+ const breakpointChanged = breakpoint !== prevBreakpointRef.current;
3077
+ const breakpointsChanged = !deepEqual(breakpoints, prevBreakpointsRef.current);
3078
+ const colsChanged = !deepEqual(colsConfig, prevColsRef.current);
3079
+ if (widthChanged || breakpointChanged || breakpointsChanged || colsChanged) {
3080
+ if (breakpointChanged || breakpointsChanged || colsChanged) {
3081
+ onBreakpointChange(breakpoint, cols);
3082
+ onLayoutChange(synchronizedLayout, effectiveLayouts);
3083
+ }
3084
+ onWidthChange(width, currentMargin, cols, currentContainerPadding);
3085
+ }
3086
+ prevWidthRef.current = width;
3087
+ prevBreakpointRef.current = breakpoint;
3088
+ prevBreakpointsRef.current = breakpoints;
3089
+ prevColsRef.current = colsConfig;
3090
+ }, [
3091
+ width,
3092
+ breakpoint,
3093
+ cols,
3094
+ breakpoints,
3095
+ colsConfig,
3096
+ currentMargin,
3097
+ currentContainerPadding,
3098
+ effectiveLayouts,
3099
+ synchronizedLayout,
3100
+ onBreakpointChange,
3101
+ onLayoutChange,
3102
+ onWidthChange
3103
+ ]);
3104
+ useEffect(() => {
3105
+ if (compactor.type === prevCompactTypeRef.current) {
3106
+ return;
3107
+ }
3108
+ prevCompactTypeRef.current = compactor.type;
3109
+ onLayoutChange(synchronizedLayout, effectiveLayouts);
3110
+ }, [compactor.type, synchronizedLayout, effectiveLayouts, onLayoutChange]);
3111
+ const handleLayoutChange = useCallback(
3112
+ (layout) => {
3113
+ const nextLayouts = {
3114
+ ...effectiveLayouts,
3115
+ [breakpoint]: cloneLayout(layout)
3116
+ };
3117
+ setLayouts(nextLayouts);
3118
+ onLayoutChange(layout, nextLayouts);
3119
+ },
3120
+ [effectiveLayouts, breakpoint, setLayouts, onLayoutChange]
3121
+ );
3122
+ const gridConfig = useMemo(
3123
+ () => ({
3124
+ cols,
3125
+ rowHeight,
3126
+ maxRows,
3127
+ margin: currentMargin,
3128
+ containerPadding: currentContainerPadding
3129
+ }),
3130
+ [cols, rowHeight, maxRows, currentMargin, currentContainerPadding]
3131
+ );
3132
+ return /* @__PURE__ */ jsx(
3133
+ GridLayout,
3134
+ {
3135
+ ...restProps,
3136
+ width,
3137
+ gridConfig,
3138
+ compactor,
3139
+ onLayoutChange: handleLayoutChange,
3140
+ layout: synchronizedLayout,
3141
+ children
3142
+ }
3143
+ );
3144
+ }
3145
+
3146
+ export { DEFAULT_BREAKPOINTS, DEFAULT_COLS, GridItem, GridLayout, ResponsiveGridLayout, useGridLayout, useResponsiveLayout };