react-grid-layout 1.1.0 → 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/.flowconfig +2 -1
- package/.husky/pre-commit +6 -0
- package/CHANGELOG.md +51 -4
- package/README.md +24 -19
- package/build/GridItem.js +34 -43
- package/build/ReactGridLayout.js +95 -58
- package/build/ReactGridLayoutPropTypes.js +86 -17
- package/build/ResponsiveReactGridLayout.js +33 -13
- package/build/calculateUtils.js +6 -2
- package/build/components/WidthProvider.js +3 -3
- package/build/fastRGLPropsEqual.js +1 -1
- package/build/utils.js +51 -4
- package/css/styles.css +56 -3
- package/dist/react-grid-layout.min.js +3 -0
- package/dist/react-grid-layout.min.js.LICENSE.txt +5 -0
- package/dist/react-grid-layout.min.js.map +1 -0
- package/lib/GridItem.jsx +49 -25
- package/lib/ReactGridLayout.jsx +86 -62
- package/lib/ReactGridLayoutPropTypes.js +48 -19
- package/lib/ResponsiveReactGridLayout.jsx +31 -11
- package/lib/calculateUtils.js +6 -2
- package/lib/responsiveUtils.js +5 -0
- package/lib/utils.js +39 -6
- package/package.json +32 -38
package/lib/GridItem.jsx
CHANGED
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
calcWH,
|
|
14
14
|
clamp
|
|
15
15
|
} from "./calculateUtils";
|
|
16
|
+
import {
|
|
17
|
+
resizeHandlesType,
|
|
18
|
+
resizeHandleType
|
|
19
|
+
} from "./ReactGridLayoutPropTypes";
|
|
16
20
|
import classNames from "classnames";
|
|
17
21
|
import type { Element as ReactElement, Node as ReactNode } from "react";
|
|
18
22
|
|
|
@@ -25,6 +29,7 @@ import type {
|
|
|
25
29
|
} from "./utils";
|
|
26
30
|
|
|
27
31
|
import type { PositionParams } from "./calculateUtils";
|
|
32
|
+
import type { ResizeHandles, ResizeHandle } from "./ReactGridLayoutPropTypes";
|
|
28
33
|
|
|
29
34
|
type PartialPosition = { top: number, left: number };
|
|
30
35
|
type GridItemCallback<Data: GridDragEvent | GridResizeEvent> = (
|
|
@@ -74,7 +79,8 @@ type Props = {
|
|
|
74
79
|
maxH: number,
|
|
75
80
|
i: string,
|
|
76
81
|
|
|
77
|
-
resizeHandles?:
|
|
82
|
+
resizeHandles?: ResizeHandles,
|
|
83
|
+
resizeHandle?: ResizeHandle,
|
|
78
84
|
|
|
79
85
|
onDrag?: GridItemCallback<GridDragEvent>,
|
|
80
86
|
onDragStart?: GridItemCallback<GridDragEvent>,
|
|
@@ -84,6 +90,17 @@ type Props = {
|
|
|
84
90
|
onResizeStop?: GridItemCallback<GridResizeEvent>
|
|
85
91
|
};
|
|
86
92
|
|
|
93
|
+
type DefaultProps = {
|
|
94
|
+
className: string,
|
|
95
|
+
cancel: string,
|
|
96
|
+
handle: string,
|
|
97
|
+
minH: number,
|
|
98
|
+
minW: number,
|
|
99
|
+
maxH: number,
|
|
100
|
+
maxW: number,
|
|
101
|
+
transformScale: number
|
|
102
|
+
};
|
|
103
|
+
|
|
87
104
|
/**
|
|
88
105
|
* An individual item within a ReactGridLayout.
|
|
89
106
|
*/
|
|
@@ -138,6 +155,10 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
138
155
|
// ID is nice to have for callbacks
|
|
139
156
|
i: PropTypes.string.isRequired,
|
|
140
157
|
|
|
158
|
+
// Resize handle options
|
|
159
|
+
resizeHandles: resizeHandlesType,
|
|
160
|
+
resizeHandle: resizeHandleType,
|
|
161
|
+
|
|
141
162
|
// Functions
|
|
142
163
|
onDragStop: PropTypes.func,
|
|
143
164
|
onDragStart: PropTypes.func,
|
|
@@ -170,7 +191,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
170
191
|
})
|
|
171
192
|
};
|
|
172
193
|
|
|
173
|
-
static defaultProps = {
|
|
194
|
+
static defaultProps: DefaultProps = {
|
|
174
195
|
className: "",
|
|
175
196
|
cancel: "",
|
|
176
197
|
handle: "",
|
|
@@ -189,7 +210,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
189
210
|
|
|
190
211
|
currentNode: HTMLElement;
|
|
191
212
|
|
|
192
|
-
shouldComponentUpdate(nextProps: Props, nextState: State) {
|
|
213
|
+
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
|
193
214
|
// We can't deeply compare children. If the developer memoizes them, we can
|
|
194
215
|
// use this optimization.
|
|
195
216
|
if (this.props.children !== nextProps.children) return true;
|
|
@@ -352,7 +373,8 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
352
373
|
maxW,
|
|
353
374
|
maxH,
|
|
354
375
|
transformScale,
|
|
355
|
-
resizeHandles
|
|
376
|
+
resizeHandles,
|
|
377
|
+
resizeHandle
|
|
356
378
|
} = this.props;
|
|
357
379
|
const positionParams = this.getPositionParams();
|
|
358
380
|
|
|
@@ -383,6 +405,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
383
405
|
onResize={this.onResize}
|
|
384
406
|
transformScale={transformScale}
|
|
385
407
|
resizeHandles={resizeHandles}
|
|
408
|
+
handle={resizeHandle}
|
|
386
409
|
>
|
|
387
410
|
{child}
|
|
388
411
|
</Resizable>
|
|
@@ -394,8 +417,8 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
394
417
|
* @param {Event} e event data
|
|
395
418
|
* @param {Object} callbackData an object with node, delta and position information
|
|
396
419
|
*/
|
|
397
|
-
onDragStart = (e
|
|
398
|
-
const { onDragStart } = this.props;
|
|
420
|
+
onDragStart: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
|
|
421
|
+
const { onDragStart, transformScale } = this.props;
|
|
399
422
|
if (!onDragStart) return;
|
|
400
423
|
|
|
401
424
|
const newPosition: PartialPosition = { top: 0, left: 0 };
|
|
@@ -405,10 +428,10 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
405
428
|
if (!offsetParent) return;
|
|
406
429
|
const parentRect = offsetParent.getBoundingClientRect();
|
|
407
430
|
const clientRect = node.getBoundingClientRect();
|
|
408
|
-
const cLeft = clientRect.left /
|
|
409
|
-
const pLeft = parentRect.left /
|
|
410
|
-
const cTop = clientRect.top /
|
|
411
|
-
const pTop = parentRect.top /
|
|
431
|
+
const cLeft = clientRect.left / transformScale;
|
|
432
|
+
const pLeft = parentRect.left / transformScale;
|
|
433
|
+
const cTop = clientRect.top / transformScale;
|
|
434
|
+
const pTop = parentRect.top / transformScale;
|
|
412
435
|
newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
|
|
413
436
|
newPosition.top = cTop - pTop + offsetParent.scrollTop;
|
|
414
437
|
this.setState({ dragging: newPosition });
|
|
@@ -434,11 +457,12 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
434
457
|
* @param {Event} e event data
|
|
435
458
|
* @param {Object} callbackData an object with node, delta and position information
|
|
436
459
|
*/
|
|
437
|
-
onDrag
|
|
438
|
-
|
|
460
|
+
onDrag: (Event, ReactDraggableCallbackData) => void = (
|
|
461
|
+
e,
|
|
462
|
+
{ node, deltaX, deltaY }
|
|
463
|
+
) => {
|
|
464
|
+
const { onDrag } = this.props;
|
|
439
465
|
if (!onDrag) return;
|
|
440
|
-
deltaX /= transformScale;
|
|
441
|
-
deltaY /= transformScale;
|
|
442
466
|
|
|
443
467
|
if (!this.state.dragging) {
|
|
444
468
|
throw new Error("onDrag called before onDragStart.");
|
|
@@ -483,7 +507,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
483
507
|
* @param {Event} e event data
|
|
484
508
|
* @param {Object} callbackData an object with node, delta and position information
|
|
485
509
|
*/
|
|
486
|
-
onDragStop = (e
|
|
510
|
+
onDragStop: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
|
|
487
511
|
const { onDragStop } = this.props;
|
|
488
512
|
if (!onDragStop) return;
|
|
489
513
|
|
|
@@ -509,9 +533,9 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
509
533
|
* @param {Event} e event data
|
|
510
534
|
* @param {Object} callbackData an object with node and size information
|
|
511
535
|
*/
|
|
512
|
-
onResizeStop = (
|
|
513
|
-
e
|
|
514
|
-
callbackData
|
|
536
|
+
onResizeStop: (Event, { node: HTMLElement, size: Position }) => void = (
|
|
537
|
+
e,
|
|
538
|
+
callbackData
|
|
515
539
|
) => {
|
|
516
540
|
this.onResizeHandler(e, callbackData, "onResizeStop");
|
|
517
541
|
};
|
|
@@ -521,9 +545,9 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
521
545
|
* @param {Event} e event data
|
|
522
546
|
* @param {Object} callbackData an object with node and size information
|
|
523
547
|
*/
|
|
524
|
-
onResizeStart = (
|
|
525
|
-
e
|
|
526
|
-
callbackData
|
|
548
|
+
onResizeStart: (Event, { node: HTMLElement, size: Position }) => void = (
|
|
549
|
+
e,
|
|
550
|
+
callbackData
|
|
527
551
|
) => {
|
|
528
552
|
this.onResizeHandler(e, callbackData, "onResizeStart");
|
|
529
553
|
};
|
|
@@ -533,9 +557,9 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
533
557
|
* @param {Event} e event data
|
|
534
558
|
* @param {Object} callbackData an object with node and size information
|
|
535
559
|
*/
|
|
536
|
-
onResize = (
|
|
537
|
-
e
|
|
538
|
-
callbackData
|
|
560
|
+
onResize: (Event, { node: HTMLElement, size: Position }) => void = (
|
|
561
|
+
e,
|
|
562
|
+
callbackData
|
|
539
563
|
) => {
|
|
540
564
|
this.onResizeHandler(e, callbackData, "onResize");
|
|
541
565
|
};
|
|
@@ -552,7 +576,7 @@ export default class GridItem extends React.Component<Props, State> {
|
|
|
552
576
|
e: Event,
|
|
553
577
|
{ node, size }: { node: HTMLElement, size: Position },
|
|
554
578
|
handlerName: string
|
|
555
|
-
) {
|
|
579
|
+
): void {
|
|
556
580
|
const handler = this.props[handlerName];
|
|
557
581
|
if (!handler) return;
|
|
558
582
|
const { cols, x, y, i, maxH, minH } = this.props;
|
package/lib/ReactGridLayout.jsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
import React from "react";
|
|
2
|
+
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
import isEqual from "lodash.isequal";
|
|
5
5
|
import classNames from "classnames";
|
|
@@ -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";
|
|
@@ -55,7 +56,7 @@ type State = {
|
|
|
55
56
|
propsLayout?: Layout
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
import type { Props } from "./ReactGridLayoutPropTypes";
|
|
59
|
+
import type { Props, DefaultProps } from "./ReactGridLayoutPropTypes";
|
|
59
60
|
|
|
60
61
|
// End Types
|
|
61
62
|
|
|
@@ -74,12 +75,12 @@ try {
|
|
|
74
75
|
|
|
75
76
|
export default class ReactGridLayout extends React.Component<Props, State> {
|
|
76
77
|
// TODO publish internal ReactClass displayName transform
|
|
77
|
-
static displayName = "ReactGridLayout";
|
|
78
|
+
static displayName: ?string = "ReactGridLayout";
|
|
78
79
|
|
|
79
80
|
// Refactored to another module to make way for preval
|
|
80
81
|
static propTypes = ReactGridLayoutPropTypes;
|
|
81
82
|
|
|
82
|
-
static defaultProps = {
|
|
83
|
+
static defaultProps: DefaultProps = {
|
|
83
84
|
autoSize: true,
|
|
84
85
|
cols: 12,
|
|
85
86
|
className: "",
|
|
@@ -133,7 +134,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
133
134
|
children: []
|
|
134
135
|
};
|
|
135
136
|
|
|
136
|
-
dragEnterCounter = 0;
|
|
137
|
+
dragEnterCounter: number = 0;
|
|
137
138
|
|
|
138
139
|
constructor(props: Props, context: any): void {
|
|
139
140
|
super(props, context);
|
|
@@ -154,7 +155,10 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
154
155
|
this.onLayoutMaybeChanged(this.state.layout, this.props.layout);
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
static getDerivedStateFromProps(
|
|
158
|
+
static getDerivedStateFromProps(
|
|
159
|
+
nextProps: Props,
|
|
160
|
+
prevState: State
|
|
161
|
+
): $Shape<State> | null {
|
|
158
162
|
let newLayoutBase;
|
|
159
163
|
|
|
160
164
|
if (prevState.activeDrag) {
|
|
@@ -197,7 +201,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
197
201
|
return null;
|
|
198
202
|
}
|
|
199
203
|
|
|
200
|
-
shouldComponentUpdate(nextProps: Props, nextState: State) {
|
|
204
|
+
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
|
201
205
|
return (
|
|
202
206
|
// NOTE: this is almost always unequal. Therefore the only way to get better performance
|
|
203
207
|
// from SCU is if the user intentionally memoizes children. If they do, and they can
|
|
@@ -223,7 +227,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
223
227
|
* Calculates a pixel value for the container.
|
|
224
228
|
* @return {String} Container height in pixels.
|
|
225
229
|
*/
|
|
226
|
-
containerHeight() {
|
|
230
|
+
containerHeight(): ?string {
|
|
227
231
|
if (!this.props.autoSize) return;
|
|
228
232
|
const nbRow = bottom(this.state.layout);
|
|
229
233
|
const containerPaddingY = this.props.containerPadding
|
|
@@ -245,9 +249,14 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
245
249
|
* @param {Event} e The mousedown event
|
|
246
250
|
* @param {Element} node The current dragging DOM element
|
|
247
251
|
*/
|
|
248
|
-
onDragStart(
|
|
252
|
+
onDragStart(
|
|
253
|
+
i: string,
|
|
254
|
+
x: number,
|
|
255
|
+
y: number,
|
|
256
|
+
{ e, node }: GridDragEvent
|
|
257
|
+
): void {
|
|
249
258
|
const { layout } = this.state;
|
|
250
|
-
|
|
259
|
+
const l = getLayoutItem(layout, i);
|
|
251
260
|
if (!l) return;
|
|
252
261
|
|
|
253
262
|
this.setState({
|
|
@@ -266,15 +275,15 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
266
275
|
* @param {Event} e The mousedown event
|
|
267
276
|
* @param {Element} node The current dragging DOM element
|
|
268
277
|
*/
|
|
269
|
-
onDrag(i: string, x: number, y: number, { e, node }: GridDragEvent) {
|
|
278
|
+
onDrag(i: string, x: number, y: number, { e, node }: GridDragEvent): void {
|
|
270
279
|
const { oldDragItem } = this.state;
|
|
271
280
|
let { layout } = this.state;
|
|
272
281
|
const { cols } = this.props;
|
|
273
|
-
|
|
282
|
+
const l = getLayoutItem(layout, i);
|
|
274
283
|
if (!l) return;
|
|
275
284
|
|
|
276
285
|
// Create placeholder (display only)
|
|
277
|
-
|
|
286
|
+
const placeholder = {
|
|
278
287
|
w: l.w,
|
|
279
288
|
h: l.h,
|
|
280
289
|
x: l.x,
|
|
@@ -312,7 +321,12 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
312
321
|
* @param {Event} e The mousedown event
|
|
313
322
|
* @param {Element} node The current dragging DOM element
|
|
314
323
|
*/
|
|
315
|
-
onDragStop(
|
|
324
|
+
onDragStop(
|
|
325
|
+
i: string,
|
|
326
|
+
x: number,
|
|
327
|
+
y: number,
|
|
328
|
+
{ e, node }: GridDragEvent
|
|
329
|
+
): void {
|
|
316
330
|
if (!this.state.activeDrag) return;
|
|
317
331
|
|
|
318
332
|
const { oldDragItem } = this.state;
|
|
@@ -359,7 +373,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
359
373
|
|
|
360
374
|
onResizeStart(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
361
375
|
const { layout } = this.state;
|
|
362
|
-
|
|
376
|
+
const l = getLayoutItem(layout, i);
|
|
363
377
|
if (!l) return;
|
|
364
378
|
|
|
365
379
|
this.setState({
|
|
@@ -373,41 +387,46 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
373
387
|
onResize(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
374
388
|
const { layout, oldResizeItem } = this.state;
|
|
375
389
|
const { cols, preventCollision } = this.props;
|
|
376
|
-
const l: ?LayoutItem = getLayoutItem(layout, i);
|
|
377
|
-
if (!l) return;
|
|
378
390
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
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
|
+
}
|
|
400
414
|
}
|
|
401
|
-
}
|
|
402
415
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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;
|
|
408
427
|
|
|
409
428
|
// Create placeholder element (display only)
|
|
410
|
-
|
|
429
|
+
const placeholder = {
|
|
411
430
|
w: l.w,
|
|
412
431
|
h: l.h,
|
|
413
432
|
x: l.x,
|
|
@@ -416,11 +435,11 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
416
435
|
i: i
|
|
417
436
|
};
|
|
418
437
|
|
|
419
|
-
this.props.onResize(
|
|
438
|
+
this.props.onResize(newLayout, oldResizeItem, l, placeholder, e, node);
|
|
420
439
|
|
|
421
|
-
// Re-compact the
|
|
440
|
+
// Re-compact the newLayout and set the drag placeholder.
|
|
422
441
|
this.setState({
|
|
423
|
-
layout: compact(
|
|
442
|
+
layout: compact(newLayout, compactType(this.props), cols),
|
|
424
443
|
activeDrag: placeholder
|
|
425
444
|
});
|
|
426
445
|
}
|
|
@@ -428,7 +447,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
428
447
|
onResizeStop(i: string, w: number, h: number, { e, node }: GridResizeEvent) {
|
|
429
448
|
const { layout, oldResizeItem } = this.state;
|
|
430
449
|
const { cols } = this.props;
|
|
431
|
-
|
|
450
|
+
const l = getLayoutItem(layout, i);
|
|
432
451
|
|
|
433
452
|
this.props.onResizeStop(layout, oldResizeItem, l, null, e, node);
|
|
434
453
|
|
|
@@ -515,7 +534,8 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
515
534
|
transformScale,
|
|
516
535
|
draggableCancel,
|
|
517
536
|
draggableHandle,
|
|
518
|
-
resizeHandles
|
|
537
|
+
resizeHandles,
|
|
538
|
+
resizeHandle
|
|
519
539
|
} = this.props;
|
|
520
540
|
const { mounted, droppingPosition } = this.state;
|
|
521
541
|
|
|
@@ -569,6 +589,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
569
589
|
static={l.static}
|
|
570
590
|
droppingPosition={isDroppingItem ? droppingPosition : undefined}
|
|
571
591
|
resizeHandles={resizeHandlesOptions}
|
|
592
|
+
resizeHandle={resizeHandle}
|
|
572
593
|
>
|
|
573
594
|
{child}
|
|
574
595
|
</GridItem>
|
|
@@ -577,14 +598,17 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
577
598
|
|
|
578
599
|
// Called while dragging an element. Part of browser native drag/drop API.
|
|
579
600
|
// Native event target might be the layout itself, or an element within the layout.
|
|
580
|
-
onDragOver =
|
|
601
|
+
onDragOver: DragOverEvent => void | false = e => {
|
|
581
602
|
// we should ignore events from layout's children in Firefox
|
|
582
603
|
// to avoid unpredictable jumping of a dropping placeholder
|
|
583
604
|
// FIXME remove this hack
|
|
584
605
|
if (
|
|
585
606
|
isFirefox &&
|
|
586
|
-
|
|
607
|
+
// $FlowIgnore can't figure this out
|
|
608
|
+
!e.nativeEvent.target?.classList.contains(layoutClassName)
|
|
587
609
|
) {
|
|
610
|
+
// without this Firefox will not allow drop if currently over droppingItem
|
|
611
|
+
e.preventDefault();
|
|
588
612
|
return false;
|
|
589
613
|
}
|
|
590
614
|
|
|
@@ -646,7 +670,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
646
670
|
e.preventDefault();
|
|
647
671
|
};
|
|
648
672
|
|
|
649
|
-
removeDroppingPlaceholder = () => {
|
|
673
|
+
removeDroppingPlaceholder: () => void = () => {
|
|
650
674
|
const { droppingItem, cols } = this.props;
|
|
651
675
|
const { layout } = this.state;
|
|
652
676
|
|
|
@@ -664,7 +688,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
664
688
|
});
|
|
665
689
|
};
|
|
666
690
|
|
|
667
|
-
onDragLeave = () => {
|
|
691
|
+
onDragLeave: () => void = () => {
|
|
668
692
|
this.dragEnterCounter--;
|
|
669
693
|
|
|
670
694
|
// onDragLeave can be triggered on each layout's child.
|
|
@@ -677,16 +701,16 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
677
701
|
}
|
|
678
702
|
};
|
|
679
703
|
|
|
680
|
-
onDragEnter = () => {
|
|
704
|
+
onDragEnter: () => void = () => {
|
|
681
705
|
this.dragEnterCounter++;
|
|
682
706
|
};
|
|
683
707
|
|
|
684
|
-
onDrop = (e: Event) => {
|
|
708
|
+
onDrop: EventHandler = (e: Event) => {
|
|
685
709
|
const { droppingItem } = this.props;
|
|
686
710
|
const { layout } = this.state;
|
|
687
711
|
const item = layout.find(l => l.i === droppingItem.i);
|
|
688
712
|
|
|
689
|
-
// reset
|
|
713
|
+
// reset dragEnter counter on drop
|
|
690
714
|
this.dragEnterCounter = 0;
|
|
691
715
|
|
|
692
716
|
this.removeDroppingPlaceholder();
|
|
@@ -694,7 +718,7 @@ export default class ReactGridLayout extends React.Component<Props, State> {
|
|
|
694
718
|
this.props.onDrop(layout, item, e);
|
|
695
719
|
};
|
|
696
720
|
|
|
697
|
-
render() {
|
|
721
|
+
render(): React.Element<"div"> {
|
|
698
722
|
const { className, style, isDroppable, innerRef } = this.props;
|
|
699
723
|
|
|
700
724
|
const mergedClassName = classNames(layoutClassName, className);
|
|
@@ -8,6 +8,30 @@ import type {
|
|
|
8
8
|
} from "react";
|
|
9
9
|
import type { EventCallback, CompactType, Layout, LayoutItem } from "./utils";
|
|
10
10
|
|
|
11
|
+
type ResizeHandleAxis = "s" | "w" | "e" | "n" | "sw" | "nw" | "se" | "ne";
|
|
12
|
+
export type ResizeHandles = Array<ResizeHandleAxis>;
|
|
13
|
+
export type ResizeHandle =
|
|
14
|
+
| ReactElement<any>
|
|
15
|
+
| ((resizeHandleAxis: ResizeHandleAxis) => ReactElement<any>);
|
|
16
|
+
|
|
17
|
+
// Defines which resize handles should be rendered (default: 'se')
|
|
18
|
+
// Allows for any combination of:
|
|
19
|
+
// 's' - South handle (bottom-center)
|
|
20
|
+
// 'w' - West handle (left-center)
|
|
21
|
+
// 'e' - East handle (right-center)
|
|
22
|
+
// 'n' - North handle (top-center)
|
|
23
|
+
// 'sw' - Southwest handle (bottom-left)
|
|
24
|
+
// 'nw' - Northwest handle (top-left)
|
|
25
|
+
// 'se' - Southeast handle (bottom-right)
|
|
26
|
+
// 'ne' - Northeast handle (top-right)
|
|
27
|
+
export const resizeHandlesType: ReactPropsChainableTypeChecker = PropTypes.arrayOf(
|
|
28
|
+
PropTypes.oneOf(["s", "w", "e", "n", "sw", "nw", "se", "ne"])
|
|
29
|
+
);
|
|
30
|
+
// Custom component for resize handles
|
|
31
|
+
export const resizeHandleType: ReactPropsChainableTypeChecker = PropTypes.oneOfType(
|
|
32
|
+
[PropTypes.node, PropTypes.func]
|
|
33
|
+
);
|
|
34
|
+
|
|
11
35
|
export type Props = {|
|
|
12
36
|
className: string,
|
|
13
37
|
style: Object,
|
|
@@ -31,7 +55,8 @@ export type Props = {|
|
|
|
31
55
|
useCSSTransforms: boolean,
|
|
32
56
|
transformScale: number,
|
|
33
57
|
droppingItem: $Shape<LayoutItem>,
|
|
34
|
-
resizeHandles:
|
|
58
|
+
resizeHandles: ResizeHandles,
|
|
59
|
+
resizeHandle?: ResizeHandle,
|
|
35
60
|
|
|
36
61
|
// Callbacks
|
|
37
62
|
onLayoutChange: Layout => void,
|
|
@@ -46,6 +71,14 @@ export type Props = {|
|
|
|
46
71
|
innerRef?: Ref<"div">
|
|
47
72
|
|};
|
|
48
73
|
|
|
74
|
+
export type DefaultProps = $Diff<
|
|
75
|
+
Props,
|
|
76
|
+
{
|
|
77
|
+
children: ReactChildrenArray<ReactElement<any>>,
|
|
78
|
+
width: number
|
|
79
|
+
}
|
|
80
|
+
>;
|
|
81
|
+
|
|
49
82
|
export default {
|
|
50
83
|
//
|
|
51
84
|
// Basic props
|
|
@@ -82,7 +115,10 @@ export default {
|
|
|
82
115
|
}
|
|
83
116
|
},
|
|
84
117
|
// Choose vertical or hotizontal compaction
|
|
85
|
-
compactType: PropTypes.oneOf([
|
|
118
|
+
compactType: (PropTypes.oneOf([
|
|
119
|
+
"vertical",
|
|
120
|
+
"horizontal"
|
|
121
|
+
]): ReactPropsChainableTypeChecker),
|
|
86
122
|
|
|
87
123
|
// layout is an array of object with the format:
|
|
88
124
|
// {x: Number, y: Number, w: Number, h: Number, i: String}
|
|
@@ -98,9 +134,11 @@ export default {
|
|
|
98
134
|
//
|
|
99
135
|
|
|
100
136
|
// Margin between items [x, y] in px
|
|
101
|
-
margin: PropTypes.arrayOf(PropTypes.number),
|
|
137
|
+
margin: (PropTypes.arrayOf(PropTypes.number): ReactPropsChainableTypeChecker),
|
|
102
138
|
// Padding inside the container [x, y] in px
|
|
103
|
-
containerPadding: PropTypes.arrayOf(
|
|
139
|
+
containerPadding: (PropTypes.arrayOf(
|
|
140
|
+
PropTypes.number
|
|
141
|
+
): ReactPropsChainableTypeChecker),
|
|
104
142
|
// Rows have a static height, but you can change this based on breakpoints if you like
|
|
105
143
|
rowHeight: PropTypes.number,
|
|
106
144
|
// Default Infinity, but you can specify a max here if you like.
|
|
@@ -124,19 +162,10 @@ export default {
|
|
|
124
162
|
transformScale: PropTypes.number,
|
|
125
163
|
// If true, an external element can trigger onDrop callback with a specific grid position as a parameter
|
|
126
164
|
isDroppable: PropTypes.bool,
|
|
127
|
-
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// 'e' - East handle (right-center)
|
|
132
|
-
// 'n' - North handle (top-center)
|
|
133
|
-
// 'sw' - Southwest handle (bottom-left)
|
|
134
|
-
// 'nw' - Northwest handle (top-left)
|
|
135
|
-
// 'se' - Southeast handle (bottom-right)
|
|
136
|
-
// 'ne' - Northeast handle (top-right)
|
|
137
|
-
resizeHandles: PropTypes.arrayOf(
|
|
138
|
-
PropTypes.oneOf(["s", "w", "e", "n", "sw", "nw", "se", "ne"])
|
|
139
|
-
),
|
|
165
|
+
|
|
166
|
+
// Resize handle options
|
|
167
|
+
resizeHandles: resizeHandlesType,
|
|
168
|
+
resizeHandle: resizeHandleType,
|
|
140
169
|
|
|
141
170
|
//
|
|
142
171
|
// Callbacks
|
|
@@ -165,11 +194,11 @@ export default {
|
|
|
165
194
|
// Other validations
|
|
166
195
|
//
|
|
167
196
|
|
|
168
|
-
droppingItem: PropTypes.shape({
|
|
197
|
+
droppingItem: (PropTypes.shape({
|
|
169
198
|
i: PropTypes.string.isRequired,
|
|
170
199
|
w: PropTypes.number.isRequired,
|
|
171
200
|
h: PropTypes.number.isRequired
|
|
172
|
-
}),
|
|
201
|
+
}): ReactPropsChainableTypeChecker),
|
|
173
202
|
|
|
174
203
|
// Children must not have duplicate keys.
|
|
175
204
|
children: function (props: Props, propName: string) {
|