Mariam
Mariam

Reputation: 1

AutoSize + react-window: how to dynamically resize each row within my table?

I'm using AutoSizer with react-window, which works fine on the general list component, but I'm not sure what the best way is to get each row to dynamically set the height. My current setup doesn't work well to create consistent padding across my rows.

import { VariableSizeList as List, ListChildComponentProps } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";

          <div className={styles.autoSizerWrapper}>
            <AutoSizer disableWidth>
              {({ height }) => (
                <List
                  height={height}
                  itemCount={rows.length}
                  width="100%"
                  itemSize={getItemSize}
                >
                  {({ index, style }) => (
                    <TaskListRow
                      style={style}
                      data={rows[index].item}
                      onClick={rows[index].onClick}
                      index={index}
                    />
                  )}
                </List>
              )}
            </AutoSizer>
          </div>

function taskListRow({ data: check, onClick, style }: ReactWindowRenderFnProps): JSX.Element {
  const styles = useStyles();

  return (
    <TableRow key={check.checkID} onClick={onClick} style={{ ...style, padding: "10px" }}>
      <TableCell>
        <TableCellLayout>
          <Flexbox direction={FlexboxDirection.VERTICAL} customClassName={styles.checkRow}>
            <strong>[{task.name}]</strong>
            <span>{task.description}</span>
          </Flexbox>
        </TableCellLayout>
      </TableCell>
    </TableRow>
  );
}

  const rows = checks?.map(
    (item, index) =>
      ({
        item,
        appearance: "none",
        onClick: () => console.log("Clicked item at index:", index),
        onKeyDown: () => {},
      }) ?? [],
  );

  const getItemSize = (index: number) => {
    if (!rows) return 0;
    const check = rows[index].item;
    const baseHeight = 50;
    const additionalHeight = getTextHeight(check.text, 500);
    return baseHeight + additionalHeight;
  };

function getTextHeight(text: string, maxWidth: number, fontSize: number = 12, padding: number = 10): number {
  const div = document.createElement("div");
  div.style.position = "absolute";
  div.style.visibility = "hidden";
  div.style.width = `${maxWidth - padding}px`;
  div.style.fontSize = `${fontSize}px`;
  div.style.whiteSpace = "pre-wrap";
  div.style.lineHeight = "1";
  div.textContent = text;
  document.body.appendChild(div);
  const height = div.clientHeight;
  document.body.removeChild(div);
  return height + padding * 1.25;
}

Upvotes: 0

Views: 171

Answers (0)

Related Questions