react-grid-layout 1.3.3 → 1.4.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/.flowconfig +3 -1
- package/.packj.yaml +153 -0
- package/.prettierignore +2 -1
- package/.prettierrc +0 -1
- package/CHANGELOG.md +38 -2
- package/README.md +35 -6
- package/build/GridItem.js +590 -493
- package/build/ReactGridLayout.js +536 -591
- package/build/ReactGridLayoutPropTypes.js +51 -48
- package/build/ResponsiveReactGridLayout.js +144 -238
- package/build/calculateUtils.js +76 -115
- package/build/components/WidthProvider.js +81 -124
- package/build/responsiveUtils.js +33 -63
- package/build/utils.js +290 -443
- package/css/styles.css +8 -3
- package/dist/react-grid-layout.min.js +1 -1
- package/dist/react-grid-layout.min.js.map +1 -1
- package/index.js +1 -0
- package/lib/GridItem.jsx +140 -50
- package/lib/ReactGridLayout.jsx +67 -23
- package/lib/ResponsiveReactGridLayout.jsx +4 -4
- package/lib/calculateUtils.js +20 -4
- package/lib/components/WidthProvider.jsx +18 -16
- package/lib/utils.js +76 -21
- package/margin.png +0 -0
- package/package.json +49 -45
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module.exports = require("./build/ReactGridLayout").default;
|
|
2
2
|
module.exports.utils = require("./build/utils");
|
|
3
|
+
module.exports.calculateUtils = require("./build/calculateUtils");
|
|
3
4
|
module.exports.Responsive =
|
|
4
5
|
require("./build/ResponsiveReactGridLayout").default;
|
|
5
6
|
module.exports.Responsive.utils = require("./build/responsiveUtils");
|
package/lib/GridItem.jsx
CHANGED
|
@@ -41,9 +41,19 @@ type GridItemCallback<Data: GridDragEvent | GridResizeEvent> = (
|
|
|
41
41
|
h: number,
|
|
42
42
|
Data
|
|
43
43
|
) => void;
|
|
44
|
+
type GridItemResizeCallback = (
|
|
45
|
+
e: Event,
|
|
46
|
+
data: ResizeCallbackData,
|
|
47
|
+
position: Position
|
|
48
|
+
) => void;
|
|
49
|
+
type ResizeCallbackData = {
|
|
50
|
+
node: HTMLElement,
|
|
51
|
+
size: Position,
|
|
52
|
+
handle: string
|
|
53
|
+
};
|
|
44
54
|
|
|
45
55
|
type State = {
|
|
46
|
-
resizing: ?{ width: number, height: number },
|
|
56
|
+
resizing: ?{ top: number, left: number, width: number, height: number },
|
|
47
57
|
dragging: ?{ top: number, left: number },
|
|
48
58
|
className: string
|
|
49
59
|
};
|
|
@@ -356,6 +366,15 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
356
366
|
);
|
|
357
367
|
}
|
|
358
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Utility function to setup callback handler definitions for
|
|
371
|
+
* similarily structured resize events.
|
|
372
|
+
*/
|
|
373
|
+
curryResizeHandler(position: Position, handler: function): function {
|
|
374
|
+
return (e: Event, data: ResizeCallbackData): function =>
|
|
375
|
+
handler(e, data, position);
|
|
376
|
+
}
|
|
377
|
+
|
|
359
378
|
/**
|
|
360
379
|
* Mix a Resizable instance into a child.
|
|
361
380
|
* @param {Element} child Child element.
|
|
@@ -381,13 +400,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
381
400
|
const positionParams = this.getPositionParams();
|
|
382
401
|
|
|
383
402
|
// This is the max possible width - doesn't go to infinity because of the width of the window
|
|
384
|
-
const maxWidth = calcGridItemPosition(
|
|
385
|
-
positionParams,
|
|
386
|
-
0,
|
|
387
|
-
0,
|
|
388
|
-
cols - x,
|
|
389
|
-
0
|
|
390
|
-
).width;
|
|
403
|
+
const maxWidth = calcGridItemPosition(positionParams, 0, 0, cols, 0).width;
|
|
391
404
|
|
|
392
405
|
// Calculate min/max constraints using our min & maxes
|
|
393
406
|
const mins = calcGridItemPosition(positionParams, 0, 0, minW, minH);
|
|
@@ -408,9 +421,9 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
408
421
|
height={position.height}
|
|
409
422
|
minConstraints={minConstraints}
|
|
410
423
|
maxConstraints={maxConstraints}
|
|
411
|
-
onResizeStop={this.onResizeStop}
|
|
412
|
-
onResizeStart={this.onResizeStart}
|
|
413
|
-
onResize={this.onResize}
|
|
424
|
+
onResizeStop={this.curryResizeHandler(position, this.onResizeStop)}
|
|
425
|
+
onResizeStart={this.curryResizeHandler(position, this.onResizeStart)}
|
|
426
|
+
onResize={this.curryResizeHandler(position, this.onResize)}
|
|
414
427
|
transformScale={transformScale}
|
|
415
428
|
resizeHandles={resizeHandles}
|
|
416
429
|
handle={resizeHandle}
|
|
@@ -541,53 +554,31 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
541
554
|
* @param {Event} e event data
|
|
542
555
|
* @param {Object} callbackData an object with node and size information
|
|
543
556
|
*/
|
|
544
|
-
onResizeStop: (
|
|
545
|
-
e,
|
|
546
|
-
callbackData
|
|
547
|
-
) => {
|
|
548
|
-
this.onResizeHandler(e, callbackData, "onResizeStop");
|
|
549
|
-
};
|
|
557
|
+
onResizeStop: GridItemResizeCallback = (e, callbackData, position) =>
|
|
558
|
+
this.onResizeHandler(e, callbackData, position, "onResizeStop");
|
|
550
559
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
* @param {Object} callbackData an object with node and size information
|
|
555
|
-
*/
|
|
556
|
-
onResizeStart: (Event, { node: HTMLElement, size: Position }) => void = (
|
|
557
|
-
e,
|
|
558
|
-
callbackData
|
|
559
|
-
) => {
|
|
560
|
-
this.onResizeHandler(e, callbackData, "onResizeStart");
|
|
561
|
-
};
|
|
560
|
+
// onResizeStart event handler
|
|
561
|
+
onResizeStart: GridItemResizeCallback = (e, callbackData, position) =>
|
|
562
|
+
this.onResizeHandler(e, callbackData, position, "onResizeStart");
|
|
562
563
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
* @param {Object} callbackData an object with node and size information
|
|
567
|
-
*/
|
|
568
|
-
onResize: (Event, { node: HTMLElement, size: Position }) => void = (
|
|
569
|
-
e,
|
|
570
|
-
callbackData
|
|
571
|
-
) => {
|
|
572
|
-
this.onResizeHandler(e, callbackData, "onResize");
|
|
573
|
-
};
|
|
564
|
+
// onResize event handler
|
|
565
|
+
onResize: GridItemResizeCallback = (e, callbackData, position) =>
|
|
566
|
+
this.onResizeHandler(e, callbackData, position, "onResize");
|
|
574
567
|
|
|
575
568
|
/**
|
|
576
569
|
* Wrapper around drag events to provide more useful data.
|
|
577
570
|
* All drag events call the function with the given handler name,
|
|
578
571
|
* with the signature (index, x, y).
|
|
579
|
-
*
|
|
580
|
-
* @param {String} handlerName Handler name to wrap.
|
|
581
|
-
* @return {Function} Handler function.
|
|
582
572
|
*/
|
|
583
573
|
onResizeHandler(
|
|
584
574
|
e: Event,
|
|
585
|
-
{ node, size }:
|
|
575
|
+
{ node, size, handle }: ResizeCallbackData,
|
|
576
|
+
position: Position,
|
|
586
577
|
handlerName: string
|
|
587
578
|
): void {
|
|
588
579
|
const handler = this.props[handlerName];
|
|
589
580
|
if (!handler) return;
|
|
590
|
-
const {
|
|
581
|
+
const { x, y, i, maxH, minH } = this.props;
|
|
591
582
|
let { minW, maxW } = this.props;
|
|
592
583
|
|
|
593
584
|
// Get new XY
|
|
@@ -596,22 +587,121 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
596
587
|
size.width,
|
|
597
588
|
size.height,
|
|
598
589
|
x,
|
|
599
|
-
y
|
|
590
|
+
y,
|
|
591
|
+
handle
|
|
600
592
|
);
|
|
601
593
|
|
|
602
594
|
// minW should be at least 1 (TODO propTypes validation?)
|
|
603
595
|
minW = Math.max(minW, 1);
|
|
604
596
|
|
|
605
|
-
// maxW should be at most (cols - x)
|
|
606
|
-
maxW = Math.min(maxW, cols - x);
|
|
607
|
-
|
|
608
597
|
// Min/max capping
|
|
609
598
|
w = clamp(w, minW, maxW);
|
|
610
599
|
h = clamp(h, minH, maxH);
|
|
611
600
|
|
|
612
|
-
|
|
601
|
+
let updatedSize = size;
|
|
602
|
+
if (node) {
|
|
603
|
+
const currentLeft = position.left;
|
|
604
|
+
const currentTop = position.top;
|
|
605
|
+
const currentWidth = position.width;
|
|
606
|
+
const currentHeight = position.height;
|
|
607
|
+
|
|
608
|
+
const resizeNorth = ({ left, height, width }) => {
|
|
609
|
+
const top = currentTop - (height - currentHeight);
|
|
610
|
+
|
|
611
|
+
return {
|
|
612
|
+
top,
|
|
613
|
+
left,
|
|
614
|
+
width,
|
|
615
|
+
height: this.constrainHeight(top, currentHeight, height),
|
|
616
|
+
top: this.constrainTop(top)
|
|
617
|
+
};
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
const resizeEast = ({ top, left, height, width }) => ({
|
|
621
|
+
top,
|
|
622
|
+
height,
|
|
623
|
+
width: this.constrainWidth(currentLeft, currentWidth, width),
|
|
624
|
+
left: this.constrainLeft(left)
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
const resizeWest = ({ top, height, width }) => {
|
|
628
|
+
const left = currentLeft - (width - currentWidth);
|
|
629
|
+
|
|
630
|
+
return {
|
|
631
|
+
height,
|
|
632
|
+
width:
|
|
633
|
+
left <= 0
|
|
634
|
+
? currentWidth
|
|
635
|
+
: this.constrainWidth(currentLeft, currentWidth, width),
|
|
636
|
+
top: this.constrainTop(top),
|
|
637
|
+
left: this.constrainLeft(left)
|
|
638
|
+
};
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
const resizeSouth = ({ top, left, height, width }) => ({
|
|
642
|
+
width,
|
|
643
|
+
left,
|
|
644
|
+
height: this.constrainHeight(top, currentHeight, height),
|
|
645
|
+
top: this.constrainTop(top)
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
const resizeNorthEast = (...args) => resizeNorth(resizeEast(...args));
|
|
649
|
+
const resizeNorthWest = (...args) => resizeNorth(resizeWest(...args));
|
|
650
|
+
const resizeSouthEast = (...args) => resizeSouth(resizeEast(...args));
|
|
651
|
+
const resizeSouthWest = (...args) => resizeSouth(resizeWest(...args));
|
|
652
|
+
|
|
653
|
+
const ordinalResizeHandlerMap = {
|
|
654
|
+
n: resizeNorth,
|
|
655
|
+
ne: resizeNorthEast,
|
|
656
|
+
e: resizeEast,
|
|
657
|
+
se: resizeSouthEast,
|
|
658
|
+
s: resizeSouth,
|
|
659
|
+
sw: resizeSouthWest,
|
|
660
|
+
w: resizeWest,
|
|
661
|
+
nw: resizeNorthWest
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
const resizeHandler = ordinalResizeHandlerMap[handle];
|
|
665
|
+
updatedSize = resizeHandler
|
|
666
|
+
? resizeHandler({
|
|
667
|
+
top: currentTop,
|
|
668
|
+
left: currentLeft,
|
|
669
|
+
height: currentHeight,
|
|
670
|
+
width: currentWidth,
|
|
671
|
+
...size
|
|
672
|
+
})
|
|
673
|
+
: size;
|
|
674
|
+
this.setState({
|
|
675
|
+
resizing: handlerName === "onResizeStop" ? null : updatedSize
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
handler.call(this, i, w, h, { e, node, size: updatedSize, handle });
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Helper functions to constrain dimensions of a GridItem
|
|
684
|
+
*/
|
|
685
|
+
constrainWidth(left: number, currentWidth: number, newWidth: number): number {
|
|
686
|
+
return left + newWidth > this.props.containerWidth
|
|
687
|
+
? currentWidth
|
|
688
|
+
: newWidth;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
constrainHeight(
|
|
692
|
+
top: number,
|
|
693
|
+
currentHeight: number,
|
|
694
|
+
newHeight: number
|
|
695
|
+
): number {
|
|
696
|
+
return top <= 0 ? currentHeight : newHeight;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
constrainLeft(left: number): number {
|
|
700
|
+
return Math.max(0, left);
|
|
701
|
+
}
|
|
613
702
|
|
|
614
|
-
|
|
703
|
+
constrainTop(top: number): number {
|
|
704
|
+
return Math.max(0, top);
|
|
615
705
|
}
|
|
616
706
|
|
|
617
707
|
render(): ReactNode {
|
package/lib/ReactGridLayout.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { deepEqual } from "fast-equals";
|
|
5
5
|
import clsx from "clsx";
|
|
6
6
|
import {
|
|
7
7
|
bottom,
|
|
@@ -47,6 +47,7 @@ type State = {
|
|
|
47
47
|
oldDragItem: ?LayoutItem,
|
|
48
48
|
oldLayout: ?Layout,
|
|
49
49
|
oldResizeItem: ?LayoutItem,
|
|
50
|
+
resizing: boolean,
|
|
50
51
|
droppingDOMNode: ?ReactElement<any>,
|
|
51
52
|
droppingPosition?: DroppingPosition,
|
|
52
53
|
// Mirrored props
|
|
@@ -132,6 +133,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
132
133
|
oldDragItem: null,
|
|
133
134
|
oldLayout: null,
|
|
134
135
|
oldResizeItem: null,
|
|
136
|
+
resizing: false,
|
|
135
137
|
droppingDOMNode: null,
|
|
136
138
|
children: []
|
|
137
139
|
};
|
|
@@ -158,7 +160,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
158
160
|
// Legacy support for compactType
|
|
159
161
|
// Allow parent to set layout directly.
|
|
160
162
|
if (
|
|
161
|
-
!
|
|
163
|
+
!deepEqual(nextProps.layout, prevState.propsLayout) ||
|
|
162
164
|
nextProps.compactType !== prevState.compactType
|
|
163
165
|
) {
|
|
164
166
|
newLayoutBase = nextProps.layout;
|
|
@@ -198,7 +200,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
198
200
|
// from SCU is if the user intentionally memoizes children. If they do, and they can
|
|
199
201
|
// handle changes properly, performance will increase.
|
|
200
202
|
this.props.children !== nextProps.children ||
|
|
201
|
-
!fastRGLPropsEqual(this.props, nextProps,
|
|
203
|
+
!fastRGLPropsEqual(this.props, nextProps, deepEqual) ||
|
|
202
204
|
this.state.activeDrag !== nextState.activeDrag ||
|
|
203
205
|
this.state.mounted !== nextState.mounted ||
|
|
204
206
|
this.state.droppingPosition !== nextState.droppingPosition
|
|
@@ -348,12 +350,13 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
348
350
|
allowOverlap
|
|
349
351
|
);
|
|
350
352
|
|
|
351
|
-
this.props.onDragStop(layout, oldDragItem, l, null, e, node);
|
|
352
|
-
|
|
353
353
|
// Set state
|
|
354
354
|
const newLayout = allowOverlap
|
|
355
355
|
? layout
|
|
356
356
|
: compact(layout, compactType(this.props), cols);
|
|
357
|
+
|
|
358
|
+
this.props.onDragStop(newLayout, oldDragItem, l, null, e, node);
|
|
359
|
+
|
|
357
360
|
const { oldLayout } = this.state;
|
|
358
361
|
this.setState({
|
|
359
362
|
activeDrag: null,
|
|
@@ -368,7 +371,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
368
371
|
onLayoutMaybeChanged(newLayout: Layout, oldLayout: ?Layout) {
|
|
369
372
|
if (!oldLayout) oldLayout = this.state.layout;
|
|
370
373
|
|
|
371
|
-
if (!
|
|
374
|
+
if (!deepEqual(oldLayout, newLayout)) {
|
|
372
375
|
this.props.onLayoutChange(newLayout);
|
|
373
376
|
}
|
|
374
377
|
}
|
|
@@ -385,7 +388,8 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
385
388
|
|
|
386
389
|
this.setState({
|
|
387
390
|
oldResizeItem: cloneLayoutItem(l),
|
|
388
|
-
oldLayout: this.state.layout
|
|
391
|
+
oldLayout: this.state.layout,
|
|
392
|
+
resizing: true
|
|
389
393
|
});
|
|
390
394
|
|
|
391
395
|
this.props.onResizeStart(layout, l, l, null, e, node);
|
|
@@ -395,9 +399,10 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
395
399
|
i,
|
|
396
400
|
w,
|
|
397
401
|
h,
|
|
398
|
-
{ e, node }
|
|
402
|
+
{ e, node, size, handle }
|
|
399
403
|
) => {
|
|
400
|
-
const {
|
|
404
|
+
const { oldResizeItem } = this.state;
|
|
405
|
+
let { layout } = this.state;
|
|
401
406
|
const { cols, preventCollision, allowOverlap } = this.props;
|
|
402
407
|
|
|
403
408
|
const [newLayout, l] = withLayoutItem(layout, i, l => {
|
|
@@ -425,18 +430,49 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
425
430
|
}
|
|
426
431
|
}
|
|
427
432
|
|
|
428
|
-
if (!hasCollisions) {
|
|
429
|
-
// Set new width and height.
|
|
430
|
-
l.w = w;
|
|
431
|
-
l.h = h;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
433
|
return l;
|
|
435
434
|
});
|
|
436
435
|
|
|
437
436
|
// Shouldn't ever happen, but typechecking makes it necessary
|
|
438
437
|
if (!l) return;
|
|
439
438
|
|
|
439
|
+
let finalLayout;
|
|
440
|
+
if (["sw", "w", "nw", "n", "ne"].indexOf(handle) !== -1) {
|
|
441
|
+
let x = l.x;
|
|
442
|
+
let y = l.y;
|
|
443
|
+
if (["sw", "nw", "w"].indexOf(handle) !== -1) {
|
|
444
|
+
x = l.x + (l.w - w);
|
|
445
|
+
w = l.x !== x && x < 0 ? l.w : w;
|
|
446
|
+
x = x < 0 ? 0 : x;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (["ne", "n", "nw"].indexOf(handle) !== -1) {
|
|
450
|
+
y = l.y + (l.h - h);
|
|
451
|
+
h = l.y !== y && y < 0 ? l.h : h;
|
|
452
|
+
y = y < 0 ? 0 : y;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
l.w = w;
|
|
456
|
+
l.h = h;
|
|
457
|
+
// Move the element to the new position.
|
|
458
|
+
const isUserAction = true;
|
|
459
|
+
finalLayout = moveElement(
|
|
460
|
+
newLayout,
|
|
461
|
+
l,
|
|
462
|
+
x,
|
|
463
|
+
y,
|
|
464
|
+
isUserAction,
|
|
465
|
+
this.props.preventCollision,
|
|
466
|
+
compactType(this.props),
|
|
467
|
+
cols,
|
|
468
|
+
allowOverlap
|
|
469
|
+
);
|
|
470
|
+
} else {
|
|
471
|
+
l.w = w;
|
|
472
|
+
l.h = h;
|
|
473
|
+
finalLayout = newLayout;
|
|
474
|
+
}
|
|
475
|
+
|
|
440
476
|
// Create placeholder element (display only)
|
|
441
477
|
const placeholder = {
|
|
442
478
|
w: l.w,
|
|
@@ -447,13 +483,13 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
447
483
|
i: i
|
|
448
484
|
};
|
|
449
485
|
|
|
450
|
-
this.props.onResize(
|
|
486
|
+
this.props.onResize(finalLayout, oldResizeItem, l, placeholder, e, node);
|
|
451
487
|
|
|
452
488
|
// Re-compact the newLayout and set the drag placeholder.
|
|
453
489
|
this.setState({
|
|
454
490
|
layout: allowOverlap
|
|
455
|
-
?
|
|
456
|
-
: compact(
|
|
491
|
+
? finalLayout
|
|
492
|
+
: compact(finalLayout, compactType(this.props), cols),
|
|
457
493
|
activeDrag: placeholder
|
|
458
494
|
});
|
|
459
495
|
};
|
|
@@ -468,18 +504,20 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
468
504
|
const { cols, allowOverlap } = this.props;
|
|
469
505
|
const l = getLayoutItem(layout, i);
|
|
470
506
|
|
|
471
|
-
this.props.onResizeStop(layout, oldResizeItem, l, null, e, node);
|
|
472
|
-
|
|
473
507
|
// Set state
|
|
474
508
|
const newLayout = allowOverlap
|
|
475
509
|
? layout
|
|
476
510
|
: compact(layout, compactType(this.props), cols);
|
|
511
|
+
|
|
512
|
+
this.props.onResizeStop(newLayout, oldResizeItem, l, null, e, node);
|
|
513
|
+
|
|
477
514
|
const { oldLayout } = this.state;
|
|
478
515
|
this.setState({
|
|
479
516
|
activeDrag: null,
|
|
480
517
|
layout: newLayout,
|
|
481
518
|
oldResizeItem: null,
|
|
482
|
-
oldLayout: null
|
|
519
|
+
oldLayout: null,
|
|
520
|
+
resizing: false
|
|
483
521
|
});
|
|
484
522
|
|
|
485
523
|
this.onLayoutMaybeChanged(newLayout, oldLayout);
|
|
@@ -511,7 +549,9 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
511
549
|
x={activeDrag.x}
|
|
512
550
|
y={activeDrag.y}
|
|
513
551
|
i={activeDrag.i}
|
|
514
|
-
className=
|
|
552
|
+
className={`react-grid-placeholder ${
|
|
553
|
+
this.state.resizing ? "placeholder-resizing" : ""
|
|
554
|
+
}`}
|
|
515
555
|
containerWidth={width}
|
|
516
556
|
cols={cols}
|
|
517
557
|
margin={margin}
|
|
@@ -713,7 +753,8 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
713
753
|
const newLayout = compact(
|
|
714
754
|
layout.filter(l => l.i !== droppingItem.i),
|
|
715
755
|
compactType(this.props),
|
|
716
|
-
cols
|
|
756
|
+
cols,
|
|
757
|
+
this.props.allowOverlap
|
|
717
758
|
);
|
|
718
759
|
|
|
719
760
|
this.setState({
|
|
@@ -726,6 +767,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
726
767
|
|
|
727
768
|
onDragLeave: EventHandler = e => {
|
|
728
769
|
e.preventDefault(); // Prevent any browser native action
|
|
770
|
+
e.stopPropagation();
|
|
729
771
|
this.dragEnterCounter--;
|
|
730
772
|
|
|
731
773
|
// onDragLeave can be triggered on each layout's child.
|
|
@@ -740,11 +782,13 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
740
782
|
|
|
741
783
|
onDragEnter: EventHandler = e => {
|
|
742
784
|
e.preventDefault(); // Prevent any browser native action
|
|
785
|
+
e.stopPropagation();
|
|
743
786
|
this.dragEnterCounter++;
|
|
744
787
|
};
|
|
745
788
|
|
|
746
789
|
onDrop: EventHandler = (e: Event) => {
|
|
747
790
|
e.preventDefault(); // Prevent any browser native action
|
|
791
|
+
e.stopPropagation();
|
|
748
792
|
const { droppingItem } = this.props;
|
|
749
793
|
const { layout } = this.state;
|
|
750
794
|
const item = layout.find(l => l.i === droppingItem.i);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
-
import
|
|
4
|
+
import { deepEqual } from "fast-equals";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
cloneLayout,
|
|
@@ -203,7 +203,7 @@ export default class ResponsiveReactGridLayout extends React.Component<
|
|
|
203
203
|
nextProps: Props<*>,
|
|
204
204
|
prevState: State
|
|
205
205
|
): ?$Shape<State> {
|
|
206
|
-
if (!
|
|
206
|
+
if (!deepEqual(nextProps.layouts, prevState.layouts)) {
|
|
207
207
|
// Allow parent to set layouts directly.
|
|
208
208
|
const { breakpoint, cols } = prevState;
|
|
209
209
|
|
|
@@ -228,8 +228,8 @@ export default class ResponsiveReactGridLayout extends React.Component<
|
|
|
228
228
|
if (
|
|
229
229
|
this.props.width != prevProps.width ||
|
|
230
230
|
this.props.breakpoint !== prevProps.breakpoint ||
|
|
231
|
-
!
|
|
232
|
-
!
|
|
231
|
+
!deepEqual(this.props.breakpoints, prevProps.breakpoints) ||
|
|
232
|
+
!deepEqual(this.props.cols, prevProps.cols)
|
|
233
233
|
) {
|
|
234
234
|
this.onWidthChange(prevProps);
|
|
235
235
|
}
|
package/lib/calculateUtils.js
CHANGED
|
@@ -71,6 +71,14 @@ export function calcGridItemPosition(
|
|
|
71
71
|
if (state && state.dragging) {
|
|
72
72
|
out.top = Math.round(state.dragging.top);
|
|
73
73
|
out.left = Math.round(state.dragging.left);
|
|
74
|
+
} else if (
|
|
75
|
+
state &&
|
|
76
|
+
state.resizing &&
|
|
77
|
+
typeof state.resizing.top === "number" &&
|
|
78
|
+
typeof state.resizing.left === "number"
|
|
79
|
+
) {
|
|
80
|
+
out.top = Math.round(state.resizing.top);
|
|
81
|
+
out.left = Math.round(state.resizing.left);
|
|
74
82
|
}
|
|
75
83
|
// Otherwise, calculate from grid units.
|
|
76
84
|
else {
|
|
@@ -123,6 +131,7 @@ export function calcXY(
|
|
|
123
131
|
* @param {Number} width Width in pixels.
|
|
124
132
|
* @param {Number} x X coordinate in grid units.
|
|
125
133
|
* @param {Number} y Y coordinate in grid units.
|
|
134
|
+
* @param {String} handle Resize Handle.
|
|
126
135
|
* @return {Object} w, h as grid units.
|
|
127
136
|
*/
|
|
128
137
|
export function calcWH(
|
|
@@ -130,7 +139,8 @@ export function calcWH(
|
|
|
130
139
|
width: number,
|
|
131
140
|
height: number,
|
|
132
141
|
x: number,
|
|
133
|
-
y: number
|
|
142
|
+
y: number,
|
|
143
|
+
handle: string
|
|
134
144
|
): { w: number, h: number } {
|
|
135
145
|
const { margin, maxRows, cols, rowHeight } = positionParams;
|
|
136
146
|
const colWidth = calcGridColWidth(positionParams);
|
|
@@ -142,9 +152,15 @@ export function calcWH(
|
|
|
142
152
|
let h = Math.round((height + margin[1]) / (rowHeight + margin[1]));
|
|
143
153
|
|
|
144
154
|
// Capping
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
let _w = clamp(w, 0, cols - x);
|
|
156
|
+
let _h = clamp(h, 0, maxRows - y);
|
|
157
|
+
if (["sw", "w", "nw"].indexOf(handle) !== -1) {
|
|
158
|
+
_w = clamp(w, 0, cols);
|
|
159
|
+
}
|
|
160
|
+
if (["nw", "n", "ne"].indexOf(handle) !== -1) {
|
|
161
|
+
_h = clamp(h, 0, maxRows);
|
|
162
|
+
}
|
|
163
|
+
return { w: _w, h: _h };
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
// Similar to _.clamp
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import ResizeObserver from "resize-observer-polyfill";
|
|
4
5
|
import clsx from "clsx";
|
|
5
6
|
import type { ReactRef } from "../ReactGridLayoutPropTypes";
|
|
6
7
|
|
|
@@ -58,30 +59,31 @@ export default function WidthProvideRGL<Config>(
|
|
|
58
59
|
|
|
59
60
|
elementRef: ReactRef<HTMLDivElement> = React.createRef();
|
|
60
61
|
mounted: boolean = false;
|
|
62
|
+
resizeObserver: ResizeObserver;
|
|
61
63
|
|
|
62
64
|
componentDidMount() {
|
|
63
65
|
this.mounted = true;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
67
|
+
const node = this.elementRef.current;
|
|
68
|
+
if (node instanceof HTMLElement) {
|
|
69
|
+
const width = entries[0].contentRect.width;
|
|
70
|
+
this.setState({ width });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
const node = this.elementRef.current;
|
|
74
|
+
if (node instanceof HTMLElement) {
|
|
75
|
+
this.resizeObserver.observe(node);
|
|
76
|
+
}
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
componentWillUnmount() {
|
|
72
80
|
this.mounted = false;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
onWindowResize = () => {
|
|
77
|
-
if (!this.mounted) return;
|
|
78
|
-
const node = this.elementRef.current; // Flow casts this to Text | Element
|
|
79
|
-
// fix: grid position error when node or parentNode display is none by window resize
|
|
80
|
-
// #924 #1084
|
|
81
|
-
if (node instanceof HTMLElement && node.offsetWidth) {
|
|
82
|
-
this.setState({ width: node.offsetWidth });
|
|
81
|
+
const node = this.elementRef.current;
|
|
82
|
+
if (node instanceof HTMLElement) {
|
|
83
|
+
this.resizeObserver.unobserve(node);
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
this.resizeObserver.disconnect();
|
|
86
|
+
}
|
|
85
87
|
|
|
86
88
|
render() {
|
|
87
89
|
const { measureBeforeMount, ...rest } = this.props;
|