Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Resizable Columns Data Table for React

An employee table whose columns resize from their edges. Heads are Name, Department, Position, Email and Salary. John Doe is first.

A table of employees with Name, Department, Position, Email and Salary. John Doe is first, in Engineering, as Senior Developer. The column edges can be dragged.

Let people drag column edges when one table serves different jobs. Fixed columns on a Table are simpler when the widths never change. On React, Base UI does not remember the widths.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Usage

<div className="w-full max-w-4xl">
  <div className="rounded-md border bg-background">
    <Table className="table-fixed" style={{ width: table.getTotalSize() }}>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <TableHead
                className="relative"
                key={header.id}
                style={{ width: header.getSize() }}
              >
                {header.isPlaceholder ? null : (
                  <table.FlexRender header={header} />
                )}
                <ResizeHandle header={header} />
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {rows.map((row) => (
          <TableRow key={row.id}>
            {row.getAllCells().map((cell) => (
              <TableCell
                className="truncate"
                key={cell.id}
                style={{ width: cell.column.getSize() }}
              >
                <table.FlexRender cell={cell} />
{/* The rest of the file is under Installation. */}

FAQ

How does a column resize?

useTable gets columnResizingFeature, columnSizingFeature and columnResizeMode: "onChange", so the width updates while you drag. The handle calls header.getResizeHandler() from onMouseDown and onTouchStart.

How is the starting width set?

Each column sets size: Name 150, Department 120, Position 180, Email 220 and Salary 120. Heads and cells take getSize() as their width, and the table takes table.getTotalSize() with table-fixed, so a cell's text is cut off with an ellipsis instead of widening its column.

What is the drag handle?

A thin div on the end edge of each TableHead, with cursor-col-resize. It shows on hover and turns bg-primary while header.column.getIsResizing() is true. The note under the table says to drag column edges.

Can I resize a column from the keyboard?

Not in this demo: the handle answers the pointer and touch only, and it's hidden from screen readers. For keyboard resizing, add buttons or keys that call column.setSize or table.setColumnSizing.

What happens when the columns outgrow the frame?

Table sits in a container that scrolls sideways, so a table wider than the frame scrolls rather than squeezing its columns.

Do the widths stick after a refresh?

No. The widths live in the table's state and start from each column's size. Save columnSizing from onColumnSizingChange and pass it back as initial state to keep them.

API Reference

Table

Sets width, table, getTotalSize, header, getSize and cell. The rest is on the Table page.