fixed table formatting and added a scroll bar
This commit is contained in:
parent
9e3ce3c00d
commit
e732cab837
1 changed files with 76 additions and 17 deletions
|
|
@ -15,11 +15,10 @@ const useStyles = makeStyles((theme: Theme) => {
|
|||
border: "none"
|
||||
},
|
||||
tableContainer: {
|
||||
// margin: theme.spacing(1),
|
||||
// [theme.breakpoints.up("sm")]: {
|
||||
// margin: theme.spacing(2)
|
||||
// },
|
||||
// width: "auto"
|
||||
width: "100%",
|
||||
maxWidth: "100%",
|
||||
overflow: "hidden",
|
||||
minWidth: 0,
|
||||
},
|
||||
title: {
|
||||
padding: theme.spacing(1),
|
||||
|
|
@ -75,6 +74,53 @@ export interface Column<T> {
|
|||
disableSort?: boolean;
|
||||
}
|
||||
|
||||
function ResizableHeaderTitle<T>(props: {
|
||||
column: Column<T>;
|
||||
index: number;
|
||||
columnsLength: number;
|
||||
resizeable: boolean;
|
||||
onColumnClick: (column: Column<T>) => void;
|
||||
showOrderIcon: (column: Column<T>) => React.ReactNode;
|
||||
}) {
|
||||
const { column, index, columnsLength, resizeable, onColumnClick, showOrderIcon } = props;
|
||||
const titleRef = useRef<HTMLDivElement>(null);
|
||||
const [isOverflowing, setIsOverflowing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const el = titleRef.current;
|
||||
if (!el) return;
|
||||
const checkOverflow = () => setIsOverflowing(el.scrollWidth > el.clientWidth);
|
||||
checkOverflow();
|
||||
const ro = new ResizeObserver(checkOverflow);
|
||||
ro.observe(el);
|
||||
return () => ro.disconnect();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid2
|
||||
ref={titleRef}
|
||||
alignItems="center"
|
||||
display="flex"
|
||||
onClick={() => !column.disableSort && onColumnClick(column)}
|
||||
sx={{
|
||||
cursor: column.disableSort ? "default" : "pointer",
|
||||
minWidth: 0,
|
||||
overflow: "hidden",
|
||||
...(isOverflowing && resizeable && index < columnsLength - 1
|
||||
? {
|
||||
maskImage: "linear-gradient(to right, black 75%, transparent 100%)",
|
||||
WebkitMaskImage: "linear-gradient(to right, black 75%, transparent 100%)",
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
>
|
||||
<Box component="span" sx={{ whiteSpace: "nowrap" }}>
|
||||
{column.title} {showOrderIcon(column)}
|
||||
</Box>
|
||||
</Grid2>
|
||||
);
|
||||
}
|
||||
|
||||
interface Props<T> {
|
||||
rows: T[],
|
||||
columns?: Column<T>[] | (() => Column<T>[]),
|
||||
|
|
@ -483,11 +529,15 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
if (!dragStart) return
|
||||
|
||||
let newWidths: number[] = [...rowWidths]
|
||||
newWidths[index] = newWidths[index] - (dragStart - e.clientX)
|
||||
const delta = dragStart - e.clientX
|
||||
const newWidthForIndex = newWidths[index] - delta
|
||||
const clampedWidth = Math.max(MIN_COLUMN_WIDTH, newWidthForIndex)
|
||||
const actualDelta = newWidths[index] - clampedWidth
|
||||
newWidths[index] = clampedWidth
|
||||
newWidths.every((width, j) => {
|
||||
if (j <= index || width === 0) return true
|
||||
else if (newWidths[j] !== undefined) {
|
||||
newWidths[j] = newWidths[j] + (dragStart - e.clientX)
|
||||
newWidths[j] = newWidths[j] + actualDelta
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
|
@ -495,8 +545,11 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
|
||||
}
|
||||
|
||||
const MIN_COLUMN_WIDTH = 24;
|
||||
|
||||
return (
|
||||
<Box className={classes.tableContainer} component={Paper}>
|
||||
<TableContainer sx={{ overflowX: "auto" }}>
|
||||
<Table>
|
||||
<TableHead className={stickyHeader ? classes.stickyHeader : undefined}>
|
||||
<TableRow sx={ !title && !setSearchText ? { display: "none" } : undefined}>
|
||||
|
|
@ -552,18 +605,23 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
)
|
||||
return (
|
||||
<TableCell key={"header-cell-"+index} width={rowWidths[index] ? rowWidths[index] : undefined}>
|
||||
<Grid2 container spacing={1} justifyContent={"space-between"}>
|
||||
<Grid2
|
||||
alignItems="center"
|
||||
display="flex"
|
||||
onClick={() => !column.disableSort && columnClick(column)}
|
||||
sx={{ cursor: column.disableSort ? "default" : "pointer" }}
|
||||
container
|
||||
spacing={1}
|
||||
justifyContent={"space-between"}
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
{column.title} {showOrderIcon(column)}
|
||||
</Grid2>
|
||||
<ResizableHeaderTitle
|
||||
column={column}
|
||||
index={index}
|
||||
columnsLength={columns.length}
|
||||
resizeable={!!resizeable}
|
||||
onColumnClick={columnClick}
|
||||
showOrderIcon={showOrderIcon}
|
||||
/>
|
||||
{index < columns.length-1 && resizeable &&
|
||||
<Grid2
|
||||
sx={{ cursor: "col-resize", userSelect: "none" }}
|
||||
sx={{ cursor: "col-resize", userSelect: "none", flexShrink: 0 }}
|
||||
onMouseDown={event => resizeClick(event, index)}
|
||||
>
|
||||
|
|
||||
|
|
@ -672,6 +730,7 @@ export default function ResponsiveTable<T extends Object>(props: Props<T>) {
|
|||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
{!hidePagination &&
|
||||
<TablePagination
|
||||
rowsPerPageOptions={rowsPerPageOptions ? rowsPerPageOptions : [5, 10, 20]}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue