Skip to content

Commit 1fccf02

Browse files
committed
loading into smaller screen with responsive layout:'list'
* fix #2947 * make sure we detect loading into a smaller responsive screen by re-using engine relayout code.
1 parent d284c18 commit 1fccf02

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

doc/CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Change log
126126
## 12-dev (TBD)
127127
* feat: [#2854](https://github.com/gridstack/gridstack.js/pull/2854) Removed dynamic stylesheet and migrated to CSS vars. Thank you [lmartorella](https://github.com/lmartorella)
128128
* feat: [#3013](https://github.com/gridstack/gridstack.js/pull/3013) columns no longer require custom classes nor `gridstack-extra.css` as we now use CSS vars.
129+
* fix: [#2978](https://github.com/gridstack/gridstack.js/issues/2978) Very slow operation in 11.2.0 and higher with large blocks
130+
* fix: [#2947](https://github.com/gridstack/gridstack.js/issues/2947) loading responsive `layout:'list'` into smaller screen doesn't layout correctly.
129131

130132
## 11.5.1 (2025-03-23)
131133
* revert: [#2981](https://github.com/gridstack/gridstack.js/issues/2981) Locked was incorrectly changed. fixed doc instead
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<head>
3+
<title>Responsive column</title>
4+
<link rel="stylesheet" href="../../../demo/demo.css"/>
5+
<script src="../../../dist/gridstack-all.js"></script>
6+
</head>
7+
<body>
8+
<h1>Responsive: load into smaller size</h1>
9+
<span>Number of Columns:</span> <span id="column-text"></span>
10+
<div class="grid-stack">
11+
12+
<script type="text/javascript">
13+
let children = [ // our initial 12 column layout
14+
{x: 0, y: 0, w: 12},
15+
{x: 0, y: 1, w: 3},
16+
{x: 3, y: 1, w: 3},
17+
{x: 6, y: 1, w: 3},
18+
{x: 9, y: 1, w: 3},
19+
];
20+
children.forEach((n, i) => {n.id = i; n.content = String(i)});
21+
22+
let grid = GridStack.init({
23+
cellHeight: 80,
24+
columnOpts: {
25+
breakpoints: [
26+
{ c: 8, w: 1200 },
27+
{ c: 6, w: 996 },
28+
{ c: 3, w: 768 },
29+
{ c: 1, w: 480 },
30+
],
31+
layout: "list",
32+
},
33+
children})
34+
.on('change', (ev, gsItems) => text.innerHTML = grid.getColumn());
35+
36+
let text = document.querySelector('#column-text');
37+
text.innerHTML = grid.getColumn();
38+
</script>
39+
</body>
40+
</html>

src/gridstack.ts

+19-7
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ export class GridStack {
253253
protected _autoColumn?: boolean;
254254
/** @internal meant to store the scale of the active grid */
255255
protected dragTransform: DragTransform = { xScale: 1, yScale: 1, xOffset: 0, yOffset: 0 };
256+
protected responseLayout: ColumnOptions;
256257
private _skipInitialResize: boolean;
257258

258259
/**
@@ -338,7 +339,7 @@ export class GridStack {
338339
opts = Utils.defaults(opts, defaults);
339340
this._initMargin(); // part of settings defaults...
340341

341-
// 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)
342+
// Now check if we're loading into !12 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)
342343
this.checkDynamicColumn();
343344
this._updateColumnVar(opts);
344345

@@ -713,7 +714,16 @@ export class GridStack {
713714
let maxColumn = 0;
714715
items.forEach(n => { maxColumn = Math.max(maxColumn, (n.x || 0) + n.w) });
715716
if (maxColumn > this.engine.defaultColumn) this.engine.defaultColumn = maxColumn;
716-
if (maxColumn > column) this.engine.cacheLayout(items, maxColumn, true);
717+
if (maxColumn > column) {
718+
// if we're loading (from empty) into a smaller column, check for special responsive layout
719+
if (this.engine.nodes.length === 0 && this.responseLayout) {
720+
this.engine.nodes = items;
721+
this.engine.columnChanged(maxColumn, column, this.responseLayout);
722+
items = this.engine.nodes;
723+
this.engine.nodes = [];
724+
delete this.responseLayout;
725+
} else this.engine.cacheLayout(items, maxColumn, true);
726+
}
717727

718728
// if given a different callback, temporally set it as global option so creating will use it
719729
const prevCB = GridStack.addRemoveCB;
@@ -948,16 +958,18 @@ export class GridStack {
948958

949959
const oldColumn = this.getColumn();
950960
this.opts.column = column;
951-
if (!this.engine) return this; // called in constructor, noting else to do
961+
if (!this.engine) {
962+
// called in constructor, noting else to do but remember that breakpoint layout
963+
this.responseLayout = layout;
964+
return this;
965+
}
952966

953967
this.engine.column = column;
954968
this.el.classList.remove('gs-' + oldColumn);
955969
this._updateColumnVar();
956970

957-
// update the items now, checking if we have a custom children layout
958-
/*const newChildren = this.opts.columnOpts?.breakpoints?.find(r => r.c === column)?.children;
959-
if (newChildren) this.load(newChildren);
960-
else*/ this.engine.columnChanged(oldColumn, column, layout);
971+
// update the items now
972+
this.engine.columnChanged(oldColumn, column, layout);
961973
if (this._isAutoCellHeight) this.cellHeight();
962974

963975
this.resizeToContentCheck(true); // wait for width resizing

0 commit comments

Comments
 (0)