Skip to content

Column DnD Table

Drag-and-drop column reordering with composable primitives.

Open in
Preview with Controlled State
Open in

For large datasets, use DataTableVirtualizedDndHeader and DataTableVirtualizedDndColumnBody which combine row virtualization with column drag-and-drop.

Open in

Column DnD lets users reorder table columns by dragging headers. Built with @dnd-kit and composable primitives following the shadcn/ui open-code pattern.

Install the DataTable core and column DnD add-on:

pnpm dlx shadcn@latest add @niko-table/data-table @niko-table/data-table-column-dnd

First time using @niko-table? See the Installation Guide to set up the registry.

For other add-ons or manual copy-paste, see the Installation Guide.

Three components work together:

  1. DataTableColumnDndProvider — Wraps the table with horizontal DnD context
  2. DataTableDndHeader — Renders headers as draggable items
  3. DataTableDndColumnBody — Cells follow column drag position
column-dnd.tsx
const [columnOrder, setColumnOrder] = React.useState<string[]>(() =>
columns.map(c => c.id as string),
)
return (
<DataTableRoot
data={data}
columns={columns}
state={{ columnOrder }}
onColumnOrderChange={setColumnOrder}
>
<DataTableColumnDndProvider
columnOrder={columnOrder}
onColumnOrderChange={setColumnOrder}
>
<DataTable>
<DataTableDndHeader />
<DataTableDndColumnBody />
</DataTable>
</DataTableColumnDndProvider>
</DataTableRoot>
)
  • Every column needs an explicit id field for column order tracking
  • columnOrder state must be passed to both DataTableRoot and DataTableColumnDndProvider
  • Headers are draggable by default — grab any header to reorder
  • Safe to combine with sorting and filtering — column order is independent of data order, unlike Row DnD

✅ Use Column DnD when:

  • Users want to customize their table layout
  • Different users prefer different column arrangements
  • Building configurable dashboards

❌ Consider other options when:

  • Column order is fixed by design
  • Tables have very few columns