Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h1>Demos</h1>
<li><a href="react.html">ReactJS</a></li>
<li><a href="responsive.html">Responsive: by column size</a></li>
<li><a href="responsive_break.html">Responsive: using breakpoints</a></li>
<li><a href="responsive_none.html">Responsive: using layout:'none'</a></li>
<li><a href="right-to-left(rtl).html">Right-To-Left (RTL)</a></li>
<li><a href="serialization.html">Serialization</a></li>
<li><a href="sizeToContent.html">Size To Content</a></li>
Expand Down
40 changes: 40 additions & 0 deletions demo/responsive_none.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive layout:'none'</title>

<link rel="stylesheet" href="demo.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
<script src="../dist/gridstack-all.js"></script>

</head>
<body>
<div class="container-fluid">
<h1>Responsive layout:'none'</h1>
<p>show loading a fixed (<b>layout:'none'</b>) but still responsive design (150px columns) with items w:2-4</p>
<p>showing how it will not change the layout unless it doesn't fit. loading into small view remembers the full layout (column:6)</p>
<div class="grid-stack"></div>
</div>
<script src="events.js"></script>
<script type="text/javascript">
let children = [ {}, {}, {}];
children.forEach((w, i) => {
w.x=i, w.y=i, // comment out to have autoPosition:true which behaves differently
w.w=i+2, w.content = `${i} w:${w.w}`})

GridStack.init({
children,
column: 6,
cellHeight: 100,
columnOpts: {
columnWidth: 150,
columnMax: 12,
layout: 'none',
},
});
</script>
</body>
</html>
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ Change log

## 11.2.0-dev (TBD)
* feat: added `isIgnoreChangeCB()` if changeCB should be ignored due to column change, sizeToContent, loading, etc...
* feat: added `responsive_none.html` demo and fixed layout:'none' to bound check the layout (no-op unless it must change)

## 11.2.0 (2024-12-29)
* feat: [#2695](https://github.com/gridstack/gridstack.js/issues/2695) 'Esc' to cancel now works on sidebar external items, also works dragging over trash.
Expand Down
9 changes: 4 additions & 5 deletions src/gridstack-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class GridStackEngine {
public _loading?: boolean
/** @internal true while we are resizing widgets during column resize to skip certain parts */
protected _inColumnResize?: boolean;
/** true when grid.load() already cached the layout and can skip out of bound caching info */
public skipCacheUpdate?: boolean;
/** @internal true if we have some items locked */
protected _hasLocked: boolean;
/** @internal unique global internal _id counter */
Expand Down Expand Up @@ -415,7 +417,7 @@ export class GridStackEngine {
// remember it's position & width so we can restore back (1 -> 12 column) #1655 #1985
// IFF we're not in the middle of column resizing!
const saveOrig = (node.x || 0) + (node.w || 1) > this.column;
if (saveOrig && this.column < this.defaultColumn && !this._inColumnResize && node._id && this.findCacheLayout(node, this.defaultColumn) === -1) {
if (saveOrig && this.column < this.defaultColumn && !this._inColumnResize && !this.skipCacheUpdate && node._id && this.findCacheLayout(node, this.defaultColumn) === -1) {
const copy = {...node}; // need _id + positions
if (copy.autoPosition || copy.x === undefined) { delete copy.x; delete copy.y; }
else copy.x = Math.min(this.defaultColumn - 1, copy.x);
Expand Down Expand Up @@ -829,9 +831,6 @@ export class GridStackEngine {
public columnChanged(prevColumn: number, column: number, layout: ColumnOptions = 'moveScale'): GridStackEngine {
if (!this.nodes.length || !column || prevColumn === column) return this;

// in this mode no layout is done whatsoever, up to the caller to handle it
if (layout === 'none') return this;

// simpler shortcuts layouts
const doCompact = layout === 'compact' || layout === 'list';
if (doCompact) {
Expand Down Expand Up @@ -900,7 +899,7 @@ export class GridStackEngine {
if (typeof layout === 'function') {
layout(column, prevColumn, newNodes, nodes);
} else {
const ratio = doCompact ? 1 : column / prevColumn;
const ratio = (doCompact || layout === 'none') ? 1 : column / prevColumn;
const move = (layout === 'move' || layout === 'moveScale');
const scale = (layout === 'scale' || layout === 'moveScale');
nodes.forEach(node => {
Expand Down
15 changes: 8 additions & 7 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,15 +696,14 @@ export class GridStack {
// sort items. those without coord will be appended last
items = Utils.sort(items);

this.engine.skipCacheUpdate = this._ignoreLayoutsNodeChange = true; // skip layout update

// if we're loading a layout into for example 1 column and items don't fit, make sure to save
// the original wanted layout so we can scale back up correctly #1471
let maxColumn = 0;
items.forEach(n => { maxColumn = Math.max(maxColumn, (n.x || 0) + n.w) });
if (maxColumn > this.engine.defaultColumn) this.engine.defaultColumn = maxColumn;
if (maxColumn > column) {
this._ignoreLayoutsNodeChange = true; // skip layout update
this.engine.cacheLayout(items, maxColumn, true);
}
if (maxColumn > column) this.engine.cacheLayout(items, maxColumn, true);

// if given a different callback, temporally set it as global option so creating will use it
const prevCB = GridStack.addRemoveCB;
Expand Down Expand Up @@ -778,6 +777,7 @@ export class GridStack {

// after commit, clear that flag
delete this._ignoreLayoutsNodeChange;
delete this.engine.skipCacheUpdate;
prevCB ? GridStack.addRemoveCB = prevCB : delete GridStack.addRemoveCB;
// delay adding animation back
if (blank && this.opts?.animate) this.setAnimation(this.opts.animate, true);
Expand Down Expand Up @@ -1098,12 +1098,13 @@ export class GridStack {

// if we're adding an item into 1 column make sure
// we don't override the larger 12 column layout that was already saved. #1985
if (this.opts.column === 1) {
this._ignoreLayoutsNodeChange = true;
let resetIgnoreLayoutsNodeChange: boolean;
if (this.opts.column === 1 && !this._ignoreLayoutsNodeChange) {
resetIgnoreLayoutsNodeChange = this._ignoreLayoutsNodeChange = true;
}
this._triggerAddEvent();
this._triggerChangeEvent();
delete this._ignoreLayoutsNodeChange;
if (resetIgnoreLayoutsNodeChange) delete this._ignoreLayoutsNodeChange;

return el;
}
Expand Down