Skip to content

Commit d2d94f9

Browse files
authored
Merge pull request #2867 from adumesny/master
more nested grid reflow
2 parents f5f7c9a + 33bcc6c commit d2d94f9

File tree

4 files changed

+121
-13
lines changed

4 files changed

+121
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>2864 nest grid resize</title>
8+
<link rel="stylesheet" href="../../../demo/demo.css"/>
9+
<link rel="stylesheet" href="../../../dist/gridstack-extra.css"/>
10+
<script src="../../../dist/gridstack-all.js"></script>
11+
</head>
12+
<body>
13+
<h1>2864 nest grid resize</h1>
14+
<p>Test for nested grid resize reflowing content (manually and API)</p>
15+
<a class="btn btn-primary" onClick="step1()" href="#">resize</a>
16+
<div class="grid-stack">
17+
<!-- <div class="grid-stack-item" gs-x="0" gs-y="0" gs-w="4" gs-h="2" gs-id="gsItem1" id="item1">
18+
<div class="grid-stack-item-content">item 1 text</div>
19+
</div>
20+
<div class="grid-stack-item" gs-x="4" gs-y="0" gs-w="4" gs-h="4" gs-id="gsItem2" id="item2">
21+
<div class="grid-stack-item-content">item 2 text</div>
22+
</div> -->
23+
</div>
24+
<script type="text/javascript">
25+
// test for spec file debugging
26+
let margin = 5;
27+
let cellHeight = 70;
28+
let children = [{},{},{}];
29+
let items = [
30+
{x: 0, y: 0, w:3, h:3, sizeToContent: true,
31+
subGridOpts: {children, column: 'auto', margin, cellHeight}}
32+
];
33+
let count = 0;
34+
[...items, ...children].forEach(n => { n.id = String(count++); if (count>1) n.content=n.id});
35+
grid = GridStack.init({cellHeight: cellHeight+20, margin, children: items});
36+
37+
step1 = function() {
38+
grid.update(grid.engine.nodes[0].el, {w:2});
39+
}
40+
</script>
41+
</body>
42+
</html>

spec/regression-spec.ts

+51
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ describe('regression >', function() {
77
let findEl = function(id: string): GridItemHTMLElement {
88
return grid.engine.nodes.find(n => n.id === id)!.el!;
99
};
10+
let findSubEl = function(id: string, index = 0): GridItemHTMLElement {
11+
return grid.engine.nodes[index].subGrid?.engine.nodes.find(n => n.id === id)!.el!;
12+
};
13+
1014

1115
// empty grid
1216
let gridstackEmptyHTML =
@@ -55,4 +59,51 @@ describe('regression >', function() {
5559
expect(parseInt(el2.getAttribute('gs-y'), 10)).toBe(0);
5660
});
5761
});
62+
63+
describe('2865 nested grid resize >', function() {
64+
beforeEach(function() {
65+
document.body.insertAdjacentHTML('afterbegin', gridstackEmptyHTML);
66+
});
67+
afterEach(function() {
68+
document.body.removeChild(document.getElementById('gs-cont'));
69+
});
70+
it('', function() {
71+
let children: GridStackWidget[] = [{},{},{}];
72+
let items: GridStackWidget[] = [
73+
{x: 0, y: 0, w:3, h:3, sizeToContent: true, subGridOpts: {children, column: 'auto'}}
74+
];
75+
let count = 0;
76+
[...items, ...children].forEach(n => n.id = String(count++));
77+
grid = GridStack.init({cellHeight: 70, margin: 5, children: items});
78+
79+
let nested = findEl('0');
80+
let el1 = findSubEl('1');
81+
let el2 = findSubEl('2');
82+
let el3 = findSubEl('3');
83+
expect(parseInt(nested.getAttribute('gs-x'), 10)).toBe(0);
84+
expect(parseInt(nested.getAttribute('gs-y'), 10)).toBe(0);
85+
expect(parseInt(nested.getAttribute('gs-w'), 10)).toBe(3);
86+
expect(nested.getAttribute('gs-h')).toBe(null); // sizeToContent 3 -> 1 which is null
87+
expect(parseInt(el1.getAttribute('gs-x'), 10)).toBe(0);
88+
expect(parseInt(el1.getAttribute('gs-y'), 10)).toBe(0);
89+
expect(parseInt(el2.getAttribute('gs-x'), 10)).toBe(1);
90+
expect(parseInt(el2.getAttribute('gs-y'), 10)).toBe(0);
91+
expect(parseInt(el3.getAttribute('gs-x'), 10)).toBe(2);
92+
expect(parseInt(el3.getAttribute('gs-y'), 10)).toBe(0);
93+
94+
// now resize the nested grid to 2 -> should reflow el3
95+
grid.update(nested, {w:2});
96+
expect(parseInt(nested.getAttribute('gs-x'), 10)).toBe(0);
97+
expect(parseInt(nested.getAttribute('gs-y'), 10)).toBe(0);
98+
expect(parseInt(nested.getAttribute('gs-w'), 10)).toBe(2);
99+
expect(nested.getAttribute('gs-h')).toBe(null); // sizeToContent not called until some delay
100+
expect(parseInt(el1.getAttribute('gs-x'), 10)).toBe(0);
101+
expect(parseInt(el1.getAttribute('gs-y'), 10)).toBe(0);
102+
expect(parseInt(el2.getAttribute('gs-x'), 10)).toBe(1);
103+
expect(parseInt(el2.getAttribute('gs-y'), 10)).toBe(0);
104+
// 3rd item pushed to next row
105+
expect(parseInt(el3.getAttribute('gs-x'), 10)).toBe(0);
106+
expect(parseInt(el3.getAttribute('gs-y'), 10)).toBe(1);
107+
});
108+
});
58109
});

