Custom icons
Every glyph is a named slot. Override any subset with the icons option, which accepts a partial. Defaults come from Lucide (shadcn's default icon library), but you can swap in any icon library.
Each value is a component that accepts a className, so any icon library works — here swapping in Remix Icon:
import { DataTable, useDataTable } from "@/components/ui/data-table"
import { RiArrowDownLine, RiArrowUpLine, RiSearchLine } from "@remixicon/react"
const table = useDataTable({
data,
columns,
getRowId: (row) => row.id,
icons: {
sortAscending: RiArrowUpLine,
sortDescending: RiArrowDownLine,
search: RiSearchLine,
},
})
return <DataTable table={table} />
App-wide defaults
For icon (and localization) defaults shared across many tables, wrap a subtree in DataTableConfigProvider.
import { DataTableConfigProvider } from "@/components/ui/data-table"
import { RiSearchLine } from "@remixicon/react"
<DataTableConfigProvider icons={{ search: RiSearchLine }}>
{children}
</DataTableConfigProvider>
Pin and clear icons
Pinning and clearing have their own slots: pinLeft, pinRight (column menu), pinTop, pinBottom (row pin button), clearSort and clearFilter (column menu). The column pins default to the Lucide pin turned to point into the edge it pins to, the row pins to the plain pin, and the clear items to ListX and FilterX.
If you only set the older slots, the new ones follow them, so existing overrides keep working:
pinLeft,pinRight,pinTopandpinBottomfall back to yourpin, without rotation.clearSortfalls back to yourclearAll, andclearFilterto yourfilterOff.
Set the new slots to tell the two pin directions apart. Code that types a full DataTableIcons object (not a Partial) must add the six new keys.
Precedence
Values resolve in this order: built-in defaults → DataTableConfigProvider →
per-call options. Per-call icons always win.