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