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.
@@ -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
- fastRGLPropsEqual
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
- var l = getLayoutItem(layout, i);
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
- var l = getLayoutItem(layout, i);
282
+ const l = getLayoutItem(layout, i);
282
283
  if (!l) return;
283
284
 
284
285
  // Create placeholder (display only)
285
- var placeholder = {
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
- var l = getLayoutItem(layout, i);
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
- const originalLayoutItem: ?LayoutItem = getLayoutItem(layout, i);
390
- if (!originalLayoutItem) return;
391
-
392
- // We're going to modify this object now, so clone it first.
393
- const l = cloneLayoutItem(originalLayoutItem);
394
-
395
- // Something like quad tree should be used
396
- // to find collisions faster
397
- let hasCollisions;
398
- if (preventCollision) {
399
- const collisions = getAllCollisions(layout, { ...l, w, h }).filter(
400
- layoutItem => layoutItem.i !== l.i
401
- );
402
- hasCollisions = collisions.length > 0;
403
-
404
- // If we're colliding, we need adjust the placeholder.
405
- if (hasCollisions) {
406
- // adjust w && h to maximum allowed space
407
- let leastX = Infinity,
408
- leastY = Infinity;
409
- collisions.forEach(layoutItem => {
410
- if (layoutItem.x > l.x) leastX = Math.min(leastX, layoutItem.x);
411
- if (layoutItem.y > l.y) leastY = Math.min(leastY, layoutItem.y);
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
- if (!hasCollisions) {
420
- // Set new width and height.
421
- l.w = w;
422
- l.h = h;
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
- var placeholder = {
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(layout, oldResizeItem, l, placeholder, e, node);
438
+ this.props.onResize(newLayout, oldResizeItem, l, placeholder, e, node);
436
439
 
437
- // Re-compact the layout and set the drag placeholder.
440
+ // Re-compact the newLayout and set the drag placeholder.
438
441
  this.setState({
439
- layout: compact(layout, compactType(this.props), cols),
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
- var l = getLayoutItem(layout, i);
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-grid-layout",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "A draggable and resizable grid layout with responsive breakpoints, for React.",
5
5
  "main": "index.js",
6
6
  "scripts": {