fix(ui): unify heading help, table sizing and navigation contracts

Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
This commit is contained in:
2026-09-09 02:03:16 +02:00
parent 6591aaa3fd
commit 6d37aa527f
54 changed files with 1728 additions and 117 deletions
+71
View File
@@ -342,6 +342,77 @@ assertWidths(
"growth does not resize a fixed peer merely to avoid overflow"
);
const mixedPeerColumns: DataGridSizingColumn[] = [
{ id: "first", width: 200, minWidth: 100, maxWidth: 500, resizable: true },
{ id: "fixed", width: 120, minWidth: 120, maxWidth: 120 },
{ id: "last", width: 300, minWidth: 100, maxWidth: 500, resizable: true },
{ id: "actions", width: 100, sticky: "end" }
];
const mixedPeerBase = { first: 200, fixed: 120, last: 300, actions: 100 };
for (const mode of ["cover", "free", "constrained"] as const) {
const grown = resizeDataGridColumn(mixedPeerColumns, mixedPeerBase, "first", 80, mode);
assertWidths(grown.widths,
{ first: 280, fixed: 120, last: mode === "constrained" ? 220 : 300, actions: 100 },
`${mode} growth crosses a fixed intermediate column without changing it`);
const shrunk = resizeDataGridColumn(mixedPeerColumns, mixedPeerBase, "first", -80, mode);
assertWidths(shrunk.widths,
{ first: 120, fixed: 120, last: mode === "free" ? 300 : 380, actions: 100 },
`${mode} shrink uses only the appropriate resizable compensation peers`);
const limited = resizeDataGridColumn(mixedPeerColumns, mixedPeerBase, "first", 800, mode);
assertEqual(limited.widths.fixed, 120, `${mode} exhaustion never changes the fixed intermediate track`);
assertEqual(limited.widths.first, mode === "constrained" ? 400 : 500, `${mode} retains declared growth limits`);
}
const preferredLimitColumns: DataGridSizingColumn[] = [
{ id: "recipients", width: "minmax(320px, 1.4fr)", preferredMaxWidth: 640, resizable: true },
{ id: "active", width: 130 },
{ id: "delivery", width: "minmax(260px, 0.9fr)", preferredMaxWidth: 480, resizable: true },
{ id: "attachments", width: 180 },
...["first", "second", "third"].map((id) => ({ id, width: 190, minWidth: 160, preferredMaxWidth: 360, resizable: true })),
{ id: "actions", width: 180, sticky: "end" }
];
const hardLimitColumns = preferredLimitColumns.map(({ preferredMaxWidth, ...column }) => ({ ...column, maxWidth: preferredMaxWidth }));
for (const container of [900, 1600, 2400, 3085]) {
assertWidths(fitDataGridColumns(preferredLimitColumns, container).widths,
fitDataGridColumns(hardLimitColumns, container).widths,
`preferred caps preserve the previous automatic fit at ${container}px without imposing manual caps`);
}
const rightPeersAtOldCaps: DataGridSizingColumn[] = [
{ id: "recipients", width: "minmax(320px, 1.4fr)", preferredMaxWidth: 640, resizable: true },
{ id: "fixed", width: 130, minWidth: 130, maxWidth: 130 },
{ id: "first", width: 190, preferredMaxWidth: 360, resizable: true },
{ id: "second", width: 190, preferredMaxWidth: 360, resizable: true },
{ id: "actions", width: 180, sticky: "end" }
];
const oversizedRecipient = { recipients: 1000, fixed: 130, first: 360, second: 360, actions: 180 };
const oldManualCaps = rightPeersAtOldCaps.map(({ preferredMaxWidth, ...column }) => ({
...column, maxWidth: preferredMaxWidth ?? column.maxWidth
}));
assertEqual(resizeDataGridColumn(oldManualCaps, oversizedRecipient, "recipients", -120, "cover", 0).appliedDelta, 0,
"regression: at the scrolled-right boundary, old field caps block shrinking an oversized recipient column");
const shrunkAcrossPreferredCaps = resizeDataGridColumn(rightPeersAtOldCaps, oversizedRecipient, "recipients", -120, "cover", 0);
assertWidths(shrunkAcrossPreferredCaps.widths,
{ recipients: 880, fixed: 130, first: 420, second: 420, actions: 180 },
"preferred field caps allow cover compensation at the right scroll boundary without moving fixed neighbors");
assertWidths(fitDataGridColumns(rightPeersAtOldCaps, 2030, {}, shrunkAcrossPreferredCaps.widths, "cover", 2030).widths,
shrunkAcrossPreferredCaps.widths, "committing a compensated shrink never refills the wide recipient column");
for (const mode of ["cover", "free", "constrained"] as const) {
const expandedField = resizeDataGridColumn(rightPeersAtOldCaps, oversizedRecipient, "first", 160, mode);
assertEqual(expandedField.widths.first, 520, `${mode} direct resizing can exceed a presentation-only field cap`);
assertEqual(expandedField.widths.fixed, 130, `${mode} preferred caps do not change a fixed neighbor`);
}
const preferredWithHardLimit: DataGridSizingColumn[] = [{ id: "text", width: 300, preferredMaxWidth: 360, maxWidth: 500, resizable: true }];
assertEqual(resizeDataGridColumn(preferredWithHardLimit, { text: 360 }, "text", 200, "cover").widths.text, 500,
"an explicitly declared hard maximum still bounds direct resizing beyond a preferred cap");
assertEqual(fitDataGridColumns([{ id: "text", width: 500, preferredMaxWidth: 400, maxWidth: 300 }], 300, {}, {}, "free").widths.text, 300,
"a preferred cap never overrides a smaller hard maximum");
assertEqual(fitDataGridColumns([{ id: "text", width: 300, minWidth: 160, preferredMaxWidth: 100 }], 160, {}, {}, "free").widths.text, 160,
"preferred caps never reduce a column below its hard minimum");
assertEqual(dataGridLayoutSignature([{ id: "text", width: 190, resizable: true }], "container", "cover"),
"v3::text:190:::r::::default:::container::cover", "omitting preferred caps preserves the existing persisted signature format");
assertEqual(dataGridLayoutSignature(preferredLimitColumns, "container", "cover") === dataGridLayoutSignature(hardLimitColumns, "container", "cover"), false,
"new preferred sizing declarations invalidate only their own obsolete manual-width contract");
const coverBeyondPassiveMax = resizeDataGridColumn([
{ id: "first", width: 200, minWidth: 100, maxWidth: 200, resizable: true },
{ id: "second", width: 300, minWidth: 100, maxWidth: 300, resizable: true },