feat(mui): add DataTable rowSx per-row style escape hatch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-07 00:31:28 +02:00
parent 3d1bd49ad6
commit 9ab2bd7ef2

View File

@@ -1,4 +1,5 @@
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import type { SxProps, Theme } from "@mui/material/styles";
import Table from "@mui/material/Table"; import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody"; import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell"; import TableCell from "@mui/material/TableCell";
@@ -36,6 +37,8 @@ export interface DataTableProps<T> {
onRowClick?: (row: T) => void; onRowClick?: (row: T) => void;
/** When it returns true, the row is tinted with the error palette (danger highlight). */ /** When it returns true, the row is tinted with the error palette (danger highlight). */
rowDanger?: (row: T) => boolean; rowDanger?: (row: T) => boolean;
/** Per-row style escape hatch (merged last) for arbitrary status tints. */
rowSx?: (row: T) => SxProps<Theme>;
empty?: ReactNode; empty?: ReactNode;
/** Server-sort wiring: active key (matches a column's sortKey), direction, handler. */ /** Server-sort wiring: active key (matches a column's sortKey), direction, handler. */
sortBy?: string; sortBy?: string;
@@ -51,6 +54,7 @@ export default function DataTable<T>({
rowInactive, rowInactive,
onRowClick, onRowClick,
rowDanger, rowDanger,
rowSx,
empty, empty,
sortBy, sortBy,
sortDir, sortDir,
@@ -117,50 +121,54 @@ export default function DataTable<T>({
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{rows.map((row) => ( {rows.map((row) => {
<TableRow const extra = rowSx?.(row);
key={rowKey(row)} return (
hover <TableRow
onClick={onRowClick ? () => onRowClick(row) : undefined} key={rowKey(row)}
sx={[ hover
onRowClick ? { cursor: "pointer" } : {}, onClick={onRowClick ? () => onRowClick(row) : undefined}
rowDanger?.(row) sx={[
? { onRowClick ? { cursor: "pointer" } : {},
bgcolor: "error.light", rowDanger?.(row)
opacity: 0.88, ? {
"&:hover": {
bgcolor: "error.light", bgcolor: "error.light",
filter: "brightness(0.97)", opacity: 0.88,
}, "&:hover": {
} bgcolor: "error.light",
: {}, filter: "brightness(0.97)",
rowInactive?.(row) ? { opacity: 0.55 } : {}, },
]} }
> : {},
{columns.map((c) => ( rowInactive?.(row) ? { opacity: 0.55 } : {},
<TableCell ...(Array.isArray(extra) ? extra : extra ? [extra] : []),
key={c.key} ]}
align={c.align} >
sx={{ {columns.map((c) => (
fontSize: ".8rem", <TableCell
...(c.bold ? { fontWeight: 500 } : {}), key={c.key}
...(c.mono align={c.align}
? { fontFamily: "'DM Mono', Menlo, monospace" } sx={{
: {}), fontSize: ".8rem",
...(hasWidths ...(c.bold ? { fontWeight: 500 } : {}),
? { ...(c.mono
whiteSpace: "nowrap", ? { fontFamily: "'DM Mono', Menlo, monospace" }
overflow: "hidden", : {}),
textOverflow: "ellipsis", ...(hasWidths
} ? {
: {}), whiteSpace: "nowrap",
}} overflow: "hidden",
> textOverflow: "ellipsis",
{c.render(row)} }
</TableCell> : {}),
))} }}
</TableRow> >
))} {c.render(row)}
</TableCell>
))}
</TableRow>
);
})}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>