Capítulo 30 de 54
Column order is decided by a fixed three-stage pipeline (pinning → manual columnOrder → grouping), and manual reordering is just table.setColumnOrder(newIdArray) wired to whatever drag-and-drop library you choose — the library only owns the drag interaction, never the ordering state itself.
columnOrder state reorders within those regions (it only affects unpinned/center columns unless pinning isn't used); (3) if grouping is active and groupedColumnMode is 'reorder' or 'remove', grouped columns move to the front of the flow.columnOrder state, columns render in columns array definition order.initialState.columnOrder: ['id1', 'id2', ...]; don't also pass state.columnOrder at the same time — state wins and makes initialState a no-op for that slice (pick one).atoms: { columnOrder: atom } (v9-recommended, fine-grained subscriptions elsewhere in the app) or classic state.columnOrder + onColumnOrderChange (simpler, less granular). table.setColumnOrder works identically regardless of which ownership mode is in play.table.setColumnOrder(...). The official example pairs DnD Kit's arrayMove with the drag-end event's active.id/over.id. TanStack Table has no opinion on which DnD library you use — DnD Kit (modular, Strict Mode-safe, plays well with semantic <table>) is the one the official examples use; native onDragStart/onDragEnter/onDragEnd events are a zero-dependency alternative if you're willing to handle touch support yourself; older libraries (react-dnd, react-beautiful-dnd) are no longer actively maintained — Atlassian's Pragmatic drag and drop is the maintained successor in that API family.table.setColumnOrder([...]), table.resetColumnOrder() (→ initialState.columnOrder), table.resetColumnOrder(true) (→ empty/default order). Position-reading helpers: column.getIndex() / getIndex('start' | 'center' | 'end'), column.getIsFirstColumn(), column.getIsLastColumn() — useful for boundary styling or drag-target logic that needs the current rendered order (post pinning/ordering/grouping).const features = tableFeatures({ columnOrderingFeature })
const table = useTable({ features, columns, data, initialState: { columnOrder: ['lastName', 'firstName', 'age'] } })
function handleDragEnd({ active, over }: DragEndEvent) {
if (!over || active.id === over.id) return
table.setColumnOrder((prev) => arrayMove(prev, prev.indexOf(active.id as string), prev.indexOf(over.id as string)))
}
setColumnOrder call in a drop handler — the table doesn't need to know which DnD library produced the new order.columnOrder is wrong.initialState.columnOrder or state.columnOrder should be set — not both.setColumnOrder is DnD-library-agnostic; the library only needs to produce a reordered id array.groupedColumnMode, the stage that happens after manual ordering.state/on[X]Change in full.