Skip to content

Commit afeef23

Browse files
committed
fix: create new rows when resizing beyond last row
1 parent 96ddba6 commit afeef23

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

src/components/tile-manager/tile-resize.spec.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { spy } from 'sinon';
1111
import { range } from 'lit/directives/range.js';
1212
import { escapeKey } from '../common/controllers/key-bindings.js';
1313
import { defineComponents } from '../common/definitions/defineComponents.js';
14-
import { first } from '../common/util.js';
14+
import { first, last } from '../common/util.js';
1515
import {
1616
simulateKeyboard,
1717
simulateLostPointerCapture,
@@ -87,6 +87,29 @@ describe('Tile resize', () => {
8787
rowSize = Number.parseFloat(tileManager.minRowHeight!) + gap;
8888
});
8989

90+
it('should create new rows when resizing last row', async () => {
91+
const lastTile = last(getTiles());
92+
const DOM = getResizeContainerDOM(lastTile);
93+
94+
expect(getRows().length).to.eql(1);
95+
expect(getComputedStyle(lastTile).gridRow).to.eql('auto / span 1');
96+
97+
simulatePointerDown(DOM.adorners.bottom);
98+
await elementUpdated(DOM.resizeElement);
99+
100+
simulatePointerMove(DOM.adorners.bottom, {
101+
clientY: rowSize * 4,
102+
});
103+
await elementUpdated(DOM.resizeElement);
104+
105+
simulateLostPointerCapture(DOM.adorners.bottom);
106+
await elementUpdated(DOM.resizeElement);
107+
await nextFrame();
108+
109+
expect(getRows().length).to.eql(4);
110+
expect(getComputedStyle(lastTile).gridRow).to.eql('auto / span 4');
111+
});
112+
90113
it('should create a ghost element on resize start', async () => {
91114
const DOM = getResizeContainerDOM(firstTile);
92115
const eventSpy = spy(DOM.resizeElement, 'emitEvent');
@@ -169,7 +192,7 @@ describe('Tile resize', () => {
169192
expect(getRows().length).to.eql(1);
170193

171194
simulatePointerMove(DOM.adorners.side, {
172-
clientX: columnSize * 3,
195+
clientX: columnSize * 4,
173196
});
174197

175198
await elementUpdated(DOM.resizeElement);

src/components/tile-manager/tile-util.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,12 @@ class TileResizeState {
262262
this._position.column,
263263
this._columns.entries
264264
);
265+
265266
this._position.row.span = this.calculateResizedSpan(
266267
rect.height,
267268
this._position.row,
268-
this._rows.entries
269+
this._rows.entries,
270+
true
269271
);
270272

271273
const cssColumn = `${column.start < 0 ? 'auto' : column.start} / span ${this._position.column.span}`;
@@ -274,6 +276,30 @@ class TileResizeState {
274276
return { column: cssColumn, row: cssRow };
275277
}
276278

279+
/**
280+
* Checks and adjusts tile spans based on the column count of the tile manager.
281+
*/
282+
// REVIEW once we decide how to handle empty columns.
283+
public adjustTileGridPosition(tiles: IgcTileComponent[]): void {
284+
const columnCount = this.columns.count;
285+
286+
for (const tile of tiles) {
287+
const colStart = tile.colStart || 0;
288+
const colSpan = tile.colSpan || 0;
289+
290+
if (colStart > columnCount) {
291+
//Prioritize span over start?
292+
tile.colSpan = 1;
293+
tile.colStart = columnCount;
294+
continue;
295+
}
296+
297+
if (colStart + colSpan - 1 > columnCount) {
298+
tile.colSpan = columnCount - colStart + 1;
299+
}
300+
}
301+
}
302+
277303
private calculatePosition(targetPosition: number, sizes: number[]): number {
278304
const gap = this._gap;
279305
let accumulatedSize = 0;
@@ -292,10 +318,11 @@ class TileResizeState {
292318
private calculateResizedSpan(
293319
targetSize: number,
294320
tilePosition: TilePosition,
295-
sizes: number[]
321+
sizes: number[],
322+
isRows = false
296323
): number {
297324
let accumulatedSize = 0;
298-
let currentSpan = tilePosition.span;
325+
let newSpan = tilePosition.span;
299326

300327
const sizesAfterStart = sizes.slice(tilePosition.start - 1);
301328
const availableSize =
@@ -307,26 +334,34 @@ class TileResizeState {
307334
}
308335

309336
if (targetSize > availableSize) {
337+
if (isRows) {
338+
const remainingSize = targetSize - availableSize;
339+
const additionalSpan = Math.ceil(
340+
remainingSize / (this._rows.minSize + this._gap)
341+
);
342+
return sizesAfterStart.length + additionalSpan;
343+
}
344+
310345
return sizesAfterStart.length;
311346
}
312347

313-
for (let i = tilePosition.start; i < sizes.length; i++) {
348+
for (let i = tilePosition.start - 1; i < sizes.length; i++) {
314349
const currentSize = sizes[i];
315350
const nextSize = sizes[i + 1] ?? currentSize;
316351

317352
const halfwayPoint =
318353
accumulatedSize + currentSize + this._gap + nextSize / 2;
319354

320355
if (targetSize > halfwayPoint) {
321-
currentSpan = i + 2 - tilePosition.start;
356+
newSpan = i + 3 - tilePosition.start;
322357
} else {
323358
break;
324359
}
325360

326361
accumulatedSize += currentSize + this._gap;
327362
}
328363

329-
return currentSpan;
364+
return newSpan;
330365
}
331366
}
332367

0 commit comments

Comments
 (0)