feat(mui): fixed-width DataTable columns + restore Projects next-number hint
DataTable: optional per-column width; when any column sets one, the table uses table-layout:fixed with a colgroup so columns keep a stable size instead of reflowing as rows are filtered (overflow clipped with ellipsis). Tables without widths keep auto layout. Projects: assign column widths; restore the original '(přiděleno automaticky)' suffix on the next-number hint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,13 @@ export interface DataColumn<T> {
|
||||
bold?: boolean;
|
||||
/** If set, the header becomes a clickable sort control (requires onSort). */
|
||||
sortKey?: string;
|
||||
/**
|
||||
* Fixed column width (number = px, string = any CSS width incl. "%"). When
|
||||
* ANY column sets a width the table switches to `table-layout: fixed`, so
|
||||
* columns keep a stable size regardless of cell content (e.g. while
|
||||
* filtering). Overflowing text is clipped with an ellipsis.
|
||||
*/
|
||||
width?: number | string;
|
||||
render: (row: T) => ReactNode;
|
||||
}
|
||||
|
||||
@@ -47,9 +54,28 @@ export default function DataTable<T>({
|
||||
console.warn("DataTable: columns with sortKey require an onSort prop.");
|
||||
}
|
||||
if (rows.length === 0 && empty) return <>{empty}</>;
|
||||
// When any column declares a width, lock the table to fixed layout so column
|
||||
// widths come from the colgroup (stable) instead of from cell content (which
|
||||
// jumps as rows are filtered). Tables that set no widths keep auto layout.
|
||||
const hasWidths = columns.some((c) => c.width != null);
|
||||
const colWidth = (w: number | string | undefined) =>
|
||||
w == null ? undefined : typeof w === "number" ? `${w}px` : w;
|
||||
return (
|
||||
<TableContainer sx={{ borderRadius: 2 }}>
|
||||
<Table size="small" sx={{ "& td, & th": { borderColor: "divider" } }}>
|
||||
<TableContainer sx={{ borderRadius: 2, overflowX: "auto" }}>
|
||||
<Table
|
||||
size="small"
|
||||
sx={{
|
||||
...(hasWidths ? { tableLayout: "fixed", minWidth: 720 } : {}),
|
||||
"& td, & th": { borderColor: "divider" },
|
||||
}}
|
||||
>
|
||||
{hasWidths && (
|
||||
<colgroup>
|
||||
{columns.map((c) => (
|
||||
<col key={c.key} style={{ width: colWidth(c.width) }} />
|
||||
))}
|
||||
</colgroup>
|
||||
)}
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{columns.map((c) => (
|
||||
@@ -101,6 +127,13 @@ export default function DataTable<T>({
|
||||
...(c.mono
|
||||
? { fontFamily: "'DM Mono', Menlo, monospace" }
|
||||
: {}),
|
||||
...(hasWidths
|
||||
? {
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
>
|
||||
{c.render(row)}
|
||||
|
||||
Reference in New Issue
Block a user