gridstack 12.2.1 → 12.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +3 -3
- package/dist/angular/README.md +2 -0
- package/dist/angular/esm2020/lib/base-widget.mjs +63 -7
- package/dist/angular/esm2020/lib/gridstack-item.component.mjs +33 -4
- package/dist/angular/esm2020/lib/gridstack.component.mjs +97 -16
- package/dist/angular/esm2020/lib/gridstack.module.mjs +25 -3
- package/dist/angular/esm2020/lib/types.mjs +2 -2
- package/dist/angular/fesm2015/gridstack-angular.mjs +191 -25
- package/dist/angular/fesm2015/gridstack-angular.mjs.map +1 -1
- package/dist/angular/fesm2020/gridstack-angular.mjs +192 -26
- package/dist/angular/fesm2020/gridstack-angular.mjs.map +1 -1
- package/dist/angular/lib/base-widget.d.ts +42 -5
- package/dist/angular/lib/gridstack-item.component.d.ts +49 -7
- package/dist/angular/lib/gridstack.component.d.ts +137 -22
- package/dist/angular/lib/gridstack.module.d.ts +23 -0
- package/dist/angular/lib/types.d.ts +32 -5
- package/dist/angular/package.json +1 -1
- package/dist/angular/src/base-widget.ts +68 -9
- package/dist/angular/src/gridstack-item.component.ts +49 -7
- package/dist/angular/src/gridstack.component.ts +154 -23
- package/dist/angular/src/gridstack.module.ts +24 -2
- package/dist/angular/src/types.ts +54 -0
- package/dist/dd-base-impl.d.ts +52 -3
- package/dist/dd-base-impl.js +41 -3
- package/dist/dd-base-impl.js.map +1 -1
- package/dist/dd-draggable.d.ts +2 -2
- package/dist/dd-draggable.js +4 -2
- package/dist/dd-draggable.js.map +1 -1
- package/dist/dd-droppable.d.ts +2 -2
- package/dist/dd-droppable.js +2 -2
- package/dist/dd-droppable.js.map +1 -1
- package/dist/dd-element.d.ts +2 -2
- package/dist/dd-element.js +2 -2
- package/dist/dd-element.js.map +1 -1
- package/dist/dd-gridstack.d.ts +54 -6
- package/dist/dd-gridstack.js +32 -2
- package/dist/dd-gridstack.js.map +1 -1
- package/dist/dd-manager.d.ts +29 -8
- package/dist/dd-manager.js +7 -3
- package/dist/dd-manager.js.map +1 -1
- package/dist/dd-resizable-handle.d.ts +2 -2
- package/dist/dd-resizable-handle.js +2 -2
- package/dist/dd-resizable-handle.js.map +1 -1
- package/dist/dd-resizable.d.ts +2 -2
- package/dist/dd-resizable.js +2 -2
- package/dist/dd-resizable.js.map +1 -1
- package/dist/dd-touch.d.ts +2 -2
- package/dist/dd-touch.js +2 -2
- package/dist/dd-touch.js.map +1 -1
- package/dist/gridstack-all.js +1 -1
- package/dist/gridstack-all.js.LICENSE.txt +2 -2
- package/dist/gridstack-all.js.map +1 -1
- package/dist/gridstack-engine.d.ts +235 -26
- package/dist/gridstack-engine.js +276 -30
- package/dist/gridstack-engine.js.map +1 -1
- package/dist/gridstack.css +2 -2
- package/dist/gridstack.d.ts +424 -82
- package/dist/gridstack.js +416 -79
- package/dist/gridstack.js.map +1 -1
- package/dist/src/gridstack.scss +2 -2
- package/dist/types.d.ts +132 -31
- package/dist/types.js +6 -3
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +208 -29
- package/dist/utils.js +275 -61
- package/dist/utils.js.map +1 -1
- package/doc/API.md +6192 -0
- package/package.json +14 -3
- package/doc/CHANGES.md +0 -955
- package/doc/README.md +0 -642
package/dist/gridstack-engine.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* gridstack-engine.ts 12.
|
|
3
|
-
* Copyright (c) 2021-
|
|
2
|
+
* gridstack-engine.ts 12.3.0
|
|
3
|
+
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
|
4
4
|
*/
|
|
5
5
|
import { Utils } from './utils';
|
|
6
6
|
/**
|
|
7
|
-
* Defines the GridStack engine that
|
|
8
|
-
*
|
|
7
|
+
* Defines the GridStack engine that handles all grid layout calculations and node positioning.
|
|
8
|
+
* This is the core engine that performs grid manipulation without any DOM operations.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* The engine manages:
|
|
11
|
+
* - Node positioning and collision detection
|
|
12
|
+
* - Layout algorithms (compact, float, etc.)
|
|
13
|
+
* - Grid resizing and column changes
|
|
14
|
+
* - Widget movement and resizing logic
|
|
15
|
+
*
|
|
16
|
+
* NOTE: Values should not be modified directly - use the main GridStack API instead
|
|
17
|
+
* to ensure proper DOM updates and event triggers.
|
|
11
18
|
*/
|
|
12
19
|
class GridStackEngine {
|
|
13
20
|
constructor(opts = {}) {
|
|
@@ -22,6 +29,21 @@ class GridStackEngine {
|
|
|
22
29
|
this.nodes = opts.nodes || [];
|
|
23
30
|
this.onChange = opts.onChange;
|
|
24
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Enable/disable batch mode for multiple operations to optimize performance.
|
|
34
|
+
* When enabled, layout updates are deferred until batch mode is disabled.
|
|
35
|
+
*
|
|
36
|
+
* @param flag true to enable batch mode, false to disable and apply changes
|
|
37
|
+
* @param doPack if true (default), pack/compact nodes when disabling batch mode
|
|
38
|
+
* @returns the engine instance for chaining
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Start batch mode for multiple operations
|
|
42
|
+
* engine.batchUpdate(true);
|
|
43
|
+
* engine.addNode(node1);
|
|
44
|
+
* engine.addNode(node2);
|
|
45
|
+
* engine.batchUpdate(false); // Apply all changes at once
|
|
46
|
+
*/
|
|
25
47
|
batchUpdate(flag = true, doPack = true) {
|
|
26
48
|
if (!!this.batchMode === flag)
|
|
27
49
|
return this;
|
|
@@ -101,12 +123,39 @@ class GridStackEngine {
|
|
|
101
123
|
}
|
|
102
124
|
return didMove;
|
|
103
125
|
}
|
|
104
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Return the first node that intercepts/collides with the given node or area.
|
|
128
|
+
* Used for collision detection during drag and drop operations.
|
|
129
|
+
*
|
|
130
|
+
* @param skip the node to skip in collision detection (usually the node being moved)
|
|
131
|
+
* @param area the area to check for collisions (defaults to skip node's area)
|
|
132
|
+
* @param skip2 optional second node to skip in collision detection
|
|
133
|
+
* @returns the first colliding node, or undefined if no collision
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* const colliding = engine.collide(draggedNode, {x: 2, y: 1, w: 2, h: 1});
|
|
137
|
+
* if (colliding) {
|
|
138
|
+
* console.log('Would collide with:', colliding.id);
|
|
139
|
+
* }
|
|
140
|
+
*/
|
|
105
141
|
collide(skip, area = skip, skip2) {
|
|
106
142
|
const skipId = skip._id;
|
|
107
143
|
const skip2Id = skip2?._id;
|
|
108
144
|
return this.nodes.find(n => n._id !== skipId && n._id !== skip2Id && Utils.isIntercepted(n, area));
|
|
109
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Return all nodes that intercept/collide with the given node or area.
|
|
148
|
+
* Similar to collide() but returns all colliding nodes instead of just the first.
|
|
149
|
+
*
|
|
150
|
+
* @param skip the node to skip in collision detection
|
|
151
|
+
* @param area the area to check for collisions (defaults to skip node's area)
|
|
152
|
+
* @param skip2 optional second node to skip in collision detection
|
|
153
|
+
* @returns array of all colliding nodes
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* const allCollisions = engine.collideAll(draggedNode);
|
|
157
|
+
* console.log('Colliding with', allCollisions.length, 'nodes');
|
|
158
|
+
*/
|
|
110
159
|
collideAll(skip, area = skip, skip2) {
|
|
111
160
|
const skipId = skip._id;
|
|
112
161
|
const skip2Id = skip2?._id;
|
|
@@ -180,7 +229,20 @@ class GridStackEngine {
|
|
|
180
229
|
return {collide, over: overMax};
|
|
181
230
|
}
|
|
182
231
|
*/
|
|
183
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* Cache the pixel rectangles for all nodes used for collision detection during drag operations.
|
|
234
|
+
* This optimization converts grid coordinates to pixel coordinates for faster collision detection.
|
|
235
|
+
*
|
|
236
|
+
* @param w width of a single grid cell in pixels
|
|
237
|
+
* @param h height of a single grid cell in pixels
|
|
238
|
+
* @param top top margin/padding in pixels
|
|
239
|
+
* @param right right margin/padding in pixels
|
|
240
|
+
* @param bottom bottom margin/padding in pixels
|
|
241
|
+
* @param left left margin/padding in pixels
|
|
242
|
+
* @returns the engine instance for chaining
|
|
243
|
+
*
|
|
244
|
+
* @internal This is typically called by GridStack during resize events
|
|
245
|
+
*/
|
|
184
246
|
cacheRects(w, h, top, right, bottom, left) {
|
|
185
247
|
this.nodes.forEach(n => n._rect = {
|
|
186
248
|
y: n.y * h + top,
|
|
@@ -190,7 +252,20 @@ class GridStackEngine {
|
|
|
190
252
|
});
|
|
191
253
|
return this;
|
|
192
254
|
}
|
|
193
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* Attempt to swap the positions of two nodes if they meet swapping criteria.
|
|
257
|
+
* Nodes can swap if they are the same size or in the same column/row, not locked, and touching.
|
|
258
|
+
*
|
|
259
|
+
* @param a first node to swap
|
|
260
|
+
* @param b second node to swap
|
|
261
|
+
* @returns true if swap was successful, false if not possible, undefined if not applicable
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* const swapped = engine.swap(nodeA, nodeB);
|
|
265
|
+
* if (swapped) {
|
|
266
|
+
* console.log('Nodes swapped successfully');
|
|
267
|
+
* }
|
|
268
|
+
*/
|
|
194
269
|
swap(a, b) {
|
|
195
270
|
if (!b || b.locked || !a || a.locked)
|
|
196
271
|
return false;
|
|
@@ -241,11 +316,41 @@ class GridStackEngine {
|
|
|
241
316
|
}
|
|
242
317
|
return false;
|
|
243
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Check if the specified rectangular area is empty (no nodes occupy any part of it).
|
|
321
|
+
*
|
|
322
|
+
* @param x the x coordinate (column) of the area to check
|
|
323
|
+
* @param y the y coordinate (row) of the area to check
|
|
324
|
+
* @param w the width in columns of the area to check
|
|
325
|
+
* @param h the height in rows of the area to check
|
|
326
|
+
* @returns true if the area is completely empty, false if any node overlaps
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* if (engine.isAreaEmpty(2, 1, 3, 2)) {
|
|
330
|
+
* console.log('Area is available for placement');
|
|
331
|
+
* }
|
|
332
|
+
*/
|
|
244
333
|
isAreaEmpty(x, y, w, h) {
|
|
245
334
|
const nn = { x: x || 0, y: y || 0, w: w || 1, h: h || 1 };
|
|
246
335
|
return !this.collide(nn);
|
|
247
336
|
}
|
|
248
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* Re-layout grid items to reclaim any empty space.
|
|
339
|
+
* This optimizes the grid layout by moving items to fill gaps.
|
|
340
|
+
*
|
|
341
|
+
* @param layout layout algorithm to use:
|
|
342
|
+
* - 'compact' (default): find truly empty spaces, may reorder items
|
|
343
|
+
* - 'list': keep the sort order exactly the same, move items up sequentially
|
|
344
|
+
* @param doSort if true (default), sort nodes by position before compacting
|
|
345
|
+
* @returns the engine instance for chaining
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* // Compact to fill empty spaces
|
|
349
|
+
* engine.compact();
|
|
350
|
+
*
|
|
351
|
+
* // Compact preserving item order
|
|
352
|
+
* engine.compact('list');
|
|
353
|
+
*/
|
|
249
354
|
compact(layout = 'compact', doSort = true) {
|
|
250
355
|
if (this.nodes.length === 0)
|
|
251
356
|
return this;
|
|
@@ -274,7 +379,17 @@ class GridStackEngine {
|
|
|
274
379
|
this.batchUpdate(false);
|
|
275
380
|
return this;
|
|
276
381
|
}
|
|
277
|
-
/**
|
|
382
|
+
/**
|
|
383
|
+
* Enable/disable floating widgets (default: `false`).
|
|
384
|
+
* When floating is enabled, widgets can move up to fill empty spaces.
|
|
385
|
+
* See [example](http://gridstackjs.com/demo/float.html)
|
|
386
|
+
*
|
|
387
|
+
* @param val true to enable floating, false to disable
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* engine.float = true; // Enable floating
|
|
391
|
+
* engine.float = false; // Disable floating (default)
|
|
392
|
+
*/
|
|
278
393
|
set float(val) {
|
|
279
394
|
if (this._float === val)
|
|
280
395
|
return;
|
|
@@ -283,9 +398,27 @@ class GridStackEngine {
|
|
|
283
398
|
this._packNodes()._notify();
|
|
284
399
|
}
|
|
285
400
|
}
|
|
286
|
-
/**
|
|
401
|
+
/**
|
|
402
|
+
* Get the current floating mode setting.
|
|
403
|
+
*
|
|
404
|
+
* @returns true if floating is enabled, false otherwise
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* const isFloating = engine.float;
|
|
408
|
+
* console.log('Floating enabled:', isFloating);
|
|
409
|
+
*/
|
|
287
410
|
get float() { return this._float || false; }
|
|
288
|
-
/**
|
|
411
|
+
/**
|
|
412
|
+
* Sort the nodes array from first to last, or reverse.
|
|
413
|
+
* This is called during collision/placement operations to enforce a specific order.
|
|
414
|
+
*
|
|
415
|
+
* @param dir sort direction: 1 for ascending (first to last), -1 for descending (last to first)
|
|
416
|
+
* @returns the engine instance for chaining
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* engine.sortNodes(); // Sort ascending (default)
|
|
420
|
+
* engine.sortNodes(-1); // Sort descending
|
|
421
|
+
*/
|
|
289
422
|
sortNodes(dir = 1) {
|
|
290
423
|
this.nodes = Utils.sort(this.nodes, dir);
|
|
291
424
|
return this;
|
|
@@ -333,9 +466,17 @@ class GridStackEngine {
|
|
|
333
466
|
return this;
|
|
334
467
|
}
|
|
335
468
|
/**
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
469
|
+
* Prepare and validate a node's coordinates and values for the current grid.
|
|
470
|
+
* This ensures the node has valid position, size, and properties before being added to the grid.
|
|
471
|
+
*
|
|
472
|
+
* @param node the node to prepare and validate
|
|
473
|
+
* @param resizing if true, resize the node down if it's out of bounds; if false, move it to fit
|
|
474
|
+
* @returns the prepared node with valid coordinates
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* const node = { w: 3, h: 2, content: 'Hello' };
|
|
478
|
+
* const prepared = engine.prepareNode(node);
|
|
479
|
+
* console.log('Node prepared at:', prepared.x, prepared.y);
|
|
339
480
|
*/
|
|
340
481
|
prepareNode(node, resizing) {
|
|
341
482
|
node._id = node._id ?? GridStackEngine._idSeq++;
|
|
@@ -394,7 +535,19 @@ class GridStackEngine {
|
|
|
394
535
|
this.nodeBoundFix(node, resizing);
|
|
395
536
|
return node;
|
|
396
537
|
}
|
|
397
|
-
/**
|
|
538
|
+
/**
|
|
539
|
+
* Part 2 of preparing a node to fit inside the grid - validates and fixes coordinates and dimensions.
|
|
540
|
+
* This ensures the node fits within grid boundaries and respects min/max constraints.
|
|
541
|
+
*
|
|
542
|
+
* @param node the node to validate and fix
|
|
543
|
+
* @param resizing if true, resize the node to fit; if false, move the node to fit
|
|
544
|
+
* @returns the engine instance for chaining
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* // Fix a node that might be out of bounds
|
|
548
|
+
* engine.nodeBoundFix(node, true); // Resize to fit
|
|
549
|
+
* engine.nodeBoundFix(node, false); // Move to fit
|
|
550
|
+
*/
|
|
398
551
|
nodeBoundFix(node, resizing) {
|
|
399
552
|
const before = node._orig || Utils.copyPos({}, node);
|
|
400
553
|
if (node.maxW) {
|
|
@@ -413,7 +566,7 @@ class GridStackEngine {
|
|
|
413
566
|
// remember it's position & width so we can restore back (1 -> 12 column) #1655 #1985
|
|
414
567
|
// IFF we're not in the middle of column resizing!
|
|
415
568
|
const saveOrig = (node.x || 0) + (node.w || 1) > this.column;
|
|
416
|
-
if (saveOrig && this.column < this.defaultColumn && !this._inColumnResize && !this.skipCacheUpdate && node._id && this.findCacheLayout(node, this.defaultColumn) === -1) {
|
|
569
|
+
if (saveOrig && this.column < this.defaultColumn && !this._inColumnResize && !this.skipCacheUpdate && node._id != null && this.findCacheLayout(node, this.defaultColumn) === -1) {
|
|
417
570
|
const copy = { ...node }; // need _id + positions
|
|
418
571
|
if (copy.autoPosition || copy.x === undefined) {
|
|
419
572
|
delete copy.x;
|
|
@@ -463,7 +616,20 @@ class GridStackEngine {
|
|
|
463
616
|
}
|
|
464
617
|
return this;
|
|
465
618
|
}
|
|
466
|
-
/**
|
|
619
|
+
/**
|
|
620
|
+
* Returns a list of nodes that have been modified from their original values.
|
|
621
|
+
* This is used to track which nodes need DOM updates.
|
|
622
|
+
*
|
|
623
|
+
* @param verify if true, performs additional verification by comparing current vs original positions
|
|
624
|
+
* @returns array of nodes that have been modified
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* const changed = engine.getDirtyNodes();
|
|
628
|
+
* console.log('Modified nodes:', changed.length);
|
|
629
|
+
*
|
|
630
|
+
* // Get verified dirty nodes
|
|
631
|
+
* const verified = engine.getDirtyNodes(true);
|
|
632
|
+
*/
|
|
467
633
|
getDirtyNodes(verify) {
|
|
468
634
|
// compare original x,y,w,h instead as _dirty can be a temporary state
|
|
469
635
|
if (verify) {
|
|
@@ -479,7 +645,14 @@ class GridStackEngine {
|
|
|
479
645
|
this.onChange(dirtyNodes);
|
|
480
646
|
return this;
|
|
481
647
|
}
|
|
482
|
-
/**
|
|
648
|
+
/**
|
|
649
|
+
* Clean all dirty and last tried information from nodes.
|
|
650
|
+
* This resets the dirty state tracking for all nodes.
|
|
651
|
+
*
|
|
652
|
+
* @returns the engine instance for chaining
|
|
653
|
+
*
|
|
654
|
+
* @internal
|
|
655
|
+
*/
|
|
483
656
|
cleanNodes() {
|
|
484
657
|
if (this.batchMode)
|
|
485
658
|
return this;
|
|
@@ -489,9 +662,16 @@ class GridStackEngine {
|
|
|
489
662
|
});
|
|
490
663
|
return this;
|
|
491
664
|
}
|
|
492
|
-
/**
|
|
493
|
-
*
|
|
494
|
-
*
|
|
665
|
+
/**
|
|
666
|
+
* Save the initial position/size of all nodes to track real dirty state.
|
|
667
|
+
* This creates a snapshot of current positions that can be restored later.
|
|
668
|
+
*
|
|
669
|
+
* Note: Should be called right after change events and before move/resize operations.
|
|
670
|
+
*
|
|
671
|
+
* @returns the engine instance for chaining
|
|
672
|
+
*
|
|
673
|
+
* @internal
|
|
674
|
+
*/
|
|
495
675
|
saveInitial() {
|
|
496
676
|
this.nodes.forEach(n => {
|
|
497
677
|
n._orig = Utils.copyPos({}, n);
|
|
@@ -500,7 +680,14 @@ class GridStackEngine {
|
|
|
500
680
|
this._hasLocked = this.nodes.some(n => n.locked);
|
|
501
681
|
return this;
|
|
502
682
|
}
|
|
503
|
-
/**
|
|
683
|
+
/**
|
|
684
|
+
* Restore all nodes back to their initial values.
|
|
685
|
+
* This is typically called when canceling an operation (e.g., Esc key during drag).
|
|
686
|
+
*
|
|
687
|
+
* @returns the engine instance for chaining
|
|
688
|
+
*
|
|
689
|
+
* @internal
|
|
690
|
+
*/
|
|
504
691
|
restoreInitial() {
|
|
505
692
|
this.nodes.forEach(n => {
|
|
506
693
|
if (!n._orig || Utils.samePos(n, n._orig))
|
|
@@ -511,9 +698,21 @@ class GridStackEngine {
|
|
|
511
698
|
this._notify();
|
|
512
699
|
return this;
|
|
513
700
|
}
|
|
514
|
-
/**
|
|
515
|
-
*
|
|
516
|
-
*
|
|
701
|
+
/**
|
|
702
|
+
* Find the first available empty spot for the given node dimensions.
|
|
703
|
+
* Updates the node's x,y attributes with the found position.
|
|
704
|
+
*
|
|
705
|
+
* @param node the node to find a position for (w,h must be set)
|
|
706
|
+
* @param nodeList optional list of nodes to check against (defaults to engine nodes)
|
|
707
|
+
* @param column optional column count (defaults to engine column count)
|
|
708
|
+
* @param after optional node to start search after (maintains order)
|
|
709
|
+
* @returns true if an empty position was found and node was updated
|
|
710
|
+
*
|
|
711
|
+
* @example
|
|
712
|
+
* const node = { w: 2, h: 1 };
|
|
713
|
+
* if (engine.findEmptyPosition(node)) {
|
|
714
|
+
* console.log('Found position at:', node.x, node.y);
|
|
715
|
+
* }
|
|
517
716
|
*/
|
|
518
717
|
findEmptyPosition(node, nodeList = this.nodes, column = this.column, after) {
|
|
519
718
|
const start = after ? after.y * column + (after.x + after.w) : 0;
|
|
@@ -536,7 +735,19 @@ class GridStackEngine {
|
|
|
536
735
|
}
|
|
537
736
|
return found;
|
|
538
737
|
}
|
|
539
|
-
/**
|
|
738
|
+
/**
|
|
739
|
+
* Add the given node to the grid, handling collision detection and re-packing.
|
|
740
|
+
* This is the main method for adding new widgets to the engine.
|
|
741
|
+
*
|
|
742
|
+
* @param node the node to add to the grid
|
|
743
|
+
* @param triggerAddEvent if true, adds node to addedNodes list for event triggering
|
|
744
|
+
* @param after optional node to place this node after (for ordering)
|
|
745
|
+
* @returns the added node (or existing node if duplicate)
|
|
746
|
+
*
|
|
747
|
+
* @example
|
|
748
|
+
* const node = { x: 0, y: 0, w: 2, h: 1, content: 'Hello' };
|
|
749
|
+
* const added = engine.addNode(node, true);
|
|
750
|
+
*/
|
|
540
751
|
addNode(node, triggerAddEvent = false, after) {
|
|
541
752
|
const dup = this.nodes.find(n => n._id === node._id);
|
|
542
753
|
if (dup)
|
|
@@ -561,6 +772,17 @@ class GridStackEngine {
|
|
|
561
772
|
}
|
|
562
773
|
return node;
|
|
563
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* Remove the given node from the grid.
|
|
777
|
+
*
|
|
778
|
+
* @param node the node to remove
|
|
779
|
+
* @param removeDOM if true (default), marks node for DOM removal
|
|
780
|
+
* @param triggerEvent if true, adds node to removedNodes list for event triggering
|
|
781
|
+
* @returns the engine instance for chaining
|
|
782
|
+
*
|
|
783
|
+
* @example
|
|
784
|
+
* engine.removeNode(node, true, true);
|
|
785
|
+
*/
|
|
564
786
|
removeNode(node, removeDOM = true, triggerEvent = false) {
|
|
565
787
|
if (!this.nodes.find(n => n._id === node._id)) {
|
|
566
788
|
// TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)
|
|
@@ -578,6 +800,16 @@ class GridStackEngine {
|
|
|
578
800
|
this._notify([node]);
|
|
579
801
|
return this;
|
|
580
802
|
}
|
|
803
|
+
/**
|
|
804
|
+
* Remove all nodes from the grid.
|
|
805
|
+
*
|
|
806
|
+
* @param removeDOM if true (default), marks all nodes for DOM removal
|
|
807
|
+
* @param triggerEvent if true (default), triggers removal events
|
|
808
|
+
* @returns the engine instance for chaining
|
|
809
|
+
*
|
|
810
|
+
* @example
|
|
811
|
+
* engine.removeAll(); // Remove all nodes
|
|
812
|
+
*/
|
|
581
813
|
removeAll(removeDOM = true, triggerEvent = true) {
|
|
582
814
|
delete this._layouts;
|
|
583
815
|
if (!this.nodes.length)
|
|
@@ -588,9 +820,23 @@ class GridStackEngine {
|
|
|
588
820
|
this.nodes = [];
|
|
589
821
|
return this._notify(removedNodes);
|
|
590
822
|
}
|
|
591
|
-
/**
|
|
592
|
-
*
|
|
593
|
-
*
|
|
823
|
+
/**
|
|
824
|
+
* Check if a node can be moved to a new position, considering layout constraints.
|
|
825
|
+
* This is a safer version of moveNode() that validates the move first.
|
|
826
|
+
*
|
|
827
|
+
* For complex cases (like maxRow constraints), it simulates the move in a clone first,
|
|
828
|
+
* then applies the changes only if they meet all specifications.
|
|
829
|
+
*
|
|
830
|
+
* @param node the node to move
|
|
831
|
+
* @param o move options including target position
|
|
832
|
+
* @returns true if the node was successfully moved
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* const canMove = engine.moveNodeCheck(node, { x: 2, y: 1 });
|
|
836
|
+
* if (canMove) {
|
|
837
|
+
* console.log('Node moved successfully');
|
|
838
|
+
* }
|
|
839
|
+
*/
|
|
594
840
|
moveNodeCheck(node, o) {
|
|
595
841
|
// if (node.locked) return false;
|
|
596
842
|
if (!this.changedPosConstrain(node, o))
|