Skip to content

Commit

Permalink
fitToContent when calling cellHeight()/addWidget/MakeWidget
Browse files Browse the repository at this point in the history
* partial fix for #2427
* when changing cellHeight, or calling addWidget() | makeWidget() we now call doContentResize()
* fixed doContentResize logic to use expected size (using cellHeight) instead of actual DOM values so we don't need to delay until animation is done (unlike column width which does affect calc height for content reflow)

TODO: support 1rem type of cellHeight.
  • Loading branch information
adumesny committed Aug 29, 2023
1 parent 8358e01 commit 404c3e5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
30 changes: 26 additions & 4 deletions demo/fitToContent.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@
<body>
<div class="container">
<h1>Cell FitToContent options demo</h1>
<p>new 9.x feature that size the items to fit their content height as to not have scroll bars (unless `fitToContent:false` in C: case) </p>
<p>new 9.x feature that size the items to fit their content height as to not have scroll bars
(unless `fitToContent:false` in C: case). Defaulting to different initial size (see code) to show grow/shrink behavior.</p>
<div>
column:
<a onClick="column(8)" class="btn btn-primary" href="#">8</a>
<a onClick="column(12)" class="btn btn-primary" href="#">12</a>
cellHeight:
<a onClick="cellHeight(25)" class="btn btn-primary" href="#">25</a>
<a onClick="cellHeight(50)" class="btn btn-primary" href="#">50</a>
<a onClick="cellHeight(75)" class="btn btn-primary" href="#">75</a>
Widget:
<a onClick="addWidget()" class="btn btn-primary" href="#">Add</a>
<a onClick="makeWidget()" class="btn btn-primary" href="#">Make</a>
</div>
<br>
<div class="grid-stack"></div>
Expand All @@ -32,22 +40,36 @@ <h1>Cell FitToContent options demo</h1>
margin: 5,
cellHeight: 50,
fitToContent: true, // default to make them all fit
resizable: { handles: 'all'} // do all sides for testing
// cellHeightThrottle: 100, // ms before fitToContent happens
}
let grid = GridStack.init(opts);
let text ='some very large content that will normally not fit in the window.'
text = text + text;
let items = [
{x:0, y:0, w:2, content: `<div>A: ${text}</div>`},
{x:2, y:0, w:1, h:2, content: '<div>B: shrink</div>'}, // make taller than needed upfront
{x:0, y:0, w:2, content: `<div>A no h: ${text}</div>`},
{x:2, y:0, w:1, h:2, content: '<div>B: shrink h=2</div>'}, // make taller than needed upfront
{x:3, y:0, w:2, fitToContent: false, content: `<div>C: WILL SCROLL. ${text}</div>`}, // prevent this from fitting testing
{x:0, y:1, w:3, content: `<div>D: ${text} ${text}</div>`},
{x:0, y:1, w:3, content: `<div>D no h: ${text} ${text}</div>`},
];
grid.load(items);

function column(n) {
grid.column(n, 'none');
}
function cellHeight(n) {
grid.cellHeight(n);
}
function addWidget() {
grid.addWidget({content: `<div>New: ${text}</div>`});
}
function makeWidget() {
let doc = document.implementation.createHTMLDocument();
doc.body.innerHTML = `<div class="item"><div class="grid-stack-item-content"><div>New Make: ${text}</div></div></div>`;
let el = doc.body.children[0];
grid.el.appendChild(el);
grid.makeWidget(el);
}
</script>
</body>
</html>
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Change log

## 9.0.1-dev (TBD)
* fix 'resizecontent' event fix not called.
* partial fix [#2427](https://github.com/gridstack/gridstack.js/issues/2427) fitToContent when calling cellHeight()/addWidget()/MakeWidget()

## 9.0.1 (2023-08-27)
* fix [#2413](https://github.com/gridstack/gridstack.js/issues/2413) support touchscreen+mouse devices. Thank you [@Ruslan207](https://github.com/Ruslan207)
Expand Down
16 changes: 11 additions & 5 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,8 @@ export class GridStack {
this.opts.cellHeightUnit = data.unit;
this.opts.cellHeight = data.h;

this.doContentResize(false);

if (update) {
this._updateStyles(true); // true = force re-create for current # of rows
}
Expand Down Expand Up @@ -996,10 +998,13 @@ export class GridStack {
public makeWidget(els: GridStackElement, options?: GridStackWidget): GridItemHTMLElement {
let el = GridStack.getElement(els);
this._prepareElement(el, true, options);
const node = el.gridstackNode;

this._updateContainerHeight();

this.doContentResize(false, node);

// see if there is a sub-grid to create
const node = el.gridstackNode;
if (node.subGridOpts) {
this.makeSubGrid(el, node.subGridOpts, undefined, false); // node.subGrid will be used as option in method, no need to pass
}
Expand Down Expand Up @@ -1266,19 +1271,20 @@ export class GridStack {
const grid = n.grid;
if (grid !== this) return grid?.resizeToContent(el);
if (el.parentElement !== this.el) return; // skip if we are not inside a grid
let height = el.clientHeight; // getBoundingClientRect().height seem to flicker back and forth
const cell = this.getCellHeight();
if (!cell) return;
let height = n.h ? n.h * cell : el.clientHeight; // getBoundingClientRect().height seem to flicker back and forth
if (!height) return; // 0 when hidden, skip
const item = el.querySelector(GridStack.resizeToContentParent);
if (!item) return;
const child = item.firstElementChild;
// NOTE: clientHeight & getBoundingClientRect() is undefined for text and other leaf nodes. use <div> container!
if (!child) { console.log(`Error: resizeToContent() '${GridStack.resizeToContentParent}'.firstElementChild is null, make sure to have a div like container. Skipping sizing.`); return; }
const itemH = item.clientHeight; // available height to our child (minus border, padding...)
const padding = el.clientHeight - item.clientHeight; // full - available height to our child (minus border, padding...)
const itemH = n.h ? n.h * cell - padding : item.clientHeight; // calculated to what cellHeight is or will become (rather than actual to prevent waiting for animation to finish)
const wantedH = child.getBoundingClientRect().height || itemH;
if (itemH === wantedH) return;
height += wantedH - itemH;
const cell = this.getCellHeight();
if (!cell) return;
let h = Math.ceil(height / cell);
if (n.minH && h < n.minH) h = n.minH;
else if (n.maxH && h > n.maxH) h = n.maxH;
Expand Down

0 comments on commit 404c3e5

Please sign in to comment.