React Radix UI ScrollArea Full Height

1.7k Views Asked by At

Im using Radix UI for my Web app and I wanted to make a scrollarea that fills the remaining space of the screen and allows scrolling. I tried setting the height of the scrollarea to 100% and such but then the table just overflows. How to make scroll area have a defined height not in pixels but by percentage?

import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
import { Table } from "@radix-ui/themes"

const TableScrollArea = () => {
    // Create an empty array to store the objects
    const dataArray = [];

    // Define the data to be filled in the objects
    const data = {
        name: 'AAA',
        email: 'AAA',
        title: 'AAA',
    };

    // Fill the array with 1000 entries, each containing the data
    for (let i = 0; i < 1000; i++) {
        dataArray.push({ ...data });
    }


    return (
        <div className='h-full'>
            <ScrollAreaPrimitive.Root>
                <ScrollAreaPrimitive.Viewport className={`h-full`}>

                    <Table.Root>
                        <Table.Header>
                            <Table.Row>
                                <Table.ColumnHeaderCell>Full name</Table.ColumnHeaderCell>
                                <Table.ColumnHeaderCell>Email</Table.ColumnHeaderCell>
                                <Table.ColumnHeaderCell>Group</Table.ColumnHeaderCell>
                            </Table.Row>
                        </Table.Header>

                        <Table.Body>
                            {dataArray.map(person => (
                                <Table.Row>
                                    <Table.RowHeaderCell>{person.name}</Table.RowHeaderCell>
                                    <Table.Cell>{person.email}</Table.Cell>
                                    <Table.Cell>{person.title}</Table.Cell>
                                </Table.Row>
                            ))}
                        </Table.Body>
                    </Table.Root>

                </ScrollAreaPrimitive.Viewport>
                <ScrollAreaPrimitive.Scrollbar
                    orientation="vertical"
                >
                    <ScrollAreaPrimitive.Thumb />
                </ScrollAreaPrimitive.Scrollbar>
            </ScrollAreaPrimitive.Root>
        </div>
    )

};

    export default TableScrollArea
3

There are 3 best solutions below

0
On BEST ANSWER

I had a similar issue; unfortunately, I couldn't make it work with 'h-full', 'h-screen', or anything similar.

Finally, to solve the problem, I used a useRef to track the space occupied in pixels by components and utilized calc to generate an absolute value.

Example:

const heightSidebarProfile = useRef<null | number>(document.getElementById(idProfile)?.offsetHeight ?? null);

<div className={`h-[calc(100%-${heightSidebarProfile.current}px)]`}>

Of course, additional validations may be necessary to ensure its effectiveness.

I also acknowledge that this may not be the optimal way to resolve the issue, but it addressed the situation for me.

0
On

I'm using shadcn which under the hood uses Radix and I've been able to make the viewport to h-full by using asChild property like this. hope it helps:

  <ScrollAreaPrimitive.Root
    className={cn("relative overflow-hidden", className)}
  >
    <ScrollAreaPrimitive.Viewport
      asChild
      className="h-full w-full rounded-[inherit]"
    >
      <div className="h-full">
         {children}
      </div>
    </ScrollAreaPrimitive.Viewport>
    <ScrollBar />
    <ScrollAreaPrimitive.Corner />
  </ScrollAreaPrimitive.Root>
0
On

Similar issue, my workaround is using absolute positioning on the child like

position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;

I use a custom tailwind plugin to target children:

// In tailwind.config.js
    plugins: [
        // Add support for targeting children with child:
        ({ addVariant }) => {
            addVariant('child', '& > *');
            addVariant('child-hover', '& > *:hover');
        },

Then on the scrollArea: child:px-4 child:absolute child:top-0 child:right-0 child:bottom-0 child:left-0