gridstack 9.5.0 → 10.0.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.
Files changed (114) hide show
  1. package/README.md +11 -1
  2. package/angular/package.json +1 -1
  3. package/angular/projects/demo/src/app/app.component.ts +0 -2
  4. package/angular/projects/lib/package.json +1 -1
  5. package/angular/projects/lib/src/lib/base-widget.ts +1 -1
  6. package/angular/projects/lib/src/lib/gridstack-item.component.ts +1 -1
  7. package/angular/projects/lib/src/lib/gridstack.component.ts +1 -1
  8. package/angular/projects/lib/src/lib/gridstack.module.ts +1 -1
  9. package/dist/angular/esm2020/lib/base-widget.mjs +2 -2
  10. package/dist/angular/esm2020/lib/gridstack-item.component.mjs +2 -2
  11. package/dist/angular/esm2020/lib/gridstack.component.mjs +2 -2
  12. package/dist/angular/esm2020/lib/gridstack.module.mjs +2 -2
  13. package/dist/angular/fesm2015/gridstack-angular.mjs +4 -4
  14. package/dist/angular/fesm2015/gridstack-angular.mjs.map +1 -1
  15. package/dist/angular/fesm2020/gridstack-angular.mjs +4 -4
  16. package/dist/angular/fesm2020/gridstack-angular.mjs.map +1 -1
  17. package/dist/angular/lib/gridstack-item.component.d.ts +1 -1
  18. package/dist/angular/lib/gridstack.component.d.ts +1 -1
  19. package/dist/angular/package.json +1 -1
  20. package/dist/angular/src/base-widget.ts +1 -1
  21. package/dist/angular/src/gridstack-item.component.ts +1 -1
  22. package/dist/angular/src/gridstack.component.ts +1 -1
  23. package/dist/angular/src/gridstack.module.ts +1 -1
  24. package/dist/dd-base-impl.d.ts +1 -1
  25. package/dist/dd-base-impl.js +1 -1
  26. package/dist/dd-base-impl.js.map +1 -1
  27. package/dist/dd-draggable.d.ts +1 -1
  28. package/dist/dd-draggable.js +2 -2
  29. package/dist/dd-draggable.js.map +1 -1
  30. package/dist/dd-droppable.d.ts +1 -1
  31. package/dist/dd-droppable.js +1 -1
  32. package/dist/dd-droppable.js.map +1 -1
  33. package/dist/dd-element.d.ts +1 -1
  34. package/dist/dd-element.js +1 -1
  35. package/dist/dd-element.js.map +1 -1
  36. package/dist/dd-gridstack.d.ts +1 -1
  37. package/dist/dd-gridstack.js +1 -1
  38. package/dist/dd-gridstack.js.map +1 -1
  39. package/dist/dd-manager.d.ts +1 -1
  40. package/dist/dd-manager.js +1 -1
  41. package/dist/dd-manager.js.map +1 -1
  42. package/dist/dd-resizable-handle.d.ts +1 -1
  43. package/dist/dd-resizable-handle.js +1 -1
  44. package/dist/dd-resizable-handle.js.map +1 -1
  45. package/dist/dd-resizable.d.ts +1 -1
  46. package/dist/dd-resizable.js +1 -1
  47. package/dist/dd-resizable.js.map +1 -1
  48. package/dist/dd-touch.d.ts +1 -1
  49. package/dist/dd-touch.js +1 -1
  50. package/dist/dd-touch.js.map +1 -1
  51. package/dist/es5/dd-base-impl.d.ts +1 -1
  52. package/dist/es5/dd-base-impl.js +1 -1
  53. package/dist/es5/dd-base-impl.js.map +1 -1
  54. package/dist/es5/dd-draggable.d.ts +1 -1
  55. package/dist/es5/dd-draggable.js +2 -2
  56. package/dist/es5/dd-draggable.js.map +1 -1
  57. package/dist/es5/dd-droppable.d.ts +1 -1
  58. package/dist/es5/dd-droppable.js +1 -1
  59. package/dist/es5/dd-droppable.js.map +1 -1
  60. package/dist/es5/dd-element.d.ts +1 -1
  61. package/dist/es5/dd-element.js +1 -1
  62. package/dist/es5/dd-element.js.map +1 -1
  63. package/dist/es5/dd-gridstack.d.ts +1 -1
  64. package/dist/es5/dd-gridstack.js +1 -1
  65. package/dist/es5/dd-gridstack.js.map +1 -1
  66. package/dist/es5/dd-manager.d.ts +1 -1
  67. package/dist/es5/dd-manager.js +1 -1
  68. package/dist/es5/dd-manager.js.map +1 -1
  69. package/dist/es5/dd-resizable-handle.d.ts +1 -1
  70. package/dist/es5/dd-resizable-handle.js +1 -1
  71. package/dist/es5/dd-resizable-handle.js.map +1 -1
  72. package/dist/es5/dd-resizable.d.ts +1 -1
  73. package/dist/es5/dd-resizable.js +1 -1
  74. package/dist/es5/dd-resizable.js.map +1 -1
  75. package/dist/es5/dd-touch.d.ts +1 -1
  76. package/dist/es5/dd-touch.js +1 -1
  77. package/dist/es5/dd-touch.js.map +1 -1
  78. package/dist/es5/gridstack-all.js +1 -1
  79. package/dist/es5/gridstack-all.js.LICENSE.txt +1 -1
  80. package/dist/es5/gridstack-all.js.map +1 -1
  81. package/dist/es5/gridstack-engine.d.ts +6 -6
  82. package/dist/es5/gridstack-engine.js +12 -7
  83. package/dist/es5/gridstack-engine.js.map +1 -1
  84. package/dist/es5/gridstack-poly.js +1 -1
  85. package/dist/es5/gridstack.d.ts +5 -3
  86. package/dist/es5/gridstack.js +104 -65
  87. package/dist/es5/gridstack.js.map +1 -1
  88. package/dist/es5/types.d.ts +25 -11
  89. package/dist/es5/types.js +1 -4
  90. package/dist/es5/types.js.map +1 -1
  91. package/dist/es5/utils.d.ts +1 -1
  92. package/dist/es5/utils.js +1 -1
  93. package/dist/es5/utils.js.map +1 -1
  94. package/dist/gridstack-all.js +1 -1
  95. package/dist/gridstack-all.js.LICENSE.txt +1 -1
  96. package/dist/gridstack-all.js.map +1 -1
  97. package/dist/gridstack-engine.d.ts +6 -6
  98. package/dist/gridstack-engine.js +11 -7
  99. package/dist/gridstack-engine.js.map +1 -1
  100. package/dist/gridstack.css +9 -3
  101. package/dist/gridstack.d.ts +5 -3
  102. package/dist/gridstack.js +98 -62
  103. package/dist/gridstack.js.map +1 -1
  104. package/dist/gridstack.min.css +1 -1
  105. package/dist/src/gridstack.scss +9 -3
  106. package/dist/types.d.ts +25 -11
  107. package/dist/types.js +1 -4
  108. package/dist/types.js.map +1 -1
  109. package/dist/utils.d.ts +1 -1
  110. package/dist/utils.js +1 -1
  111. package/dist/utils.js.map +1 -1
  112. package/doc/CHANGES.md +12 -0
  113. package/doc/README.md +17 -4
  114. package/package.json +1 -1
