react-table-library icon indicating copy to clipboard operation
react-table-library copied to clipboard

Scroll to selected row

Open JeMeister opened this issue 2 years ago • 2 comments

Hi, I have a huge set of data so I am using the virtualized options. Also, I am selecting a row programmatically using select.fns.onToggleById(selectedId) . Is it possible to scroll to the selected row on that call? It is really hard to find the selected row manually.

JeMeister avatar Sep 27 '23 03:09 JeMeister

Did you find a solution yet? This would be really nice and I haven't found any suitable solution

I recently implemented a feature like this for an app where I'm using react-table-library. It's possible to programmatically scroll to a specific row index in a virtualized table list with a bit of DOM querying and offset math. I've made a sandbox demo here: https://codesandbox.io/p/devbox/2t84lv

The table code is based on Compact Table - Virtualized from the docs.

Screen recording gif of demo:

Screen Recording 2024-02-02 at 11 00 42 AM

The interesting bit of code is written in a custom hook in my sandbox. I'm sure there are improvements & optimizations possible here, but this fulfills the basic requirements:

function useScrollToRowIndex(
  containerElement: React.RefObject<HTMLElement>,
  index: number,
) {
  const scrollToRow = React.useCallback(() => {
    const scrollingContainer = containerElement.current?.querySelector(
      "[data-table-library_body]",
    )?.parentElement?.parentElement;

    if (scrollingContainer == null || index < 0) {
      return;
    }

    const minHeightToViewTargetRow = index * ROW_HEIGHT;
    const isRowAboveViewableWindow =
      scrollingContainer.scrollTop >
      minHeightToViewTargetRow - VERTICAL_SCROLL_BUFFER;
    const isRowBelowViewableWindow =
      scrollingContainer.scrollTop + scrollingContainer.clientHeight <
      minHeightToViewTargetRow - VERTICAL_SCROLL_BUFFER;

    if (isRowAboveViewableWindow || isRowBelowViewableWindow) {
      scrollingContainer.scrollTo({
        top: minHeightToViewTargetRow - VERTICAL_SCROLL_BUFFER,
        behavior: "smooth",
      });
    }
  }, [containerElement]);

  return scrollToRow;
}

The containerElement argument to this hook is expected to be the parent element of a react-table-library <Table>:

const containerElement = React.useRef<HTMLDivElement>(null);
const scrollToRow = useScrollToRowIndex(containerElement, nodes.length - 1);

return (
  <div>
    <div style={{ height: "300px" }} ref={containerElement}>
      <CompactTable
        columns={COLUMNS}
        virtualizedOptions={VIRTUALIZED_OPTIONS}
        data={data}
        theme={theme}
        layout={{ isDiv: true, fixedHeader: true }}
      />
    </div>
    {/* ... */}
  </div>
);

adidahiya avatar Feb 02 '24 16:02 adidahiya