Replacing built-in icons
The copied table source keeps built-in table icons behind one proxy file:
src/react-datatable/icons.tsxThat file currently re-exports Phosphor icons. The rest of the table imports from the local proxy instead of importing an icon library directly.
This means you can replace the table's built-in icon set without hunting through toolbar, filter, view, grid, dialog, and pagination components one by one.
What the kit uses today
The core kit uses @phosphor-icons/react through icons.tsx.
Icons are used for table-owned controls such as:
- sort direction
- filters
- column visibility
- saved views
- copy link
- pagination
- dialogs
- empty and error states
- row preview close buttons
- bulk-action controls
The docs site and showcase examples also use lucide-react for product examples. Those are not part of the core table icon proxy.
Replace the proxy, not every component
Start by opening:
// src/react-datatable/icons.tsxThe default file looks like this conceptually:
export {
ArrowDownIcon,
ArrowUpIcon,
CheckIcon,
FunnelIcon,
XIcon,
// ...
} from "@phosphor-icons/react"
export type { Icon } from "@phosphor-icons/react"If you want to use another icon set, keep the exported names stable and change what they point to.
Example: replace built-ins with Lucide
Some Phosphor icons are passed a weight prop in the table source. Lucide icons do not use that prop, so wrap Lucide once and drop unsupported props there.
import type { ComponentType, SVGProps } from "react"
import {
ArrowDown,
ArrowLeftRight,
ArrowLeft,
ArrowRight,
ArrowUp,
Bookmark,
Calendar,
Check,
ChevronDown,
Circle,
Copy,
Eye,
EyeOff,
Filter,
GripVertical,
Hash as HashIcon,
Link,
List as ListIcon,
ListFilter,
MoreHorizontal,
Plus,
RotateCcw,
Ruler,
Save,
Search,
Settings,
SlidersHorizontal,
Snowflake as SnowflakeIcon,
Trash,
TriangleAlert,
Type,
Users as UsersIcon,
Workflow,
X,
type LucideIcon,
} from "lucide-react"
export type Icon = ComponentType<
SVGProps<SVGSVGElement> & {
size?: string | number
weight?: unknown
}
>
function asDatatableIcon(IconComponent: LucideIcon): Icon {
return function DatatableIcon({ weight: _weight, ...props }) {
return <IconComponent {...props} />
}
}
export const ArrowCounterClockwiseIcon = asDatatableIcon(RotateCcw)
export const ArrowDownIcon = asDatatableIcon(ArrowDown)
export const ArrowUpIcon = asDatatableIcon(ArrowUp)
export const ArrowsLeftRight = asDatatableIcon(ArrowLeftRight)
export const CloseIcon = asDatatableIcon(X)
export const BookmarkSimpleIcon = asDatatableIcon(Bookmark)
export const CalendarBlank = asDatatableIcon(Calendar)
export const CaretDown = asDatatableIcon(ChevronDown)
export const CaretDownIcon = asDatatableIcon(ChevronDown)
export const CheckIcon = asDatatableIcon(Check)
export const ChevronDownIcon = asDatatableIcon(ChevronDown)
export const ChevronLeftIcon = asDatatableIcon(ArrowLeft)
export const ChevronRightIcon = asDatatableIcon(ArrowRight)
export const DotsSixVertical = asDatatableIcon(GripVertical)
export const DotsSixVerticalIcon = asDatatableIcon(GripVertical)
export const DotsThreeIcon = asDatatableIcon(MoreHorizontal)
export const MoreHorizontalIcon = asDatatableIcon(MoreHorizontal)
export const EyeIcon = asDatatableIcon(Eye)
export const EyeSlashIcon = asDatatableIcon(EyeOff)
export const FunnelIcon = asDatatableIcon(Filter)
export const FunnelSimpleIcon = asDatatableIcon(ListFilter)
export const Gear = asDatatableIcon(Settings)
export const Gradient = asDatatableIcon(Circle)
export const Hash = asDatatableIcon(HashIcon)
export const LinkIcon = asDatatableIcon(Link)
export const List = asDatatableIcon(ListIcon)
export const ListBullets = asDatatableIcon(ListIcon)
export const MagnifyingGlassIcon = asDatatableIcon(Search)
export const PlusIcon = asDatatableIcon(Plus)
export const RadioDotIcon = asDatatableIcon(Circle)
export const RulerIcon = asDatatableIcon(Ruler)
export const SlidersHorizontalIcon = asDatatableIcon(SlidersHorizontal)
export const Snowflake = asDatatableIcon(SnowflakeIcon)
export const SortAscendingIcon = asDatatableIcon(ArrowUp)
export const SortDescendingIcon = asDatatableIcon(ArrowDown)
export const TextT = asDatatableIcon(Type)
export const ToggleLeft = asDatatableIcon(Circle)
export const TrashIcon = asDatatableIcon(Trash)
export const Users = asDatatableIcon(UsersIcon)
export const WarningCircleIcon = asDatatableIcon(TriangleAlert)
export const WarningIcon = asDatatableIcon(TriangleAlert)
export const XIcon = asDatatableIcon(X)
export const AddIcon = PlusIcon
export const AlertIcon = WarningCircleIcon
export const SaveIcon = asDatatableIcon(Save)
export const SaveAsNewIcon = asDatatableIcon(Copy)
export const WorkflowIcon = asDatatableIcon(Workflow)Treat this as a starting point. Pick the exact icons that fit your product language.
Keep product icons out of the proxy
The proxy is for table-owned chrome.
Use column and cell code for product-specific icons:
const columns = [
{
id: "status",
accessorKey: "status",
header: "Status",
filterType: "text-list",
meta: {
filterName: "Status",
filterIcon: StatusIcon,
},
cell: ({ row }) => <StatusCell status={row.original.status} />,
},
]That keeps the table's control icons separate from domain icons like status, priority, owner, health, or billing state.
Check the result
After replacing the proxy, scan the table surfaces that use icons:
- toolbar buttons
- filter chips and filter editors
- display options
- saved views
- column header actions
- empty and error states
- pagination and calendar controls
- row preview and bulk-action surfaces
Then run TypeScript. If the icon set does not support a prop the table passes, adapt it in the proxy instead of changing every caller.
Where to go next
- For changing the toolbar around those icons, read Customizing toolbar and controls.
- For filter-specific labels and icons, read Customizing filter UI.
- For replacing larger UI surfaces, read Replacing built-in UI elements.