2024-11-28 11:26:01 +01:00

119 lines
3.6 KiB
TypeScript

import InfiniteScroll from "@Front/Components/Elements/InfiniteScroll";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Typography, { ETypo, ETypoColor } from "../../Typography";
import classes from "./classes.module.scss";
import { SxProps, Theme } from "@mui/material";
export type IRowProps = { key: string } & Record<string, React.ReactNode | { sx: SxProps<Theme>; content: React.ReactNode }>;
type IRow = {
key?: string;
content: Record<string, CellContent>;
};
type IProps = {
header: readonly IHead[];
rows: IRowProps[];
onNext?: ((release: () => void, reset?: () => void) => Promise<void> | void) | null;
};
export type IHead = {
key: string;
title?: string;
};
type CellContent = {
key: string;
value: React.ReactNode | { sx: SxProps<Theme>; content: React.ReactNode };
};
export default function MuiTable(props: IProps) {
const rows: IRow[] = props.rows.map((rowProps) => {
const row: IRow = {
key: rowProps.key,
content: {},
};
props.header.forEach((column) => {
const cellContent: CellContent = {
key: column.key + rowProps.key,
value: rowProps[column.key],
};
row.content[column.key] = cellContent;
});
return row;
});
return (
<InfiniteScroll orientation="vertical" onNext={props.onNext} offset={0}>
<TableContainer
className={classes["root"]}
sx={{ height: "45vh", overflowY: "auto", overflowX: "hidden", backgroundColor: "var(--table-background-default)" }}>
<Table aria-label="simple table" sx={{ border: "0" }}>
<TableHead
sx={{
position: "sticky",
top: "0",
borderBottom: "1px solid var(--table-header-border)",
backgroundColor: "var(--table-background-default)",
}}>
<TableRow>
{props.header.map((column) => (
<TableCell key={column.key} align={"left"} sx={{ border: 0, padding: "4px 8px" }}>
{column.title && (
<span className={classes["head"]}>
<Typography
className={classes["text"]}
typo={ETypo.TEXT_SM_REGULAR}
color={ETypoColor.COLOR_NEUTRAL_600}>
{column.title}
</Typography>
{/* <ChevronDownIcon width={21} /> */}
</span>
)}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => {
return (
<TableRow key={row.key} sx={{ verticalAlign: "middle" }} className={classes["row"]}>
{Object.values(row.content).map((cell) => (
<TableCell
className={classes["cell"]}
key={cell.key}
align="left"
sx={{ ...getCellValueStyle(cell.value), border: 0, padding: "4px 8px", height: "53px" }}>
<Typography
className={classes["content"]}
typo={ETypo.TEXT_MD_REGULAR}
color={ETypoColor.COLOR_NEUTRAL_900}>
{cell.value && typeof cell.value === "object" && "content" in cell.value
? cell.value.content
: cell.value}
</Typography>
</TableCell>
))}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</InfiniteScroll>
);
function getCellValueStyle(value: React.ReactNode | { sx: SxProps<Theme>; content: React.ReactNode }) {
if (typeof value === "object" && value !== null && "sx" in value) {
return value.sx;
}
return {};
}
}