Using Virtualized lists inside MUI table (react)

29 Views Asked by At

I am trying to do a rather complicated system to allow a table to be viewed on desktop and mobile.

I have incorporated css from this site https://css-tricks.com/responsive-data-tables/

I have a media query to change the table from MUI to a 'collapsed' table view, and I'm having trouble with table hierarchy. Avoiding all errors gives me a 'list' form table that only renders the first few rows that are visible on page load, and the rest of the data is not rendered when I scroll down.

Please excuse the mess - I'm not terribly experienced, and this is probably not the best way to do it. I've been fumbling through this to try and make it work.

Currently, this is my component, which seems to display with no errors in the console. However, when I include the outer and inner table element tags, the virtualization with react-window stops working and only renders the first visible rows on page load, and when i scroll down, it no other rows are rendered.

<StyledCollapsedTable id={collapsedTableId.current}>
        <Loading />
        <TableContainer id="test" style={{ height: "100%", width: "100%" }} component="div">
          <Table>
            <TableHead key={"header"}>
              <TableRow>
                {rows &&
                  columns.map((column, index) => {
                    if (column.field === "parameter") {
                      return null;
                    }
                    return (hiddenColumns[column.field] === undefined ? true : hiddenColumns[column.field]) ? (
                      <TableCell key={index}>
                        {index < columns.length - 1 ? (
                          <span style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
                            <span className={getHeaderClassName(column.headerAlign)} style={{ width: "100%", paddingLeft: index === 0 ? "5px" : "0" }}>
                              {column.headerName}
                            </span>
                          </span>
                        ) : (
                          column.headerName
                        )}
                      </TableCell>
                    ) : null;
                  })}
              </TableRow>
            </TableHead>
          </Table>
          <VariableSizeList
            outerElementType={"table"}
            innerElementType={"tbody"}
            className="list-box"
            ref={listRef}
            height={height}
            itemCount={rows.length}
            width={"100%"}
            estimatedItemSize={300}
            itemSize={getItemSize}
            itemData={{ rows, columns, hiddenColumns, formatCell, onCellClick }}
          >
            {({ index, style }) => <CollapsedTableRow index={index} style={style} data={{ rows, columns, hiddenColumns, formatCell, onCellClick }} />}
          </VariableSizeList>
        </TableContainer>
      </StyledCollapsedTable>

When I remove the inner and outer element types of my variable size list, I get errors, but everything works the way I want it to.

I am hoping someone might be aware of how react-window handles virtualization and how I can get it to show correctly.

The <CollapsedTableRow /> tag is as follows:

const CollapsedTableRow = ({ index, style, data }: CollapsedTableRowProps) => {
  const { rows, columns, hiddenColumns, formatCell, onCellClick } = data; // Destructure hiddenColumns and formatCell

  const row = rows[index];
  return (
    <TableRow key={row.name} className={`${index % 2 === 0 ? "even" : "odd"}`} style={style}>
      {columns.map((column: any, index: number) => {
        let clickable = false;
        if (row.errors && row.error !== 0 && onCellClick) {
          clickable = true;
        } else if (onCellClick) {
          clickable = true;
        }
        return hiddenColumns[column.field] === undefined || hiddenColumns[column.field] ? (
          <TableCell
            key={index}
            className={getClassName(column.type)}
            title={column.headerName}
            onClick={() => {
              onCellClick && onCellClick({ row: row });
            }}
            style={{ cursor: clickable ? "pointer" : "default" }}
          >
            <div className="collapsed-row">{formatCell(row, column) || row[column.field]}</div>
          </TableCell>
        ) : null;
      })}
    </TableRow>
  );
};

Any help would be amazing. ChatGPT can only help me so much ><

Would be more than happy to share more of the code to assist with my question - just let me know what needs to be shared - I just don't know what ya'll need to know.

Thanks in advance

0

There are 0 best solutions below