react-grid-layout 0.16.4 → 0.17.1
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/.babelrc.js +25 -0
- package/.browserslistrc +3 -0
- package/.flowconfig +1 -1
- package/.prettierignore +2 -0
- package/.prettierrc +18 -0
- package/.travis.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +99 -52
- package/build/GridItem.js +596 -414
- package/build/ReactGridLayout.js +648 -423
- package/build/ResponsiveReactGridLayout.js +270 -151
- package/build/components/WidthProvider.js +96 -53
- package/build/responsiveUtils.js +56 -12
- package/build/utils.js +376 -183
- package/css/styles.css +4 -0
- package/index.js +5 -5
- package/index.js.flow +5 -7
- package/interfaces/classnames.js +1 -0
- package/{build/GridItem.js.flow → lib/GridItem.jsx} +230 -96
- package/{build/ReactGridLayout.js.flow → lib/ReactGridLayout.jsx} +220 -35
- package/{build/ResponsiveReactGridLayout.js.flow → lib/ResponsiveReactGridLayout.jsx} +73 -20
- package/{build/components/WidthProvider.js.flow → lib/components/WidthProvider.jsx} +1 -1
- package/{build/responsiveUtils.js.flow → lib/responsiveUtils.js} +0 -0
- package/{build/utils.js.flow → lib/utils.js} +49 -37
- package/package.json +37 -43
- package/.babelrc +0 -12
- package/.jshintignore +0 -1
- package/.jshintrc +0 -10
package/build/utils.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
exports
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
7
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
8
6
|
exports.bottom = bottom;
|
|
9
7
|
exports.cloneLayout = cloneLayout;
|
|
10
8
|
exports.cloneLayoutItem = cloneLayoutItem;
|
|
@@ -28,47 +26,65 @@ exports.sortLayoutItemsByColRow = sortLayoutItemsByColRow;
|
|
|
28
26
|
exports.synchronizeLayoutWithChildren = synchronizeLayoutWithChildren;
|
|
29
27
|
exports.validateLayout = validateLayout;
|
|
30
28
|
exports.autoBindHandlers = autoBindHandlers;
|
|
29
|
+
exports.noop = void 0;
|
|
31
30
|
|
|
32
|
-
var _lodash = require("lodash.isequal");
|
|
31
|
+
var _lodash = _interopRequireDefault(require("lodash.isequal"));
|
|
33
32
|
|
|
34
|
-
var
|
|
33
|
+
var _react = _interopRequireDefault(require("react"));
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
37
36
|
|
|
38
|
-
var
|
|
37
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
39
38
|
|
|
40
|
-
function
|
|
39
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
40
|
+
|
|
41
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
41
42
|
|
|
42
|
-
// All callbacks are of the signature (layout, oldItem, newItem, placeholder, e).
|
|
43
43
|
var isProduction = process.env.NODE_ENV === "production";
|
|
44
44
|
var DEBUG = false;
|
|
45
|
-
|
|
46
45
|
/**
|
|
47
46
|
* Return the bottom coordinate of the layout.
|
|
48
47
|
*
|
|
49
48
|
* @param {Array} layout Layout array.
|
|
50
49
|
* @return {Number} Bottom coordinate.
|
|
51
50
|
*/
|
|
52
|
-
|
|
51
|
+
|
|
52
|
+
function bottom(layout
|
|
53
|
+
/*: Layout*/
|
|
54
|
+
)
|
|
55
|
+
/*: number*/
|
|
56
|
+
{
|
|
53
57
|
var max = 0,
|
|
54
|
-
bottomY
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
bottomY;
|
|
59
|
+
|
|
60
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
61
|
+
bottomY = layout[i].y + layout[i].h;
|
|
57
62
|
if (bottomY > max) max = bottomY;
|
|
58
63
|
}
|
|
64
|
+
|
|
59
65
|
return max;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
function cloneLayout(layout
|
|
68
|
+
function cloneLayout(layout
|
|
69
|
+
/*: Layout*/
|
|
70
|
+
)
|
|
71
|
+
/*: Layout*/
|
|
72
|
+
{
|
|
63
73
|
var newLayout = Array(layout.length);
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
|
|
75
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
76
|
+
newLayout[i] = cloneLayoutItem(layout[i]);
|
|
66
77
|
}
|
|
78
|
+
|
|
67
79
|
return newLayout;
|
|
68
|
-
}
|
|
80
|
+
} // Fast path to cloning, since this is monomorphic
|
|
69
81
|
|
|
70
|
-
|
|
71
|
-
function cloneLayoutItem(layoutItem
|
|
82
|
+
|
|
83
|
+
function cloneLayoutItem(layoutItem
|
|
84
|
+
/*: LayoutItem*/
|
|
85
|
+
)
|
|
86
|
+
/*: LayoutItem*/
|
|
87
|
+
{
|
|
72
88
|
return {
|
|
73
89
|
w: layoutItem.w,
|
|
74
90
|
h: layoutItem.h,
|
|
@@ -86,31 +102,49 @@ function cloneLayoutItem(layoutItem) {
|
|
|
86
102
|
isResizable: layoutItem.isResizable
|
|
87
103
|
};
|
|
88
104
|
}
|
|
89
|
-
|
|
90
105
|
/**
|
|
91
106
|
* Comparing React `children` is a bit difficult. This is a good way to compare them.
|
|
92
107
|
* This will catch differences in keys, order, and length.
|
|
93
108
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
function childrenEqual(a
|
|
112
|
+
/*: ReactChildren*/
|
|
113
|
+
, b
|
|
114
|
+
/*: ReactChildren*/
|
|
115
|
+
)
|
|
116
|
+
/*: boolean*/
|
|
117
|
+
{
|
|
118
|
+
return (0, _lodash.default)(_react.default.Children.map(a, function (c) {
|
|
96
119
|
return c.key;
|
|
97
|
-
}),
|
|
120
|
+
}), _react.default.Children.map(b, function (c) {
|
|
98
121
|
return c.key;
|
|
99
122
|
}));
|
|
100
123
|
}
|
|
101
|
-
|
|
102
124
|
/**
|
|
103
125
|
* Given two layoutitems, check if they collide.
|
|
104
126
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
function collides(l1
|
|
130
|
+
/*: LayoutItem*/
|
|
131
|
+
, l2
|
|
132
|
+
/*: LayoutItem*/
|
|
133
|
+
)
|
|
134
|
+
/*: boolean*/
|
|
135
|
+
{
|
|
136
|
+
if (l1.i === l2.i) return false; // same element
|
|
137
|
+
|
|
107
138
|
if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2
|
|
139
|
+
|
|
108
140
|
if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2
|
|
141
|
+
|
|
109
142
|
if (l1.y + l1.h <= l2.y) return false; // l1 is above l2
|
|
143
|
+
|
|
110
144
|
if (l1.y >= l2.y + l2.h) return false; // l1 is below l2
|
|
145
|
+
|
|
111
146
|
return true; // boxes overlap
|
|
112
147
|
}
|
|
113
|
-
|
|
114
148
|
/**
|
|
115
149
|
* Given a layout, compact it. This involves going down each y coordinate and removing gaps
|
|
116
150
|
* between items.
|
|
@@ -120,51 +154,73 @@ function collides(l1, l2) {
|
|
|
120
154
|
* vertically.
|
|
121
155
|
* @return {Array} Compacted Layout.
|
|
122
156
|
*/
|
|
123
|
-
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
function compact(layout
|
|
160
|
+
/*: Layout*/
|
|
161
|
+
, compactType
|
|
162
|
+
/*: CompactType*/
|
|
163
|
+
, cols
|
|
164
|
+
/*: number*/
|
|
165
|
+
)
|
|
166
|
+
/*: Layout*/
|
|
167
|
+
{
|
|
124
168
|
// Statics go in the compareWith array right away so items flow around them.
|
|
125
|
-
var compareWith = getStatics(layout);
|
|
126
|
-
|
|
127
|
-
var sorted = sortLayoutItems(layout, compactType);
|
|
128
|
-
|
|
169
|
+
var compareWith = getStatics(layout); // We go through the items by row and column.
|
|
170
|
+
|
|
171
|
+
var sorted = sortLayoutItems(layout, compactType); // Holding for new items.
|
|
172
|
+
|
|
129
173
|
var out = Array(layout.length);
|
|
130
174
|
|
|
131
|
-
for (var
|
|
132
|
-
var l = cloneLayoutItem(sorted[
|
|
175
|
+
for (var i = 0, len = sorted.length; i < len; i++) {
|
|
176
|
+
var l = cloneLayoutItem(sorted[i]); // Don't move static elements
|
|
133
177
|
|
|
134
|
-
// Don't move static elements
|
|
135
178
|
if (!l.static) {
|
|
136
|
-
l = compactItem(compareWith, l, compactType, cols, sorted);
|
|
137
|
-
|
|
138
|
-
// Add to comparison array. We only collide with items before this one.
|
|
179
|
+
l = compactItem(compareWith, l, compactType, cols, sorted); // Add to comparison array. We only collide with items before this one.
|
|
139
180
|
// Statics are already in this array.
|
|
181
|
+
|
|
140
182
|
compareWith.push(l);
|
|
141
|
-
}
|
|
183
|
+
} // Add to output array to make sure they still come out in the right order.
|
|
184
|
+
|
|
142
185
|
|
|
143
|
-
|
|
144
|
-
out[layout.indexOf(sorted[_i3])] = l;
|
|
186
|
+
out[layout.indexOf(sorted[i])] = l; // Clear moved flag, if it exists.
|
|
145
187
|
|
|
146
|
-
// Clear moved flag, if it exists.
|
|
147
188
|
l.moved = false;
|
|
148
189
|
}
|
|
149
190
|
|
|
150
191
|
return out;
|
|
151
192
|
}
|
|
152
193
|
|
|
153
|
-
var heightWidth = {
|
|
194
|
+
var heightWidth = {
|
|
195
|
+
x: "w",
|
|
196
|
+
y: "h"
|
|
197
|
+
};
|
|
154
198
|
/**
|
|
155
199
|
* Before moving item down, it will check if the movement will cause collisions and move those items down before.
|
|
156
200
|
*/
|
|
157
|
-
|
|
201
|
+
|
|
202
|
+
function resolveCompactionCollision(layout
|
|
203
|
+
/*: Layout*/
|
|
204
|
+
, item
|
|
205
|
+
/*: LayoutItem*/
|
|
206
|
+
, moveToCoord
|
|
207
|
+
/*: number*/
|
|
208
|
+
, axis
|
|
209
|
+
/*: "x" | "y"*/
|
|
210
|
+
) {
|
|
158
211
|
var sizeProp = heightWidth[axis];
|
|
159
212
|
item[axis] += 1;
|
|
160
|
-
var itemIndex = layout.
|
|
213
|
+
var itemIndex = layout.map(function (layoutItem) {
|
|
214
|
+
return layoutItem.i;
|
|
215
|
+
}).indexOf(item.i); // Go through each item we collide with.
|
|
216
|
+
|
|
217
|
+
for (var i = itemIndex + 1; i < layout.length; i++) {
|
|
218
|
+
var otherItem = layout[i]; // Ignore static items
|
|
161
219
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
var otherItem = layout[_i4];
|
|
220
|
+
if (otherItem.static) continue; // Optimization: we can break early if we know we're past this el
|
|
221
|
+
// We can do this b/c it's a sorted layout
|
|
165
222
|
|
|
166
|
-
|
|
167
|
-
if (otherItem.static) continue;
|
|
223
|
+
if (otherItem.y > item.y + item.h) break;
|
|
168
224
|
|
|
169
225
|
if (collides(item, otherItem)) {
|
|
170
226
|
resolveCompactionCollision(layout, otherItem, moveToCoord + item[sizeProp], axis);
|
|
@@ -173,64 +229,90 @@ function resolveCompactionCollision(layout, item, moveToCoord, axis) {
|
|
|
173
229
|
|
|
174
230
|
item[axis] = moveToCoord;
|
|
175
231
|
}
|
|
176
|
-
|
|
177
232
|
/**
|
|
178
233
|
* Compact an item in the layout.
|
|
179
234
|
*/
|
|
180
|
-
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
function compactItem(compareWith
|
|
238
|
+
/*: Layout*/
|
|
239
|
+
, l
|
|
240
|
+
/*: LayoutItem*/
|
|
241
|
+
, compactType
|
|
242
|
+
/*: CompactType*/
|
|
243
|
+
, cols
|
|
244
|
+
/*: number*/
|
|
245
|
+
, fullLayout
|
|
246
|
+
/*: Layout*/
|
|
247
|
+
)
|
|
248
|
+
/*: LayoutItem*/
|
|
249
|
+
{
|
|
181
250
|
var compactV = compactType === "vertical";
|
|
182
251
|
var compactH = compactType === "horizontal";
|
|
252
|
+
|
|
183
253
|
if (compactV) {
|
|
184
254
|
// Bottom 'y' possible is the bottom of the layout.
|
|
185
255
|
// This allows you to do nice stuff like specify {y: Infinity}
|
|
186
256
|
// This is here because the layout must be sorted in order to get the correct bottom `y`.
|
|
187
|
-
l.y = Math.min(bottom(compareWith), l.y);
|
|
188
|
-
|
|
257
|
+
l.y = Math.min(bottom(compareWith), l.y); // Move the element up as far as it can go without colliding.
|
|
258
|
+
|
|
189
259
|
while (l.y > 0 && !getFirstCollision(compareWith, l)) {
|
|
190
260
|
l.y--;
|
|
191
261
|
}
|
|
192
262
|
} else if (compactH) {
|
|
193
|
-
l.y = Math.min(bottom(compareWith), l.y);
|
|
194
|
-
|
|
263
|
+
l.y = Math.min(bottom(compareWith), l.y); // Move the element left as far as it can go without colliding.
|
|
264
|
+
|
|
195
265
|
while (l.x > 0 && !getFirstCollision(compareWith, l)) {
|
|
196
266
|
l.x--;
|
|
197
267
|
}
|
|
198
|
-
}
|
|
268
|
+
} // Move it down, and keep moving it down if it's colliding.
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
var collides;
|
|
199
272
|
|
|
200
|
-
// Move it down, and keep moving it down if it's colliding.
|
|
201
|
-
var collides = void 0;
|
|
202
273
|
while (collides = getFirstCollision(compareWith, l)) {
|
|
203
274
|
if (compactH) {
|
|
204
275
|
resolveCompactionCollision(fullLayout, l, collides.x + collides.w, "x");
|
|
205
276
|
} else {
|
|
206
277
|
resolveCompactionCollision(fullLayout, l, collides.y + collides.h, "y");
|
|
207
|
-
}
|
|
208
|
-
|
|
278
|
+
} // Since we can't grow without bounds horizontally, if we've overflown, let's move it down and try again.
|
|
279
|
+
|
|
280
|
+
|
|
209
281
|
if (compactH && l.x + l.w > cols) {
|
|
210
282
|
l.x = cols - l.w;
|
|
211
283
|
l.y++;
|
|
212
284
|
}
|
|
213
285
|
}
|
|
286
|
+
|
|
214
287
|
return l;
|
|
215
288
|
}
|
|
216
|
-
|
|
217
289
|
/**
|
|
218
290
|
* Given a layout, make sure all elements fit within its bounds.
|
|
219
291
|
*
|
|
220
292
|
* @param {Array} layout Layout array.
|
|
221
293
|
* @param {Number} bounds Number of columns.
|
|
222
294
|
*/
|
|
223
|
-
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
function correctBounds(layout
|
|
298
|
+
/*: Layout*/
|
|
299
|
+
, bounds
|
|
300
|
+
/*: { cols: number }*/
|
|
301
|
+
)
|
|
302
|
+
/*: Layout*/
|
|
303
|
+
{
|
|
224
304
|
var collidesWith = getStatics(layout);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
// Overflows right
|
|
228
|
-
|
|
229
|
-
// Overflows left
|
|
305
|
+
|
|
306
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
307
|
+
var l = layout[i]; // Overflows right
|
|
308
|
+
|
|
309
|
+
if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w; // Overflows left
|
|
310
|
+
|
|
230
311
|
if (l.x < 0) {
|
|
231
312
|
l.x = 0;
|
|
232
313
|
l.w = bounds.cols;
|
|
233
314
|
}
|
|
315
|
+
|
|
234
316
|
if (!l.static) collidesWith.push(l);else {
|
|
235
317
|
// If this is static and collides with other statics, we must move it down.
|
|
236
318
|
// We have to do something nicer than just letting them overlap.
|
|
@@ -239,9 +321,9 @@ function correctBounds(layout, bounds) {
|
|
|
239
321
|
}
|
|
240
322
|
}
|
|
241
323
|
}
|
|
324
|
+
|
|
242
325
|
return layout;
|
|
243
326
|
}
|
|
244
|
-
|
|
245
327
|
/**
|
|
246
328
|
* Get a layout item by ID. Used so we can override later on if necessary.
|
|
247
329
|
*
|
|
@@ -249,12 +331,19 @@ function correctBounds(layout, bounds) {
|
|
|
249
331
|
* @param {String} id ID
|
|
250
332
|
* @return {LayoutItem} Item at ID.
|
|
251
333
|
*/
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
function getLayoutItem(layout
|
|
337
|
+
/*: Layout*/
|
|
338
|
+
, id
|
|
339
|
+
/*: string*/
|
|
340
|
+
)
|
|
341
|
+
/*: ?LayoutItem*/
|
|
342
|
+
{
|
|
343
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
344
|
+
if (layout[i].i === id) return layout[i];
|
|
255
345
|
}
|
|
256
346
|
}
|
|
257
|
-
|
|
258
347
|
/**
|
|
259
348
|
* Returns the first item this layout collides with.
|
|
260
349
|
* It doesn't appear to matter which order we approach this from, although
|
|
@@ -263,29 +352,47 @@ function getLayoutItem(layout, id) {
|
|
|
263
352
|
* @param {Object} layoutItem Layout item.
|
|
264
353
|
* @return {Object|undefined} A colliding layout item, or undefined.
|
|
265
354
|
*/
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
function getFirstCollision(layout
|
|
358
|
+
/*: Layout*/
|
|
359
|
+
, layoutItem
|
|
360
|
+
/*: LayoutItem*/
|
|
361
|
+
)
|
|
362
|
+
/*: ?LayoutItem*/
|
|
363
|
+
{
|
|
364
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
365
|
+
if (collides(layout[i], layoutItem)) return layout[i];
|
|
269
366
|
}
|
|
270
367
|
}
|
|
271
368
|
|
|
272
|
-
function getAllCollisions(layout
|
|
369
|
+
function getAllCollisions(layout
|
|
370
|
+
/*: Layout*/
|
|
371
|
+
, layoutItem
|
|
372
|
+
/*: LayoutItem*/
|
|
373
|
+
)
|
|
374
|
+
/*: Array<LayoutItem>*/
|
|
375
|
+
{
|
|
273
376
|
return layout.filter(function (l) {
|
|
274
377
|
return collides(l, layoutItem);
|
|
275
378
|
});
|
|
276
379
|
}
|
|
277
|
-
|
|
278
380
|
/**
|
|
279
381
|
* Get all static elements.
|
|
280
382
|
* @param {Array} layout Array of layout objects.
|
|
281
383
|
* @return {Array} Array of static layout items..
|
|
282
384
|
*/
|
|
283
|
-
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
function getStatics(layout
|
|
388
|
+
/*: Layout*/
|
|
389
|
+
)
|
|
390
|
+
/*: Array<LayoutItem>*/
|
|
391
|
+
{
|
|
284
392
|
return layout.filter(function (l) {
|
|
285
393
|
return l.static;
|
|
286
394
|
});
|
|
287
395
|
}
|
|
288
|
-
|
|
289
396
|
/**
|
|
290
397
|
* Move an element. Responsible for doing cascading movements of other elements.
|
|
291
398
|
*
|
|
@@ -294,48 +401,61 @@ function getStatics(layout) {
|
|
|
294
401
|
* @param {Number} [x] X position in grid units.
|
|
295
402
|
* @param {Number} [y] Y position in grid units.
|
|
296
403
|
*/
|
|
297
|
-
function moveElement(layout, l, x, y, isUserAction, preventCollision, compactType, cols) {
|
|
298
|
-
if (l.static) return layout;
|
|
299
|
-
log("Moving element " + l.i + " to [" + x + "," + y + "] from [" + l.x + "," + l.y + "]");
|
|
300
404
|
|
|
301
|
-
// Short-circuit if nothing to do.
|
|
302
|
-
if (l.y === y && l.x === x) return layout;
|
|
303
405
|
|
|
304
|
-
|
|
305
|
-
|
|
406
|
+
function moveElement(layout
|
|
407
|
+
/*: Layout*/
|
|
408
|
+
, l
|
|
409
|
+
/*: LayoutItem*/
|
|
410
|
+
, x
|
|
411
|
+
/*: ?number*/
|
|
412
|
+
, y
|
|
413
|
+
/*: ?number*/
|
|
414
|
+
, isUserAction
|
|
415
|
+
/*: ?boolean*/
|
|
416
|
+
, preventCollision
|
|
417
|
+
/*: ?boolean*/
|
|
418
|
+
, compactType
|
|
419
|
+
/*: CompactType*/
|
|
420
|
+
, cols
|
|
421
|
+
/*: number*/
|
|
422
|
+
)
|
|
423
|
+
/*: Layout*/
|
|
424
|
+
{
|
|
425
|
+
if (l.static) return layout; // Short-circuit if nothing to do.
|
|
306
426
|
|
|
307
|
-
|
|
308
|
-
l.x
|
|
309
|
-
|
|
310
|
-
l.
|
|
427
|
+
if (l.y === y && l.x === x) return layout;
|
|
428
|
+
log("Moving element ".concat(l.i, " to [").concat(String(x), ",").concat(String(y), "] from [").concat(l.x, ",").concat(l.y, "]"));
|
|
429
|
+
var oldX = l.x;
|
|
430
|
+
var oldY = l.y; // This is quite a bit faster than extending the object
|
|
311
431
|
|
|
312
|
-
|
|
432
|
+
if (typeof x === "number") l.x = x;
|
|
433
|
+
if (typeof y === "number") l.y = y;
|
|
434
|
+
l.moved = true; // If this collides with anything, move it.
|
|
313
435
|
// When doing this comparison, we have to sort the items we compare with
|
|
314
436
|
// to ensure, in the case of multiple collisions, that we're getting the
|
|
315
437
|
// nearest collision.
|
|
438
|
+
|
|
316
439
|
var sorted = sortLayoutItems(layout, compactType);
|
|
317
|
-
var movingUp = compactType === "vertical" ? oldY >= y : compactType === "horizontal" ? oldX >= x : false;
|
|
440
|
+
var movingUp = compactType === "vertical" && typeof y === "number" ? oldY >= y : compactType === "horizontal" && typeof x === "number" ? oldX >= x : false;
|
|
318
441
|
if (movingUp) sorted = sorted.reverse();
|
|
319
|
-
var collisions = getAllCollisions(sorted, l);
|
|
442
|
+
var collisions = getAllCollisions(sorted, l); // There was a collision; abort
|
|
320
443
|
|
|
321
|
-
// There was a collision; abort
|
|
322
444
|
if (preventCollision && collisions.length) {
|
|
323
|
-
log("Collision prevented on "
|
|
445
|
+
log("Collision prevented on ".concat(l.i, ", reverting."));
|
|
324
446
|
l.x = oldX;
|
|
325
447
|
l.y = oldY;
|
|
326
448
|
l.moved = false;
|
|
327
449
|
return layout;
|
|
328
|
-
}
|
|
450
|
+
} // Move each item that collides away from this element.
|
|
451
|
+
|
|
329
452
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
log("Resolving collision between " + l.i + " at [" + l.x + "," + l.y + "] and " + collision.i + " at [" + collision.x + "," + collision.y + "]");
|
|
453
|
+
for (var i = 0, len = collisions.length; i < len; i++) {
|
|
454
|
+
var collision = collisions[i];
|
|
455
|
+
log("Resolving collision between ".concat(l.i, " at [").concat(l.x, ",").concat(l.y, "] and ").concat(collision.i, " at [").concat(collision.x, ",").concat(collision.y, "]")); // Short circuit so we can't infinite loop
|
|
334
456
|
|
|
335
|
-
//
|
|
336
|
-
if (collision.moved) continue;
|
|
457
|
+
if (collision.moved) continue; // Don't move static items - we have to move *this* element away
|
|
337
458
|
|
|
338
|
-
// Don't move static items - we have to move *this* element away
|
|
339
459
|
if (collision.static) {
|
|
340
460
|
layout = moveElementAwayFromCollision(layout, collision, l, isUserAction, compactType, cols);
|
|
341
461
|
} else {
|
|
@@ -345,7 +465,6 @@ function moveElement(layout, l, x, y, isUserAction, preventCollision, compactTyp
|
|
|
345
465
|
|
|
346
466
|
return layout;
|
|
347
467
|
}
|
|
348
|
-
|
|
349
468
|
/**
|
|
350
469
|
* This is where the magic needs to happen - given a collision, move an element away from the collision.
|
|
351
470
|
* We attempt to move it up if there's room, otherwise it goes below.
|
|
@@ -354,100 +473,128 @@ function moveElement(layout, l, x, y, isUserAction, preventCollision, compactTyp
|
|
|
354
473
|
* @param {LayoutItem} collidesWith Layout item we're colliding with.
|
|
355
474
|
* @param {LayoutItem} itemToMove Layout item we're moving.
|
|
356
475
|
*/
|
|
357
|
-
function moveElementAwayFromCollision(layout, collidesWith, itemToMove, isUserAction, compactType, cols) {
|
|
358
|
-
var compactH = compactType === "horizontal";
|
|
359
|
-
var compactV = compactType === "vertical";
|
|
360
|
-
var preventCollision = false; // we're already colliding
|
|
361
476
|
|
|
477
|
+
|
|
478
|
+
function moveElementAwayFromCollision(layout
|
|
479
|
+
/*: Layout*/
|
|
480
|
+
, collidesWith
|
|
481
|
+
/*: LayoutItem*/
|
|
482
|
+
, itemToMove
|
|
483
|
+
/*: LayoutItem*/
|
|
484
|
+
, isUserAction
|
|
485
|
+
/*: ?boolean*/
|
|
486
|
+
, compactType
|
|
487
|
+
/*: CompactType*/
|
|
488
|
+
, cols
|
|
489
|
+
/*: number*/
|
|
490
|
+
)
|
|
491
|
+
/*: Layout*/
|
|
492
|
+
{
|
|
493
|
+
var compactH = compactType === "horizontal"; // Compact vertically if not set to horizontal
|
|
494
|
+
|
|
495
|
+
var compactV = compactType !== "horizontal";
|
|
496
|
+
var preventCollision = collidesWith.static; // we're already colliding (not for static items)
|
|
362
497
|
// If there is enough space above the collision to put this element, move it there.
|
|
363
498
|
// We only do this on the main collision as this can get funky in cascades and cause
|
|
364
499
|
// unwanted swapping behavior.
|
|
500
|
+
|
|
365
501
|
if (isUserAction) {
|
|
366
|
-
//
|
|
367
|
-
|
|
502
|
+
// Reset isUserAction flag because we're not in the main collision anymore.
|
|
503
|
+
isUserAction = false; // Make a mock item so we don't modify the item here, only modify in moveElement.
|
|
504
|
+
|
|
505
|
+
var fakeItem
|
|
506
|
+
/*: LayoutItem*/
|
|
507
|
+
= {
|
|
368
508
|
x: compactH ? Math.max(collidesWith.x - itemToMove.w, 0) : itemToMove.x,
|
|
369
|
-
y:
|
|
509
|
+
y: compactV ? Math.max(collidesWith.y - itemToMove.h, 0) : itemToMove.y,
|
|
370
510
|
w: itemToMove.w,
|
|
371
511
|
h: itemToMove.h,
|
|
372
512
|
i: "-1"
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
// This makes it feel a bit more precise by waiting to swap for just a bit when moving up.
|
|
376
|
-
|
|
377
|
-
var _ref = compactType === "horizontal" ? ["x", "w"] : ["y", "h"],
|
|
378
|
-
axis = _ref[0],
|
|
379
|
-
dimension = _ref[1];
|
|
380
|
-
|
|
381
|
-
var shouldSkip = false &&
|
|
382
|
-
// Our collision is below the item to move, and only encroaches by 25% of its dimension; ignore
|
|
383
|
-
collidesWith[axis] > itemToMove[axis] && collidesWith[axis] - itemToMove[axis] > itemToMove[dimension] / 4;
|
|
513
|
+
}; // No collision? If so, we can go up there; otherwise, we'll end up moving down as normal
|
|
384
514
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
return moveElement(layout, itemToMove, fakeItem.x, fakeItem.y, isUserAction, preventCollision, compactType, cols);
|
|
515
|
+
if (!getFirstCollision(layout, fakeItem)) {
|
|
516
|
+
log("Doing reverse collision on ".concat(itemToMove.i, " up to [").concat(fakeItem.x, ",").concat(fakeItem.y, "]."));
|
|
517
|
+
return moveElement(layout, itemToMove, compactH ? fakeItem.x : undefined, compactV ? fakeItem.y : undefined, isUserAction, preventCollision, compactType, cols);
|
|
389
518
|
}
|
|
390
519
|
}
|
|
391
520
|
|
|
392
|
-
return moveElement(layout, itemToMove, compactH ?
|
|
521
|
+
return moveElement(layout, itemToMove, compactH ? itemToMove.x + 1 : undefined, compactV ? itemToMove.y + 1 : undefined, isUserAction, preventCollision, compactType, cols);
|
|
393
522
|
}
|
|
394
|
-
|
|
395
523
|
/**
|
|
396
524
|
* Helper to convert a number to a percentage string.
|
|
397
525
|
*
|
|
398
526
|
* @param {Number} num Any number
|
|
399
527
|
* @return {String} That number as a percentage.
|
|
400
528
|
*/
|
|
401
|
-
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
function perc(num
|
|
532
|
+
/*: number*/
|
|
533
|
+
)
|
|
534
|
+
/*: string*/
|
|
535
|
+
{
|
|
402
536
|
return num * 100 + "%";
|
|
403
537
|
}
|
|
404
538
|
|
|
405
|
-
function setTransform(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
539
|
+
function setTransform(_ref)
|
|
540
|
+
/*: Object*/
|
|
541
|
+
{
|
|
542
|
+
var top = _ref.top,
|
|
543
|
+
left = _ref.left,
|
|
544
|
+
width = _ref.width,
|
|
545
|
+
height = _ref.height;
|
|
411
546
|
// Replace unitless items with px
|
|
412
|
-
var translate = "translate("
|
|
547
|
+
var translate = "translate(".concat(left, "px,").concat(top, "px)");
|
|
413
548
|
return {
|
|
414
549
|
transform: translate,
|
|
415
550
|
WebkitTransform: translate,
|
|
416
551
|
MozTransform: translate,
|
|
417
552
|
msTransform: translate,
|
|
418
553
|
OTransform: translate,
|
|
419
|
-
width: width
|
|
420
|
-
height: height
|
|
554
|
+
width: "".concat(width, "px"),
|
|
555
|
+
height: "".concat(height, "px"),
|
|
421
556
|
position: "absolute"
|
|
422
557
|
};
|
|
423
558
|
}
|
|
424
559
|
|
|
425
|
-
function setTopLeft(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
560
|
+
function setTopLeft(_ref2)
|
|
561
|
+
/*: Object*/
|
|
562
|
+
{
|
|
563
|
+
var top = _ref2.top,
|
|
564
|
+
left = _ref2.left,
|
|
565
|
+
width = _ref2.width,
|
|
566
|
+
height = _ref2.height;
|
|
431
567
|
return {
|
|
432
|
-
top: top
|
|
433
|
-
left: left
|
|
434
|
-
width: width
|
|
435
|
-
height: height
|
|
568
|
+
top: "".concat(top, "px"),
|
|
569
|
+
left: "".concat(left, "px"),
|
|
570
|
+
width: "".concat(width, "px"),
|
|
571
|
+
height: "".concat(height, "px"),
|
|
436
572
|
position: "absolute"
|
|
437
573
|
};
|
|
438
574
|
}
|
|
439
|
-
|
|
440
575
|
/**
|
|
441
576
|
* Get layout items sorted from top left to right and down.
|
|
442
577
|
*
|
|
443
578
|
* @return {Array} Array of layout objects.
|
|
444
579
|
* @return {Array} Layout, sorted static items first.
|
|
445
580
|
*/
|
|
446
|
-
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
function sortLayoutItems(layout
|
|
584
|
+
/*: Layout*/
|
|
585
|
+
, compactType
|
|
586
|
+
/*: CompactType*/
|
|
587
|
+
)
|
|
588
|
+
/*: Layout*/
|
|
589
|
+
{
|
|
447
590
|
if (compactType === "horizontal") return sortLayoutItemsByColRow(layout);else return sortLayoutItemsByRowCol(layout);
|
|
448
591
|
}
|
|
449
592
|
|
|
450
|
-
function sortLayoutItemsByRowCol(layout
|
|
593
|
+
function sortLayoutItemsByRowCol(layout
|
|
594
|
+
/*: Layout*/
|
|
595
|
+
)
|
|
596
|
+
/*: Layout*/
|
|
597
|
+
{
|
|
451
598
|
return [].concat(layout).sort(function (a, b) {
|
|
452
599
|
if (a.y > b.y || a.y === b.y && a.x > b.x) {
|
|
453
600
|
return 1;
|
|
@@ -455,19 +602,24 @@ function sortLayoutItemsByRowCol(layout) {
|
|
|
455
602
|
// Without this, we can get different sort results in IE vs. Chrome/FF
|
|
456
603
|
return 0;
|
|
457
604
|
}
|
|
605
|
+
|
|
458
606
|
return -1;
|
|
459
607
|
});
|
|
460
608
|
}
|
|
461
609
|
|
|
462
|
-
function sortLayoutItemsByColRow(layout
|
|
610
|
+
function sortLayoutItemsByColRow(layout
|
|
611
|
+
/*: Layout*/
|
|
612
|
+
)
|
|
613
|
+
/*: Layout*/
|
|
614
|
+
{
|
|
463
615
|
return [].concat(layout).sort(function (a, b) {
|
|
464
616
|
if (a.x > b.x || a.x === b.x && a.y > b.y) {
|
|
465
617
|
return 1;
|
|
466
618
|
}
|
|
619
|
+
|
|
467
620
|
return -1;
|
|
468
621
|
});
|
|
469
622
|
}
|
|
470
|
-
|
|
471
623
|
/**
|
|
472
624
|
* Generate a layout using the initialLayout and children as a template.
|
|
473
625
|
* Missing entries will be added, extraneous ones will be truncated.
|
|
@@ -477,14 +629,33 @@ function sortLayoutItemsByColRow(layout) {
|
|
|
477
629
|
* @param {?String} compact Compaction option.
|
|
478
630
|
* @return {Array} Working layout.
|
|
479
631
|
*/
|
|
480
|
-
function synchronizeLayoutWithChildren(initialLayout, children, cols, compactType) {
|
|
481
|
-
initialLayout = initialLayout || [];
|
|
482
632
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
633
|
+
|
|
634
|
+
function synchronizeLayoutWithChildren(initialLayout
|
|
635
|
+
/*: Layout*/
|
|
636
|
+
, children
|
|
637
|
+
/*: ReactChildren*/
|
|
638
|
+
, cols
|
|
639
|
+
/*: number*/
|
|
640
|
+
, compactType
|
|
641
|
+
/*: CompactType*/
|
|
642
|
+
)
|
|
643
|
+
/*: Layout*/
|
|
644
|
+
{
|
|
645
|
+
initialLayout = initialLayout || []; // Generate one layout item per child.
|
|
646
|
+
|
|
647
|
+
var layout
|
|
648
|
+
/*: Layout*/
|
|
649
|
+
= [];
|
|
650
|
+
|
|
651
|
+
_react.default.Children.forEach(children, function (child
|
|
652
|
+
/*: ReactElement<any>*/
|
|
653
|
+
, i
|
|
654
|
+
/*: number*/
|
|
655
|
+
) {
|
|
486
656
|
// Don't overwrite if it already exists.
|
|
487
657
|
var exists = getLayoutItem(initialLayout, String(child.key));
|
|
658
|
+
|
|
488
659
|
if (exists) {
|
|
489
660
|
layout[i] = cloneLayoutItem(exists);
|
|
490
661
|
} else {
|
|
@@ -492,14 +663,17 @@ function synchronizeLayoutWithChildren(initialLayout, children, cols, compactTyp
|
|
|
492
663
|
console.warn("`_grid` properties on children have been deprecated as of React 15.2. " + // eslint-disable-line
|
|
493
664
|
"Please use `data-grid` or add your properties directly to the `layout`.");
|
|
494
665
|
}
|
|
495
|
-
var g = child.props["data-grid"] || child.props._grid;
|
|
496
666
|
|
|
497
|
-
// Hey, this item has a data-grid property, use it.
|
|
667
|
+
var g = child.props["data-grid"] || child.props._grid; // Hey, this item has a data-grid property, use it.
|
|
668
|
+
|
|
498
669
|
if (g) {
|
|
499
670
|
if (!isProduction) {
|
|
500
671
|
validateLayout([g], "ReactGridLayout.children");
|
|
501
672
|
}
|
|
502
|
-
|
|
673
|
+
|
|
674
|
+
layout[i] = cloneLayoutItem(_objectSpread({}, g, {
|
|
675
|
+
i: child.key
|
|
676
|
+
}));
|
|
503
677
|
} else {
|
|
504
678
|
// Nothing provided: ensure this is added to the bottom
|
|
505
679
|
layout[i] = cloneLayoutItem({
|
|
@@ -511,15 +685,15 @@ function synchronizeLayoutWithChildren(initialLayout, children, cols, compactTyp
|
|
|
511
685
|
});
|
|
512
686
|
}
|
|
513
687
|
}
|
|
514
|
-
});
|
|
688
|
+
}); // Correct the layout.
|
|
515
689
|
|
|
516
|
-
// Correct the layout.
|
|
517
|
-
layout = correctBounds(layout, { cols: cols });
|
|
518
|
-
layout = compact(layout, compactType, cols);
|
|
519
690
|
|
|
691
|
+
layout = correctBounds(layout, {
|
|
692
|
+
cols: cols
|
|
693
|
+
});
|
|
694
|
+
layout = compact(layout, compactType, cols);
|
|
520
695
|
return layout;
|
|
521
696
|
}
|
|
522
|
-
|
|
523
697
|
/**
|
|
524
698
|
* Validate a layout. Throws errors.
|
|
525
699
|
*
|
|
@@ -527,29 +701,46 @@ function synchronizeLayoutWithChildren(initialLayout, children, cols, compactTyp
|
|
|
527
701
|
* @param {String} [contextName] Context name for errors.
|
|
528
702
|
* @throw {Error} Validation error.
|
|
529
703
|
*/
|
|
530
|
-
function validateLayout(layout) {
|
|
531
|
-
var contextName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Layout";
|
|
532
704
|
|
|
705
|
+
|
|
706
|
+
function validateLayout(layout
|
|
707
|
+
/*: Layout*/
|
|
708
|
+
)
|
|
709
|
+
/*: void*/
|
|
710
|
+
{
|
|
711
|
+
var contextName
|
|
712
|
+
/*: string*/
|
|
713
|
+
= arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Layout";
|
|
533
714
|
var subProps = ["x", "y", "w", "h"];
|
|
534
715
|
if (!Array.isArray(layout)) throw new Error(contextName + " must be an array!");
|
|
535
|
-
|
|
536
|
-
|
|
716
|
+
|
|
717
|
+
for (var i = 0, len = layout.length; i < len; i++) {
|
|
718
|
+
var item = layout[i];
|
|
719
|
+
|
|
537
720
|
for (var j = 0; j < subProps.length; j++) {
|
|
538
721
|
if (typeof item[subProps[j]] !== "number") {
|
|
539
|
-
throw new Error("ReactGridLayout: " + contextName + "[" +
|
|
722
|
+
throw new Error("ReactGridLayout: " + contextName + "[" + i + "]." + subProps[j] + " must be a number!");
|
|
540
723
|
}
|
|
541
724
|
}
|
|
725
|
+
|
|
542
726
|
if (item.i && typeof item.i !== "string") {
|
|
543
|
-
throw new Error("ReactGridLayout: " + contextName + "[" +
|
|
727
|
+
throw new Error("ReactGridLayout: " + contextName + "[" + i + "].i must be a string!");
|
|
544
728
|
}
|
|
729
|
+
|
|
545
730
|
if (item.static !== undefined && typeof item.static !== "boolean") {
|
|
546
|
-
throw new Error("ReactGridLayout: " + contextName + "[" +
|
|
731
|
+
throw new Error("ReactGridLayout: " + contextName + "[" + i + "].static must be a boolean!");
|
|
547
732
|
}
|
|
548
733
|
}
|
|
549
|
-
}
|
|
734
|
+
} // Flow can't really figure this out, so we just use Object
|
|
550
735
|
|
|
551
|
-
|
|
552
|
-
function autoBindHandlers(el
|
|
736
|
+
|
|
737
|
+
function autoBindHandlers(el
|
|
738
|
+
/*: Object*/
|
|
739
|
+
, fns
|
|
740
|
+
/*: Array<string>*/
|
|
741
|
+
)
|
|
742
|
+
/*: void*/
|
|
743
|
+
{
|
|
553
744
|
fns.forEach(function (key) {
|
|
554
745
|
return el[key] = el[key].bind(el);
|
|
555
746
|
});
|
|
@@ -558,9 +749,11 @@ function autoBindHandlers(el, fns) {
|
|
|
558
749
|
function log() {
|
|
559
750
|
var _console;
|
|
560
751
|
|
|
561
|
-
if (!DEBUG) return;
|
|
562
|
-
|
|
752
|
+
if (!DEBUG) return; // eslint-disable-next-line no-console
|
|
753
|
+
|
|
563
754
|
(_console = console).log.apply(_console, arguments);
|
|
564
755
|
}
|
|
565
756
|
|
|
566
|
-
var noop =
|
|
757
|
+
var noop = function noop() {};
|
|
758
|
+
|
|
759
|
+
exports.noop = noop;
|