react-grid-layout 1.2.1 → 1.2.2
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/CHANGELOG.md +7 -0
- package/build/ReactGridLayout.js +48 -36
- package/build/utils.js +47 -1
- package/dist/react-grid-layout.min.js +1 -1
- package/dist/react-grid-layout.min.js.map +1 -1
- package/lib/ReactGridLayout.jsx +49 -46
- package/lib/utils.js +31 -0
- package/package.json +1 -1
package/lib/ReactGridLayout.jsx
CHANGED
|
@@ -9,13 +9,14 @@ import {
|
|
|
9
9
|
childrenEqual,
|
|
10
10
|
cloneLayoutItem,
|
|
11
11
|
compact,
|
|
12
|
+
compactType,
|
|
13
|
+
fastRGLPropsEqual,
|
|
14
|
+
getAllCollisions,
|
|
12
15
|
getLayoutItem,
|
|
13
16
|
moveElement,
|
|
14
|
-
synchronizeLayoutWithChildren,
|
|
15
|
-
getAllCollisions,
|
|
16
|
-
compactType,
|
|
17
17
|
noop,
|
|
18
|
-
|
|
18
|
+
synchronizeLayoutWithChildren,
|
|
19
|
+
withLayoutItem
|
|
19
20
|
} from "./utils";
|
|
20
21
|
|
|
21
22
|
import { calcXY } from "./calculateUtils";
|
|
@@ -255,7 +256,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
255
256
|
{ e, node }: GridDragEvent
|
|
256
257
|
): void {
|
|
257
258
|
const { layout } = this.state;
|
|
258
|
-
|
|
259
|
+
const l = getLayoutItem(layout, i);
|
|
259
260
|
if (!l) return;
|
|
260
261
|
|
|
261
262
|
this.setState({
|
|
@@ -278,11 +279,11 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
278
279
|
const { oldDragItem } = this.state;
|
|
279
280
|
let { layout } = this.state;
|
|
280
281
|
const { cols } = this.props;
|
|
281
|
-
|
|
282
|
+
const l = getLayoutItem(layout, i);
|
|
282
283
|
if (!l) return;
|
|
283
284
|
|
|
284
285
|
// Create placeholder (display only)
|
|
285
|
-
|
|
286
|
+
const placeholder = {
|
|
286
287
|
w: l.w,
|
|
287
288
|
h: l.h,
|
|
288
289
|
x: l.x,
|
|
@@ -372,7 +373,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
372
373
|
|
|
373
374
|
onResizeStart(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
374
375
|
const { layout } = this.state;
|
|
375
|
-
|
|
376
|
+
const l = getLayoutItem(layout, i);
|
|
376
377
|
if (!l) return;
|
|
377
378
|
|
|
378
379
|
this.setState({
|
|
@@ -386,44 +387,46 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
386
387
|
onResize(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
387
388
|
const { layout, oldResizeItem } = this.state;
|
|
388
389
|
const { cols, preventCollision } = this.props;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if (
|
|
411
|
-
if (
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (Number.isFinite(leastX)) l.w = leastX - l.x;
|
|
415
|
-
if (Number.isFinite(leastY)) l.h = leastY - l.y;
|
|
390
|
+
|
|
391
|
+
const [newLayout, l] = withLayoutItem(layout, i, l => {
|
|
392
|
+
// Something like quad tree should be used
|
|
393
|
+
// to find collisions faster
|
|
394
|
+
let hasCollisions;
|
|
395
|
+
if (preventCollision) {
|
|
396
|
+
const collisions = getAllCollisions(layout, { ...l, w, h }).filter(
|
|
397
|
+
layoutItem => layoutItem.i !== l.i
|
|
398
|
+
);
|
|
399
|
+
hasCollisions = collisions.length > 0;
|
|
400
|
+
|
|
401
|
+
// If we're colliding, we need adjust the placeholder.
|
|
402
|
+
if (hasCollisions) {
|
|
403
|
+
// adjust w && h to maximum allowed space
|
|
404
|
+
let leastX = Infinity,
|
|
405
|
+
leastY = Infinity;
|
|
406
|
+
collisions.forEach(layoutItem => {
|
|
407
|
+
if (layoutItem.x > l.x) leastX = Math.min(leastX, layoutItem.x);
|
|
408
|
+
if (layoutItem.y > l.y) leastY = Math.min(leastY, layoutItem.y);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
if (Number.isFinite(leastX)) l.w = leastX - l.x;
|
|
412
|
+
if (Number.isFinite(leastY)) l.h = leastY - l.y;
|
|
413
|
+
}
|
|
416
414
|
}
|
|
417
|
-
}
|
|
418
415
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
416
|
+
if (!hasCollisions) {
|
|
417
|
+
// Set new width and height.
|
|
418
|
+
l.w = w;
|
|
419
|
+
l.h = h;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return l;
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Shouldn't ever happen, but typechecking makes it necessary
|
|
426
|
+
if (!l) return;
|
|
424
427
|
|
|
425
428
|
// Create placeholder element (display only)
|
|
426
|
-
|
|
429
|
+
const placeholder = {
|
|
427
430
|
w: l.w,
|
|
428
431
|
h: l.h,
|
|
429
432
|
x: l.x,
|
|
@@ -432,11 +435,11 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
432
435
|
i: i
|
|
433
436
|
};
|
|
434
437
|
|
|
435
|
-
this.props.onResize(
|
|
438
|
+
this.props.onResize(newLayout, oldResizeItem, l, placeholder, e, node);
|
|
436
439
|
|
|
437
|
-
// Re-compact the
|
|
440
|
+
// Re-compact the newLayout and set the drag placeholder.
|
|
438
441
|
this.setState({
|
|
439
|
-
layout: compact(
|
|
442
|
+
layout: compact(newLayout, compactType(this.props), cols),
|
|
440
443
|
activeDrag: placeholder
|
|
441
444
|
});
|
|
442
445
|
}
|
|
@@ -444,7 +447,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
444
447
|
onResizeStop(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
445
448
|
const { layout, oldResizeItem } = this.state;
|
|
446
449
|
const { cols } = this.props;
|
|
447
|
-
|
|
450
|
+
const l = getLayoutItem(layout, i);
|
|
448
451
|
|
|
449
452
|
this.props.onResizeStop(layout, oldResizeItem, l, null, e, node);
|
|
450
453
|
|
package/lib/utils.js
CHANGED
|
@@ -102,6 +102,35 @@ export function cloneLayout(layout: Layout): Layout {
|
|
|
102
102
|
return newLayout;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// Modify a layoutItem inside a layout. Returns a new Layout,
|
|
106
|
+
// does not mutate. Carries over all other LayoutItems unmodified.
|
|
107
|
+
export function modifyLayout(layout: Layout, layoutItem: LayoutItem): Layout {
|
|
108
|
+
const newLayout = Array(layout.length);
|
|
109
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
110
|
+
if (layoutItem.i === layout[i].i) {
|
|
111
|
+
newLayout[i] = layoutItem;
|
|
112
|
+
} else {
|
|
113
|
+
newLayout[i] = layout[i];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return newLayout;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Function to be called to modify a layout item.
|
|
120
|
+
// Does defensive clones to ensure the layout is not modified.
|
|
121
|
+
export function withLayoutItem(
|
|
122
|
+
layout: Layout,
|
|
123
|
+
itemKey: string,
|
|
124
|
+
cb: LayoutItem => LayoutItem
|
|
125
|
+
): [Layout, ?LayoutItem] {
|
|
126
|
+
let item = getLayoutItem(layout, itemKey);
|
|
127
|
+
if (!item) return [layout, null];
|
|
128
|
+
item = cb(cloneLayoutItem(item)); // defensive clone then modify
|
|
129
|
+
// FIXME could do this faster if we already knew the index
|
|
130
|
+
layout = modifyLayout(layout, item);
|
|
131
|
+
return [layout, item];
|
|
132
|
+
}
|
|
133
|
+
|
|
105
134
|
// Fast path to cloning, since this is monomorphic
|
|
106
135
|
export function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {
|
|
107
136
|
return {
|
|
@@ -667,9 +696,11 @@ export function synchronizeLayoutWithChildren(
|
|
|
667
696
|
if (!isProduction) {
|
|
668
697
|
validateLayout([g], "ReactGridLayout.children");
|
|
669
698
|
}
|
|
699
|
+
// FIXME clone not really necessary here
|
|
670
700
|
layout[i] = cloneLayoutItem({ ...g, i: child.key });
|
|
671
701
|
} else {
|
|
672
702
|
// Nothing provided: ensure this is added to the bottom
|
|
703
|
+
// FIXME clone not really necessary here
|
|
673
704
|
layout[i] = cloneLayoutItem({
|
|
674
705
|
w: 1,
|
|
675
706
|
h: 1,
|