From 1b375967f03f1a7a4a13ff767cbf6650bb2fdd17 Mon Sep 17 00:00:00 2001 From: "dawid.wolosz" Date: Thu, 5 Dec 2024 15:30:24 +0100 Subject: [PATCH] added table gradient scroll bar info. --- ngui/ui/src/components/Table/Table.styles.ts | 9 + ngui/ui/src/components/Table/Table.tsx | 294 +++++++++++-------- 2 files changed, 173 insertions(+), 130 deletions(-) diff --git a/ngui/ui/src/components/Table/Table.styles.ts b/ngui/ui/src/components/Table/Table.styles.ts index 85367cd64..e719b06d9 100644 --- a/ngui/ui/src/components/Table/Table.styles.ts +++ b/ngui/ui/src/components/Table/Table.styles.ts @@ -6,6 +6,15 @@ const useStyles = makeStyles()(() => ({ display: "block", wordBreak: "initial" // shown inside MUI Drawer table inherits word-break: "break-word" which leads to letter-by-letter break in side modals, for example }, + tableGradientOverlay: { + position: "absolute", + top: "0", + right: "0", + width: "250px", + height: "100%", + background: "linear-gradient(to left, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))", + pointerEvents: "none" + }, hoverableRow: { cursor: "pointer" } diff --git a/ngui/ui/src/components/Table/Table.tsx b/ngui/ui/src/components/Table/Table.tsx index 05881cf99..7a6016e69 100644 --- a/ngui/ui/src/components/Table/Table.tsx +++ b/ngui/ui/src/components/Table/Table.tsx @@ -1,4 +1,4 @@ -import { useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import { Box, TableBody, TableCell, TableFooter, TableHead, TableRow } from "@mui/material"; import MuiTable from "@mui/material/Table"; import { getCoreRowModel, useReactTable } from "@tanstack/react-table"; @@ -92,6 +92,35 @@ const Table = ({ manualGlobalFiltering }) => { const headerRef = useRef(); + const tableContainerRef = useRef(); + const [isGradientVisible, setIsGradientVisible] = useState(false); + + const updateGradientVisibility = () => { + const container = tableContainerRef.current as HTMLElement; + if (container) { + const isScrollable = container.scrollWidth > container.clientWidth; + const atScrollEnd = container.scrollLeft + container.clientWidth >= container.scrollWidth; + setIsGradientVisible(isScrollable && !atScrollEnd); + } + }; + + useEffect(() => { + const container = tableContainerRef.current; + + updateGradientVisibility(); + + if (container) { + container.addEventListener("scroll", updateGradientVisibility); + window.addEventListener("resize", updateGradientVisibility); + } + + return () => { + if (container) { + container.removeEventListener("scroll", updateGradientVisibility); + window.removeEventListener("resize", updateGradientVisibility); + } + }; + }, []); const { classes } = useStyles(); @@ -273,141 +302,146 @@ const Table = ({ /> {/* Wrap with box in order to make table fit 100% width with small amount of columns */} {/* TODO: Consider using MUI TableContainer */} - - {isLoading ? ( - - ) : ( - - {withHeader && ( - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - ))} - - ))} - - )} - - {isEmptyArray(rows) ? ( - td": { - borderBottom: "none" +
+ + {isLoading ? ( + + ) : ( + + {withHeader && ( + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + ))} + + ))} + + )} + + {isEmptyArray(rows) ? ( + td": { + borderBottom: "none" + } } - } - : {} - } - > - - - - - ) : ( - rows.map((row, index) => { - const rowStyle = typeof getRowStyle === "function" ? getRowStyle(row.original) : {}; - - return ( - td": { - borderBottom: "none" + : {} + } + > + + + + + ) : ( + rows.map((row, index) => { + const rowStyle = typeof getRowStyle === "function" ? getRowStyle(row.original) : {}; + + return ( + td": { + borderBottom: "none" + } } - } - : {} - } - > - {row.getVisibleCells().map((cell) => { - if (cell.column.id === SELECTION_COLUMN_ID) { - return ; + : {} } - const Cell = memoBodyCells ? MemoTableBodyCell : TableBodyCell; - - return ( - - ); - })} + > + {row.getVisibleCells().map((cell) => { + if (cell.column.id === SELECTION_COLUMN_ID) { + return ; + } + const Cell = memoBodyCells ? MemoTableBodyCell : TableBodyCell; + + return ( + + ); + })} + + ); + }) + )} + + {withFooter && ( + + {table.getFooterGroups().map((footerGroup) => ( + + {footerGroup.headers.map((footerContext) => ( + + ))} - ); - }) + ))} + )} - - {withFooter && ( - - {table.getFooterGroups().map((footerGroup) => ( - - {footerGroup.headers.map((footerContext) => ( - - ))} - - ))} - - )} - - )} - - - - {paginationSettings.pageCount > 1 && ( - + )} + + {isGradientVisible &&
} + + - )} - + {paginationSettings.pageCount > 1 && ( + + )} + +
); };