package/dist/gridstack.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * GridStack 9.5.0
2
+ * GridStack 10.0.0
3
3
  * https://gridstackjs.com/
4
4
  *
5
5
  * Copyright (c) 2021-2022 Alain Dumesny
@@ -17,7 +17,6 @@ import { gridDefaults, dragInDefaultOptions } from './types';
17
17
  import { DDGridStack } from './dd-gridstack';
18
18
  import { isTouch } from './dd-touch';
19
19
  import { DDManager } from './dd-manager';
20
- /** global instance */
21
20
  const dd = new DDGridStack;
22
21
  // export all dependent file as well to make it easier for users to just import the main file
23
22
  export * from './types';
@@ -175,6 +174,41 @@ class GridStack {
175
174
  if (opts.alwaysShowResizeHandle !== undefined) {
176
175
  opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;
177
176
  }
177
+ let bk = opts.columnOpts?.breakpoints;
178
+ // LEGACY: oneColumnMode stuff changed in v10.x - check if user explicitly set something to convert over
179
+ const oldOpts = opts;
180
+ if (oldOpts.oneColumnModeDomSort) {
181
+ delete oldOpts.oneColumnModeDomSort;
182
+ console.log('Error: Gridstack oneColumnModeDomSort no longer supported. Check GridStackOptions.columnOpts instead.');
183
+ }
184
+ if (oldOpts.oneColumnSize || oldOpts.disableOneColumnMode === false) {
185
+ const oneSize = oldOpts.oneColumnSize || 768;
186
+ delete oldOpts.oneColumnSize;
187
+ delete oldOpts.disableOneColumnMode;
188
+ opts.columnOpts = opts.columnOpts || {};
189
+ bk = opts.columnOpts.breakpoints = opts.columnOpts.breakpoints || [];
190
+ let oneColumn = bk.find(b => b.c === 1);
191
+ if (!oneColumn) {
192
+ oneColumn = { c: 1, w: oneSize };
193
+ bk.push(oneColumn, { c: 12, w: oneSize + 1 });
194
+ }
195
+ else
196
+ oneColumn.w = oneSize;
197
+ }
198
+ //...end LEGACY
199
+ // cleanup responsive opts (must have columnWidth | breakpoints) then sort breakpoints by size (so we can match during resize)
200
+ const resp = opts.columnOpts;
201
+ if (resp) {
202
+ if (!resp.columnWidth && !resp.breakpoints?.length) {
203
+ delete opts.columnOpts;
204
+ bk = undefined;
205
+ }
206
+ else {
207
+ resp.columnMax = resp.columnMax || 12;
208
+ }
209
+ }
210
+ if (bk?.length > 1)
211
+ bk.sort((a, b) => (b.w || 0) - (a.w || 0));
178
212
  // elements DOM attributes override any passed options (like CSS style) - merge the two together
179
213
  let defaults = { ...Utils.cloneDeep(gridDefaults),
180
214
  column: Utils.toNumber(el.getAttribute('gs-column')) || gridDefaults.column,
@@ -196,10 +230,7 @@ class GridStack {
196
230
  opts = null; // make sure we use this.opts instead
197
231
  this._initMargin(); // part of settings defaults...
198
232
  // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)
199
- if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {
200
- this._prevColumn = this.getColumn();
201
- this.opts.column = 1;
202
- }
233
+ this.checkDynamicColumn();
203
234
  if (this.opts.rtl === 'auto') {
204
235
  this.opts.rtl = (el.style.direction === 'rtl');
205
236
  }
@@ -380,7 +411,7 @@ class GridStack {
380
411
  if (ops.column === 'auto') {
381
412
  autoColumn = true;
382
413
  ops.column = Math.max(node.w || 1, nodeToAdd?.w || 1);
383
- ops.disableOneColumnMode = true; // driven by parent
414
+ delete ops.columnOpts; // driven by parent
384
415
  }
385
416
  // if we're converting an existing full item, move over the content to be the first sub item in the new grid
386
417
  let content = node.el.querySelector('.grid-stack-item-content');
@@ -516,7 +547,6 @@ class GridStack {
516
547
  }
517
548
  if (this._autoColumn) {
518
549
  o.column = 'auto';
519
- delete o.disableOneColumnMode;
520
550
  }
521
551
  const origShow = o._alwaysShowResizeHandle;
522
552
  delete o._alwaysShowResizeHandle;
@@ -544,16 +574,17 @@ class GridStack {
544
574
  */
545
575
  load(items, addRemove = GridStack.addRemoveCB || true) {
546
576
  items = Utils.cloneDeep(items); // so we can mod
547
- // if passed list has coordinates, use them (insert from end to beginning for conflict resolution) else force widget same order
577
+ const column = this.getColumn();
578
+ // if passed list has coordinates, use them (insert from end to beginning for conflict resolution) else keep widget order
548
579
  const haveCoord = items.some(w => w.x !== undefined || w.y !== undefined);
549
580
  if (haveCoord)
550
- items = Utils.sort(items, -1, this._prevColumn || this.getColumn());
581
+ items = Utils.sort(items, -1, column);
551
582
  this._insertNotAppend = haveCoord; // if we create in reverse order...
552
- // if we're loading a layout into for example 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save
583
+ // if we're loading a layout into for example 1 column and items don't fit, make sure to save
553
584
  // the original wanted layout so we can scale back up correctly #1471
554
- if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => ((n.x || 0) + n.w) > this.opts.column)) {
585
+ if (items.some(n => ((n.x || 0) + (n.w || 1)) > column)) {
555
586
  this._ignoreLayoutsNodeChange = true; // skip layout update
556
- this.engine.cacheLayout(items, this._prevColumn, true);
587
+ this.engine.cacheLayout(items, 12, true); // TODO: 12 is arbitrary. use max value in layout ?
557
588
  }
558
589
  // if given a different callback, temporally set it as global option so creating will use it
559
590
  const prevCB = GridStack.addRemoveCB;
@@ -594,6 +625,7 @@ class GridStack {
594
625
  if (Utils.shouldSizeToContent(item))
595
626
  w.h = item.h;
596
627
  // check if missing coord, in which case find next empty slot with new (or old if missing) sizes
628
+ this.engine.nodeBoundFix(w); // before widthChanged is checked below...
597
629
  if (w.autoPosition || w.x === undefined || w.y === undefined) {
598
630
  w.w = w.w || item.w;
599
631
  w.h = w.h || item.h;
@@ -604,7 +636,6 @@ class GridStack {
604
636
  this.engine.nodes.push(item);
605
637
  if (Utils.samePos(item, w)) {
606
638
  this.moveNode(item, { ...w, forceCollide: true });
607
- Utils.copyPos(w, item, true);
608
639
  }
609
640
  this.update(item.el, w);
610
641
  if (w.subGridOpts?.children) { // update any sub grid as well
@@ -707,11 +738,37 @@ class GridStack {
707
738
  cellWidth() {
708
739
  return this._widthOrContainer() / this.getColumn();
709
740
  }
710
- /** return our expected width (or parent) for 1 column check */
711
- _widthOrContainer() {
741
+ /** return our expected width (or parent) , and optionally of window for dynamic column check */
742
+ _widthOrContainer(forBreakpoint = false) {
712
743
  // use `offsetWidth` or `clientWidth` (no scrollbar) ?
713
744
  // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
714
- return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);
745
+ return forBreakpoint && this.opts.columnOpts?.breakpointForWindow ? window.innerWidth : (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);
746
+ }
747
+ /** checks for dynamic column count for our current size, returning true if changed */
748
+ checkDynamicColumn() {
749
+ const resp = this.opts.columnOpts;
750
+ if (!resp || (!resp.columnWidth && !resp.breakpoints?.length))
751
+ return false;
752
+ const column = this.getColumn();
753
+ let newColumn = column;
754
+ const w = this._widthOrContainer(true);
755
+ if (resp.columnWidth) {
756
+ newColumn = Math.min(Math.round(w / resp.columnWidth) || 1, resp.columnMax);
757
+ }
758
+ else {
759
+ // find the closest breakpoint (already sorted big to small) that matches
760
+ newColumn = resp.columnMax;
761
+ let i = 0;
762
+ while (i < resp.breakpoints.length && w <= resp.breakpoints[i].w) {
763
+ newColumn = resp.breakpoints[i++].c || column;
764
+ }
765
+ }
766
+ if (newColumn !== column) {
767
+ const bk = resp.breakpoints?.find(b => b.c === newColumn);
768
+ this.column(newColumn, bk?.layout || resp.layout);
769
+ return true;
770
+ }
771
+ return false;
715
772
  }
716
773
  /**
717
774
  * re-layout grid items to reclaim any empty space. Options are:
@@ -738,31 +795,16 @@ class GridStack {
738
795
  if (!column || column < 1 || this.opts.column === column)
739
796
  return this;
740
797
  let oldColumn = this.getColumn();
741
- // if we go into 1 column mode due to size change (disableOneColumnMode is off and we hit min width)
742
- // then remember the original columns so we can restore.
743
- if (column === 1 && !this.opts.disableOneColumnMode) {
744
- this._prevColumn = oldColumn;
745
- }
746
- else {
747
- delete this._prevColumn;
748
- }
798
+ this.opts.column = column;
799
+ if (!this.engine)
800
+ return this; // called in constructor, noting else to do
801
+ this.engine.column = column;
749
802
  this.el.classList.remove('gs-' + oldColumn);
750
803
  this.el.classList.add('gs-' + column);
751
- this.opts.column = this.engine.column = column;
752
- // update the items now - see if the dom order nodes should be passed instead (else default to current list)
753
- let domNodes;
754
- if (column === 1 && this.opts.oneColumnModeDomSort) {
755
- domNodes = [];
756
- this.getGridItems().forEach(el => {
757
- if (el.gridstackNode) {
758
- domNodes.push(el.gridstackNode);
759
- }
760
- });
761
- if (!domNodes.length) {
762
- domNodes = undefined;
763
- }
764
- }
765
- this.engine.columnChanged(oldColumn, column, domNodes, layout);
804
+ // update the items now, checking if we have a custom children layout
805
+ /*const newChildren = this.opts.columnOpts?.breakpoints?.find(r => r.c === column)?.children;
806
+ if (newChildren) this.load(newChildren);
807
+ else*/ this.engine.columnChanged(oldColumn, column, undefined, layout);
766
808
  if (this._isAutoCellHeight)
767
809
  this.cellHeight();
768
810
  this.doContentResize();
@@ -775,9 +817,7 @@ class GridStack {
775
817
  /**
776
818
  * get the number of columns in the grid (default 12)
777
819
  */
778
- getColumn() {
779
- return this.opts.column;
780
- }
820
+ getColumn() { return this.opts.column; }
781
821
  /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */
782
822
  getGridItems() {
783
823
  return Array.from(this.el.children)
@@ -894,9 +934,9 @@ class GridStack {
894
934
  if (node.subGridOpts) {
895
935
  this.makeSubGrid(el, node.subGridOpts, undefined, false); // node.subGrid will be used as option in method, no need to pass
896
936
  }
897
- // if we're adding an item into 1 column (_prevColumn is set only when going to 1) make sure
937
+ // if we're adding an item into 1 column make sure
898
938
  // we don't override the larger 12 column layout that was already saved. #1985
899
- if (this._prevColumn && this.opts.column === 1) {
939
+ if (this.opts.column === 1) {
900
940
  this._ignoreLayoutsNodeChange = true;
901
941
  }
902
942
  this._triggerAddEvent();
@@ -927,8 +967,8 @@ class GridStack {
927
967
  names.forEach(name => this.on(name, callback));
928
968
  return this;
929
969
  }
970
+ // native CustomEvent handlers - cash the generic handlers so we can easily remove
930
971
  if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
931
- // native CustomEvent handlers - cash the generic handlers so we can easily remove
932
972
  let noData = (name === 'enable' || name === 'disable');
933
973
  if (noData) {
934
974
  this._gsEventHandler[name] = (event) => callback(event);
@@ -945,7 +985,7 @@ class GridStack {
945
985
  this._gsEventHandler[name] = callback;
946
986
  }
947
987
  else {
948
- console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');
988
+ console.log('GridStack.on(' + name + ') event not supported');
949
989
  }
950
990
  return this;
951
991
  }
@@ -1077,6 +1117,7 @@ class GridStack {
1077
1117
  if (!n)
1078
1118
  return;
1079
1119
  let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items
1120
+ this.engine.nodeBoundFix(w);
1080
1121
  delete w.autoPosition;
1081
1122
  delete w.id;
1082
1123
  // move/resize widget if anything changed
@@ -1118,10 +1159,10 @@ class GridStack {
1118
1159
  }
1119
1160
  }
1120
1161
  Utils.sanitizeMinMax(n);
1121
- // finally move the widget
1122
- if (m !== undefined)
1162
+ // finally move the widget and update attr
1163
+ if (m)
1123
1164
  this.moveNode(n, m);
1124
- if (changed) { // move will only update x,y,w,h so update the rest too
1165
+ if (m || changed) {
1125
1166
  this._writeAttr(el, n);
1126
1167
  }
1127
1168
  if (ddChanged) {
@@ -1526,15 +1567,8 @@ class GridStack {
1526
1567
  }
1527
1568
  }
1528
1569
  else {
1529
- // else check for 1 column in/out behavior
1530
- let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize ||
1531
- (this.opts.column === 1 && !this._prevColumn);
1532
- if ((this.opts.column === 1) !== oneColumn) {
1533
- // if (this.opts.animate) this.setAnimation(false); // 1 <-> 12 is too radical, turn off animation and we need it for sizeToContent
1534
- this.column(oneColumn ? 1 : this._prevColumn);
1535
- // if (this.opts.animate) setTimeout(() => this.setAnimation(true));
1536
- columnChanged = true;
1537
- }
1570
+ // else check for dynamic column
1571
+ columnChanged = this.checkDynamicColumn();
1538
1572
  }
1539
1573
  // make the cells content square again
1540
1574
  if (this._isAutoCellHeight)
@@ -1554,6 +1588,8 @@ class GridStack {
1554
1588
  // update any gridItem height with sizeToContent, but wait for DOM $animation_speed to settle if we changed column count
1555
1589
  // TODO: is there a way to know what the final (post animation) size of the content will be so we can animate the column width and height together rather than sequentially ?
1556
1590
  setTimeout(() => {
1591
+ if (!this.engine)
1592
+ return; // we've been deleted in between!
1557
1593
  if (n) {
1558
1594
  if (Utils.shouldSizeToContent(n))
1559
1595
  this.resizeToContentCheck(n.el, useAttr);
@@ -1574,9 +1610,9 @@ class GridStack {
1574
1610
  }
1575
1611
  /** add or remove the grid element size event handler */
1576
1612
  _updateResizeEvent(forceRemove = false) {
1577
- // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)
1613
+ // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting dynamic column (i.e. doing work)
1578
1614
  // or supporting new sizeToContent option.
1579
- const trackSize = !this.parentGridItem && (this._isAutoCellHeight || this.opts.sizeToContent || !this.opts.disableOneColumnMode
1615
+ const trackSize = !this.parentGridItem && (this._isAutoCellHeight || this.opts.sizeToContent || this.opts.columnOpts
1580
1616
  || this.engine.nodes.find(n => n.sizeToContent));
1581
1617
  if (!forceRemove && trackSize && !this.resizeObserver) {
1582
1618
  this._sizeThrottle = Utils.throttle(() => this.onResize(), this.opts.cellHeightThrottle);
@@ -2301,6 +2337,6 @@ GridStack.resizeToContentParent = '.grid-stack-item-content';
2301
2337
  GridStack.Utils = Utils;
2302
2338
  /** scoping so users can call new GridStack.Engine(12) for example */
2303
2339
  GridStack.Engine = GridStackEngine;
2304
- GridStack.GDRev = '9.5.0';
2340
+ GridStack.GDRev = '10.0.0';
2305
2341
  export { GridStack };
2306
2342
  //# sourceMappingURL=gridstack.js.map