Column DnD Table
Drag-and-drop column reordering with composable primitives.
Drag column headers to reorder them, wired through DataTableColumnDndProvider on top of @dnd-kit. Unlike row DnD, column DnD is safe to combine with sorting, filtering, and virtualization — the user’s column order is independent of the row model.
Overview
Section titled “Overview”Preview with Controlled State
View Full State
{
"columnOrder": [
"id",
"name",
"department",
"role",
"location",
"status"
],
"columnVisibility": {},
"globalFilter": ""
}Virtualized Column DnD
Section titled “Virtualized Column DnD”For large datasets, use DataTableVirtualizedDndHeader and DataTableVirtualizedDndColumnBody which combine row virtualization with column drag-and-drop.
Introduction
Section titled “Introduction”Column DnD lets users reorder table columns by dragging headers. Built with @dnd-kit and composable primitives following the shadcn/ui open-code pattern.
Installation
Section titled “Installation”Install the DataTable core and column DnD add-ons. Add data-table-view-dnd-menu and data-table-search-filter for the toolbar shown in the example:
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.
Basic Column DnD
Section titled “Basic Column DnD”Three components work together:
DataTableColumnDndProvider— Wraps the table with horizontal DnD contextDataTableDndHeader— Renders headers as draggable itemsDataTableDndColumnBody— Cells follow column drag position
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>)Two Reorder Surfaces, One State
Section titled “Two Reorder Surfaces, One State”DataTableViewDndMenu is a drag-to-reorder variant of the View menu that shares the same columnOrder state as the column-header drag. Users get two ways to reorder, and visibility toggles + a Reset live in the same dropdown:
<DataTableToolbarSection className="justify-between"> <DataTableSearchFilter placeholder="Search employees..." /> <DataTableViewDndMenu columnOrder={columnOrder} onColumnOrderChange={setColumnOrder} onReset={() => setColumnOrder(initialColumnOrder)} /></DataTableToolbarSection>Use DataTableViewMenu (no DnD) instead if you don’t need drag-to-reorder — it skips the @dnd-kit/* bundle.
Key Points
Section titled “Key Points”- Every column needs an explicit
idfield for column order tracking columnOrderstate must be passed to bothDataTableRootandDataTableColumnDndProvider— andDataTableViewDndMenuif you use it- 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
DataTableViewDndMenuand the column-header drag share state, so both surfaces stay in lockstep
When to Use
Section titled “When to Use”✅ 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
Next Steps
Section titled “Next Steps”- Row DnD Table — Drag-and-drop row reordering
- Virtualization Table — Virtual scrolling for large datasets
- Column Pinning Table — Pin columns to edges