react-grid-layout 2.0.0 → 2.1.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/README.md +117 -28
- package/css/styles.css +0 -1
- package/dist/{ResponsiveGridLayout-D6lFRE3f.d.mts → ResponsiveGridLayout-BkHF9YHa.d.mts} +10 -1
- package/dist/{ResponsiveGridLayout-CH4s0tKj.d.ts → ResponsiveGridLayout-CLn16-X3.d.ts} +10 -1
- package/dist/{calculate-CwYDW8na.d.mts → calculate-DsVTldEE.d.ts} +30 -2
- package/dist/{calculate-mgLpNJ5O.d.ts → calculate-DwbL1D06.d.mts} +30 -2
- package/dist/chunk-526JND3R.mjs +3 -0
- package/dist/{chunk-ZWN22PS2.mjs.map → chunk-526JND3R.mjs.map} +1 -1
- package/dist/chunk-7ELO5FRW.js +4 -0
- package/dist/{chunk-PBQSHIID.js.map → chunk-7ELO5FRW.js.map} +1 -1
- package/dist/chunk-AWM66AWF.mjs +422 -0
- package/dist/chunk-AWM66AWF.mjs.map +1 -0
- package/dist/chunk-BJFPTW5Q.js +449 -0
- package/dist/chunk-BJFPTW5Q.js.map +1 -0
- package/dist/{chunk-4HNUMWQK.mjs → chunk-FLITZMQC.mjs} +198 -311
- package/dist/chunk-FLITZMQC.mjs.map +1 -0
- package/dist/{chunk-ZCXE6SR5.mjs → chunk-LIKX67MZ.mjs} +7 -5
- package/dist/chunk-LIKX67MZ.mjs.map +1 -0
- package/dist/{chunk-R35HZZTA.mjs → chunk-PLWMASMX.mjs} +208 -90
- package/dist/chunk-PLWMASMX.mjs.map +1 -0
- package/dist/{chunk-BFTKGAP3.js → chunk-RB2IKK5B.js} +260 -142
- package/dist/chunk-RB2IKK5B.js.map +1 -0
- package/dist/{chunk-3WO4SAYB.js → chunk-WWS3M5Y3.js} +238 -355
- package/dist/chunk-WWS3M5Y3.js.map +1 -0
- package/dist/{chunk-H5KMDLY3.js → chunk-YQQYHEEG.js} +43 -41
- package/dist/chunk-YQQYHEEG.js.map +1 -0
- package/dist/core.d.mts +159 -6
- package/dist/core.d.ts +159 -6
- package/dist/core.js +145 -85
- package/dist/core.mjs +3 -3
- package/dist/extras.d.mts +133 -3
- package/dist/extras.d.ts +133 -3
- package/dist/extras.js +373 -2
- package/dist/extras.js.map +1 -1
- package/dist/extras.mjs +367 -2
- package/dist/extras.mjs.map +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +64 -64
- package/dist/index.mjs +5 -5
- package/dist/legacy.d.mts +2 -2
- package/dist/legacy.d.ts +2 -2
- package/dist/legacy.js +26 -25
- package/dist/legacy.js.map +1 -1
- package/dist/legacy.mjs +16 -15
- package/dist/legacy.mjs.map +1 -1
- package/dist/{position-Dk2b4ZMS.d.ts → position-CXNzFxI0.d.mts} +18 -7
- package/dist/{position-BmN1z36J.d.mts → position-Dk0FRWA9.d.ts} +18 -7
- package/dist/react.d.mts +11 -5
- package/dist/react.d.ts +11 -5
- package/dist/react.js +38 -38
- package/dist/react.mjs +5 -5
- package/dist/{responsive-CJxefsYw.d.mts → responsive-BB5d98xz.d.mts} +1 -1
- package/dist/{responsive-C4L1ESlm.d.ts → responsive-BXI-GCXG.d.ts} +1 -1
- package/dist/{types-Cxf4nHNr.d.mts → types-CokovIMH.d.mts} +98 -4
- package/dist/{types-Cxf4nHNr.d.ts → types-CokovIMH.d.ts} +98 -4
- package/index-dev.js +16 -0
- package/package.json +5 -3
- package/dist/chunk-2KUHNJXF.mjs +0 -90
- package/dist/chunk-2KUHNJXF.mjs.map +0 -1
- package/dist/chunk-3WO4SAYB.js.map +0 -1
- package/dist/chunk-4HNUMWQK.mjs.map +0 -1
- package/dist/chunk-BFTKGAP3.js.map +0 -1
- package/dist/chunk-F6NQPYKT.js +0 -98
- package/dist/chunk-F6NQPYKT.js.map +0 -1
- package/dist/chunk-H5KMDLY3.js.map +0 -1
- package/dist/chunk-PBQSHIID.js +0 -4
- package/dist/chunk-R35HZZTA.mjs.map +0 -1
- package/dist/chunk-ZCXE6SR5.mjs.map +0 -1
- package/dist/chunk-ZWN22PS2.mjs +0 -3
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// src/core/calculate.ts
|
|
2
|
+
function calcGridColWidth(positionParams) {
|
|
3
|
+
const { margin, containerPadding, containerWidth, cols } = positionParams;
|
|
4
|
+
return (containerWidth - margin[0] * (cols - 1) - containerPadding[0] * 2) / cols;
|
|
5
|
+
}
|
|
6
|
+
function calcGridItemWHPx(gridUnits, colOrRowSize, marginPx) {
|
|
7
|
+
if (!Number.isFinite(gridUnits)) return gridUnits;
|
|
8
|
+
return Math.round(
|
|
9
|
+
colOrRowSize * gridUnits + Math.max(0, gridUnits - 1) * marginPx
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
function calcGridItemPosition(positionParams, x, y, w, h, dragPosition, resizePosition) {
|
|
13
|
+
const { margin, containerPadding, rowHeight } = positionParams;
|
|
14
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
15
|
+
let width;
|
|
16
|
+
let height;
|
|
17
|
+
let top;
|
|
18
|
+
let left;
|
|
19
|
+
if (resizePosition) {
|
|
20
|
+
width = Math.round(resizePosition.width);
|
|
21
|
+
height = Math.round(resizePosition.height);
|
|
22
|
+
} else {
|
|
23
|
+
width = calcGridItemWHPx(w, colWidth, margin[0]);
|
|
24
|
+
height = calcGridItemWHPx(h, rowHeight, margin[1]);
|
|
25
|
+
}
|
|
26
|
+
if (dragPosition) {
|
|
27
|
+
top = Math.round(dragPosition.top);
|
|
28
|
+
left = Math.round(dragPosition.left);
|
|
29
|
+
} else if (resizePosition) {
|
|
30
|
+
top = Math.round(resizePosition.top);
|
|
31
|
+
left = Math.round(resizePosition.left);
|
|
32
|
+
} else {
|
|
33
|
+
top = Math.round((rowHeight + margin[1]) * y + containerPadding[1]);
|
|
34
|
+
left = Math.round((colWidth + margin[0]) * x + containerPadding[0]);
|
|
35
|
+
}
|
|
36
|
+
if (!dragPosition && !resizePosition) {
|
|
37
|
+
if (Number.isFinite(w)) {
|
|
38
|
+
const siblingLeft = Math.round(
|
|
39
|
+
(colWidth + margin[0]) * (x + w) + containerPadding[0]
|
|
40
|
+
);
|
|
41
|
+
const actualMarginRight = siblingLeft - left - width;
|
|
42
|
+
if (actualMarginRight !== margin[0]) {
|
|
43
|
+
width += actualMarginRight - margin[0];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (Number.isFinite(h)) {
|
|
47
|
+
const siblingTop = Math.round(
|
|
48
|
+
(rowHeight + margin[1]) * (y + h) + containerPadding[1]
|
|
49
|
+
);
|
|
50
|
+
const actualMarginBottom = siblingTop - top - height;
|
|
51
|
+
if (actualMarginBottom !== margin[1]) {
|
|
52
|
+
height += actualMarginBottom - margin[1];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { top, left, width, height };
|
|
57
|
+
}
|
|
58
|
+
function calcXY(positionParams, top, left, w, h) {
|
|
59
|
+
const { margin, containerPadding, cols, rowHeight, maxRows } = positionParams;
|
|
60
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
61
|
+
let x = Math.round((left - containerPadding[0]) / (colWidth + margin[0]));
|
|
62
|
+
let y = Math.round((top - containerPadding[1]) / (rowHeight + margin[1]));
|
|
63
|
+
x = clamp(x, 0, cols - w);
|
|
64
|
+
y = clamp(y, 0, maxRows - h);
|
|
65
|
+
return { x, y };
|
|
66
|
+
}
|
|
67
|
+
function calcXYRaw(positionParams, top, left) {
|
|
68
|
+
const { margin, containerPadding, rowHeight } = positionParams;
|
|
69
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
70
|
+
const x = Math.round((left - containerPadding[0]) / (colWidth + margin[0]));
|
|
71
|
+
const y = Math.round((top - containerPadding[1]) / (rowHeight + margin[1]));
|
|
72
|
+
return { x, y };
|
|
73
|
+
}
|
|
74
|
+
function calcWH(positionParams, width, height, x, y, handle) {
|
|
75
|
+
const { margin, maxRows, cols, rowHeight } = positionParams;
|
|
76
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
77
|
+
const w = Math.round((width + margin[0]) / (colWidth + margin[0]));
|
|
78
|
+
const h = Math.round((height + margin[1]) / (rowHeight + margin[1]));
|
|
79
|
+
let _w = clamp(w, 0, cols - x);
|
|
80
|
+
let _h = clamp(h, 0, maxRows - y);
|
|
81
|
+
if (handle === "sw" || handle === "w" || handle === "nw") {
|
|
82
|
+
_w = clamp(w, 0, cols);
|
|
83
|
+
}
|
|
84
|
+
if (handle === "nw" || handle === "n" || handle === "ne") {
|
|
85
|
+
_h = clamp(h, 0, maxRows);
|
|
86
|
+
}
|
|
87
|
+
return { w: _w, h: _h };
|
|
88
|
+
}
|
|
89
|
+
function calcWHRaw(positionParams, width, height) {
|
|
90
|
+
const { margin, rowHeight } = positionParams;
|
|
91
|
+
const colWidth = calcGridColWidth(positionParams);
|
|
92
|
+
const w = Math.max(
|
|
93
|
+
1,
|
|
94
|
+
Math.round((width + margin[0]) / (colWidth + margin[0]))
|
|
95
|
+
);
|
|
96
|
+
const h = Math.max(
|
|
97
|
+
1,
|
|
98
|
+
Math.round((height + margin[1]) / (rowHeight + margin[1]))
|
|
99
|
+
);
|
|
100
|
+
return { w, h };
|
|
101
|
+
}
|
|
102
|
+
function clamp(num, lowerBound, upperBound) {
|
|
103
|
+
return Math.max(Math.min(num, upperBound), lowerBound);
|
|
104
|
+
}
|
|
105
|
+
function calcGridCellDimensions(config) {
|
|
106
|
+
const {
|
|
107
|
+
width,
|
|
108
|
+
cols,
|
|
109
|
+
rowHeight,
|
|
110
|
+
margin = [10, 10],
|
|
111
|
+
containerPadding
|
|
112
|
+
} = config;
|
|
113
|
+
const padding = containerPadding ?? margin;
|
|
114
|
+
const cellWidth = (width - padding[0] * 2 - margin[0] * (cols - 1)) / cols;
|
|
115
|
+
const cellHeight = rowHeight;
|
|
116
|
+
return {
|
|
117
|
+
cellWidth,
|
|
118
|
+
cellHeight,
|
|
119
|
+
offsetX: padding[0],
|
|
120
|
+
offsetY: padding[1],
|
|
121
|
+
gapX: margin[0],
|
|
122
|
+
gapY: margin[1],
|
|
123
|
+
cols,
|
|
124
|
+
containerWidth: width
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/core/collision.ts
|
|
129
|
+
function collides(l1, l2) {
|
|
130
|
+
if (l1.i === l2.i) return false;
|
|
131
|
+
if (l1.x + l1.w <= l2.x) return false;
|
|
132
|
+
if (l1.x >= l2.x + l2.w) return false;
|
|
133
|
+
if (l1.y + l1.h <= l2.y) return false;
|
|
134
|
+
if (l1.y >= l2.y + l2.h) return false;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
function getFirstCollision(layout, layoutItem) {
|
|
138
|
+
for (let i = 0; i < layout.length; i++) {
|
|
139
|
+
const item = layout[i];
|
|
140
|
+
if (item !== void 0 && collides(item, layoutItem)) {
|
|
141
|
+
return item;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return void 0;
|
|
145
|
+
}
|
|
146
|
+
function getAllCollisions(layout, layoutItem) {
|
|
147
|
+
return layout.filter((l) => collides(l, layoutItem));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/core/sort.ts
|
|
151
|
+
function sortLayoutItems(layout, compactType) {
|
|
152
|
+
if (compactType === "horizontal") {
|
|
153
|
+
return sortLayoutItemsByColRow(layout);
|
|
154
|
+
}
|
|
155
|
+
if (compactType === "vertical") {
|
|
156
|
+
return sortLayoutItemsByRowCol(layout);
|
|
157
|
+
}
|
|
158
|
+
if (compactType === "wrap") {
|
|
159
|
+
return sortLayoutItemsByRowCol(layout);
|
|
160
|
+
}
|
|
161
|
+
return [...layout];
|
|
162
|
+
}
|
|
163
|
+
function sortLayoutItemsByRowCol(layout) {
|
|
164
|
+
return [...layout].sort((a, b) => {
|
|
165
|
+
if (a.y !== b.y) {
|
|
166
|
+
return a.y - b.y;
|
|
167
|
+
}
|
|
168
|
+
return a.x - b.x;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function sortLayoutItemsByColRow(layout) {
|
|
172
|
+
return [...layout].sort((a, b) => {
|
|
173
|
+
if (a.x !== b.x) {
|
|
174
|
+
return a.x - b.x;
|
|
175
|
+
}
|
|
176
|
+
return a.y - b.y;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/core/layout.ts
|
|
181
|
+
function bottom(layout) {
|
|
182
|
+
let max = 0;
|
|
183
|
+
for (let i = 0; i < layout.length; i++) {
|
|
184
|
+
const item = layout[i];
|
|
185
|
+
if (item !== void 0) {
|
|
186
|
+
const bottomY = item.y + item.h;
|
|
187
|
+
if (bottomY > max) max = bottomY;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return max;
|
|
191
|
+
}
|
|
192
|
+
function getLayoutItem(layout, id) {
|
|
193
|
+
for (let i = 0; i < layout.length; i++) {
|
|
194
|
+
const item = layout[i];
|
|
195
|
+
if (item !== void 0 && item.i === id) {
|
|
196
|
+
return item;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
}
|
|
201
|
+
function getStatics(layout) {
|
|
202
|
+
return layout.filter((l) => l.static === true);
|
|
203
|
+
}
|
|
204
|
+
function cloneLayoutItem(layoutItem) {
|
|
205
|
+
return {
|
|
206
|
+
i: layoutItem.i,
|
|
207
|
+
x: layoutItem.x,
|
|
208
|
+
y: layoutItem.y,
|
|
209
|
+
w: layoutItem.w,
|
|
210
|
+
h: layoutItem.h,
|
|
211
|
+
minW: layoutItem.minW,
|
|
212
|
+
maxW: layoutItem.maxW,
|
|
213
|
+
minH: layoutItem.minH,
|
|
214
|
+
maxH: layoutItem.maxH,
|
|
215
|
+
moved: Boolean(layoutItem.moved),
|
|
216
|
+
static: Boolean(layoutItem.static),
|
|
217
|
+
isDraggable: layoutItem.isDraggable,
|
|
218
|
+
isResizable: layoutItem.isResizable,
|
|
219
|
+
resizeHandles: layoutItem.resizeHandles,
|
|
220
|
+
constraints: layoutItem.constraints,
|
|
221
|
+
isBounded: layoutItem.isBounded
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function cloneLayout(layout) {
|
|
225
|
+
const newLayout = new Array(layout.length);
|
|
226
|
+
for (let i = 0; i < layout.length; i++) {
|
|
227
|
+
const item = layout[i];
|
|
228
|
+
if (item !== void 0) {
|
|
229
|
+
newLayout[i] = cloneLayoutItem(item);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return newLayout;
|
|
233
|
+
}
|
|
234
|
+
function modifyLayout(layout, layoutItem) {
|
|
235
|
+
const newLayout = new Array(layout.length);
|
|
236
|
+
for (let i = 0; i < layout.length; i++) {
|
|
237
|
+
const item = layout[i];
|
|
238
|
+
if (item !== void 0) {
|
|
239
|
+
if (layoutItem.i === item.i) {
|
|
240
|
+
newLayout[i] = layoutItem;
|
|
241
|
+
} else {
|
|
242
|
+
newLayout[i] = item;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return newLayout;
|
|
247
|
+
}
|
|
248
|
+
function withLayoutItem(layout, itemKey, cb) {
|
|
249
|
+
let item = getLayoutItem(layout, itemKey);
|
|
250
|
+
if (!item) {
|
|
251
|
+
return [[...layout], null];
|
|
252
|
+
}
|
|
253
|
+
item = cb(cloneLayoutItem(item));
|
|
254
|
+
const newLayout = modifyLayout(layout, item);
|
|
255
|
+
return [newLayout, item];
|
|
256
|
+
}
|
|
257
|
+
function correctBounds(layout, bounds) {
|
|
258
|
+
const collidesWith = getStatics(layout);
|
|
259
|
+
for (let i = 0; i < layout.length; i++) {
|
|
260
|
+
const l = layout[i];
|
|
261
|
+
if (l === void 0) continue;
|
|
262
|
+
if (l.x + l.w > bounds.cols) {
|
|
263
|
+
l.x = bounds.cols - l.w;
|
|
264
|
+
}
|
|
265
|
+
if (l.x < 0) {
|
|
266
|
+
l.x = 0;
|
|
267
|
+
l.w = bounds.cols;
|
|
268
|
+
}
|
|
269
|
+
if (!l.static) {
|
|
270
|
+
collidesWith.push(l);
|
|
271
|
+
} else {
|
|
272
|
+
while (getFirstCollision(collidesWith, l)) {
|
|
273
|
+
l.y++;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return layout;
|
|
278
|
+
}
|
|
279
|
+
function moveElement(layout, l, x, y, isUserAction, preventCollision, compactType, cols, allowOverlap) {
|
|
280
|
+
if (l.static && l.isDraggable !== true) {
|
|
281
|
+
return [...layout];
|
|
282
|
+
}
|
|
283
|
+
if (l.y === y && l.x === x) {
|
|
284
|
+
return [...layout];
|
|
285
|
+
}
|
|
286
|
+
const oldX = l.x;
|
|
287
|
+
const oldY = l.y;
|
|
288
|
+
if (typeof x === "number") l.x = x;
|
|
289
|
+
if (typeof y === "number") l.y = y;
|
|
290
|
+
l.moved = true;
|
|
291
|
+
let sorted = sortLayoutItems(layout, compactType);
|
|
292
|
+
const movingUp = compactType === "vertical" && typeof y === "number" ? oldY >= y : compactType === "horizontal" && typeof x === "number" ? oldX >= x : false;
|
|
293
|
+
if (movingUp) {
|
|
294
|
+
sorted = sorted.reverse();
|
|
295
|
+
}
|
|
296
|
+
const collisions = getAllCollisions(sorted, l);
|
|
297
|
+
const hasCollisions = collisions.length > 0;
|
|
298
|
+
if (hasCollisions && allowOverlap) {
|
|
299
|
+
return cloneLayout(layout);
|
|
300
|
+
}
|
|
301
|
+
if (hasCollisions && preventCollision) {
|
|
302
|
+
l.x = oldX;
|
|
303
|
+
l.y = oldY;
|
|
304
|
+
l.moved = false;
|
|
305
|
+
return layout;
|
|
306
|
+
}
|
|
307
|
+
let resultLayout = [...layout];
|
|
308
|
+
for (let i = 0; i < collisions.length; i++) {
|
|
309
|
+
const collision = collisions[i];
|
|
310
|
+
if (collision === void 0) continue;
|
|
311
|
+
if (collision.moved) continue;
|
|
312
|
+
if (collision.static) {
|
|
313
|
+
resultLayout = moveElementAwayFromCollision(
|
|
314
|
+
resultLayout,
|
|
315
|
+
collision,
|
|
316
|
+
l,
|
|
317
|
+
isUserAction,
|
|
318
|
+
compactType);
|
|
319
|
+
} else {
|
|
320
|
+
resultLayout = moveElementAwayFromCollision(
|
|
321
|
+
resultLayout,
|
|
322
|
+
l,
|
|
323
|
+
collision,
|
|
324
|
+
isUserAction,
|
|
325
|
+
compactType);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return resultLayout;
|
|
329
|
+
}
|
|
330
|
+
function moveElementAwayFromCollision(layout, collidesWith, itemToMove, isUserAction, compactType, cols) {
|
|
331
|
+
const compactH = compactType === "horizontal";
|
|
332
|
+
const compactV = compactType === "vertical";
|
|
333
|
+
const preventCollision = collidesWith.static;
|
|
334
|
+
if (isUserAction) {
|
|
335
|
+
isUserAction = false;
|
|
336
|
+
const fakeItem = {
|
|
337
|
+
x: compactH ? Math.max(collidesWith.x - itemToMove.w, 0) : itemToMove.x,
|
|
338
|
+
y: compactV ? Math.max(collidesWith.y - itemToMove.h, 0) : itemToMove.y,
|
|
339
|
+
w: itemToMove.w,
|
|
340
|
+
h: itemToMove.h,
|
|
341
|
+
i: "-1"
|
|
342
|
+
};
|
|
343
|
+
const firstCollision = getFirstCollision(layout, fakeItem);
|
|
344
|
+
const collisionNorth = firstCollision !== void 0 && firstCollision.y + firstCollision.h > collidesWith.y;
|
|
345
|
+
const collisionWest = firstCollision !== void 0 && collidesWith.x + collidesWith.w > firstCollision.x;
|
|
346
|
+
if (!firstCollision) {
|
|
347
|
+
return moveElement(
|
|
348
|
+
layout,
|
|
349
|
+
itemToMove,
|
|
350
|
+
compactH ? fakeItem.x : void 0,
|
|
351
|
+
compactV ? fakeItem.y : void 0,
|
|
352
|
+
isUserAction,
|
|
353
|
+
preventCollision,
|
|
354
|
+
compactType);
|
|
355
|
+
}
|
|
356
|
+
if (collisionNorth && compactV) {
|
|
357
|
+
return moveElement(
|
|
358
|
+
layout,
|
|
359
|
+
itemToMove,
|
|
360
|
+
void 0,
|
|
361
|
+
itemToMove.y + 1,
|
|
362
|
+
isUserAction,
|
|
363
|
+
preventCollision,
|
|
364
|
+
compactType);
|
|
365
|
+
}
|
|
366
|
+
if (collisionNorth && compactType === null) {
|
|
367
|
+
collidesWith.y = itemToMove.y;
|
|
368
|
+
itemToMove.y = itemToMove.y + itemToMove.h;
|
|
369
|
+
return [...layout];
|
|
370
|
+
}
|
|
371
|
+
if (collisionWest && compactH) {
|
|
372
|
+
return moveElement(
|
|
373
|
+
layout,
|
|
374
|
+
collidesWith,
|
|
375
|
+
itemToMove.x,
|
|
376
|
+
void 0,
|
|
377
|
+
isUserAction,
|
|
378
|
+
preventCollision,
|
|
379
|
+
compactType);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const newX = compactH ? itemToMove.x + 1 : void 0;
|
|
383
|
+
const newY = compactV ? itemToMove.y + 1 : void 0;
|
|
384
|
+
if (newX === void 0 && newY === void 0) {
|
|
385
|
+
return [...layout];
|
|
386
|
+
}
|
|
387
|
+
return moveElement(
|
|
388
|
+
layout,
|
|
389
|
+
itemToMove,
|
|
390
|
+
newX,
|
|
391
|
+
newY,
|
|
392
|
+
isUserAction,
|
|
393
|
+
preventCollision,
|
|
394
|
+
compactType);
|
|
395
|
+
}
|
|
396
|
+
function validateLayout(layout, contextName = "Layout") {
|
|
397
|
+
const requiredProps = ["x", "y", "w", "h"];
|
|
398
|
+
if (!Array.isArray(layout)) {
|
|
399
|
+
throw new Error(`${contextName} must be an array!`);
|
|
400
|
+
}
|
|
401
|
+
for (let i = 0; i < layout.length; i++) {
|
|
402
|
+
const item = layout[i];
|
|
403
|
+
if (item === void 0) continue;
|
|
404
|
+
for (const key of requiredProps) {
|
|
405
|
+
const value = item[key];
|
|
406
|
+
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
407
|
+
throw new Error(
|
|
408
|
+
`ReactGridLayout: ${contextName}[${i}].${key} must be a number! Received: ${String(value)} (${typeof value})`
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (item.i !== void 0 && typeof item.i !== "string") {
|
|
413
|
+
throw new Error(
|
|
414
|
+
`ReactGridLayout: ${contextName}[${i}].i must be a string! Received: ${String(item.i)} (${typeof item.i})`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export { bottom, calcGridCellDimensions, calcGridColWidth, calcGridItemPosition, calcGridItemWHPx, calcWH, calcWHRaw, calcXY, calcXYRaw, clamp, cloneLayout, cloneLayoutItem, collides, correctBounds, getAllCollisions, getFirstCollision, getLayoutItem, getStatics, modifyLayout, moveElement, moveElementAwayFromCollision, sortLayoutItems, sortLayoutItemsByColRow, sortLayoutItemsByRowCol, validateLayout, withLayoutItem };
|
|
421
|
+
//# sourceMappingURL=chunk-AWM66AWF.mjs.map
|
|
422
|
+
//# sourceMappingURL=chunk-AWM66AWF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/calculate.ts","../src/core/collision.ts","../src/core/sort.ts","../src/core/layout.ts"],"names":[],"mappings":"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","file":"chunk-AWM66AWF.mjs","sourcesContent":["/**\n * Grid calculation utilities.\n *\n * These functions convert between grid units and pixel positions.\n */\n\nimport type { Position, ResizeHandleAxis } from \"./types.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Parameters needed for position calculations.\n */\nexport interface PositionParams {\n readonly margin: readonly [number, number];\n readonly containerPadding: readonly [number, number];\n readonly containerWidth: number;\n readonly cols: number;\n readonly rowHeight: number;\n readonly maxRows: number;\n}\n\n// ============================================================================\n// Grid Column/Row Calculations\n// ============================================================================\n\n/**\n * Calculate the width of a single grid column in pixels.\n *\n * @param positionParams - Grid parameters\n * @returns Column width in pixels\n */\nexport function calcGridColWidth(positionParams: PositionParams): number {\n const { margin, containerPadding, containerWidth, cols } = positionParams;\n return (\n (containerWidth - margin[0] * (cols - 1) - containerPadding[0] * 2) / cols\n );\n}\n\n/**\n * Calculate the pixel size for a grid unit dimension (width or height).\n *\n * Can be called as:\n * - calcGridItemWHPx(w, colWidth, margin[0]) for width\n * - calcGridItemWHPx(h, rowHeight, margin[1]) for height\n *\n * @param gridUnits - Size in grid units\n * @param colOrRowSize - Column width or row height in pixels\n * @param marginPx - Margin between items in pixels\n * @returns Size in pixels\n */\nexport function calcGridItemWHPx(\n gridUnits: number,\n colOrRowSize: number,\n marginPx: number\n): number {\n // 0 * Infinity === NaN, which causes problems with resize constraints\n if (!Number.isFinite(gridUnits)) return gridUnits;\n return Math.round(\n colOrRowSize * gridUnits + Math.max(0, gridUnits - 1) * marginPx\n );\n}\n\n// ============================================================================\n// Position Calculations\n// ============================================================================\n\n/**\n * Calculate pixel position for a grid item.\n *\n * Returns left, top, width, height in pixels.\n *\n * @param positionParams - Grid parameters\n * @param x - X coordinate in grid units\n * @param y - Y coordinate in grid units\n * @param w - Width in grid units\n * @param h - Height in grid units\n * @param dragPosition - If present, use exact left/top from drag callbacks\n * @param resizePosition - If present, use exact dimensions from resize callbacks\n * @returns Position in pixels\n */\nexport function calcGridItemPosition(\n positionParams: PositionParams,\n x: number,\n y: number,\n w: number,\n h: number,\n dragPosition?: { top: number; left: number } | null,\n resizePosition?: {\n top: number;\n left: number;\n height: number;\n width: number;\n } | null\n): Position {\n const { margin, containerPadding, rowHeight } = positionParams;\n const colWidth = calcGridColWidth(positionParams);\n\n let width: number;\n let height: number;\n let top: number;\n let left: number;\n\n // If resizing, use the exact width and height from resize callbacks\n if (resizePosition) {\n width = Math.round(resizePosition.width);\n height = Math.round(resizePosition.height);\n } else {\n // Calculate from grid units\n width = calcGridItemWHPx(w, colWidth, margin[0]);\n height = calcGridItemWHPx(h, rowHeight, margin[1]);\n }\n\n // If dragging, use the exact left/top from drag callbacks\n if (dragPosition) {\n top = Math.round(dragPosition.top);\n left = Math.round(dragPosition.left);\n } else if (resizePosition) {\n // If resizing, use the exact left/top from resize position\n top = Math.round(resizePosition.top);\n left = Math.round(resizePosition.left);\n } else {\n // Calculate from grid units\n top = Math.round((rowHeight + margin[1]) * y + containerPadding[1]);\n left = Math.round((colWidth + margin[0]) * x + containerPadding[0]);\n }\n\n // When not dragging or resizing, fix margin inconsistencies caused by rounding.\n // Due to Math.round(), the gap between adjacent items can differ from the\n // expected margin (e.g., 0px or 2px instead of 1px). We fix this by comparing\n // where the next sibling would start vs where this item ends, and adjusting\n // the width/height to maintain consistent margins.\n if (!dragPosition && !resizePosition) {\n if (Number.isFinite(w)) {\n // Calculate where the next column's item would start\n const siblingLeft = Math.round(\n (colWidth + margin[0]) * (x + w) + containerPadding[0]\n );\n // Calculate actual margin: sibling start - (our left + our width)\n const actualMarginRight = siblingLeft - left - width;\n // Adjust width if margin doesn't match\n if (actualMarginRight !== margin[0]) {\n width += actualMarginRight - margin[0];\n }\n }\n\n if (Number.isFinite(h)) {\n // Calculate where the next row's item would start\n const siblingTop = Math.round(\n (rowHeight + margin[1]) * (y + h) + containerPadding[1]\n );\n // Calculate actual margin: sibling start - (our top + our height)\n const actualMarginBottom = siblingTop - top - height;\n // Adjust height if margin doesn't match\n if (actualMarginBottom !== margin[1]) {\n height += actualMarginBottom - margin[1];\n }\n }\n }\n\n return { top, left, width, height };\n}\n\n/**\n * Translate pixel coordinates to grid units.\n *\n * @param positionParams - Grid parameters\n * @param top - Top position in pixels (relative to parent)\n * @param left - Left position in pixels (relative to parent)\n * @param w - Width in grid units (for clamping)\n * @param h - Height in grid units (for clamping)\n * @returns x and y in grid units\n */\nexport function calcXY(\n positionParams: PositionParams,\n top: number,\n left: number,\n w: number,\n h: number\n): { x: number; y: number } {\n const { margin, containerPadding, cols, rowHeight, maxRows } = positionParams;\n const colWidth = calcGridColWidth(positionParams);\n\n // left = containerPaddingX + x * (colWidth + marginX)\n // x = (left - containerPaddingX) / (colWidth + marginX)\n let x = Math.round((left - containerPadding[0]) / (colWidth + margin[0]));\n let y = Math.round((top - containerPadding[1]) / (rowHeight + margin[1]));\n\n // Clamp to grid bounds\n x = clamp(x, 0, cols - w);\n y = clamp(y, 0, maxRows - h);\n\n return { x, y };\n}\n\n/**\n * Translate pixel coordinates to grid units without clamping.\n *\n * Use this with the constraint system for custom boundary control.\n *\n * @param positionParams - Grid parameters\n * @param top - Top position in pixels (relative to parent)\n * @param left - Left position in pixels (relative to parent)\n * @returns x and y in grid units (unclamped)\n */\nexport function calcXYRaw(\n positionParams: PositionParams,\n top: number,\n left: number\n): { x: number; y: number } {\n const { margin, containerPadding, rowHeight } = positionParams;\n const colWidth = calcGridColWidth(positionParams);\n\n const x = Math.round((left - containerPadding[0]) / (colWidth + margin[0]));\n const y = Math.round((top - containerPadding[1]) / (rowHeight + margin[1]));\n\n return { x, y };\n}\n\n/**\n * Calculate grid units from pixel dimensions.\n *\n * @param positionParams - Grid parameters\n * @param width - Width in pixels\n * @param height - Height in pixels\n * @param x - X coordinate in grid units (for clamping)\n * @param y - Y coordinate in grid units (for clamping)\n * @param handle - Resize handle being used\n * @returns w, h in grid units\n */\nexport function calcWH(\n positionParams: PositionParams,\n width: number,\n height: number,\n x: number,\n y: number,\n handle: ResizeHandleAxis\n): { w: number; h: number } {\n const { margin, maxRows, cols, rowHeight } = positionParams;\n const colWidth = calcGridColWidth(positionParams);\n\n // width = colWidth * w - (margin * (w - 1))\n // w = (width + margin) / (colWidth + margin)\n const w = Math.round((width + margin[0]) / (colWidth + margin[0]));\n const h = Math.round((height + margin[1]) / (rowHeight + margin[1]));\n\n // Clamp based on resize handle direction\n let _w = clamp(w, 0, cols - x);\n let _h = clamp(h, 0, maxRows - y);\n\n // West handles can resize to full width\n if (handle === \"sw\" || handle === \"w\" || handle === \"nw\") {\n _w = clamp(w, 0, cols);\n }\n\n // North handles can resize to full height\n if (handle === \"nw\" || handle === \"n\" || handle === \"ne\") {\n _h = clamp(h, 0, maxRows);\n }\n\n return { w: _w, h: _h };\n}\n\n/**\n * Calculate grid units from pixel dimensions without clamping.\n *\n * Use this with the constraint system for custom size control.\n *\n * @param positionParams - Grid parameters\n * @param width - Width in pixels\n * @param height - Height in pixels\n * @returns w, h in grid units (unclamped, minimum 1)\n */\nexport function calcWHRaw(\n positionParams: PositionParams,\n width: number,\n height: number\n): { w: number; h: number } {\n const { margin, rowHeight } = positionParams;\n const colWidth = calcGridColWidth(positionParams);\n\n // width = colWidth * w - (margin * (w - 1))\n // w = (width + margin) / (colWidth + margin)\n const w = Math.max(\n 1,\n Math.round((width + margin[0]) / (colWidth + margin[0]))\n );\n const h = Math.max(\n 1,\n Math.round((height + margin[1]) / (rowHeight + margin[1]))\n );\n\n return { w, h };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Clamp a number between bounds.\n *\n * @param num - Number to clamp\n * @param lowerBound - Minimum value\n * @param upperBound - Maximum value\n * @returns Clamped value\n */\nexport function clamp(\n num: number,\n lowerBound: number,\n upperBound: number\n): number {\n return Math.max(Math.min(num, upperBound), lowerBound);\n}\n\n// ============================================================================\n// Grid Background Calculations\n// ============================================================================\n\n/**\n * Grid cell dimension information for rendering backgrounds or overlays.\n */\nexport interface GridCellDimensions {\n /** Width of a single cell in pixels */\n readonly cellWidth: number;\n /** Height of a single cell in pixels */\n readonly cellHeight: number;\n /** Horizontal offset from container edge to first cell */\n readonly offsetX: number;\n /** Vertical offset from container edge to first cell */\n readonly offsetY: number;\n /** Horizontal gap between cells */\n readonly gapX: number;\n /** Vertical gap between cells */\n readonly gapY: number;\n /** Number of columns */\n readonly cols: number;\n /** Total container width */\n readonly containerWidth: number;\n}\n\n/**\n * Configuration for grid cell dimension calculation.\n */\nexport interface GridCellConfig {\n /** Container width in pixels */\n width: number;\n /** Number of columns */\n cols: number;\n /** Row height in pixels */\n rowHeight: number;\n /** Margin between items [x, y] */\n margin?: readonly [number, number];\n /** Container padding [x, y], defaults to margin if not specified */\n containerPadding?: readonly [number, number] | null;\n}\n\n/**\n * Calculate grid cell dimensions for rendering backgrounds or overlays.\n *\n * This function provides all the measurements needed to render a visual\n * grid background that aligns with the actual grid cells.\n *\n * @param config - Grid configuration\n * @returns Cell dimensions and offsets\n *\n * @example\n * ```tsx\n * import { calcGridCellDimensions } from 'react-grid-layout/core';\n *\n * const dims = calcGridCellDimensions({\n * width: 1200,\n * cols: 12,\n * rowHeight: 30,\n * margin: [10, 10],\n * containerPadding: [10, 10]\n * });\n *\n * // dims.cellWidth = 88.33...\n * // dims.cellHeight = 30\n * // dims.offsetX = 10 (containerPadding[0])\n * // dims.offsetY = 10 (containerPadding[1])\n * // dims.gapX = 10 (margin[0])\n * // dims.gapY = 10 (margin[1])\n * ```\n */\nexport function calcGridCellDimensions(\n config: GridCellConfig\n): GridCellDimensions {\n const {\n width,\n cols,\n rowHeight,\n margin = [10, 10],\n containerPadding\n } = config;\n\n // Container padding defaults to margin if not specified\n const padding = containerPadding ?? margin;\n\n // Calculate cell width: total width minus padding and gaps, divided by columns\n // Formula: width = 2*padding + cols*cellWidth + (cols-1)*gap\n // Solving for cellWidth: cellWidth = (width - 2*padding - (cols-1)*gap) / cols\n const cellWidth = (width - padding[0] * 2 - margin[0] * (cols - 1)) / cols;\n const cellHeight = rowHeight;\n\n return {\n cellWidth,\n cellHeight,\n offsetX: padding[0],\n offsetY: padding[1],\n gapX: margin[0],\n gapY: margin[1],\n cols,\n containerWidth: width\n };\n}\n","/**\n * Collision detection utilities for grid layouts.\n *\n * These functions determine if and where layout items overlap.\n */\n\nimport type { Layout, LayoutItem } from \"./types.js\";\n\n/**\n * Check if two layout items collide (overlap).\n *\n * Two items collide if their bounding boxes overlap and they are\n * not the same item.\n *\n * @param l1 - First layout item\n * @param l2 - Second layout item\n * @returns true if the items collide\n */\nexport function collides(l1: LayoutItem, l2: LayoutItem): boolean {\n // Same element - can't collide with itself\n if (l1.i === l2.i) return false;\n\n // Check if bounding boxes don't overlap (any gap means no collision)\n if (l1.x + l1.w <= l2.x) return false; // l1 is completely left of l2\n if (l1.x >= l2.x + l2.w) return false; // l1 is completely right of l2\n if (l1.y + l1.h <= l2.y) return false; // l1 is completely above l2\n if (l1.y >= l2.y + l2.h) return false; // l1 is completely below l2\n\n // Bounding boxes overlap\n return true;\n}\n\n/**\n * Find the first item in the layout that collides with the given item.\n *\n * @param layout - Layout to search\n * @param layoutItem - Item to check for collisions\n * @returns The first colliding item, or undefined if none\n */\nexport function getFirstCollision(\n layout: Layout,\n layoutItem: LayoutItem\n): LayoutItem | undefined {\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item !== undefined && collides(item, layoutItem)) {\n return item;\n }\n }\n return undefined;\n}\n\n/**\n * Find all items in the layout that collide with the given item.\n *\n * @param layout - Layout to search\n * @param layoutItem - Item to check for collisions\n * @returns Array of all colliding items (may be empty)\n */\nexport function getAllCollisions(\n layout: Layout,\n layoutItem: LayoutItem\n): LayoutItem[] {\n return layout.filter((l): l is LayoutItem => collides(l, layoutItem));\n}\n","/**\n * Sorting utilities for grid layouts.\n *\n * These functions sort layout items for compaction and iteration.\n */\n\nimport type { CompactType, Layout, LayoutItem } from \"./types.js\";\n\n/**\n * Sort layout items based on the compaction type.\n *\n * - Vertical compaction: sort by row (y) then column (x)\n * - Horizontal compaction: sort by column (x) then row (y)\n * - No compaction (null): return original order\n *\n * Does not modify the original layout.\n *\n * @param layout - Layout to sort\n * @param compactType - Type of compaction\n * @returns Sorted layout\n */\nexport function sortLayoutItems(\n layout: Layout,\n compactType: CompactType\n): LayoutItem[] {\n if (compactType === \"horizontal\") {\n return sortLayoutItemsByColRow(layout);\n }\n if (compactType === \"vertical\") {\n return sortLayoutItemsByRowCol(layout);\n }\n if (compactType === \"wrap\") {\n // Wrap mode uses row-col order (reading order: left-to-right, top-to-bottom)\n return sortLayoutItemsByRowCol(layout);\n }\n // No compaction - return a copy to maintain immutability\n return [...layout];\n}\n\n/**\n * Sort layout items by row ascending, then column ascending.\n *\n * Items are ordered from top-left to bottom-right, row by row.\n * This is the natural reading order for vertical compaction.\n *\n * Does not modify the original layout.\n *\n * @param layout - Layout to sort\n * @returns Sorted array of layout items\n */\nexport function sortLayoutItemsByRowCol(layout: Layout): LayoutItem[] {\n return [...layout].sort((a, b) => {\n // Primary sort by row (y)\n if (a.y !== b.y) {\n return a.y - b.y;\n }\n // Secondary sort by column (x)\n return a.x - b.x;\n });\n}\n\n/**\n * Sort layout items by column ascending, then row ascending.\n *\n * Items are ordered from top-left to bottom-right, column by column.\n * This is the natural order for horizontal compaction.\n *\n * Does not modify the original layout.\n *\n * @param layout - Layout to sort\n * @returns Sorted array of layout items\n */\nexport function sortLayoutItemsByColRow(layout: Layout): LayoutItem[] {\n return [...layout].sort((a, b) => {\n // Primary sort by column (x)\n if (a.x !== b.x) {\n return a.x - b.x;\n }\n // Secondary sort by row (y)\n return a.y - b.y;\n });\n}\n","/**\n * Core layout manipulation utilities.\n *\n * These functions create, modify, and query grid layouts.\n * All functions treat layouts as immutable - they return new arrays/objects.\n */\n\nimport type { CompactType, Layout, LayoutItem, Mutable } from \"./types.js\";\nimport { getAllCollisions, getFirstCollision } from \"./collision.js\";\nimport { sortLayoutItems } from \"./sort.js\";\n\n// ============================================================================\n// Layout Queries\n// ============================================================================\n\n/**\n * Get the bottom-most Y coordinate of the layout.\n *\n * This is the Y position plus height of the lowest item.\n *\n * @param layout - Layout to measure\n * @returns The bottom Y coordinate (0 if layout is empty)\n */\nexport function bottom(layout: Layout): number {\n let max = 0;\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item !== undefined) {\n const bottomY = item.y + item.h;\n if (bottomY > max) max = bottomY;\n }\n }\n return max;\n}\n\n/**\n * Get a layout item by its ID.\n *\n * @param layout - Layout to search\n * @param id - Item ID to find\n * @returns The layout item, or undefined if not found\n */\nexport function getLayoutItem(\n layout: Layout,\n id: string\n): LayoutItem | undefined {\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item !== undefined && item.i === id) {\n return item;\n }\n }\n return undefined;\n}\n\n/**\n * Get all static items from the layout.\n *\n * Static items cannot be moved or resized by the user.\n *\n * @param layout - Layout to filter\n * @returns Array of static layout items\n */\nexport function getStatics(layout: Layout): LayoutItem[] {\n return layout.filter((l): l is LayoutItem => l.static === true);\n}\n\n// ============================================================================\n// Layout Cloning\n// ============================================================================\n\n/**\n * Clone a layout item.\n *\n * Creates a shallow copy with all properties preserved.\n * Boolean properties are normalized (undefined becomes false).\n *\n * @param layoutItem - Item to clone\n * @returns A new layout item with the same properties\n */\nexport function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {\n return {\n i: layoutItem.i,\n x: layoutItem.x,\n y: layoutItem.y,\n w: layoutItem.w,\n h: layoutItem.h,\n minW: layoutItem.minW,\n maxW: layoutItem.maxW,\n minH: layoutItem.minH,\n maxH: layoutItem.maxH,\n moved: Boolean(layoutItem.moved),\n static: Boolean(layoutItem.static),\n isDraggable: layoutItem.isDraggable,\n isResizable: layoutItem.isResizable,\n resizeHandles: layoutItem.resizeHandles,\n constraints: layoutItem.constraints,\n isBounded: layoutItem.isBounded\n };\n}\n\n/**\n * Clone an entire layout.\n *\n * Creates a new array with cloned items.\n *\n * @param layout - Layout to clone\n * @returns A new layout with cloned items\n */\nexport function cloneLayout(layout: Layout): LayoutItem[] {\n const newLayout: LayoutItem[] = new Array(layout.length);\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item !== undefined) {\n newLayout[i] = cloneLayoutItem(item);\n }\n }\n return newLayout;\n}\n\n// ============================================================================\n// Layout Modification\n// ============================================================================\n\n/**\n * Replace a layout item in a layout.\n *\n * Returns a new layout with the item replaced. Other items are not cloned.\n *\n * @param layout - Layout to modify\n * @param layoutItem - New item (matched by `i` property)\n * @returns New layout with the item replaced\n */\nexport function modifyLayout(\n layout: Layout,\n layoutItem: LayoutItem\n): LayoutItem[] {\n const newLayout: LayoutItem[] = new Array(layout.length);\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item !== undefined) {\n if (layoutItem.i === item.i) {\n newLayout[i] = layoutItem;\n } else {\n newLayout[i] = item;\n }\n }\n }\n return newLayout;\n}\n\n/**\n * Apply a transformation to a layout item.\n *\n * Finds the item by key, clones it, applies the callback, and returns\n * a new layout with the modified item.\n *\n * @param layout - Layout to modify\n * @param itemKey - Key of the item to modify\n * @param cb - Callback that receives the cloned item and returns the modified item\n * @returns Tuple of [new layout, modified item or null if not found]\n */\nexport function withLayoutItem(\n layout: Layout,\n itemKey: string,\n cb: (item: LayoutItem) => LayoutItem\n): [LayoutItem[], LayoutItem | null] {\n let item = getLayoutItem(layout, itemKey);\n if (!item) {\n return [[...layout], null];\n }\n\n // Clone, then modify via callback\n item = cb(cloneLayoutItem(item));\n const newLayout = modifyLayout(layout, item);\n\n return [newLayout, item];\n}\n\n// ============================================================================\n// Bounds Correction\n// ============================================================================\n\n/**\n * Ensure all layout items fit within the grid bounds.\n *\n * - Items overflowing right are moved left\n * - Items overflowing left are moved to x=0 and clamped to grid width\n * - Static items that collide with other statics are moved down\n *\n * **IMPORTANT**: This function mutates the layout items in place for performance.\n * The type signature uses `Mutable<LayoutItem>[]` to make this explicit.\n * Clone the layout first (e.g., with `cloneLayout()`) if you need immutability.\n *\n * @param layout - Layout to correct (items WILL be mutated)\n * @param bounds - Grid bounds\n * @returns The same layout array (for chaining)\n */\nexport function correctBounds(\n layout: Mutable<LayoutItem>[],\n bounds: { cols: number }\n): LayoutItem[] {\n const collidesWith = getStatics(layout);\n\n for (let i = 0; i < layout.length; i++) {\n const l = layout[i];\n if (l === undefined) continue;\n\n // Overflows right\n if (l.x + l.w > bounds.cols) {\n l.x = bounds.cols - l.w;\n }\n\n // Overflows left\n if (l.x < 0) {\n l.x = 0;\n l.w = bounds.cols;\n }\n\n if (!l.static) {\n collidesWith.push(l);\n } else {\n // Static items that collide with other statics must be moved down\n while (getFirstCollision(collidesWith, l)) {\n l.y++;\n }\n }\n }\n\n return layout;\n}\n\n// ============================================================================\n// Move Operations\n// ============================================================================\n\n/**\n * Move a layout element to a new position.\n *\n * Handles collision detection and cascading movements.\n * Does not compact the layout - call `compact()` separately.\n *\n * **Note**: This function mutates the `l` parameter directly for performance.\n * The item's x, y, and moved properties will be modified. Callers should\n * ideally pass a cloned item if they need to preserve the original.\n *\n * @param layout - Full layout\n * @param l - Item to move (will be mutated)\n * @param x - New X position (or undefined to keep current)\n * @param y - New Y position (or undefined to keep current)\n * @param isUserAction - True if this is a direct user action (affects collision resolution)\n * @param preventCollision - True to block movement into occupied space (item snaps back). No effect if allowOverlap is true.\n * @param compactType - Compaction type for collision resolution\n * @param cols - Number of columns in the grid\n * @param allowOverlap - True to allow items to stack on top of each other\n * @returns The updated layout\n */\nexport function moveElement(\n layout: Layout,\n l: LayoutItem,\n x: number | undefined,\n y: number | undefined,\n isUserAction: boolean | undefined,\n preventCollision: boolean | undefined,\n compactType: CompactType,\n cols: number,\n allowOverlap?: boolean\n): LayoutItem[] {\n // Static items can't be moved unless explicitly draggable\n if (l.static && l.isDraggable !== true) {\n return [...layout];\n }\n\n // Short-circuit if position unchanged\n if (l.y === y && l.x === x) {\n return [...layout];\n }\n\n const oldX = l.x;\n const oldY = l.y;\n\n // Update position (mutates l directly - see JSDoc note)\n if (typeof x === \"number\") (l as Mutable<LayoutItem>).x = x;\n if (typeof y === \"number\") (l as Mutable<LayoutItem>).y = y;\n (l as Mutable<LayoutItem>).moved = true;\n\n // Sort for proper collision detection order\n let sorted = sortLayoutItems(layout, compactType);\n const movingUp =\n compactType === \"vertical\" && typeof y === \"number\"\n ? oldY >= y\n : compactType === \"horizontal\" && typeof x === \"number\"\n ? oldX >= x\n : false;\n\n if (movingUp) {\n sorted = sorted.reverse();\n }\n\n const collisions = getAllCollisions(sorted, l);\n const hasCollisions = collisions.length > 0;\n\n // Handle overlap mode - just clone and return\n if (hasCollisions && allowOverlap) {\n return cloneLayout(layout);\n }\n\n // Handle prevent collision mode - revert position\n // Return same reference to signal no change occurred\n if (hasCollisions && preventCollision) {\n (l as Mutable<LayoutItem>).x = oldX;\n (l as Mutable<LayoutItem>).y = oldY;\n (l as Mutable<LayoutItem>).moved = false;\n return layout as LayoutItem[];\n }\n\n // Resolve collisions by moving other items\n let resultLayout: LayoutItem[] = [...layout];\n for (let i = 0; i < collisions.length; i++) {\n const collision = collisions[i];\n if (collision === undefined) continue;\n\n // Skip already-moved items to prevent infinite loops\n if (collision.moved) continue;\n\n // Static items can't be moved - move the dragged item instead\n if (collision.static) {\n resultLayout = moveElementAwayFromCollision(\n resultLayout,\n collision,\n l,\n isUserAction,\n compactType,\n cols\n );\n } else {\n resultLayout = moveElementAwayFromCollision(\n resultLayout,\n l,\n collision,\n isUserAction,\n compactType,\n cols\n );\n }\n }\n\n return resultLayout;\n}\n\n/**\n * Move an item away from a collision.\n *\n * Attempts to move the item up/left first if there's room,\n * otherwise moves it down/right.\n *\n * @param layout - Full layout\n * @param collidesWith - The item being collided with\n * @param itemToMove - The item to move away\n * @param isUserAction - True if this is a direct user action\n * @param compactType - Compaction type\n * @param cols - Number of columns\n * @returns Updated layout\n */\nexport function moveElementAwayFromCollision(\n layout: Layout,\n collidesWith: LayoutItem,\n itemToMove: LayoutItem,\n isUserAction: boolean | undefined,\n compactType: CompactType,\n cols: number\n): LayoutItem[] {\n const compactH = compactType === \"horizontal\";\n const compactV = compactType === \"vertical\";\n const preventCollision = collidesWith.static;\n\n // Try to move up/left first (only on primary collision from user action)\n if (isUserAction) {\n isUserAction = false; // Only try this once\n\n // Create a fake item to test if there's room above/left\n const fakeItem: LayoutItem = {\n x: compactH ? Math.max(collidesWith.x - itemToMove.w, 0) : itemToMove.x,\n y: compactV ? Math.max(collidesWith.y - itemToMove.h, 0) : itemToMove.y,\n w: itemToMove.w,\n h: itemToMove.h,\n i: \"-1\"\n };\n\n const firstCollision = getFirstCollision(layout, fakeItem);\n const collisionNorth =\n firstCollision !== undefined &&\n firstCollision.y + firstCollision.h > collidesWith.y;\n const collisionWest =\n firstCollision !== undefined &&\n collidesWith.x + collidesWith.w > firstCollision.x;\n\n // No collision above/left - we can move there\n if (!firstCollision) {\n return moveElement(\n layout,\n itemToMove,\n compactH ? fakeItem.x : undefined,\n compactV ? fakeItem.y : undefined,\n isUserAction,\n preventCollision,\n compactType,\n cols\n );\n }\n\n // Handle specific collision cases\n if (collisionNorth && compactV) {\n return moveElement(\n layout,\n itemToMove,\n undefined,\n itemToMove.y + 1,\n isUserAction,\n preventCollision,\n compactType,\n cols\n );\n }\n\n if (collisionNorth && compactType === null) {\n // Swap positions in free-form mode\n (collidesWith as Mutable<LayoutItem>).y = itemToMove.y;\n (itemToMove as Mutable<LayoutItem>).y = itemToMove.y + itemToMove.h;\n return [...layout];\n }\n\n if (collisionWest && compactH) {\n return moveElement(\n layout,\n collidesWith,\n itemToMove.x,\n undefined,\n isUserAction,\n preventCollision,\n compactType,\n cols\n );\n }\n }\n\n // Default: move down/right by 1\n const newX = compactH ? itemToMove.x + 1 : undefined;\n const newY = compactV ? itemToMove.y + 1 : undefined;\n\n if (newX === undefined && newY === undefined) {\n return [...layout];\n }\n\n return moveElement(\n layout,\n itemToMove,\n newX,\n newY,\n isUserAction,\n preventCollision,\n compactType,\n cols\n );\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Validate that a layout has the required properties.\n *\n * @param layout - Layout to validate\n * @param contextName - Name for error messages\n * @throws Error if layout is invalid\n */\nexport function validateLayout(\n layout: Layout,\n contextName: string = \"Layout\"\n): void {\n const requiredProps = [\"x\", \"y\", \"w\", \"h\"] as const;\n\n if (!Array.isArray(layout)) {\n throw new Error(`${contextName} must be an array!`);\n }\n\n for (let i = 0; i < layout.length; i++) {\n const item = layout[i];\n if (item === undefined) continue;\n\n for (const key of requiredProps) {\n const value = item[key];\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new Error(\n `ReactGridLayout: ${contextName}[${i}].${key} must be a number! ` +\n `Received: ${String(value)} (${typeof value})`\n );\n }\n }\n\n if (item.i !== undefined && typeof item.i !== \"string\") {\n throw new Error(\n `ReactGridLayout: ${contextName}[${i}].i must be a string! ` +\n `Received: ${String(item.i)} (${typeof item.i})`\n );\n }\n }\n}\n"]}
|