spec/test.html

+12-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1">
77
<title>Grid Spec test</title>
88
<link rel="stylesheet" href="../demo/demo.css"/>
9+
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
910
<script src="../dist/gridstack-all.js"></script>
1011
</head>
1112
<body>
@@ -22,15 +23,21 @@ <h1>Grid Spec test</h1>
2223
</div>
2324
<script type="text/javascript">
2425
// test for spec file debugging
25-
let items = [{ x:0, y:0, w:12, h:1, id:'left', content:'left' }, { x:12, y:0, w:12, h:1, id:'right', content:'right' }];
26-
27-
let grid = GridStack.init({cellHeight:50, margin:5, children:items});
26+
let margin = 5;
27+
let cellHeight = 70;
28+
let children = [{},{},{}];
29+
let items = [
30+
{x: 0, y: 0, w:3, h:3, sizeToContent: true,
31+
subGridOpts: {children, column: 'auto', margin, cellHeight}}
32+
];
33+
let count = 0;
34+
[...items, ...children].forEach(n => { n.id = String(count++); if (count>1) n.content=n.id});
35+
grid = GridStack.init({cellHeight: cellHeight+20, margin, children: items});
2836

2937
step1 = function() {
30-
grid.column(1);
38+
grid.update(grid.engine.nodes[0].el, {w:2});
3139
}
3240
step2 = function() {
33-
grid.column(12);
3441
}
3542
</script>
3643
</body>

src/gridstack.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ export class GridStack {
219219
/** point to a parent grid item if we're nested (inside a grid-item in between 2 Grids) */
220220
public parentGridNode?: GridStackNode;
221221

222+
/** time to wait for animation (if enabled) to be done so content sizing can happen */
223+
public animationDelay = 300 + 10;
224+
222225
protected static engineClass: typeof GridStackEngine;
223226
protected resizeObserver: ResizeObserver;
224227

@@ -1345,7 +1348,12 @@ export class GridStack {
13451348
if (m) {
13461349
const widthChanged = (m.w !== undefined && m.w !== n.w);
13471350
this.moveNode(n, m);
1348-
this.resizeToContentCheck(widthChanged, n); // wait for animation if we changed width
1351+
if (widthChanged && n.subGrid) {
1352+
// if we're animating the client size hasn't changed yet, so force a change (not exact size)
1353+
n.subGrid.onResize(this.hasAnimationCSS() ? n.w : undefined);
1354+
} else {
1355+
this.resizeToContentCheck(widthChanged, n);
1356+
}
13491357
delete n._orig; // clear out original position now that we moved #2669
13501358
}
13511359
if (m || changed) {
@@ -1774,19 +1782,19 @@ export class GridStack {
17741782
* and remember the prev columns we used, or get our count from parent, as well as check for cellHeight==='auto' (square)
17751783
* or `sizeToContent` gridItem options.
17761784
*/
1777-
public onResize(): GridStack {
1778-
if (!this.el?.clientWidth) return; // return if we're gone or no size yet (will get called again)
1779-
if (this.prevWidth === this.el.clientWidth) return; // no-op
1780-
this.prevWidth = this.el.clientWidth
1781-
// console.log('onResize ', this.el.clientWidth);
1785+
public onResize(clientWidth = this.el?.clientWidth): GridStack {
1786+
if (!clientWidth) return; // return if we're gone or no size yet (will get called again)
1787+
if (this.prevWidth === clientWidth) return; // no-op
1788+
this.prevWidth = clientWidth
1789+
// console.log('onResize ', clientWidth);
17821790

17831791
this.batchUpdate();
17841792

17851793
// see if we're nested and take our column count from our parent....
17861794
let columnChanged = false;
17871795
if (this._autoColumn && this.parentGridNode) {
17881796
if (this.opts.column !== this.parentGridNode.w) {
1789-
this.column(this.parentGridNode.w, this.opts.layout || 'none');
1797+
this.column(this.parentGridNode.w, this.opts.layout || 'list');
17901798
columnChanged = true;
17911799
}
17921800
} else {
@@ -1816,7 +1824,7 @@ export class GridStack {
18161824

18171825
// update any gridItem height with sizeToContent, but wait for DOM $animation_speed to settle if we changed column count
18181826
// 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 ?
1819-
if (delay && this.hasAnimationCSS()) return setTimeout(() => this.resizeToContentCheck(false, n), 300 + 10);
1827+
if (delay && this.hasAnimationCSS()) return setTimeout(() => this.resizeToContentCheck(false, n), this.animationDelay);
18201828

18211829
if (n) {
18221830
if (Utils.shouldSizeToContent(n)) this.resizeToContentCBCheck(n.el);

0 commit comments

Comments
 (0)