react-grid-layout 2.2.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/{ResponsiveGridLayout-BjVraYMQ.d.mts → ResponsiveGridLayout-BSYEMZ9d.d.ts} +4 -4
- package/dist/{ResponsiveGridLayout-BrhkSyZk.d.ts → ResponsiveGridLayout-RNuyRTPe.d.mts} +4 -4
- package/dist/{calculate-DH4EVtn1.d.mts → calculate-BXoe3Mfz.d.mts} +1 -1
- package/dist/{calculate-rP3DHexe.d.ts → calculate-Tc1WkIxl.d.ts} +1 -1
- package/dist/{chunk-BPZQUJ7Y.js → chunk-CUP5Y2ZG.js} +500 -155
- package/dist/{chunk-55DQUWLA.js → chunk-QAIA5KAO.js} +33 -22
- package/dist/{chunk-7MZZ6T4J.js → chunk-SL4EZ2NU.js} +67 -38
- package/dist/{chunk-PZLKKWSX.mjs → chunk-TW4BCTKD.mjs} +37 -8
- package/dist/{chunk-KDANGDDL.mjs → chunk-VBU6B7II.mjs} +13 -2
- package/dist/{chunk-A5WIFECI.js → chunk-VJJIA3HC.js} +7 -3
- package/dist/{chunk-WGL5FSZH.mjs → chunk-Z6CWRR74.mjs} +431 -86
- package/dist/{chunk-76RTO6EO.mjs → chunk-ZYNFVPDS.mjs} +7 -3
- package/dist/core.d.mts +5 -5
- package/dist/core.d.ts +5 -5
- package/dist/core.js +67 -67
- package/dist/core.mjs +2 -2
- package/dist/extras.d.mts +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/extras.js +8 -8
- package/dist/extras.mjs +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +39 -39
- package/dist/index.mjs +4 -4
- package/dist/legacy.d.mts +18 -9
- package/dist/legacy.d.ts +18 -9
- package/dist/legacy.js +35 -25
- package/dist/legacy.mjs +18 -9
- package/dist/{position-CSgQSjwQ.d.ts → position-VdYnMJql.d.ts} +1 -1
- package/dist/{position-BV-g3Ezg.d.mts → position-iPly-ecb.d.mts} +1 -1
- package/dist/react.d.mts +24 -6
- package/dist/react.d.ts +24 -6
- package/dist/react.js +25 -25
- package/dist/react.mjs +4 -4
- package/dist/{responsive-BrTV_0tK.d.mts → responsive-BVtXrrTF.d.mts} +1 -1
- package/dist/{responsive-C_YtBQYq.d.ts → responsive-C6s9JAJU.d.ts} +1 -1
- package/dist/{types-jd8MiKM1.d.mts → types-DlzNckle.d.mts} +22 -0
- package/dist/{types-jd8MiKM1.d.ts → types-DlzNckle.d.ts} +22 -0
- package/package.json +3 -2
|
@@ -1,13 +1,77 @@
|
|
|
1
|
-
import { defaultConstraints, setTransform, setTopLeft, perc, applyPositionConstraints, resizeItemInDirection, applySizeConstraints,
|
|
2
|
-
import { calcXYRaw, calcGridItemWHPx, clamp, calcGridColWidth, calcWHRaw, calcGridItemPosition, bottom, getLayoutItem, cloneLayoutItem, moveElement, withLayoutItem, getAllCollisions, calcXY
|
|
3
|
-
import React2, { useState, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
1
|
+
import { defaultConstraints, setTransform, setTopLeft, perc, applyPositionConstraints, resizeItemInDirection, applySizeConstraints, getCompactor, getBreakpointFromWidth, getColsFromBreakpoint, findOrGenerateResponsiveLayout, getIndentationValue, defaultPositionStrategy, defaultGridConfig, defaultDragConfig, defaultResizeConfig, defaultDropConfig } from './chunk-VBU6B7II.mjs';
|
|
2
|
+
import { calcXYRaw, calcGridItemWHPx, clamp, calcGridColWidth, calcWHRaw, calcGridItemPosition, cloneLayout, bottom, correctBounds, getLayoutItem, cloneLayoutItem, moveElement, withLayoutItem, getAllCollisions, calcXY } from './chunk-ZYNFVPDS.mjs';
|
|
3
|
+
import React2, { useState, useRef, useMemo, useCallback, useEffect, useLayoutEffect } from 'react';
|
|
4
4
|
import { DraggableCore } from 'react-draggable';
|
|
5
5
|
import { Resizable } from 'react-resizable';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { deepEqual } from 'fast-equals';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// src/react/components/edgeScroll.ts
|
|
11
|
+
var EDGE_THRESHOLD = 50;
|
|
12
|
+
var SCROLL_STEP = 12;
|
|
13
|
+
function getNearestScrollable(node) {
|
|
14
|
+
let el = node;
|
|
15
|
+
while (el) {
|
|
16
|
+
const style = window.getComputedStyle(el);
|
|
17
|
+
const overflowY = style.overflowY;
|
|
18
|
+
const scrollable = (overflowY === "auto" || overflowY === "scroll") && el.scrollHeight > el.clientHeight;
|
|
19
|
+
if (scrollable) return el;
|
|
20
|
+
el = el.parentElement;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function createEdgeScrollController(node) {
|
|
25
|
+
const scrollContainer = getNearestScrollable(node);
|
|
26
|
+
let rafId = null;
|
|
27
|
+
let lastX = 0;
|
|
28
|
+
let lastY = 0;
|
|
29
|
+
let running = false;
|
|
30
|
+
function step() {
|
|
31
|
+
const container = scrollContainer;
|
|
32
|
+
if (!container) return;
|
|
33
|
+
const rect = container.getBoundingClientRect();
|
|
34
|
+
const { clientHeight, scrollTop, scrollHeight } = container;
|
|
35
|
+
const { scrollLeft, scrollWidth, clientWidth } = container;
|
|
36
|
+
let dy = 0;
|
|
37
|
+
let dx = 0;
|
|
38
|
+
if (lastY < rect.top + EDGE_THRESHOLD && scrollTop > 0) {
|
|
39
|
+
dy = -SCROLL_STEP;
|
|
40
|
+
} else if (lastY > rect.bottom - EDGE_THRESHOLD && scrollTop + clientHeight < scrollHeight) {
|
|
41
|
+
dy = SCROLL_STEP;
|
|
42
|
+
}
|
|
43
|
+
if (lastX < rect.left + EDGE_THRESHOLD && scrollLeft > 0) {
|
|
44
|
+
dx = -SCROLL_STEP;
|
|
45
|
+
} else if (lastX > rect.right - EDGE_THRESHOLD && scrollLeft + clientWidth < scrollWidth) {
|
|
46
|
+
dx = SCROLL_STEP;
|
|
47
|
+
}
|
|
48
|
+
if (dy !== 0 || dx !== 0) {
|
|
49
|
+
container.scrollTop += dy;
|
|
50
|
+
container.scrollLeft += dx;
|
|
51
|
+
}
|
|
52
|
+
if (running) {
|
|
53
|
+
rafId = requestAnimationFrame(step);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
feed(clientX, clientY) {
|
|
58
|
+
lastX = clientX;
|
|
59
|
+
lastY = clientY;
|
|
60
|
+
if (!running) {
|
|
61
|
+
running = true;
|
|
62
|
+
rafId = requestAnimationFrame(step);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
stop() {
|
|
66
|
+
running = false;
|
|
67
|
+
if (rafId !== null) {
|
|
68
|
+
cancelAnimationFrame(rafId);
|
|
69
|
+
rafId = null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function GridItemInner(props) {
|
|
11
75
|
const {
|
|
12
76
|
children,
|
|
13
77
|
cols,
|
|
@@ -19,6 +83,7 @@ function GridItem(props) {
|
|
|
19
83
|
isDraggable,
|
|
20
84
|
isResizable,
|
|
21
85
|
isBounded,
|
|
86
|
+
allowMobileScroll,
|
|
22
87
|
static: isStatic,
|
|
23
88
|
useCSSTransforms = true,
|
|
24
89
|
usePercentages = false,
|
|
@@ -71,6 +136,7 @@ function GridItem(props) {
|
|
|
71
136
|
const dragPendingRef = useRef(false);
|
|
72
137
|
const initialDragClientRef = useRef({ x: 0, y: 0 });
|
|
73
138
|
const thresholdExceededRef = useRef(false);
|
|
139
|
+
const edgeScrollRef = useRef(null);
|
|
74
140
|
const positionParams = useMemo(
|
|
75
141
|
() => ({
|
|
76
142
|
cols,
|
|
@@ -88,7 +154,7 @@ function GridItem(props) {
|
|
|
88
154
|
maxRows,
|
|
89
155
|
containerWidth,
|
|
90
156
|
containerHeight: 0,
|
|
91
|
-
//
|
|
157
|
+
// Overridden per-interaction with the measured container height
|
|
92
158
|
rowHeight,
|
|
93
159
|
margin,
|
|
94
160
|
// Use empty layout here - the actual layout will be accessed via layoutRef when needed
|
|
@@ -98,8 +164,9 @@ function GridItem(props) {
|
|
|
98
164
|
[cols, maxRows, containerWidth, rowHeight, margin]
|
|
99
165
|
);
|
|
100
166
|
const getConstraintContext = useCallback(
|
|
101
|
-
() => ({
|
|
167
|
+
(containerHeight) => ({
|
|
102
168
|
...constraintContext,
|
|
169
|
+
containerHeight: containerHeight ?? constraintContext.containerHeight,
|
|
103
170
|
layout: layoutRef.current
|
|
104
171
|
}),
|
|
105
172
|
[constraintContext]
|
|
@@ -165,6 +232,11 @@ function GridItem(props) {
|
|
|
165
232
|
};
|
|
166
233
|
}
|
|
167
234
|
dragPositionRef.current = newPosition;
|
|
235
|
+
if (!edgeScrollRef.current) {
|
|
236
|
+
edgeScrollRef.current = createEdgeScrollController(
|
|
237
|
+
node instanceof HTMLElement ? node : null
|
|
238
|
+
);
|
|
239
|
+
}
|
|
168
240
|
if (dragThreshold > 0) {
|
|
169
241
|
const mouseEvent = e;
|
|
170
242
|
initialDragClientRef.current = {
|
|
@@ -240,6 +312,7 @@ function GridItem(props) {
|
|
|
240
312
|
});
|
|
241
313
|
}
|
|
242
314
|
}
|
|
315
|
+
edgeScrollRef.current?.feed(mouseEvent.clientX, mouseEvent.clientY);
|
|
243
316
|
let top = dragPositionRef.current.top + deltaY;
|
|
244
317
|
let left = dragPositionRef.current.left + deltaX;
|
|
245
318
|
if (isBounded) {
|
|
@@ -289,6 +362,8 @@ function GridItem(props) {
|
|
|
289
362
|
const onDragStop = useCallback(
|
|
290
363
|
(e, { node }) => {
|
|
291
364
|
if (!onDragStopProp || !dragging) return;
|
|
365
|
+
edgeScrollRef.current?.stop();
|
|
366
|
+
edgeScrollRef.current = null;
|
|
292
367
|
const wasPending = dragPendingRef.current;
|
|
293
368
|
dragPendingRef.current = false;
|
|
294
369
|
thresholdExceededRef.current = false;
|
|
@@ -348,6 +423,7 @@ function GridItem(props) {
|
|
|
348
423
|
};
|
|
349
424
|
}
|
|
350
425
|
resizePositionRef.current = updatedSize;
|
|
426
|
+
const containerHeight = node?.offsetParent?.clientHeight ?? 0;
|
|
351
427
|
const rawSize = calcWHRaw(
|
|
352
428
|
positionParams,
|
|
353
429
|
updatedSize.width,
|
|
@@ -359,10 +435,14 @@ function GridItem(props) {
|
|
|
359
435
|
rawSize.w,
|
|
360
436
|
rawSize.h,
|
|
361
437
|
resizeHandle2,
|
|
362
|
-
getConstraintContext()
|
|
438
|
+
getConstraintContext(containerHeight)
|
|
363
439
|
);
|
|
364
440
|
handler(i, newW, newH, {
|
|
365
|
-
|
|
441
|
+
// react-resizable forwards react-draggable's callback event, which is
|
|
442
|
+
// already a native MouseEvent/TouchEvent and has no `nativeEvent`.
|
|
443
|
+
// Reading it unconditionally handed consumers `undefined` (#2264).
|
|
444
|
+
// The drag handlers above pass the raw event for the same reason.
|
|
445
|
+
e: e.nativeEvent ?? e,
|
|
366
446
|
node,
|
|
367
447
|
size: updatedSize,
|
|
368
448
|
handle: resizeHandle2
|
|
@@ -525,12 +605,104 @@ function GridItem(props) {
|
|
|
525
605
|
handle,
|
|
526
606
|
cancel: ".react-resizable-handle" + (cancel ? "," + cancel : ""),
|
|
527
607
|
scale: transformScale,
|
|
608
|
+
allowMobileScroll,
|
|
528
609
|
nodeRef: elementRef,
|
|
529
610
|
children: newChild
|
|
530
611
|
}
|
|
531
612
|
);
|
|
532
613
|
return newChild;
|
|
533
614
|
}
|
|
615
|
+
var GridItem = React2.memo(GridItemInner, (prev, next) => {
|
|
616
|
+
if (prev.x !== next.x || prev.y !== next.y) return false;
|
|
617
|
+
if (prev.w !== next.w || prev.h !== next.h) return false;
|
|
618
|
+
if (prev.minW !== next.minW || prev.maxW !== next.maxW) return false;
|
|
619
|
+
if (prev.minH !== next.minH || prev.maxH !== next.maxH) return false;
|
|
620
|
+
if (prev.cols !== next.cols) return false;
|
|
621
|
+
if (prev.containerWidth !== next.containerWidth) return false;
|
|
622
|
+
if (prev.rowHeight !== next.rowHeight) return false;
|
|
623
|
+
if (prev.maxRows !== next.maxRows) return false;
|
|
624
|
+
if (prev.margin !== next.margin) return false;
|
|
625
|
+
if (prev.containerPadding !== next.containerPadding) return false;
|
|
626
|
+
if (prev.transformScale !== next.transformScale) return false;
|
|
627
|
+
if (prev.isDraggable !== next.isDraggable) return false;
|
|
628
|
+
if (prev.isResizable !== next.isResizable) return false;
|
|
629
|
+
if (prev.isBounded !== next.isBounded) return false;
|
|
630
|
+
if (prev.allowMobileScroll !== next.allowMobileScroll) return false;
|
|
631
|
+
if (prev.useCSSTransforms !== next.useCSSTransforms) return false;
|
|
632
|
+
if (prev.usePercentages !== next.usePercentages) return false;
|
|
633
|
+
if (prev.children !== next.children) return false;
|
|
634
|
+
if (prev.onDrag !== next.onDrag) return false;
|
|
635
|
+
if (prev.onDragStop !== next.onDragStop) return false;
|
|
636
|
+
if (prev.onResize !== next.onResize) return false;
|
|
637
|
+
if (prev.onResizeStop !== next.onResizeStop) return false;
|
|
638
|
+
if (prev.droppingPosition !== next.droppingPosition) return false;
|
|
639
|
+
return true;
|
|
640
|
+
});
|
|
641
|
+
GridItem.displayName = "GridItem";
|
|
642
|
+
|
|
643
|
+
// src/react/components/dropMath.ts
|
|
644
|
+
function computeDropPosition(input) {
|
|
645
|
+
const {
|
|
646
|
+
clientX,
|
|
647
|
+
clientY,
|
|
648
|
+
gridElement,
|
|
649
|
+
droppingItem,
|
|
650
|
+
event,
|
|
651
|
+
dragOffsetX = 0,
|
|
652
|
+
dragOffsetY = 0,
|
|
653
|
+
transformScale,
|
|
654
|
+
cols,
|
|
655
|
+
margin,
|
|
656
|
+
maxRows,
|
|
657
|
+
rowHeight,
|
|
658
|
+
width,
|
|
659
|
+
containerPadding
|
|
660
|
+
} = input;
|
|
661
|
+
const gridRect = gridElement.getBoundingClientRect();
|
|
662
|
+
const positionParams = {
|
|
663
|
+
cols,
|
|
664
|
+
margin,
|
|
665
|
+
maxRows,
|
|
666
|
+
rowHeight,
|
|
667
|
+
containerWidth: width,
|
|
668
|
+
containerPadding
|
|
669
|
+
};
|
|
670
|
+
const actualColWidth = calcGridColWidth(positionParams);
|
|
671
|
+
const itemPixelWidth = calcGridItemWHPx(
|
|
672
|
+
droppingItem.w,
|
|
673
|
+
actualColWidth,
|
|
674
|
+
margin[0]
|
|
675
|
+
);
|
|
676
|
+
const itemPixelHeight = calcGridItemWHPx(
|
|
677
|
+
droppingItem.h,
|
|
678
|
+
rowHeight,
|
|
679
|
+
margin[1]
|
|
680
|
+
);
|
|
681
|
+
const itemCenterOffsetX = itemPixelWidth / 2;
|
|
682
|
+
const itemCenterOffsetY = itemPixelHeight / 2;
|
|
683
|
+
const scrollLeft = gridElement.scrollLeft ?? 0;
|
|
684
|
+
const scrollTop = gridElement.scrollTop ?? 0;
|
|
685
|
+
const rawGridX = clientX - gridRect.left + scrollLeft + dragOffsetX - itemCenterOffsetX;
|
|
686
|
+
const rawGridY = clientY - gridRect.top + scrollTop + dragOffsetY - itemCenterOffsetY;
|
|
687
|
+
const clampedGridX = Math.max(0, rawGridX);
|
|
688
|
+
const clampedGridY = Math.max(0, rawGridY);
|
|
689
|
+
const newDroppingPosition = {
|
|
690
|
+
left: clampedGridX / transformScale,
|
|
691
|
+
top: clampedGridY / transformScale,
|
|
692
|
+
e: event
|
|
693
|
+
};
|
|
694
|
+
const calculatedXY = calcXY(
|
|
695
|
+
positionParams,
|
|
696
|
+
clampedGridY,
|
|
697
|
+
clampedGridX,
|
|
698
|
+
droppingItem.w,
|
|
699
|
+
droppingItem.h
|
|
700
|
+
);
|
|
701
|
+
return {
|
|
702
|
+
newDroppingPosition,
|
|
703
|
+
calculatedXY
|
|
704
|
+
};
|
|
705
|
+
}
|
|
534
706
|
var noop = () => {
|
|
535
707
|
};
|
|
536
708
|
var layoutClassName = "react-grid-layout";
|
|
@@ -648,7 +820,8 @@ function GridLayout(props) {
|
|
|
648
820
|
bounded: isBounded,
|
|
649
821
|
handle: draggableHandle,
|
|
650
822
|
cancel: draggableCancel,
|
|
651
|
-
threshold: dragThreshold
|
|
823
|
+
threshold: dragThreshold,
|
|
824
|
+
allowMobileScroll: dragAllowMobileScroll
|
|
652
825
|
} = dragConfig;
|
|
653
826
|
const {
|
|
654
827
|
enabled: isResizable,
|
|
@@ -658,7 +831,9 @@ function GridLayout(props) {
|
|
|
658
831
|
const {
|
|
659
832
|
enabled: isDroppable,
|
|
660
833
|
defaultItem: defaultDropItem,
|
|
661
|
-
onDragOver: dropConfigOnDragOver
|
|
834
|
+
onDragOver: dropConfigOnDragOver,
|
|
835
|
+
touchEnabled = true,
|
|
836
|
+
touchDragSource = "[data-rgl-draggable]"
|
|
662
837
|
} = dropConfig;
|
|
663
838
|
const compactor = compactorProp ?? getCompactor("vertical");
|
|
664
839
|
const compactType = compactor.type;
|
|
@@ -684,6 +859,8 @@ function GridLayout(props) {
|
|
|
684
859
|
null
|
|
685
860
|
);
|
|
686
861
|
const [droppingPosition, setDroppingPosition] = useState();
|
|
862
|
+
const droppingPositionRef = useRef(void 0);
|
|
863
|
+
droppingPositionRef.current = droppingPosition;
|
|
687
864
|
const oldDragItemRef = useRef(null);
|
|
688
865
|
const oldResizeItemRef = useRef(null);
|
|
689
866
|
const oldLayoutRef = useRef(null);
|
|
@@ -692,6 +869,15 @@ function GridLayout(props) {
|
|
|
692
869
|
const prevPropsLayoutRef = useRef(propsLayout);
|
|
693
870
|
const prevChildrenRef = useRef(children);
|
|
694
871
|
const prevCompactTypeRef = useRef(compactType);
|
|
872
|
+
const gridContainerRef = useRef(null);
|
|
873
|
+
const touchDragActiveRef = useRef(false);
|
|
874
|
+
const activeTouchIdRef = useRef(null);
|
|
875
|
+
const droppingDOMNodeRef = useRef(null);
|
|
876
|
+
droppingDOMNodeRef.current = droppingDOMNode;
|
|
877
|
+
const onDropPropRef = useRef(onDropProp);
|
|
878
|
+
useLayoutEffect(() => {
|
|
879
|
+
onDropPropRef.current = onDropProp;
|
|
880
|
+
});
|
|
695
881
|
const layoutRef = useRef(layout);
|
|
696
882
|
layoutRef.current = layout;
|
|
697
883
|
useEffect(() => {
|
|
@@ -732,12 +918,12 @@ function GridLayout(props) {
|
|
|
732
918
|
layout
|
|
733
919
|
]);
|
|
734
920
|
useEffect(() => {
|
|
735
|
-
if (!activeDrag && !deepEqual(layout, prevLayoutRef.current)) {
|
|
921
|
+
if (!activeDrag && !droppingDOMNode && !deepEqual(layout, prevLayoutRef.current)) {
|
|
736
922
|
prevLayoutRef.current = layout;
|
|
737
923
|
const publicLayout = layout.filter((l) => l.i !== droppingItem.i);
|
|
738
924
|
onLayoutChange(publicLayout);
|
|
739
925
|
}
|
|
740
|
-
}, [layout, activeDrag, onLayoutChange, droppingItem.i]);
|
|
926
|
+
}, [layout, activeDrag, droppingDOMNode, onLayoutChange, droppingItem.i]);
|
|
741
927
|
const containerHeight = useMemo(() => {
|
|
742
928
|
if (!autoSize) return void 0;
|
|
743
929
|
const nbRow = bottom(layout);
|
|
@@ -795,7 +981,7 @@ function GridLayout(props) {
|
|
|
795
981
|
);
|
|
796
982
|
const onDragStop = useCallback(
|
|
797
983
|
(i, x, y, data) => {
|
|
798
|
-
if (!
|
|
984
|
+
if (!oldDragItemRef.current) return;
|
|
799
985
|
const currentLayout = layoutRef.current;
|
|
800
986
|
const oldDragItem = oldDragItemRef.current;
|
|
801
987
|
const l = getLayoutItem(currentLayout, i);
|
|
@@ -823,7 +1009,6 @@ function GridLayout(props) {
|
|
|
823
1009
|
}
|
|
824
1010
|
},
|
|
825
1011
|
[
|
|
826
|
-
activeDrag,
|
|
827
1012
|
preventCollision,
|
|
828
1013
|
compactType,
|
|
829
1014
|
cols,
|
|
@@ -887,6 +1072,9 @@ function GridLayout(props) {
|
|
|
887
1072
|
}
|
|
888
1073
|
item.w = w;
|
|
889
1074
|
item.h = h;
|
|
1075
|
+
if (handle === "n" || handle === "nw" || handle === "ne") {
|
|
1076
|
+
item.y = newY ?? item.y;
|
|
1077
|
+
}
|
|
890
1078
|
return item;
|
|
891
1079
|
});
|
|
892
1080
|
if (!l) return;
|
|
@@ -920,7 +1108,14 @@ function GridLayout(props) {
|
|
|
920
1108
|
data.e,
|
|
921
1109
|
data.node
|
|
922
1110
|
);
|
|
923
|
-
|
|
1111
|
+
const compactedLayout = compactor.compact(finalLayout, cols);
|
|
1112
|
+
if (handle === "n" || handle === "nw" || handle === "ne") {
|
|
1113
|
+
const resized = compactedLayout.find((item) => item.i === i);
|
|
1114
|
+
if (resized) {
|
|
1115
|
+
resized.y = l.y;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
setLayout(compactedLayout);
|
|
924
1119
|
setActiveDrag(placeholder);
|
|
925
1120
|
},
|
|
926
1121
|
[preventCollision, compactType, cols, allowOverlap, compactor, onResizeProp]
|
|
@@ -951,6 +1146,73 @@ function GridLayout(props) {
|
|
|
951
1146
|
},
|
|
952
1147
|
[cols, compactor, onResizeStopProp, onLayoutChange]
|
|
953
1148
|
);
|
|
1149
|
+
const placeDroppingItem = useCallback(
|
|
1150
|
+
(itemToPlace, newDroppingPosition, calculatedXY, hasPlaceholder) => {
|
|
1151
|
+
if (!hasPlaceholder) {
|
|
1152
|
+
setDroppingDOMNode(/* @__PURE__ */ jsx("div", {}, itemToPlace.i));
|
|
1153
|
+
setDroppingPosition(newDroppingPosition);
|
|
1154
|
+
const baseLayout = layoutRef.current.filter((l) => l.i !== itemToPlace.i);
|
|
1155
|
+
setLayout([
|
|
1156
|
+
...baseLayout,
|
|
1157
|
+
{
|
|
1158
|
+
...itemToPlace,
|
|
1159
|
+
x: calculatedXY.x,
|
|
1160
|
+
y: calculatedXY.y,
|
|
1161
|
+
static: false,
|
|
1162
|
+
isDraggable: true
|
|
1163
|
+
}
|
|
1164
|
+
]);
|
|
1165
|
+
} else if (droppingPositionRef.current) {
|
|
1166
|
+
const shouldUpdate = droppingPositionRef.current.left !== newDroppingPosition.left || droppingPositionRef.current.top !== newDroppingPosition.top;
|
|
1167
|
+
if (shouldUpdate) {
|
|
1168
|
+
setDroppingPosition(newDroppingPosition);
|
|
1169
|
+
setLayout(
|
|
1170
|
+
(currentLayout) => currentLayout.map(
|
|
1171
|
+
(item) => item.i === itemToPlace.i && (item.x !== calculatedXY.x || item.y !== calculatedXY.y) ? { ...item, x: calculatedXY.x, y: calculatedXY.y } : item
|
|
1172
|
+
)
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
[]
|
|
1178
|
+
);
|
|
1179
|
+
const applyTouchDropPosition = useCallback(
|
|
1180
|
+
(clientX, clientY, nativeEvent) => {
|
|
1181
|
+
const gridEl = gridContainerRef.current;
|
|
1182
|
+
if (!gridEl) return;
|
|
1183
|
+
const { newDroppingPosition, calculatedXY } = computeDropPosition({
|
|
1184
|
+
clientX,
|
|
1185
|
+
clientY,
|
|
1186
|
+
gridElement: gridEl,
|
|
1187
|
+
droppingItem,
|
|
1188
|
+
event: nativeEvent,
|
|
1189
|
+
transformScale,
|
|
1190
|
+
cols,
|
|
1191
|
+
margin,
|
|
1192
|
+
maxRows,
|
|
1193
|
+
rowHeight,
|
|
1194
|
+
width,
|
|
1195
|
+
containerPadding: effectiveContainerPadding
|
|
1196
|
+
});
|
|
1197
|
+
placeDroppingItem(
|
|
1198
|
+
droppingItem,
|
|
1199
|
+
newDroppingPosition,
|
|
1200
|
+
calculatedXY,
|
|
1201
|
+
!!droppingDOMNodeRef.current
|
|
1202
|
+
);
|
|
1203
|
+
},
|
|
1204
|
+
[
|
|
1205
|
+
droppingItem,
|
|
1206
|
+
transformScale,
|
|
1207
|
+
cols,
|
|
1208
|
+
margin,
|
|
1209
|
+
maxRows,
|
|
1210
|
+
rowHeight,
|
|
1211
|
+
width,
|
|
1212
|
+
effectiveContainerPadding,
|
|
1213
|
+
placeDroppingItem
|
|
1214
|
+
]
|
|
1215
|
+
);
|
|
954
1216
|
const removeDroppingPlaceholder = useCallback(() => {
|
|
955
1217
|
const currentLayout = layoutRef.current;
|
|
956
1218
|
const hasDroppingItem = currentLayout.some((l) => l.i === droppingItem.i);
|
|
@@ -991,74 +1253,36 @@ function GridLayout(props) {
|
|
|
991
1253
|
...onDragOverResult
|
|
992
1254
|
} = rawResult ?? {};
|
|
993
1255
|
const finalDroppingItem = { ...droppingItem, ...onDragOverResult };
|
|
994
|
-
const
|
|
995
|
-
|
|
1256
|
+
const { newDroppingPosition, calculatedXY } = computeDropPosition({
|
|
1257
|
+
clientX: e.clientX,
|
|
1258
|
+
clientY: e.clientY,
|
|
1259
|
+
gridElement: e.currentTarget,
|
|
1260
|
+
droppingItem: finalDroppingItem,
|
|
1261
|
+
event: e.nativeEvent,
|
|
1262
|
+
dragOffsetX,
|
|
1263
|
+
dragOffsetY,
|
|
1264
|
+
transformScale,
|
|
996
1265
|
cols,
|
|
997
1266
|
margin,
|
|
998
1267
|
maxRows,
|
|
999
1268
|
rowHeight,
|
|
1000
|
-
|
|
1269
|
+
width,
|
|
1001
1270
|
containerPadding: effectiveContainerPadding
|
|
1002
|
-
};
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
);
|
|
1009
|
-
const itemPixelHeight = calcGridItemWHPx(
|
|
1010
|
-
finalDroppingItem.h,
|
|
1011
|
-
rowHeight,
|
|
1012
|
-
margin[1]
|
|
1271
|
+
});
|
|
1272
|
+
placeDroppingItem(
|
|
1273
|
+
finalDroppingItem,
|
|
1274
|
+
newDroppingPosition,
|
|
1275
|
+
calculatedXY,
|
|
1276
|
+
!!droppingDOMNode
|
|
1013
1277
|
);
|
|
1014
|
-
const itemCenterOffsetX = itemPixelWidth / 2;
|
|
1015
|
-
const itemCenterOffsetY = itemPixelHeight / 2;
|
|
1016
|
-
const rawGridX = e.clientX - gridRect.left + dragOffsetX - itemCenterOffsetX;
|
|
1017
|
-
const rawGridY = e.clientY - gridRect.top + dragOffsetY - itemCenterOffsetY;
|
|
1018
|
-
const clampedGridX = Math.max(0, rawGridX);
|
|
1019
|
-
const clampedGridY = Math.max(0, rawGridY);
|
|
1020
|
-
const newDroppingPosition = {
|
|
1021
|
-
left: clampedGridX / transformScale,
|
|
1022
|
-
top: clampedGridY / transformScale,
|
|
1023
|
-
e: e.nativeEvent
|
|
1024
|
-
};
|
|
1025
|
-
if (!droppingDOMNode) {
|
|
1026
|
-
const calculatedPosition = calcXY(
|
|
1027
|
-
positionParams,
|
|
1028
|
-
clampedGridY,
|
|
1029
|
-
clampedGridX,
|
|
1030
|
-
finalDroppingItem.w,
|
|
1031
|
-
finalDroppingItem.h
|
|
1032
|
-
);
|
|
1033
|
-
setDroppingDOMNode(/* @__PURE__ */ jsx("div", {}, finalDroppingItem.i));
|
|
1034
|
-
setDroppingPosition(newDroppingPosition);
|
|
1035
|
-
const baseLayout = layoutRef.current.filter(
|
|
1036
|
-
(l) => l.i !== finalDroppingItem.i
|
|
1037
|
-
);
|
|
1038
|
-
setLayout([
|
|
1039
|
-
...baseLayout,
|
|
1040
|
-
{
|
|
1041
|
-
...finalDroppingItem,
|
|
1042
|
-
x: calculatedPosition.x,
|
|
1043
|
-
y: calculatedPosition.y,
|
|
1044
|
-
static: false,
|
|
1045
|
-
isDraggable: true
|
|
1046
|
-
}
|
|
1047
|
-
]);
|
|
1048
|
-
} else if (droppingPosition) {
|
|
1049
|
-
const shouldUpdate = droppingPosition.left !== newDroppingPosition.left || droppingPosition.top !== newDroppingPosition.top;
|
|
1050
|
-
if (shouldUpdate) {
|
|
1051
|
-
setDroppingPosition(newDroppingPosition);
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
1278
|
},
|
|
1055
1279
|
[
|
|
1056
1280
|
droppingDOMNode,
|
|
1057
|
-
droppingPosition,
|
|
1058
1281
|
droppingItem,
|
|
1059
1282
|
dropConfigOnDragOver,
|
|
1060
1283
|
onDropDragOverProp,
|
|
1061
1284
|
removeDroppingPlaceholder,
|
|
1285
|
+
placeDroppingItem,
|
|
1062
1286
|
transformScale,
|
|
1063
1287
|
cols,
|
|
1064
1288
|
margin,
|
|
@@ -1087,18 +1311,106 @@ function GridLayout(props) {
|
|
|
1087
1311
|
e.stopPropagation();
|
|
1088
1312
|
dragEnterCounterRef.current++;
|
|
1089
1313
|
}, []);
|
|
1314
|
+
const commitDrop = useCallback(
|
|
1315
|
+
(nativeEvent) => {
|
|
1316
|
+
const currentLayout = layoutRef.current;
|
|
1317
|
+
const item = currentLayout.find((l) => l.i === droppingItem.i);
|
|
1318
|
+
removeDroppingPlaceholder();
|
|
1319
|
+
onDropPropRef.current(currentLayout, item, nativeEvent);
|
|
1320
|
+
},
|
|
1321
|
+
[droppingItem.i, removeDroppingPlaceholder]
|
|
1322
|
+
);
|
|
1090
1323
|
const handleDrop = useCallback(
|
|
1091
1324
|
(e) => {
|
|
1092
1325
|
e.preventDefault();
|
|
1093
1326
|
e.stopPropagation();
|
|
1094
|
-
const currentLayout = layoutRef.current;
|
|
1095
|
-
const item = currentLayout.find((l) => l.i === droppingItem.i);
|
|
1096
1327
|
dragEnterCounterRef.current = 0;
|
|
1097
|
-
|
|
1098
|
-
onDropProp(currentLayout, item, e.nativeEvent);
|
|
1328
|
+
commitDrop(e.nativeEvent);
|
|
1099
1329
|
},
|
|
1100
|
-
[
|
|
1330
|
+
[commitDrop]
|
|
1101
1331
|
);
|
|
1332
|
+
useEffect(() => {
|
|
1333
|
+
if (!isDroppable || !touchEnabled) return;
|
|
1334
|
+
const gridEl = gridContainerRef.current;
|
|
1335
|
+
if (!gridEl) return;
|
|
1336
|
+
const isOverGrid = (clientX, clientY) => {
|
|
1337
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
1338
|
+
return el ? gridEl.contains(el) : false;
|
|
1339
|
+
};
|
|
1340
|
+
const isSourceElement = (target) => {
|
|
1341
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
1342
|
+
return target.closest(touchDragSource) !== null;
|
|
1343
|
+
};
|
|
1344
|
+
const getTouch = (e) => {
|
|
1345
|
+
const touches = e.changedTouches;
|
|
1346
|
+
if (!touches || touches.length === 0) return void 0;
|
|
1347
|
+
const id = activeTouchIdRef.current;
|
|
1348
|
+
if (id === null) return touches[0];
|
|
1349
|
+
for (let i = 0; i < touches.length; i++) {
|
|
1350
|
+
const touch = touches[i];
|
|
1351
|
+
if (touch && touch.identifier === id) return touch;
|
|
1352
|
+
}
|
|
1353
|
+
return void 0;
|
|
1354
|
+
};
|
|
1355
|
+
const handleTouchStart = (e) => {
|
|
1356
|
+
if (!isSourceElement(e.target)) return;
|
|
1357
|
+
if (activeTouchIdRef.current !== null) return;
|
|
1358
|
+
e.preventDefault();
|
|
1359
|
+
const touch = e.changedTouches?.[0];
|
|
1360
|
+
if (!touch) return;
|
|
1361
|
+
activeTouchIdRef.current = touch.identifier;
|
|
1362
|
+
touchDragActiveRef.current = true;
|
|
1363
|
+
};
|
|
1364
|
+
const handleTouchMove = (e) => {
|
|
1365
|
+
if (!touchDragActiveRef.current) return;
|
|
1366
|
+
e.preventDefault();
|
|
1367
|
+
const touch = getTouch(e);
|
|
1368
|
+
if (!touch) return;
|
|
1369
|
+
if (!isOverGrid(touch.clientX, touch.clientY)) {
|
|
1370
|
+
if (droppingDOMNodeRef.current) removeDroppingPlaceholder();
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
applyTouchDropPosition(touch.clientX, touch.clientY, e);
|
|
1374
|
+
};
|
|
1375
|
+
const handleTouchEnd = (e) => {
|
|
1376
|
+
if (!touchDragActiveRef.current) return;
|
|
1377
|
+
e.preventDefault();
|
|
1378
|
+
const touch = getTouch(e);
|
|
1379
|
+
touchDragActiveRef.current = false;
|
|
1380
|
+
activeTouchIdRef.current = null;
|
|
1381
|
+
if (!touch) return;
|
|
1382
|
+
if (!isOverGrid(touch.clientX, touch.clientY)) {
|
|
1383
|
+
removeDroppingPlaceholder();
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
commitDrop(e);
|
|
1387
|
+
};
|
|
1388
|
+
const handleTouchCancel = () => {
|
|
1389
|
+
if (!touchDragActiveRef.current) return;
|
|
1390
|
+
touchDragActiveRef.current = false;
|
|
1391
|
+
activeTouchIdRef.current = null;
|
|
1392
|
+
removeDroppingPlaceholder();
|
|
1393
|
+
};
|
|
1394
|
+
const opts = { passive: false };
|
|
1395
|
+
document.addEventListener("touchstart", handleTouchStart, opts);
|
|
1396
|
+
document.addEventListener("touchmove", handleTouchMove, opts);
|
|
1397
|
+
document.addEventListener("touchend", handleTouchEnd, opts);
|
|
1398
|
+
document.addEventListener("touchcancel", handleTouchCancel, opts);
|
|
1399
|
+
return () => {
|
|
1400
|
+
document.removeEventListener("touchstart", handleTouchStart, opts);
|
|
1401
|
+
document.removeEventListener("touchmove", handleTouchMove, opts);
|
|
1402
|
+
document.removeEventListener("touchend", handleTouchEnd, opts);
|
|
1403
|
+
document.removeEventListener("touchcancel", handleTouchCancel, opts);
|
|
1404
|
+
};
|
|
1405
|
+
}, [
|
|
1406
|
+
isDroppable,
|
|
1407
|
+
touchEnabled,
|
|
1408
|
+
touchDragSource,
|
|
1409
|
+
applyTouchDropPosition,
|
|
1410
|
+
removeDroppingPlaceholder,
|
|
1411
|
+
commitDrop,
|
|
1412
|
+
droppingItem.i
|
|
1413
|
+
]);
|
|
1102
1414
|
const processGridItem = useCallback(
|
|
1103
1415
|
(child, isDroppingItem) => {
|
|
1104
1416
|
if (!child || !child.key) return null;
|
|
@@ -1129,6 +1441,7 @@ function GridLayout(props) {
|
|
|
1129
1441
|
isDraggable: draggable,
|
|
1130
1442
|
isResizable: resizable,
|
|
1131
1443
|
isBounded: bounded,
|
|
1444
|
+
allowMobileScroll: dragAllowMobileScroll,
|
|
1132
1445
|
useCSSTransforms: useCSSTransforms && mounted,
|
|
1133
1446
|
usePercentages: !mounted,
|
|
1134
1447
|
transformScale,
|
|
@@ -1213,6 +1526,17 @@ function GridLayout(props) {
|
|
|
1213
1526
|
}
|
|
1214
1527
|
);
|
|
1215
1528
|
};
|
|
1529
|
+
const setGridRef = useCallback(
|
|
1530
|
+
(node) => {
|
|
1531
|
+
gridContainerRef.current = node;
|
|
1532
|
+
if (typeof innerRef === "function") {
|
|
1533
|
+
innerRef(node);
|
|
1534
|
+
} else if (innerRef && "current" in innerRef) {
|
|
1535
|
+
innerRef.current = node;
|
|
1536
|
+
}
|
|
1537
|
+
},
|
|
1538
|
+
[innerRef]
|
|
1539
|
+
);
|
|
1216
1540
|
const mergedClassName = clsx(layoutClassName, className);
|
|
1217
1541
|
const mergedStyle = {
|
|
1218
1542
|
height: containerHeight,
|
|
@@ -1221,7 +1545,7 @@ function GridLayout(props) {
|
|
|
1221
1545
|
return /* @__PURE__ */ jsxs(
|
|
1222
1546
|
"div",
|
|
1223
1547
|
{
|
|
1224
|
-
ref:
|
|
1548
|
+
ref: setGridRef,
|
|
1225
1549
|
className: mergedClassName,
|
|
1226
1550
|
style: mergedStyle,
|
|
1227
1551
|
onDrop: isDroppable ? handleDrop : void 0,
|
|
@@ -1255,20 +1579,33 @@ var DEFAULT_COLS = {
|
|
|
1255
1579
|
};
|
|
1256
1580
|
var noop2 = () => {
|
|
1257
1581
|
};
|
|
1258
|
-
function synchronizeLayoutWithChildren2(initialLayout, children, cols, compactor) {
|
|
1582
|
+
function synchronizeLayoutWithChildren2(initialLayout, children, cols, compactor, reSeedFromDataGrid = false) {
|
|
1259
1583
|
const layout = [];
|
|
1260
1584
|
React2.Children.forEach(children, (child) => {
|
|
1261
1585
|
if (!React2.isValidElement(child) || child.key === null) return;
|
|
1262
1586
|
const key = String(child.key);
|
|
1587
|
+
const childProps = child.props;
|
|
1588
|
+
const dataGrid = childProps["data-grid"];
|
|
1263
1589
|
const existingItem = initialLayout.find((l) => l.i === key);
|
|
1264
1590
|
if (existingItem) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1591
|
+
if (reSeedFromDataGrid && dataGrid) {
|
|
1592
|
+
layout.push({
|
|
1593
|
+
...existingItem,
|
|
1594
|
+
i: key,
|
|
1595
|
+
w: dataGrid.w ?? existingItem.w,
|
|
1596
|
+
h: dataGrid.h ?? existingItem.h,
|
|
1597
|
+
minW: dataGrid.minW ?? existingItem.minW,
|
|
1598
|
+
maxW: dataGrid.maxW ?? existingItem.maxW,
|
|
1599
|
+
minH: dataGrid.minH ?? existingItem.minH,
|
|
1600
|
+
maxH: dataGrid.maxH ?? existingItem.maxH
|
|
1601
|
+
});
|
|
1602
|
+
} else {
|
|
1603
|
+
layout.push({
|
|
1604
|
+
...existingItem,
|
|
1605
|
+
i: key
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1269
1608
|
} else {
|
|
1270
|
-
const childProps = child.props;
|
|
1271
|
-
const dataGrid = childProps["data-grid"];
|
|
1272
1609
|
if (dataGrid) {
|
|
1273
1610
|
layout.push({
|
|
1274
1611
|
i: key,
|
|
@@ -1300,7 +1637,7 @@ function synchronizeLayoutWithChildren2(initialLayout, children, cols, compactor
|
|
|
1300
1637
|
const corrected = correctBounds(layout, { cols });
|
|
1301
1638
|
return compactor.compact(corrected, cols);
|
|
1302
1639
|
}
|
|
1303
|
-
function
|
|
1640
|
+
function ResponsiveGridLayoutInner(props) {
|
|
1304
1641
|
const {
|
|
1305
1642
|
children,
|
|
1306
1643
|
width,
|
|
@@ -1420,11 +1757,13 @@ function ResponsiveGridLayout(props) {
|
|
|
1420
1757
|
newCols,
|
|
1421
1758
|
compactor
|
|
1422
1759
|
);
|
|
1760
|
+
const layoutWasGenerated = !newLayouts[newBreakpoint];
|
|
1423
1761
|
newLayout = synchronizeLayoutWithChildren2(
|
|
1424
1762
|
newLayout,
|
|
1425
1763
|
children,
|
|
1426
1764
|
newCols,
|
|
1427
|
-
compactor
|
|
1765
|
+
compactor,
|
|
1766
|
+
layoutWasGenerated
|
|
1428
1767
|
);
|
|
1429
1768
|
newLayouts[newBreakpoint] = newLayout;
|
|
1430
1769
|
setBreakpoint(newBreakpoint);
|
|
@@ -1517,5 +1856,11 @@ function ResponsiveGridLayout(props) {
|
|
|
1517
1856
|
}
|
|
1518
1857
|
);
|
|
1519
1858
|
}
|
|
1859
|
+
var ResponsiveGridLayoutWithRef = React2.forwardRef(function ResponsiveGridLayoutForwardRef(props, ref) {
|
|
1860
|
+
const { innerRef, ...rest } = props;
|
|
1861
|
+
const effectiveInnerRef = innerRef ?? ref;
|
|
1862
|
+
return /* @__PURE__ */ jsx(ResponsiveGridLayoutInner, { ...rest, innerRef: effectiveInnerRef });
|
|
1863
|
+
});
|
|
1864
|
+
ResponsiveGridLayoutWithRef.displayName = "ResponsiveGridLayout";
|
|
1520
1865
|
|
|
1521
|
-
export { GridItem, GridLayout,
|
|
1866
|
+
export { GridItem, GridLayout, ResponsiveGridLayoutWithRef };
|