react-grid-layout 1.3.4 → 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/lib/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @flow
2
- import isEqual from "lodash.isequal";
2
+ import { deepEqual } from "fast-equals";
3
3
  import React from "react";
4
4
  import type {
5
5
  ChildrenArray as ReactChildrenArray,
@@ -47,7 +47,12 @@ export type GridDragEvent = {
47
47
  node: HTMLElement,
48
48
  newPosition: PartialPosition
49
49
  };
50
- export type GridResizeEvent = { e: Event, node: HTMLElement, size: Size };
50
+ export type GridResizeEvent = {
51
+ e: Event,
52
+ node: HTMLElement,
53
+ size: Size,
54
+ handle: string
55
+ };
51
56
  export type DragOverEvent = MouseEvent & {
52
57
  nativeEvent: {
53
58
  layerX: number,
@@ -158,9 +163,15 @@ export function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {
158
163
  * This will catch differences in keys, order, and length.
159
164
  */
160
165
  export function childrenEqual(a: ReactChildren, b: ReactChildren): boolean {
161
- return isEqual(
162
- React.Children.map(a, c => c?.key),
163
- React.Children.map(b, c => c?.key)
166
+ return (
167
+ deepEqual(
168
+ React.Children.map(a, c => c?.key),
169
+ React.Children.map(b, c => c?.key)
170
+ ) &&
171
+ deepEqual(
172
+ React.Children.map(a, c => c?.props["data-grid"]),
173
+ React.Children.map(b, c => c?.props["data-grid"])
174
+ )
164
175
  );
165
176
  }
166
177
 
@@ -206,12 +217,14 @@ export function collides(l1: LayoutItem, l2: LayoutItem): boolean {
206
217
  * @param {Array} layout Layout.
207
218
  * @param {Boolean} verticalCompact Whether or not to compact the layout
208
219
  * vertically.
220
+ * @param {Boolean} allowOverlap When `true`, allows overlapping grid items.
209
221
  * @return {Array} Compacted Layout.
210
222
  */
211
223
  export function compact(
212
224
  layout: Layout,
213
225
  compactType: CompactType,
214
- cols: number
226
+ cols: number,
227
+ allowOverlap: ?boolean
215
228
  ): Layout {
216
229
  // Statics go in the compareWith array right away so items flow around them.
217
230
  const compareWith = getStatics(layout);
@@ -225,7 +238,7 @@ export function compact(
225
238
 
226
239
  // Don't move static elements
227
240
  if (!l.static) {
228
- l = compactItem(compareWith, l, compactType, cols, sorted);
241
+ l = compactItem(compareWith, l, compactType, cols, sorted, allowOverlap);
229
242
 
230
243
  // Add to comparison array. We only collide with items before this one.
231
244
  // Statics are already in this array.
@@ -294,7 +307,8 @@ export function compactItem(
294
307
  l: LayoutItem,
295
308
  compactType: CompactType,
296
309
  cols: number,
297
- fullLayout: Layout
310
+ fullLayout: Layout,
311
+ allowOverlap: ?boolean
298
312
  ): LayoutItem {
299
313
  const compactV = compactType === "vertical";
300
314
  const compactH = compactType === "horizontal";
@@ -316,7 +330,11 @@ export function compactItem(
316
330
 
317
331
  // Move it down, and keep moving it down if it's colliding.
318
332
  let collides;
319
- while ((collides = getFirstCollision(compareWith, l))) {
333
+ // Checking the compactType null value to avoid breaking the layout when overlapping is allowed.
334
+ while (
335
+ (collides = getFirstCollision(compareWith, l)) &&
336
+ !(compactType === null && allowOverlap)
337
+ ) {
320
338
  if (compactH) {
321
339
  resolveCompactionCollision(fullLayout, l, collides.x + collides.w, "x");
322
340
  } else {
@@ -326,6 +344,10 @@ export function compactItem(
326
344
  if (compactH && l.x + l.w > cols) {
327
345
  l.x = cols - l.w;
328
346
  l.y++;
347
+ // ALso move element as left as we can
348
+ while (l.x > 0 && !getFirstCollision(compareWith, l)) {
349
+ l.x--;
350
+ }
329
351
  }
330
352
  }
331
353
 
@@ -541,7 +563,7 @@ export function moveElementAwayFromCollision(
541
563
  ): Layout {
542
564
  const compactH = compactType === "horizontal";
543
565
  // Compact vertically if not set to horizontal
544
- const compactV = compactType !== "horizontal";
566
+ const compactV = compactType === "vertical";
545
567
  const preventCollision = collidesWith.static; // we're already colliding (not for static items)
546
568
 
547
569
  // If there is enough space above the collision to put this element, move it there.
@@ -560,8 +582,14 @@ export function moveElementAwayFromCollision(
560
582
  i: "-1"
561
583
  };
562
584
 
585
+ const firstCollision = getFirstCollision(layout, fakeItem);
586
+ const collisionNorth =
587
+ firstCollision && firstCollision.y + firstCollision.h > collidesWith.y;
588
+ const collisionWest =
589
+ firstCollision && collidesWith.x + collidesWith.w > firstCollision.x;
590
+
563
591
  // No collision? If so, we can go up there; otherwise, we'll end up moving down as normal
564
- if (!getFirstCollision(layout, fakeItem)) {
592
+ if (!firstCollision) {
565
593
  log(
566
594
  `Doing reverse collision on ${itemToMove.i} up to [${fakeItem.x},${fakeItem.y}].`
567
595
  );
@@ -575,9 +603,42 @@ export function moveElementAwayFromCollision(
575
603
  compactType,
576
604
  cols
577
605
  );
606
+ } else if (collisionNorth && compactV) {
607
+ return moveElement(
608
+ layout,
609
+ itemToMove,
610
+ undefined,
611
+ collidesWith.y + 1,
612
+ isUserAction,
613
+ preventCollision,
614
+ compactType,
615
+ cols
616
+ );
617
+ } else if (collisionNorth && compactType == null) {
618
+ collidesWith.y = itemToMove.y;
619
+ itemToMove.y = itemToMove.y + itemToMove.h;
620
+
621
+ return layout;
622
+ } else if (collisionWest && compactH) {
623
+ return moveElement(
624
+ layout,
625
+ collidesWith,
626
+ itemToMove.x,
627
+ undefined,
628
+ isUserAction,
629
+ preventCollision,
630
+ compactType,
631
+ cols
632
+ );
578
633
  }
579
634
  }
580
635
 
636
+ const newX = compactH ? itemToMove.x + 1 : undefined;
637
+ const newY = compactV ? itemToMove.y + 1 : undefined;
638
+
639
+ if (newX == null && newY == null) {
640
+ return layout;
641
+ }
581
642
  return moveElement(
582
643
  layout,
583
644
  itemToMove,
@@ -698,19 +759,13 @@ export function synchronizeLayoutWithChildren(
698
759
  // Child may not exist
699
760
  if (child?.key == null) return;
700
761
 
701
- // Don't overwrite if it already exists.
702
762
  const exists = getLayoutItem(initialLayout, String(child.key));
703
- if (exists) {
763
+ const g = child.props["data-grid"];
764
+ // Don't overwrite the layout item if it's already in the initial layout.
765
+ // If it has a `data-grid` property, prefer that over what's in the layout.
766
+ if (exists && g == null) {
704
767
  layout.push(cloneLayoutItem(exists));
705
768
  } else {
706
- if (!isProduction && child.props._grid) {
707
- console.warn(
708
- "`_grid` properties on children have been deprecated as of React 15.2. " +
709
- "Please use `data-grid` or add your properties directly to the `layout`."
710
- );
711
- }
712
- const g = child.props["data-grid"] || child.props._grid;
713
-
714
769
  // Hey, this item has a data-grid property, use it.
715
770
  if (g) {
716
771
  if (!isProduction) {
package/margin.png ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-grid-layout",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "A draggable and resizable grid layout with responsive breakpoints, for React.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -37,54 +37,56 @@
37
37
  },
38
38
  "homepage": "https://github.com/STRML/react-grid-layout",
39
39
  "dependencies": {
40
- "clsx": "^1.1.1",
41
- "lodash.isequal": "^4.0.0",
40
+ "clsx": "^2.0.0",
41
+ "fast-equals": "^5.0.1",
42
42
  "prop-types": "^15.8.1",
43
- "react-draggable": "^4.0.0",
44
- "react-resizable": "^3.0.4"
43
+ "react-draggable": "^4.4.5",
44
+ "react-resizable": "^3.0.5",
45
+ "resize-observer-polyfill": "^1.5.1"
45
46
  },
46
47
  "devDependencies": {
47
- "@babel/cli": "^7.17.3",
48
- "@babel/core": "^7.17.5",
49
- "@babel/eslint-parser": "^7.17.0",
50
- "@babel/plugin-proposal-class-properties": "^7.16.7",
51
- "@babel/plugin-transform-flow-comments": "^7.16.7",
52
- "@babel/preset-env": "^7.16.11",
53
- "@babel/preset-flow": "^7.16.7",
54
- "@babel/preset-react": "^7.16.7",
55
- "@babel/register": "^7.17.0",
56
- "@webpack-cli/serve": "^1.6.1",
57
- "babel-jest": "^27.5.1",
58
- "babel-loader": "^8.2.2",
48
+ "@babel/cli": "^7.22.15",
49
+ "@babel/core": "^7.22.17",
50
+ "@babel/eslint-parser": "^7.22.15",
51
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
52
+ "@babel/plugin-transform-flow-comments": "^7.22.10",
53
+ "@babel/preset-env": "^7.22.15",
54
+ "@babel/preset-flow": "^7.22.15",
55
+ "@babel/preset-react": "^7.22.15",
56
+ "@babel/register": "^7.22.15",
57
+ "@webpack-cli/serve": "^2.0.5",
58
+ "babel-jest": "^29.6.4",
59
+ "babel-loader": "^9.1.3",
59
60
  "babel-plugin-preval": "^5.1.0",
60
- "css-loader": "^6.6.0",
61
- "ejs": "^3.1.6",
61
+ "css-loader": "^6.8.1",
62
+ "ejs": "^3.1.9",
62
63
  "enzyme": "^3.11.0",
63
- "enzyme-adapter-react-16": "^1.15.6",
64
+ "enzyme-adapter-react-16": "^1.15.7",
64
65
  "enzyme-to-json": "^3.6.2",
65
- "eslint": "^8.9.0",
66
+ "eslint": "^8.49.0",
66
67
  "eslint-plugin-flowtype": "^8.0.3",
67
- "eslint-plugin-mocha": "^10.0.3",
68
- "eslint-plugin-react": "^7.28.0",
69
- "eslint-plugin-unicorn": "^41.0.0",
70
- "exports-loader": "^3.0.0",
68
+ "eslint-plugin-mocha": "^10.1.0",
69
+ "eslint-plugin-react": "^7.33.2",
70
+ "eslint-plugin-unicorn": "^48.0.1",
71
+ "exports-loader": "^4.0.0",
71
72
  "flow-bin": "^0.172.0",
72
- "husky": "^7.0.2",
73
- "imports-loader": "^3.0.0",
74
- "jest": "^27.5.1",
75
- "lint-staged": "^12.3.4",
73
+ "husky": "^8.0.3",
74
+ "imports-loader": "^4.0.1",
75
+ "jest": "^29.6.4",
76
+ "jest-environment-jsdom": "^29.6.4",
77
+ "lint-staged": "^14.0.1",
76
78
  "lodash": "^4.17.21",
77
79
  "opener": "^1.5.2",
78
- "prettier": "^2.3.2",
80
+ "prettier": "^3.0.3",
79
81
  "react": "^16.13.1",
80
82
  "react-dom": "^16.13.1",
81
- "react-hot-loader": "^4.13.0",
83
+ "react-hot-loader": "^4.13.1",
82
84
  "react-transform-hmr": "^1.0.2",
83
- "style-loader": "^3.2.1",
85
+ "style-loader": "^3.3.3",
84
86
  "timsort": "^0.3.0",
85
- "webpack": "^5.69.1",
86
- "webpack-cli": "^4.9.2",
87
- "webpack-dev-server": "^4.7.4"
87
+ "webpack": "^5.88.2",
88
+ "webpack-cli": "^5.1.4",
89
+ "webpack-dev-server": "^4.15.1"
88
90
  },
89
91
  "peerDependencies": {
90
92
  "react": ">= 16.3.0",
@@ -104,7 +106,9 @@
104
106
  "<rootDir>/test/spec/*.js"
105
107
  ],
106
108
  "testEnvironment": "jsdom",
107
- "testURL": "http://localhost",
109
+ "testEnvironmentOptions": {
110
+ "url": "http://localhost"
111
+ },
108
112
  "coverageThreshold": {
109
113
  "global": {
110
114
  "statements": 77,