improved column resize logic

This commit is contained in:
2026-02-22 14:53:35 -05:00
parent d3b04a9c29
commit 8a2ceb9107
+120 -20
View File
@@ -130,7 +130,9 @@ export class TrackList extends LitElement implements SelectionHost {
private resizingColumn: number | null = null; private resizingColumn: number | null = null;
private resizeStartX = 0; private resizeStartX = 0;
private resizeStartWidths: number[] = []; private resizeStartWidths: number[] = [];
private resizeObserver: ResizeObserver | null = null; private resizeObserver: ResizeObserver | null =
null;
private flowLayout = flow(); private flowLayout = flow();
private hasRestoredScroll = false; private hasRestoredScroll = false;
@@ -192,7 +194,11 @@ export class TrackList extends LitElement implements SelectionHost {
const positions: number[] = []; const positions: number[] = [];
let cumulative = padding; let cumulative = padding;
for (let i = 0; i < this.columnWidths.length - 1; i++) { for (
let i = 0;
i < this.columnWidths.length - 1;
i++
) {
cumulative += this.columnWidths[i] ?? 0; cumulative += this.columnWidths[i] ?? 0;
positions.push(cumulative); positions.push(cumulative);
} }
@@ -429,30 +435,122 @@ export class TrackList extends LitElement implements SelectionHost {
private onColResizeMove = (e: MouseEvent) => { private onColResizeMove = (e: MouseEvent) => {
if (this.resizingColumn === null) return; if (this.resizingColumn === null) return;
const container = this.clientWidth;
if (container <= 0) return;
const delta = e.clientX - this.resizeStartX; const delta = e.clientX - this.resizeStartX;
const col = this.resizingColumn; const col = this.resizingColumn;
const nextCol = col + 1; const starts = this.resizeStartWidths;
const startLeft = this.resizeStartWidths[col] ?? 0;
const startRight = this.resizeStartWidths[nextCol] ?? 0;
const total = startLeft + startRight;
let newLeft = startLeft + delta; // Sum of columns to the left (unchanged).
let newRight = startRight - delta; let leftSum = 0;
if (newLeft < MIN_COLUMN_WIDTH) { for (let i = 0; i < col; i++) {
newLeft = MIN_COLUMN_WIDTH; leftSum += starts[i] ?? 0;
newRight = total - MIN_COLUMN_WIDTH;
} }
if (newRight < MIN_COLUMN_WIDTH) { // Count and sum of columns to the right.
newRight = MIN_COLUMN_WIDTH; const rightCount =
newLeft = total - MIN_COLUMN_WIDTH; starts.length - col - 1;
let rightSum = 0;
for (
let i = col + 1;
i < starts.length;
i++
) {
rightSum += starts[i] ?? 0;
} }
const updated = [...this.resizeStartWidths]; // Clamp dragged column: leave at least
// MIN_COLUMN_WIDTH for each right column.
const maxWidth =
container -
leftSum -
rightCount * MIN_COLUMN_WIDTH;
let newWidth = Math.max(
MIN_COLUMN_WIDTH,
Math.min(
maxWidth,
(starts[col] ?? 0) + delta,
),
);
const updated: number[] = new Array(
starts.length,
);
// Left columns keep starting widths.
for (let i = 0; i < col; i++) {
updated[i] = starts[i] ?? 0;
}
updated[col] = newWidth;
// Right columns always fill remaining space
// proportionally (handles both grow & shrink).
const availableForRight =
container - leftSum - newWidth;
if (rightCount === 0 || rightSum <= 0) {
// Nothing to distribute.
} else {
const scale =
availableForRight / rightSum;
let roundedSum = 0;
let maxIdx = -1;
let maxVal = 0;
for (
let i = col + 1;
i < starts.length;
i++
) {
const scaled = Math.max(
MIN_COLUMN_WIDTH,
Math.round(
(starts[i] ?? 0) * scale,
),
);
updated[i] = scaled;
roundedSum += scaled;
if (scaled > maxVal) {
maxVal = scaled;
maxIdx = i;
}
}
// Fix rounding remainder on the widest
// right column.
const diff =
availableForRight - roundedSum;
if (diff !== 0 && maxIdx >= 0) {
updated[maxIdx] =
(updated[maxIdx] ?? 0) + diff;
}
// Re-derive dragged width so total is
// exactly container.
newWidth =
container -
leftSum -
roundedSum -
diff;
if (newWidth < MIN_COLUMN_WIDTH) {
newWidth = MIN_COLUMN_WIDTH;
}
updated[col] = newWidth;
}
updated[col] = newLeft;
updated[nextCol] = newRight;
this.columnWidths = updated; this.columnWidths = updated;
}; };
@@ -660,9 +758,11 @@ export class TrackList extends LitElement implements SelectionHost {
document.addEventListener('mousemove', this.onColResizeMove); document.addEventListener('mousemove', this.onColResizeMove);
document.addEventListener('mouseup', this.onColResizeEnd); document.addEventListener('mouseup', this.onColResizeEnd);
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(
this.onHostResize(); () => {
}); this.onHostResize();
},
);
this.resizeObserver.observe(this); this.resizeObserver.observe(this);
} }