radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.35k stars 765 forks source link

[ScrollArea] Improve composability with virtualized list libraries #1134

Open jjenzz opened 2 years ago

jjenzz commented 2 years ago

Discussed in https://github.com/radix-ui/primitives/discussions/1078

Originally posted by **davbrito** January 12, 2022 There are several good packages for making virtualized lists. We have [react-virtual](https://github.com/tannerlinsley/react-virtual#readme), [react-virtualized](https://github.com/bvaughn/react-virtualized), [react-virtuoso](https://virtuoso.dev/), [react-window](http://react-window.now.sh/), etc. What would be the "official" or recommended approach for doing that kind of list with the `ScrollArea` primitive, and what library is best suited for the job? I've tried to do it in the past with no success. If you have had some experience doing it, please share your approach.
benoitgrelard commented 2 years ago

Linked to #750

grumd commented 2 years ago

@jjenzz I might be too late but here's a pretty easy way to combine ScrollArea with react-virtuoso using customScrollParent: https://codesandbox.io/p/sandbox/wispy-field-g8w2t3?file=%2FApp.jsx


const TAGS = Array.from({ length: 500 }).map(
  (_, i, a) => `v1.2.0-beta.${a.length - i}`
);

const ScrollAreaDemo = () => {
  const [scrollParent, setScrollParent] = useState();

  return (
    <ScrollArea.Root className="ScrollAreaRoot">
      <ScrollArea.Viewport className="ScrollAreaViewport" ref={setScrollParent}>
        <Virtuoso
          data={TAGS}
          itemContent={(index, tag) => <div className="Tag">{tag}</div>}
          customScrollParent={scrollParent ?? undefined}
        />
      </ScrollArea.Viewport>
      <ScrollArea.Scrollbar
        className="ScrollAreaScrollbar"
        orientation="vertical"
      >
        <ScrollArea.Thumb className="ScrollAreaThumb" />
      </ScrollArea.Scrollbar>
    </ScrollArea.Root>
  );
};
alissawix commented 6 months ago

sandbox

example with react-window

partial code :

<ScrollArea.Root className="ScrollAreaRoot">
      <List
        height={250}
        itemCount={TAGS.length}
        itemData={TAGS}
        itemSize={35}
        outerElementType={ScrollArea.Viewport}
      >
        {Row}
      </List>
      <ScrollArea.Scrollbar
        className="ScrollAreaScrollbar"
        orientation="vertical"
      >
        <ScrollArea.Thumb className="ScrollAreaThumb" />
      </ScrollArea.Scrollbar>
    </ScrollArea.Root>