fix: enforce DataGrid cover boundary

This commit is contained in:
2026-07-31 04:44:24 +02:00
parent 7b8072d049
commit 5211e07d0b
4 changed files with 151 additions and 32 deletions
+5 -3
View File
@@ -135,9 +135,11 @@ type DataGridBaseProps<T> = {
/** @deprecated Use initialFit instead. */
fit?: DataGridInitialFit;
/**
* Cover keeps the right edge fixed by redistributing every resize across
* real columns. Free permits underflow and horizontal growth. Free is
* automatically promoted to cover when a right-sticky column exists.
* Cover prevents underflow while allowing horizontal overflow. Shrinking
* consumes existing overflow and then grows eligible columns to the right;
* it stops when no such capacity remains. Free permits both underflow and
* overflow. Free is automatically promoted to cover when a right-sticky
* column exists.
*/
resizeBehavior?: DataGridResizeBehavior;
className?: string;
+40 -11
View File
@@ -210,15 +210,8 @@ export function fitDataGridColumns(
resizeTargetForLayout(column, widths, widths[column.id])
)
);
// A persisted user layout is preferred, not a reason to overflow. Under
// viewport pressure every ordinary track may shrink down to its hard floor.
remaining = applyDataGridDistribution(
widths,
remaining,
coverageColumns.map((column) =>
resizeTargetForLayout(column, widths, widths[column.id])
)
);
// Explicit user widths are hard during reconciliation. Cover prevents
// underflow, but intentional user growth may remain horizontally scrollable.
}
const roundedWidths = roundDataGridWidths(widths);
@@ -268,6 +261,43 @@ export function resizeDataGridColumn(
};
}
if (fitMode === "cover") {
if (boundedDelta >= 0) {
widths[columnId] = startWidth + boundedDelta;
return {
widths: roundDataGridWidths(widths),
appliedDelta: roundWidth(boundedDelta)
};
}
const requestedShrink = -boundedDelta;
const freeShrink = Math.min(
requestedShrink,
Math.max(0, uncompensatedShrinkRoom)
);
const rightTargets = columns
.slice(activeIndex + 1)
.filter((column) => column.resizable && !column.sticky)
.map((column) =>
resizeTargetForLayout(
column,
widths,
dataGridColumnResizeWeight(column)
)
);
const compensation = distributeDataGridResizeAmount(
requestedShrink - freeShrink,
rightTargets
);
applyDataGridAmounts(widths, compensation.amounts);
const appliedShrink = freeShrink + compensation.applied;
widths[columnId] = startWidth - appliedShrink;
return {
widths: roundDataGridWidths(widths),
appliedDelta: roundWidth(-appliedShrink)
};
}
const freeShrink = boundedDelta < 0
? Math.min(-boundedDelta, Math.max(0, uncompensatedShrinkRoom))
: 0;
@@ -282,8 +312,7 @@ export function resizeDataGridColumn(
resizeTargetForLayout(
column,
widths,
dataGridColumnResizeWeight(column),
fitMode === "cover" ? DATA_GRID_MAX_TRACK_WIDTH : undefined
dataGridColumnResizeWeight(column)
)
);
const distribution = distributeDataGridResizeAmount(remainingCompensation, targets);