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/.flowconfig +1 -0
- package/.packj.yaml +153 -0
- package/.prettierignore +2 -1
- package/.prettierrc +0 -1
- package/CHANGELOG.md +36 -0
- package/README.md +35 -6
- package/build/GridItem.js +590 -493
- package/build/ReactGridLayout.js +534 -592
- package/build/ReactGridLayoutPropTypes.js +51 -48
- package/build/ResponsiveReactGridLayout.js +144 -238
- package/build/calculateUtils.js +76 -115
- package/build/components/WidthProvider.js +79 -122
- 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 +64 -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 +40 -36
package/build/utils.js
CHANGED
|
@@ -31,106 +31,136 @@ exports.sortLayoutItemsByRowCol = sortLayoutItemsByRowCol;
|
|
|
31
31
|
exports.synchronizeLayoutWithChildren = synchronizeLayoutWithChildren;
|
|
32
32
|
exports.validateLayout = validateLayout;
|
|
33
33
|
exports.withLayoutItem = withLayoutItem;
|
|
34
|
-
|
|
35
|
-
var _lodash = _interopRequireDefault(require("lodash.isequal"));
|
|
36
|
-
|
|
34
|
+
var _fastEquals = require("fast-equals");
|
|
37
35
|
var _react = _interopRequireDefault(require("react"));
|
|
38
|
-
|
|
39
36
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
37
|
+
/*:: import type {
|
|
38
|
+
ChildrenArray as ReactChildrenArray,
|
|
39
|
+
Element as ReactElement
|
|
40
|
+
} from "react";*/
|
|
41
|
+
/*:: export type LayoutItem = {
|
|
42
|
+
w: number,
|
|
43
|
+
h: number,
|
|
44
|
+
x: number,
|
|
45
|
+
y: number,
|
|
46
|
+
i: string,
|
|
47
|
+
minW?: number,
|
|
48
|
+
minH?: number,
|
|
49
|
+
maxW?: number,
|
|
50
|
+
maxH?: number,
|
|
51
|
+
moved?: boolean,
|
|
52
|
+
static?: boolean,
|
|
53
|
+
isDraggable?: ?boolean,
|
|
54
|
+
isResizable?: ?boolean,
|
|
55
|
+
resizeHandles?: Array<"s" | "w" | "e" | "n" | "sw" | "nw" | "se" | "ne">,
|
|
56
|
+
isBounded?: ?boolean
|
|
57
|
+
};*/
|
|
58
|
+
/*:: export type Layout = $ReadOnlyArray<LayoutItem>;*/
|
|
59
|
+
/*:: export type Position = {
|
|
60
|
+
left: number,
|
|
61
|
+
top: number,
|
|
62
|
+
width: number,
|
|
63
|
+
height: number
|
|
64
|
+
};*/
|
|
65
|
+
/*:: export type ReactDraggableCallbackData = {
|
|
66
|
+
node: HTMLElement,
|
|
67
|
+
x?: number,
|
|
68
|
+
y?: number,
|
|
69
|
+
deltaX: number,
|
|
70
|
+
deltaY: number,
|
|
71
|
+
lastX?: number,
|
|
72
|
+
lastY?: number
|
|
73
|
+
};*/
|
|
74
|
+
/*:: export type PartialPosition = { left: number, top: number };*/
|
|
75
|
+
/*:: export type DroppingPosition = { left: number, top: number, e: Event };*/
|
|
76
|
+
/*:: export type Size = { width: number, height: number };*/
|
|
77
|
+
/*:: export type GridDragEvent = {
|
|
78
|
+
e: Event,
|
|
79
|
+
node: HTMLElement,
|
|
80
|
+
newPosition: PartialPosition
|
|
81
|
+
};*/
|
|
82
|
+
/*:: export type GridResizeEvent = {
|
|
83
|
+
e: Event,
|
|
84
|
+
node: HTMLElement,
|
|
85
|
+
size: Size,
|
|
86
|
+
handle: string
|
|
87
|
+
};*/
|
|
88
|
+
/*:: export type DragOverEvent = MouseEvent & {
|
|
89
|
+
nativeEvent: {
|
|
90
|
+
layerX: number,
|
|
91
|
+
layerY: number,
|
|
92
|
+
...Event
|
|
93
|
+
}
|
|
94
|
+
};*/
|
|
95
|
+
/*:: export type Pick<FromType, Properties: { [string]: 0 }> = $Exact<
|
|
96
|
+
$ObjMapi<Properties, <K, V>(k: K, v: V) => $ElementType<FromType, K>>
|
|
97
|
+
>;*/
|
|
98
|
+
// Helpful port from TS
|
|
99
|
+
/*:: type REl = ReactElement<any>;*/
|
|
100
|
+
/*:: export type ReactChildren = ReactChildrenArray<REl>;*/
|
|
101
|
+
/*:: export type EventCallback = (
|
|
102
|
+
Layout,
|
|
103
|
+
oldItem: ?LayoutItem,
|
|
104
|
+
newItem: ?LayoutItem,
|
|
105
|
+
placeholder: ?LayoutItem,
|
|
106
|
+
Event,
|
|
107
|
+
?HTMLElement
|
|
108
|
+
) => void;*/
|
|
109
|
+
// All callbacks are of the signature (layout, oldItem, newItem, placeholder, e).
|
|
110
|
+
/*:: export type CompactType = ?("horizontal" | "vertical");*/
|
|
111
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
112
|
+
const DEBUG = false;
|
|
40
113
|
|
|
41
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
42
|
-
|
|
43
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
44
|
-
|
|
45
|
-
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; }
|
|
46
|
-
|
|
47
|
-
var isProduction = process.env.NODE_ENV === "production";
|
|
48
|
-
var DEBUG = false;
|
|
49
114
|
/**
|
|
50
115
|
* Return the bottom coordinate of the layout.
|
|
51
116
|
*
|
|
52
117
|
* @param {Array} layout Layout array.
|
|
53
118
|
* @return {Number} Bottom coordinate.
|
|
54
119
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
59
|
-
/*: number*/
|
|
60
|
-
{
|
|
61
|
-
var max = 0,
|
|
62
|
-
bottomY;
|
|
63
|
-
|
|
64
|
-
for (var i = 0, len = layout.length; i < len; i++) {
|
|
120
|
+
function bottom(layout /*: Layout*/) /*: number*/{
|
|
121
|
+
let max = 0,
|
|
122
|
+
bottomY;
|
|
123
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
65
124
|
bottomY = layout[i].y + layout[i].h;
|
|
66
125
|
if (bottomY > max) max = bottomY;
|
|
67
126
|
}
|
|
68
|
-
|
|
69
127
|
return max;
|
|
70
128
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
/*: Layout*/
|
|
76
|
-
{
|
|
77
|
-
var newLayout = Array(layout.length);
|
|
78
|
-
|
|
79
|
-
for (var i = 0, len = layout.length; i < len; i++) {
|
|
129
|
+
function cloneLayout(layout /*: Layout*/) /*: Layout*/{
|
|
130
|
+
const newLayout = Array(layout.length);
|
|
131
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
80
132
|
newLayout[i] = cloneLayoutItem(layout[i]);
|
|
81
133
|
}
|
|
82
|
-
|
|
83
134
|
return newLayout;
|
|
84
|
-
}
|
|
85
|
-
// does not mutate. Carries over all other LayoutItems unmodified.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
function modifyLayout(layout
|
|
89
|
-
/*: Layout*/
|
|
90
|
-
, layoutItem
|
|
91
|
-
/*: LayoutItem*/
|
|
92
|
-
)
|
|
93
|
-
/*: Layout*/
|
|
94
|
-
{
|
|
95
|
-
var newLayout = Array(layout.length);
|
|
135
|
+
}
|
|
96
136
|
|
|
97
|
-
|
|
137
|
+
// Modify a layoutItem inside a layout. Returns a new Layout,
|
|
138
|
+
// does not mutate. Carries over all other LayoutItems unmodified.
|
|
139
|
+
function modifyLayout(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: Layout*/{
|
|
140
|
+
const newLayout = Array(layout.length);
|
|
141
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
98
142
|
if (layoutItem.i === layout[i].i) {
|
|
99
143
|
newLayout[i] = layoutItem;
|
|
100
144
|
} else {
|
|
101
145
|
newLayout[i] = layout[i];
|
|
102
146
|
}
|
|
103
147
|
}
|
|
104
|
-
|
|
105
148
|
return newLayout;
|
|
106
|
-
}
|
|
107
|
-
// Does defensive clones to ensure the layout is not modified.
|
|
108
|
-
|
|
149
|
+
}
|
|
109
150
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
,
|
|
113
|
-
|
|
114
|
-
, cb
|
|
115
|
-
/*: LayoutItem => LayoutItem*/
|
|
116
|
-
)
|
|
117
|
-
/*: [Layout, ?LayoutItem]*/
|
|
118
|
-
{
|
|
119
|
-
var item = getLayoutItem(layout, itemKey);
|
|
151
|
+
// Function to be called to modify a layout item.
|
|
152
|
+
// Does defensive clones to ensure the layout is not modified.
|
|
153
|
+
function withLayoutItem(layout /*: Layout*/, itemKey /*: string*/, cb /*: LayoutItem => LayoutItem*/) /*: [Layout, ?LayoutItem]*/{
|
|
154
|
+
let item = getLayoutItem(layout, itemKey);
|
|
120
155
|
if (!item) return [layout, null];
|
|
121
156
|
item = cb(cloneLayoutItem(item)); // defensive clone then modify
|
|
122
157
|
// FIXME could do this faster if we already knew the index
|
|
123
|
-
|
|
124
158
|
layout = modifyLayout(layout, item);
|
|
125
159
|
return [layout, item];
|
|
126
|
-
}
|
|
127
|
-
|
|
160
|
+
}
|
|
128
161
|
|
|
129
|
-
|
|
130
|
-
/*: LayoutItem*/
|
|
131
|
-
)
|
|
132
|
-
/*: LayoutItem*/
|
|
133
|
-
{
|
|
162
|
+
// Fast path to cloning, since this is monomorphic
|
|
163
|
+
function cloneLayoutItem(layoutItem /*: LayoutItem*/) /*: LayoutItem*/{
|
|
134
164
|
return {
|
|
135
165
|
w: layoutItem.w,
|
|
136
166
|
h: layoutItem.h,
|
|
@@ -150,25 +180,15 @@ function cloneLayoutItem(layoutItem
|
|
|
150
180
|
isBounded: layoutItem.isBounded
|
|
151
181
|
};
|
|
152
182
|
}
|
|
183
|
+
|
|
153
184
|
/**
|
|
154
185
|
* Comparing React `children` is a bit difficult. This is a good way to compare them.
|
|
155
186
|
* This will catch differences in keys, order, and length.
|
|
156
187
|
*/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
function childrenEqual(a
|
|
160
|
-
/*: ReactChildren*/
|
|
161
|
-
, b
|
|
162
|
-
/*: ReactChildren*/
|
|
163
|
-
)
|
|
164
|
-
/*: boolean*/
|
|
165
|
-
{
|
|
166
|
-
return (0, _lodash.default)(_react.default.Children.map(a, function (c) {
|
|
167
|
-
return c === null || c === void 0 ? void 0 : c.key;
|
|
168
|
-
}), _react.default.Children.map(b, function (c) {
|
|
169
|
-
return c === null || c === void 0 ? void 0 : c.key;
|
|
170
|
-
}));
|
|
188
|
+
function childrenEqual(a /*: ReactChildren*/, b /*: ReactChildren*/) /*: boolean*/{
|
|
189
|
+
return (0, _fastEquals.deepEqual)(_react.default.Children.map(a, c => c === null || c === void 0 ? void 0 : c.key), _react.default.Children.map(b, c => c === null || c === void 0 ? void 0 : c.key)) && (0, _fastEquals.deepEqual)(_react.default.Children.map(a, c => c === null || c === void 0 ? void 0 : c.props["data-grid"]), _react.default.Children.map(b, c => c === null || c === void 0 ? void 0 : c.props["data-grid"]));
|
|
171
190
|
}
|
|
191
|
+
|
|
172
192
|
/**
|
|
173
193
|
* See `fastRGLPropsEqual.js`.
|
|
174
194
|
* We want this to run as fast as possible - it is called often - and to be
|
|
@@ -177,50 +197,27 @@ function childrenEqual(a
|
|
|
177
197
|
* function in conjunction with preval to generate the fastest possible comparison
|
|
178
198
|
* function, tuned for exactly our props.
|
|
179
199
|
*/
|
|
180
|
-
|
|
181
200
|
/*:: type FastRGLPropsEqual = (Object, Object, Function) => boolean;*/
|
|
201
|
+
const fastRGLPropsEqual /*: FastRGLPropsEqual*/ = require("./fastRGLPropsEqual");
|
|
182
202
|
|
|
183
|
-
|
|
184
|
-
var fastRGLPropsEqual
|
|
185
|
-
/*: FastRGLPropsEqual*/
|
|
186
|
-
= require("./fastRGLPropsEqual"); // Like the above, but a lot simpler.
|
|
187
|
-
|
|
188
|
-
|
|
203
|
+
// Like the above, but a lot simpler.
|
|
189
204
|
exports.fastRGLPropsEqual = fastRGLPropsEqual;
|
|
190
|
-
|
|
191
|
-
function fastPositionEqual(a
|
|
192
|
-
/*: Position*/
|
|
193
|
-
, b
|
|
194
|
-
/*: Position*/
|
|
195
|
-
)
|
|
196
|
-
/*: boolean*/
|
|
197
|
-
{
|
|
205
|
+
function fastPositionEqual(a /*: Position*/, b /*: Position*/) /*: boolean*/{
|
|
198
206
|
return a.left === b.left && a.top === b.top && a.width === b.width && a.height === b.height;
|
|
199
207
|
}
|
|
208
|
+
|
|
200
209
|
/**
|
|
201
210
|
* Given two layoutitems, check if they collide.
|
|
202
211
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function collides(l1
|
|
206
|
-
/*: LayoutItem*/
|
|
207
|
-
, l2
|
|
208
|
-
/*: LayoutItem*/
|
|
209
|
-
)
|
|
210
|
-
/*: boolean*/
|
|
211
|
-
{
|
|
212
|
+
function collides(l1 /*: LayoutItem*/, l2 /*: LayoutItem*/) /*: boolean*/{
|
|
212
213
|
if (l1.i === l2.i) return false; // same element
|
|
213
|
-
|
|
214
214
|
if (l1.x + l1.w <= l2.x) return false; // l1 is left of l2
|
|
215
|
-
|
|
216
215
|
if (l1.x >= l2.x + l2.w) return false; // l1 is right of l2
|
|
217
|
-
|
|
218
216
|
if (l1.y + l1.h <= l2.y) return false; // l1 is above l2
|
|
219
|
-
|
|
220
217
|
if (l1.y >= l2.y + l2.h) return false; // l1 is below l2
|
|
221
|
-
|
|
222
218
|
return true; // boxes overlap
|
|
223
219
|
}
|
|
220
|
+
|
|
224
221
|
/**
|
|
225
222
|
* Given a layout, compact it. This involves going down each y coordinate and removing gaps
|
|
226
223
|
* between items.
|
|
@@ -230,113 +227,81 @@ function collides(l1
|
|
|
230
227
|
* @param {Array} layout Layout.
|
|
231
228
|
* @param {Boolean} verticalCompact Whether or not to compact the layout
|
|
232
229
|
* vertically.
|
|
230
|
+
* @param {Boolean} allowOverlap When `true`, allows overlapping grid items.
|
|
233
231
|
* @return {Array} Compacted Layout.
|
|
234
232
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
function compact(layout
|
|
238
|
-
/*: Layout*/
|
|
239
|
-
, compactType
|
|
240
|
-
/*: CompactType*/
|
|
241
|
-
, cols
|
|
242
|
-
/*: number*/
|
|
243
|
-
)
|
|
244
|
-
/*: Layout*/
|
|
245
|
-
{
|
|
233
|
+
function compact(layout /*: Layout*/, compactType /*: CompactType*/, cols /*: number*/, allowOverlap /*: ?boolean*/) /*: Layout*/{
|
|
246
234
|
// Statics go in the compareWith array right away so items flow around them.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
235
|
+
const compareWith = getStatics(layout);
|
|
236
|
+
// We go through the items by row and column.
|
|
237
|
+
const sorted = sortLayoutItems(layout, compactType);
|
|
238
|
+
// Holding for new items.
|
|
239
|
+
const out = Array(layout.length);
|
|
240
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
241
|
+
let l = cloneLayoutItem(sorted[i]);
|
|
242
|
+
|
|
243
|
+
// Don't move static elements
|
|
256
244
|
if (!l.static) {
|
|
257
|
-
l = compactItem(compareWith, l, compactType, cols, sorted);
|
|
258
|
-
// Statics are already in this array.
|
|
245
|
+
l = compactItem(compareWith, l, compactType, cols, sorted, allowOverlap);
|
|
259
246
|
|
|
247
|
+
// Add to comparison array. We only collide with items before this one.
|
|
248
|
+
// Statics are already in this array.
|
|
260
249
|
compareWith.push(l);
|
|
261
|
-
}
|
|
262
|
-
|
|
250
|
+
}
|
|
263
251
|
|
|
264
|
-
|
|
252
|
+
// Add to output array to make sure they still come out in the right order.
|
|
253
|
+
out[layout.indexOf(sorted[i])] = l;
|
|
265
254
|
|
|
255
|
+
// Clear moved flag, if it exists.
|
|
266
256
|
l.moved = false;
|
|
267
257
|
}
|
|
268
|
-
|
|
269
258
|
return out;
|
|
270
259
|
}
|
|
271
|
-
|
|
272
|
-
var heightWidth = {
|
|
260
|
+
const heightWidth = {
|
|
273
261
|
x: "w",
|
|
274
262
|
y: "h"
|
|
275
263
|
};
|
|
276
264
|
/**
|
|
277
265
|
* Before moving item down, it will check if the movement will cause collisions and move those items down before.
|
|
278
266
|
*/
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
/*: Layout*/
|
|
282
|
-
, item
|
|
283
|
-
/*: LayoutItem*/
|
|
284
|
-
, moveToCoord
|
|
285
|
-
/*: number*/
|
|
286
|
-
, axis
|
|
287
|
-
/*: "x" | "y"*/
|
|
288
|
-
) {
|
|
289
|
-
var sizeProp = heightWidth[axis];
|
|
267
|
+
function resolveCompactionCollision(layout /*: Layout*/, item /*: LayoutItem*/, moveToCoord /*: number*/, axis /*: "x" | "y"*/) {
|
|
268
|
+
const sizeProp = heightWidth[axis];
|
|
290
269
|
item[axis] += 1;
|
|
291
|
-
|
|
270
|
+
const itemIndex = layout.map(layoutItem => {
|
|
292
271
|
return layoutItem.i;
|
|
293
|
-
}).indexOf(item.i);
|
|
272
|
+
}).indexOf(item.i);
|
|
294
273
|
|
|
295
|
-
|
|
296
|
-
|
|
274
|
+
// Go through each item we collide with.
|
|
275
|
+
for (let i = itemIndex + 1; i < layout.length; i++) {
|
|
276
|
+
const otherItem = layout[i];
|
|
277
|
+
// Ignore static items
|
|
278
|
+
if (otherItem.static) continue;
|
|
297
279
|
|
|
298
|
-
|
|
280
|
+
// Optimization: we can break early if we know we're past this el
|
|
299
281
|
// We can do this b/c it's a sorted layout
|
|
300
|
-
|
|
301
282
|
if (otherItem.y > item.y + item.h) break;
|
|
302
|
-
|
|
303
283
|
if (collides(item, otherItem)) {
|
|
304
284
|
resolveCompactionCollision(layout, otherItem, moveToCoord + item[sizeProp], axis);
|
|
305
285
|
}
|
|
306
286
|
}
|
|
307
|
-
|
|
308
287
|
item[axis] = moveToCoord;
|
|
309
288
|
}
|
|
289
|
+
|
|
310
290
|
/**
|
|
311
291
|
* Compact an item in the layout.
|
|
312
292
|
*
|
|
313
293
|
* Modifies item.
|
|
314
294
|
*
|
|
315
295
|
*/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
/*: Layout*/
|
|
320
|
-
, l
|
|
321
|
-
/*: LayoutItem*/
|
|
322
|
-
, compactType
|
|
323
|
-
/*: CompactType*/
|
|
324
|
-
, cols
|
|
325
|
-
/*: number*/
|
|
326
|
-
, fullLayout
|
|
327
|
-
/*: Layout*/
|
|
328
|
-
)
|
|
329
|
-
/*: LayoutItem*/
|
|
330
|
-
{
|
|
331
|
-
var compactV = compactType === "vertical";
|
|
332
|
-
var compactH = compactType === "horizontal";
|
|
333
|
-
|
|
296
|
+
function compactItem(compareWith /*: Layout*/, l /*: LayoutItem*/, compactType /*: CompactType*/, cols /*: number*/, fullLayout /*: Layout*/, allowOverlap /*: ?boolean*/) /*: LayoutItem*/{
|
|
297
|
+
const compactV = compactType === "vertical";
|
|
298
|
+
const compactH = compactType === "horizontal";
|
|
334
299
|
if (compactV) {
|
|
335
300
|
// Bottom 'y' possible is the bottom of the layout.
|
|
336
301
|
// This allows you to do nice stuff like specify {y: Infinity}
|
|
337
302
|
// This is here because the layout must be sorted in order to get the correct bottom `y`.
|
|
338
|
-
l.y = Math.min(bottom(compareWith), l.y);
|
|
339
|
-
|
|
303
|
+
l.y = Math.min(bottom(compareWith), l.y);
|
|
304
|
+
// Move the element up as far as it can go without colliding.
|
|
340
305
|
while (l.y > 0 && !getFirstCollision(compareWith, l)) {
|
|
341
306
|
l.y--;
|
|
342
307
|
}
|
|
@@ -345,30 +310,34 @@ function compactItem(compareWith
|
|
|
345
310
|
while (l.x > 0 && !getFirstCollision(compareWith, l)) {
|
|
346
311
|
l.x--;
|
|
347
312
|
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
var collides;
|
|
313
|
+
}
|
|
352
314
|
|
|
353
|
-
|
|
315
|
+
// Move it down, and keep moving it down if it's colliding.
|
|
316
|
+
let collides;
|
|
317
|
+
// Checking the compactType null value to avoid breaking the layout when overlapping is allowed.
|
|
318
|
+
while ((collides = getFirstCollision(compareWith, l)) && !(compactType === null && allowOverlap)) {
|
|
354
319
|
if (compactH) {
|
|
355
320
|
resolveCompactionCollision(fullLayout, l, collides.x + collides.w, "x");
|
|
356
321
|
} else {
|
|
357
322
|
resolveCompactionCollision(fullLayout, l, collides.y + collides.h, "y");
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
323
|
+
}
|
|
324
|
+
// Since we can't grow without bounds horizontally, if we've overflown, let's move it down and try again.
|
|
361
325
|
if (compactH && l.x + l.w > cols) {
|
|
362
326
|
l.x = cols - l.w;
|
|
363
327
|
l.y++;
|
|
328
|
+
// ALso move element as left as we can
|
|
329
|
+
while (l.x > 0 && !getFirstCollision(compareWith, l)) {
|
|
330
|
+
l.x--;
|
|
331
|
+
}
|
|
364
332
|
}
|
|
365
|
-
}
|
|
366
|
-
|
|
333
|
+
}
|
|
367
334
|
|
|
335
|
+
// Ensure that there are no negative positions
|
|
368
336
|
l.y = Math.max(l.y, 0);
|
|
369
337
|
l.x = Math.max(l.x, 0);
|
|
370
338
|
return l;
|
|
371
339
|
}
|
|
340
|
+
|
|
372
341
|
/**
|
|
373
342
|
* Given a layout, make sure all elements fit within its bounds.
|
|
374
343
|
*
|
|
@@ -377,27 +346,17 @@ function compactItem(compareWith
|
|
|
377
346
|
* @param {Array} layout Layout array.
|
|
378
347
|
* @param {Number} bounds Number of columns.
|
|
379
348
|
*/
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
/*: Layout*/
|
|
388
|
-
{
|
|
389
|
-
var collidesWith = getStatics(layout);
|
|
390
|
-
|
|
391
|
-
for (var i = 0, len = layout.length; i < len; i++) {
|
|
392
|
-
var l = layout[i]; // Overflows right
|
|
393
|
-
|
|
394
|
-
if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w; // Overflows left
|
|
395
|
-
|
|
349
|
+
function correctBounds(layout /*: Layout*/, bounds /*: { cols: number }*/) /*: Layout*/{
|
|
350
|
+
const collidesWith = getStatics(layout);
|
|
351
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
352
|
+
const l = layout[i];
|
|
353
|
+
// Overflows right
|
|
354
|
+
if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w;
|
|
355
|
+
// Overflows left
|
|
396
356
|
if (l.x < 0) {
|
|
397
357
|
l.x = 0;
|
|
398
358
|
l.w = bounds.cols;
|
|
399
359
|
}
|
|
400
|
-
|
|
401
360
|
if (!l.static) collidesWith.push(l);else {
|
|
402
361
|
// If this is static and collides with other statics, we must move it down.
|
|
403
362
|
// We have to do something nicer than just letting them overlap.
|
|
@@ -406,9 +365,9 @@ function correctBounds(layout
|
|
|
406
365
|
}
|
|
407
366
|
}
|
|
408
367
|
}
|
|
409
|
-
|
|
410
368
|
return layout;
|
|
411
369
|
}
|
|
370
|
+
|
|
412
371
|
/**
|
|
413
372
|
* Get a layout item by ID. Used so we can override later on if necessary.
|
|
414
373
|
*
|
|
@@ -416,19 +375,12 @@ function correctBounds(layout
|
|
|
416
375
|
* @param {String} id ID
|
|
417
376
|
* @return {LayoutItem} Item at ID.
|
|
418
377
|
*/
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
function getLayoutItem(layout
|
|
422
|
-
/*: Layout*/
|
|
423
|
-
, id
|
|
424
|
-
/*: string*/
|
|
425
|
-
)
|
|
426
|
-
/*: ?LayoutItem*/
|
|
427
|
-
{
|
|
428
|
-
for (var i = 0, len = layout.length; i < len; i++) {
|
|
378
|
+
function getLayoutItem(layout /*: Layout*/, id /*: string*/) /*: ?LayoutItem*/{
|
|
379
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
429
380
|
if (layout[i].i === id) return layout[i];
|
|
430
381
|
}
|
|
431
382
|
}
|
|
383
|
+
|
|
432
384
|
/**
|
|
433
385
|
* Returns the first item this layout collides with.
|
|
434
386
|
* It doesn't appear to matter which order we approach this from, although
|
|
@@ -437,47 +389,24 @@ function getLayoutItem(layout
|
|
|
437
389
|
* @param {Object} layoutItem Layout item.
|
|
438
390
|
* @return {Object|undefined} A colliding layout item, or undefined.
|
|
439
391
|
*/
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
function getFirstCollision(layout
|
|
443
|
-
/*: Layout*/
|
|
444
|
-
, layoutItem
|
|
445
|
-
/*: LayoutItem*/
|
|
446
|
-
)
|
|
447
|
-
/*: ?LayoutItem*/
|
|
448
|
-
{
|
|
449
|
-
for (var i = 0, len = layout.length; i < len; i++) {
|
|
392
|
+
function getFirstCollision(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: ?LayoutItem*/{
|
|
393
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
450
394
|
if (collides(layout[i], layoutItem)) return layout[i];
|
|
451
395
|
}
|
|
452
396
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
/*: Layout*/
|
|
456
|
-
, layoutItem
|
|
457
|
-
/*: LayoutItem*/
|
|
458
|
-
)
|
|
459
|
-
/*: Array<LayoutItem>*/
|
|
460
|
-
{
|
|
461
|
-
return layout.filter(function (l) {
|
|
462
|
-
return collides(l, layoutItem);
|
|
463
|
-
});
|
|
397
|
+
function getAllCollisions(layout /*: Layout*/, layoutItem /*: LayoutItem*/) /*: Array<LayoutItem>*/{
|
|
398
|
+
return layout.filter(l => collides(l, layoutItem));
|
|
464
399
|
}
|
|
400
|
+
|
|
465
401
|
/**
|
|
466
402
|
* Get all static elements.
|
|
467
403
|
* @param {Array} layout Array of layout objects.
|
|
468
404
|
* @return {Array} Array of static layout items..
|
|
469
405
|
*/
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
function getStatics(layout
|
|
473
|
-
/*: Layout*/
|
|
474
|
-
)
|
|
475
|
-
/*: Array<LayoutItem>*/
|
|
476
|
-
{
|
|
477
|
-
return layout.filter(function (l) {
|
|
478
|
-
return l.static;
|
|
479
|
-
});
|
|
406
|
+
function getStatics(layout /*: Layout*/) /*: Array<LayoutItem>*/{
|
|
407
|
+
return layout.filter(l => l.static);
|
|
480
408
|
}
|
|
409
|
+
|
|
481
410
|
/**
|
|
482
411
|
* Move an element. Responsible for doing cascading movements of other elements.
|
|
483
412
|
*
|
|
@@ -488,53 +417,35 @@ function getStatics(layout
|
|
|
488
417
|
* @param {Number} [x] X position in grid units.
|
|
489
418
|
* @param {Number} [y] Y position in grid units.
|
|
490
419
|
*/
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
function moveElement(layout
|
|
494
|
-
/*: Layout*/
|
|
495
|
-
, l
|
|
496
|
-
/*: LayoutItem*/
|
|
497
|
-
, x
|
|
498
|
-
/*: ?number*/
|
|
499
|
-
, y
|
|
500
|
-
/*: ?number*/
|
|
501
|
-
, isUserAction
|
|
502
|
-
/*: ?boolean*/
|
|
503
|
-
, preventCollision
|
|
504
|
-
/*: ?boolean*/
|
|
505
|
-
, compactType
|
|
506
|
-
/*: CompactType*/
|
|
507
|
-
, cols
|
|
508
|
-
/*: number*/
|
|
509
|
-
, allowOverlap
|
|
510
|
-
/*: ?boolean*/
|
|
511
|
-
)
|
|
512
|
-
/*: Layout*/
|
|
513
|
-
{
|
|
420
|
+
function moveElement(layout /*: Layout*/, l /*: LayoutItem*/, x /*: ?number*/, y /*: ?number*/, isUserAction /*: ?boolean*/, preventCollision /*: ?boolean*/, compactType /*: CompactType*/, cols /*: number*/, allowOverlap /*: ?boolean*/) /*: Layout*/{
|
|
514
421
|
// If this is static and not explicitly enabled as draggable,
|
|
515
422
|
// no move is possible, so we can short-circuit this immediately.
|
|
516
|
-
if (l.static && l.isDraggable !== true) return layout;
|
|
423
|
+
if (l.static && l.isDraggable !== true) return layout;
|
|
517
424
|
|
|
425
|
+
// Short-circuit if nothing to do.
|
|
518
426
|
if (l.y === y && l.x === x) return layout;
|
|
519
427
|
log("Moving element ".concat(l.i, " to [").concat(String(x), ",").concat(String(y), "] from [").concat(l.x, ",").concat(l.y, "]"));
|
|
520
|
-
|
|
521
|
-
|
|
428
|
+
const oldX = l.x;
|
|
429
|
+
const oldY = l.y;
|
|
522
430
|
|
|
431
|
+
// This is quite a bit faster than extending the object
|
|
523
432
|
if (typeof x === "number") l.x = x;
|
|
524
433
|
if (typeof y === "number") l.y = y;
|
|
525
|
-
l.moved = true;
|
|
434
|
+
l.moved = true;
|
|
435
|
+
|
|
436
|
+
// If this collides with anything, move it.
|
|
526
437
|
// When doing this comparison, we have to sort the items we compare with
|
|
527
438
|
// to ensure, in the case of multiple collisions, that we're getting the
|
|
528
439
|
// nearest collision.
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
440
|
+
let sorted = sortLayoutItems(layout, compactType);
|
|
441
|
+
const movingUp = compactType === "vertical" && typeof y === "number" ? oldY >= y : compactType === "horizontal" && typeof x === "number" ? oldX >= x : false;
|
|
442
|
+
// $FlowIgnore acceptable modification of read-only array as it was recently cloned
|
|
533
443
|
if (movingUp) sorted = sorted.reverse();
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
// allowed overlap.
|
|
444
|
+
const collisions = getAllCollisions(sorted, l);
|
|
445
|
+
const hasCollisions = collisions.length > 0;
|
|
537
446
|
|
|
447
|
+
// We may have collisions. We can short-circuit if we've turned off collisions or
|
|
448
|
+
// allowed overlap.
|
|
538
449
|
if (hasCollisions && allowOverlap) {
|
|
539
450
|
// Easy, we don't need to resolve collisions. But we *did* change the layout,
|
|
540
451
|
// so clone it on the way out.
|
|
@@ -548,24 +459,26 @@ function moveElement(layout
|
|
|
548
459
|
l.y = oldY;
|
|
549
460
|
l.moved = false;
|
|
550
461
|
return layout; // did not change so don't clone
|
|
551
|
-
}
|
|
552
|
-
|
|
462
|
+
}
|
|
553
463
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
464
|
+
// Move each item that collides away from this element.
|
|
465
|
+
for (let i = 0, len = collisions.length; i < len; i++) {
|
|
466
|
+
const collision = collisions[i];
|
|
467
|
+
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, "]"));
|
|
557
468
|
|
|
558
|
-
|
|
469
|
+
// Short circuit so we can't infinite loop
|
|
470
|
+
if (collision.moved) continue;
|
|
559
471
|
|
|
472
|
+
// Don't move static items - we have to move *this* element away
|
|
560
473
|
if (collision.static) {
|
|
561
474
|
layout = moveElementAwayFromCollision(layout, collision, l, isUserAction, compactType, cols);
|
|
562
475
|
} else {
|
|
563
476
|
layout = moveElementAwayFromCollision(layout, l, collision, isUserAction, compactType, cols);
|
|
564
477
|
}
|
|
565
478
|
}
|
|
566
|
-
|
|
567
479
|
return layout;
|
|
568
480
|
}
|
|
481
|
+
|
|
569
482
|
/**
|
|
570
483
|
* This is where the magic needs to happen - given a collision, move an element away from the collision.
|
|
571
484
|
* We attempt to move it up if there's room, otherwise it goes below.
|
|
@@ -574,78 +487,71 @@ function moveElement(layout
|
|
|
574
487
|
* @param {LayoutItem} collidesWith Layout item we're colliding with.
|
|
575
488
|
* @param {LayoutItem} itemToMove Layout item we're moving.
|
|
576
489
|
*/
|
|
490
|
+
function moveElementAwayFromCollision(layout /*: Layout*/, collidesWith /*: LayoutItem*/, itemToMove /*: LayoutItem*/, isUserAction /*: ?boolean*/, compactType /*: CompactType*/, cols /*: number*/) /*: Layout*/{
|
|
491
|
+
const compactH = compactType === "horizontal";
|
|
492
|
+
// Compact vertically if not set to horizontal
|
|
493
|
+
const compactV = compactType === "vertical";
|
|
494
|
+
const preventCollision = collidesWith.static; // we're already colliding (not for static items)
|
|
577
495
|
|
|
578
|
-
|
|
579
|
-
function moveElementAwayFromCollision(layout
|
|
580
|
-
/*: Layout*/
|
|
581
|
-
, collidesWith
|
|
582
|
-
/*: LayoutItem*/
|
|
583
|
-
, itemToMove
|
|
584
|
-
/*: LayoutItem*/
|
|
585
|
-
, isUserAction
|
|
586
|
-
/*: ?boolean*/
|
|
587
|
-
, compactType
|
|
588
|
-
/*: CompactType*/
|
|
589
|
-
, cols
|
|
590
|
-
/*: number*/
|
|
591
|
-
)
|
|
592
|
-
/*: Layout*/
|
|
593
|
-
{
|
|
594
|
-
var compactH = compactType === "horizontal"; // Compact vertically if not set to horizontal
|
|
595
|
-
|
|
596
|
-
var compactV = compactType !== "horizontal";
|
|
597
|
-
var preventCollision = collidesWith.static; // we're already colliding (not for static items)
|
|
598
496
|
// If there is enough space above the collision to put this element, move it there.
|
|
599
497
|
// We only do this on the main collision as this can get funky in cascades and cause
|
|
600
498
|
// unwanted swapping behavior.
|
|
601
|
-
|
|
602
499
|
if (isUserAction) {
|
|
603
500
|
// Reset isUserAction flag because we're not in the main collision anymore.
|
|
604
|
-
isUserAction = false;
|
|
501
|
+
isUserAction = false;
|
|
605
502
|
|
|
606
|
-
|
|
607
|
-
/*: LayoutItem*/
|
|
608
|
-
= {
|
|
503
|
+
// Make a mock item so we don't modify the item here, only modify in moveElement.
|
|
504
|
+
const fakeItem /*: LayoutItem*/ = {
|
|
609
505
|
x: compactH ? Math.max(collidesWith.x - itemToMove.w, 0) : itemToMove.x,
|
|
610
506
|
y: compactV ? Math.max(collidesWith.y - itemToMove.h, 0) : itemToMove.y,
|
|
611
507
|
w: itemToMove.w,
|
|
612
508
|
h: itemToMove.h,
|
|
613
509
|
i: "-1"
|
|
614
|
-
};
|
|
510
|
+
};
|
|
511
|
+
const firstCollision = getFirstCollision(layout, fakeItem);
|
|
512
|
+
const collisionNorth = firstCollision && firstCollision.y + firstCollision.h > collidesWith.y;
|
|
513
|
+
const collisionWest = firstCollision && collidesWith.x + collidesWith.w > firstCollision.x;
|
|
615
514
|
|
|
616
|
-
|
|
515
|
+
// No collision? If so, we can go up there; otherwise, we'll end up moving down as normal
|
|
516
|
+
if (!firstCollision) {
|
|
617
517
|
log("Doing reverse collision on ".concat(itemToMove.i, " up to [").concat(fakeItem.x, ",").concat(fakeItem.y, "]."));
|
|
618
518
|
return moveElement(layout, itemToMove, compactH ? fakeItem.x : undefined, compactV ? fakeItem.y : undefined, isUserAction, preventCollision, compactType, cols);
|
|
519
|
+
} else if (collisionNorth && compactV) {
|
|
520
|
+
return moveElement(layout, itemToMove, undefined, collidesWith.y + 1, isUserAction, preventCollision, compactType, cols);
|
|
521
|
+
} else if (collisionNorth && compactType == null) {
|
|
522
|
+
collidesWith.y = itemToMove.y;
|
|
523
|
+
itemToMove.y = itemToMove.y + itemToMove.h;
|
|
524
|
+
return layout;
|
|
525
|
+
} else if (collisionWest && compactH) {
|
|
526
|
+
return moveElement(layout, collidesWith, itemToMove.x, undefined, isUserAction, preventCollision, compactType, cols);
|
|
619
527
|
}
|
|
620
528
|
}
|
|
621
|
-
|
|
529
|
+
const newX = compactH ? itemToMove.x + 1 : undefined;
|
|
530
|
+
const newY = compactV ? itemToMove.y + 1 : undefined;
|
|
531
|
+
if (newX == null && newY == null) {
|
|
532
|
+
return layout;
|
|
533
|
+
}
|
|
622
534
|
return moveElement(layout, itemToMove, compactH ? itemToMove.x + 1 : undefined, compactV ? itemToMove.y + 1 : undefined, isUserAction, preventCollision, compactType, cols);
|
|
623
535
|
}
|
|
536
|
+
|
|
624
537
|
/**
|
|
625
538
|
* Helper to convert a number to a percentage string.
|
|
626
539
|
*
|
|
627
540
|
* @param {Number} num Any number
|
|
628
541
|
* @return {String} That number as a percentage.
|
|
629
542
|
*/
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
function perc(num
|
|
633
|
-
/*: number*/
|
|
634
|
-
)
|
|
635
|
-
/*: string*/
|
|
636
|
-
{
|
|
543
|
+
function perc(num /*: number*/) /*: string*/{
|
|
637
544
|
return num * 100 + "%";
|
|
638
545
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
height = _ref.height;
|
|
546
|
+
function setTransform(_ref /*:: */) /*: Object*/{
|
|
547
|
+
let {
|
|
548
|
+
top,
|
|
549
|
+
left,
|
|
550
|
+
width,
|
|
551
|
+
height
|
|
552
|
+
} /*: Position*/ = _ref /*: Position*/;
|
|
647
553
|
// Replace unitless items with px
|
|
648
|
-
|
|
554
|
+
const translate = "translate(".concat(left, "px,").concat(top, "px)");
|
|
649
555
|
return {
|
|
650
556
|
transform: translate,
|
|
651
557
|
WebkitTransform: translate,
|
|
@@ -657,14 +563,13 @@ function setTransform(_ref)
|
|
|
657
563
|
position: "absolute"
|
|
658
564
|
};
|
|
659
565
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
height = _ref2.height;
|
|
566
|
+
function setTopLeft(_ref2 /*:: */) /*: Object*/{
|
|
567
|
+
let {
|
|
568
|
+
top,
|
|
569
|
+
left,
|
|
570
|
+
width,
|
|
571
|
+
height
|
|
572
|
+
} /*: Position*/ = _ref2 /*: Position*/;
|
|
668
573
|
return {
|
|
669
574
|
top: "".concat(top, "px"),
|
|
670
575
|
left: "".concat(left, "px"),
|
|
@@ -673,36 +578,24 @@ function setTopLeft(_ref2)
|
|
|
673
578
|
position: "absolute"
|
|
674
579
|
};
|
|
675
580
|
}
|
|
581
|
+
|
|
676
582
|
/**
|
|
677
583
|
* Get layout items sorted from top left to right and down.
|
|
678
584
|
*
|
|
679
585
|
* @return {Array} Array of layout objects.
|
|
680
586
|
* @return {Array} Layout, sorted static items first.
|
|
681
587
|
*/
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
function sortLayoutItems(layout
|
|
685
|
-
/*: Layout*/
|
|
686
|
-
, compactType
|
|
687
|
-
/*: CompactType*/
|
|
688
|
-
)
|
|
689
|
-
/*: Layout*/
|
|
690
|
-
{
|
|
588
|
+
function sortLayoutItems(layout /*: Layout*/, compactType /*: CompactType*/) /*: Layout*/{
|
|
691
589
|
if (compactType === "horizontal") return sortLayoutItemsByColRow(layout);
|
|
692
590
|
if (compactType === "vertical") return sortLayoutItemsByRowCol(layout);else return layout;
|
|
693
591
|
}
|
|
592
|
+
|
|
694
593
|
/**
|
|
695
594
|
* Sort layout items by row ascending and column ascending.
|
|
696
595
|
*
|
|
697
596
|
* Does not modify Layout.
|
|
698
597
|
*/
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
function sortLayoutItemsByRowCol(layout
|
|
702
|
-
/*: Layout*/
|
|
703
|
-
)
|
|
704
|
-
/*: Layout*/
|
|
705
|
-
{
|
|
598
|
+
function sortLayoutItemsByRowCol(layout /*: Layout*/) /*: Layout*/{
|
|
706
599
|
// Slice to clone array as sort modifies
|
|
707
600
|
return layout.slice(0).sort(function (a, b) {
|
|
708
601
|
if (a.y > b.y || a.y === b.y && a.x > b.x) {
|
|
@@ -711,30 +604,24 @@ function sortLayoutItemsByRowCol(layout
|
|
|
711
604
|
// Without this, we can get different sort results in IE vs. Chrome/FF
|
|
712
605
|
return 0;
|
|
713
606
|
}
|
|
714
|
-
|
|
715
607
|
return -1;
|
|
716
608
|
});
|
|
717
609
|
}
|
|
610
|
+
|
|
718
611
|
/**
|
|
719
612
|
* Sort layout items by column ascending then row ascending.
|
|
720
613
|
*
|
|
721
614
|
* Does not modify Layout.
|
|
722
615
|
*/
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
function sortLayoutItemsByColRow(layout
|
|
726
|
-
/*: Layout*/
|
|
727
|
-
)
|
|
728
|
-
/*: Layout*/
|
|
729
|
-
{
|
|
616
|
+
function sortLayoutItemsByColRow(layout /*: Layout*/) /*: Layout*/{
|
|
730
617
|
return layout.slice(0).sort(function (a, b) {
|
|
731
618
|
if (a.x > b.x || a.x === b.x && a.y > b.y) {
|
|
732
619
|
return 1;
|
|
733
620
|
}
|
|
734
|
-
|
|
735
621
|
return -1;
|
|
736
622
|
});
|
|
737
623
|
}
|
|
624
|
+
|
|
738
625
|
/**
|
|
739
626
|
* Generate a layout using the initialLayout and children as a template.
|
|
740
627
|
* Missing entries will be added, extraneous ones will be truncated.
|
|
@@ -746,53 +633,31 @@ function sortLayoutItemsByColRow(layout
|
|
|
746
633
|
* @param {?String} compact Compaction option.
|
|
747
634
|
* @return {Array} Working layout.
|
|
748
635
|
*/
|
|
636
|
+
function synchronizeLayoutWithChildren(initialLayout /*: Layout*/, children /*: ReactChildren*/, cols /*: number*/, compactType /*: CompactType*/, allowOverlap /*: ?boolean*/) /*: Layout*/{
|
|
637
|
+
initialLayout = initialLayout || [];
|
|
749
638
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
/*:
|
|
753
|
-
, children
|
|
754
|
-
/*: ReactChildren*/
|
|
755
|
-
, cols
|
|
756
|
-
/*: number*/
|
|
757
|
-
, compactType
|
|
758
|
-
/*: CompactType*/
|
|
759
|
-
, allowOverlap
|
|
760
|
-
/*: ?boolean*/
|
|
761
|
-
)
|
|
762
|
-
/*: Layout*/
|
|
763
|
-
{
|
|
764
|
-
initialLayout = initialLayout || []; // Generate one layout item per child.
|
|
765
|
-
|
|
766
|
-
var layout
|
|
767
|
-
/*: LayoutItem[]*/
|
|
768
|
-
= [];
|
|
769
|
-
|
|
770
|
-
_react.default.Children.forEach(children, function (child
|
|
771
|
-
/*: ReactElement<any>*/
|
|
772
|
-
) {
|
|
639
|
+
// Generate one layout item per child.
|
|
640
|
+
const layout /*: LayoutItem[]*/ = [];
|
|
641
|
+
_react.default.Children.forEach(children, (child /*: ReactElement<any>*/) => {
|
|
773
642
|
// Child may not exist
|
|
774
|
-
if ((child === null || child === void 0 ? void 0 : child.key) == null) return;
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
643
|
+
if ((child === null || child === void 0 ? void 0 : child.key) == null) return;
|
|
644
|
+
const exists = getLayoutItem(initialLayout, String(child.key));
|
|
645
|
+
const g = child.props["data-grid"];
|
|
646
|
+
// Don't overwrite the layout item if it's already in the initial layout.
|
|
647
|
+
// If it has a `data-grid` property, prefer that over what's in the layout.
|
|
648
|
+
if (exists && g == null) {
|
|
779
649
|
layout.push(cloneLayoutItem(exists));
|
|
780
650
|
} else {
|
|
781
|
-
|
|
782
|
-
console.warn("`_grid` properties on children have been deprecated as of React 15.2. " + "Please use `data-grid` or add your properties directly to the `layout`.");
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
var g = child.props["data-grid"] || child.props._grid; // Hey, this item has a data-grid property, use it.
|
|
786
|
-
|
|
651
|
+
// Hey, this item has a data-grid property, use it.
|
|
787
652
|
if (g) {
|
|
788
653
|
if (!isProduction) {
|
|
789
654
|
validateLayout([g], "ReactGridLayout.children");
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
655
|
+
}
|
|
656
|
+
// FIXME clone not really necessary here
|
|
657
|
+
layout.push(cloneLayoutItem({
|
|
658
|
+
...g,
|
|
794
659
|
i: child.key
|
|
795
|
-
}))
|
|
660
|
+
}));
|
|
796
661
|
} else {
|
|
797
662
|
// Nothing provided: ensure this is added to the bottom
|
|
798
663
|
// FIXME clone not really necessary here
|
|
@@ -805,14 +670,15 @@ function synchronizeLayoutWithChildren(initialLayout
|
|
|
805
670
|
}));
|
|
806
671
|
}
|
|
807
672
|
}
|
|
808
|
-
});
|
|
809
|
-
|
|
673
|
+
});
|
|
810
674
|
|
|
811
|
-
|
|
675
|
+
// Correct the layout.
|
|
676
|
+
const correctedLayout = correctBounds(layout, {
|
|
812
677
|
cols: cols
|
|
813
678
|
});
|
|
814
679
|
return allowOverlap ? correctedLayout : compact(correctedLayout, compactType, cols);
|
|
815
680
|
}
|
|
681
|
+
|
|
816
682
|
/**
|
|
817
683
|
* Validate a layout. Throws errors.
|
|
818
684
|
*
|
|
@@ -820,51 +686,32 @@ function synchronizeLayoutWithChildren(initialLayout
|
|
|
820
686
|
* @param {String} [contextName] Context name for errors.
|
|
821
687
|
* @throw {Error} Validation error.
|
|
822
688
|
*/
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
/*: Layout*/
|
|
827
|
-
)
|
|
828
|
-
/*: void*/
|
|
829
|
-
{
|
|
830
|
-
var contextName
|
|
831
|
-
/*: string*/
|
|
832
|
-
= arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Layout";
|
|
833
|
-
var subProps = ["x", "y", "w", "h"];
|
|
689
|
+
function validateLayout(layout /*: Layout*/) /*: void*/{
|
|
690
|
+
let contextName /*: string*/ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "Layout";
|
|
691
|
+
const subProps = ["x", "y", "w", "h"];
|
|
834
692
|
if (!Array.isArray(layout)) throw new Error(contextName + " must be an array!");
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
for (var j = 0; j < subProps.length; j++) {
|
|
693
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
694
|
+
const item = layout[i];
|
|
695
|
+
for (let j = 0; j < subProps.length; j++) {
|
|
840
696
|
if (typeof item[subProps[j]] !== "number") {
|
|
841
697
|
throw new Error("ReactGridLayout: " + contextName + "[" + i + "]." + subProps[j] + " must be a number!");
|
|
842
698
|
}
|
|
843
699
|
}
|
|
844
700
|
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
function compactType(props
|
|
849
|
-
/*: ?{ verticalCompact: boolean, compactType: CompactType }*/
|
|
850
|
-
)
|
|
851
|
-
/*: CompactType*/
|
|
852
|
-
{
|
|
853
|
-
var _ref3 = props || {},
|
|
854
|
-
verticalCompact = _ref3.verticalCompact,
|
|
855
|
-
compactType = _ref3.compactType;
|
|
701
|
+
}
|
|
856
702
|
|
|
703
|
+
// Legacy support for verticalCompact: false
|
|
704
|
+
function compactType(props /*: ?{ verticalCompact: boolean, compactType: CompactType }*/) /*: CompactType*/{
|
|
705
|
+
const {
|
|
706
|
+
verticalCompact,
|
|
707
|
+
compactType
|
|
708
|
+
} = props || {};
|
|
857
709
|
return verticalCompact === false ? null : compactType;
|
|
858
710
|
}
|
|
859
|
-
|
|
860
711
|
function log() {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
(_console = console).log.apply(_console, arguments);
|
|
712
|
+
if (!DEBUG) return;
|
|
713
|
+
// eslint-disable-next-line no-console
|
|
714
|
+
console.log(...arguments);
|
|
866
715
|
}
|
|
867
|
-
|
|
868
|
-
var noop = function noop() {};
|
|
869
|
-
|
|
716
|
+
const noop = () => {};
|
|
870
717
|
exports.noop = noop;
|