Guides
Customize (Style) Components Guide
How to customize and pass props to shadcn/ui components and set up a shadcn/ui Theme in Shadcn Table
One of the strengths of Shadcn Table is that it exposes a majority of all the underlying shadcn/ui component props used to build the table.
Additionally, in one of the sections below, you will learn how to theme your table to customize colors, typography, or any other default CSS that is used by Shadcn Table.
Relevant Table Options
All props labeled st...Props get forwarded to shadcn/ui components. Here is a list of all the props that are exposed in both the root props and column options.
Relevant Column Options
Some of the column options expose the same props as above, but on a per column basis.
Props and Types
Each prop can either be passed as an object or as a callback function where you get access to the underlying table instance and any other relevant callback parameters, such as cell, row, column, etc. This lets you easily run conditional logic on the props you pass. Let's take a look at a few examples.
All
st...Propsprops are strongly typed and you should get ts hints as you write them. Each one forwardsclassName,styleand the props of the element or shadcn/ui component it targets.
Static Prop Objects
const table = useShadcnTable({
columns,
data,
enableRowSelection: true,
//passing the static object variant if no dynamic logic is needed
stSelectCheckboxProps: {
className: 'rounded-full', //makes all checkboxes round
},
});
return <ShadcnTable table={table} />;Callback Functions to Dynamically Set Prop Values
const table = useShadcnTable({
columns,
data,
enableRowSelection: true,
//passing the callback function variant. (You should get type hints for all the callback parameters available)
stSelectCheckboxProps: ({ row }) => ({
className: 'rounded-full',
disabled: row.original.isAccountLocked, //access the row data to determine if the checkbox should be disabled
}),
});
return <ShadcnTable table={table} />;Styling Components
Each st...Props prop accepts className and style, which are forwarded to the underlying element. Since Shadcn Table is built with Tailwind CSS, the recommended way to style components is with Tailwind classes in className. They are merged with the default classes, and they can use the shadcn/ui CSS variables from your theme.
- The
styleprop works just like a style prop in any React component.
const table = useShadcnTable({
columns,
data,
stTableHeadCellProps: {
//simple styling with the `style` prop
style: {
fontWeight: 'normal',
fontSize: '14px',
},
},
});
return <ShadcnTable table={table} />;- Tailwind classes in
classNameget easy access to your theme colors, no hook needed.
const table = useShadcnTable({
columns,
data,
stTableHeadCellProps: {
//shadcn/ui theme colors are available as Tailwind classes
className: 'text-muted-foreground',
},
});
return <ShadcnTable table={table} />;- Tailwind responsive variants give you a concise way to add media queries to your styling.
const table = useShadcnTable({
columns,
data,
stTableHeadCellProps: {
//responsive variants instead of media queries
className:
'text-[10px] sm:text-[11px] md:text-[12px] lg:text-[13px] xl:text-[14px]',
},
});
return <ShadcnTable table={table} />;- Tailwind arbitrary variants let you target nested elements and states.
const table = useShadcnTable({
columns,
data,
stTableHeadCellProps: {
//target nested elements (the buttons in the header cell) and the hover state
className: '[&_button]:p-0 hover:font-bold',
},
});You can learn more about utility classes in the official Tailwind CSS Docs and about the theme variables in the shadcn/ui Theming Docs.
Conditional Styling
Using the style or className props and the parameters from the callback functions (cell, column, row, table instance APIs, etc.), you can easily add conditional styling to your shadcn/ui components. Here's a few examples
Style Selected Rows
const table = useShadcnTable({
stTableBodyRowProps: ({ row }) => ({
//conditionally style selected rows
className: row.getIsSelected() ? 'font-bold' : 'font-normal',
}),
});Style Expanded Rows
const table = useShadcnTable({
stTableBodyRowProps: ({ row }) => ({
//conditionally style expanded rows
className: row.getIsExpanded() ? 'font-bold' : 'font-normal',
}),
});Style Pinned Columns
const table = useShadcnTable({
stTableHeadCellProps: ({ column }) => ({
//conditionally style pinned columns
className: column.getIsPinned() ? 'bg-muted' : undefined,
}),
stTableBodyCellProps: ({ column }) => ({
//conditionally style pinned columns
className: column.getIsPinned() ? 'font-bold' : 'font-normal',
}),
});There are hundreds of table, column, header, row, and cell instance APIs that you can use for conditional styling and other logic. See the Table Instance APIs, Column Instance APIs, Row Instance APIs, and Cell Instance APIs docs for more info.
Theming
Shadcn Table respects your shadcn/ui theme. If you have already set up shadcn/ui with shadcn init, you should already be set. The table reads the CSS variables from your global stylesheet (--background, --foreground, --primary, --border, --muted, etc.), so changing them changes the table along with the rest of your app. If you have not set that up, you should visit the official shadcn/ui Theming Docs to learn how.
/* app/globals.css: have you set up your theme variables globally in your app root? */
:root {
--primary: oklch(0.45 0.2 280);
--border: oklch(0.9 0 0);
}
.dark {
--primary: oklch(0.7 0.18 280);
--border: oklch(0.3 0 0);
}Customize Theme Just for your Table
Because the theme is CSS variables, you can change it just for the <ShadcnTable /> component by redefining the variables on an element around just your table (or on the table root through the stTableLayoutProps table option). The values only effect the <ShadcnTable /> component, and not the rest of your site. Everything you do not redefine is inherited from your global theme, so you do not have to redefine everything again. You can just tweak the values you want to change.
//in one of your normal components
return (
<div className="[--primary:var(--secondary)] [--background:rgb(254,255,244)] dark:[--background:#000]">
<ShadcnTable table={table} />
</div>
);Custom Theme Example
Table Theme Values
The colors Shadcn Table uses internally come from the shadcn/ui theme variables, so there is no separate theme object to pass in. Here is where the default values come from, if you want to override them:
- the table and toolbars use
--backgroundand--foreground - selected rows use
--primaryat 20% opacity, pinned rows at 10%, hovered rows use--foregroundat 10% - dragging borders use
--primary - filter match highlighting uses
--destructiveat 20% opacity (30% in dark mode), on the element withdata-slot="st-match-highlight"
Customize Table Layout Styling
You can customize both the props and the styles of the internal <ST_TableLayout /> component that wraps the table by passing in a stTableLayoutProps table option. This is useful if you want to remove the shadow, or change the border radius, or any other styling you want to do to the wrapper.
const table = useShadcnTable({
columns,
data,
stTableLayoutProps: {
//customize wrapper styles
className: 'rounded-none border-dashed shadow-none',
},
});
return <ShadcnTable table={table} />;Customize Table Body, Rows, Columns, and Cells
Stripe Rows Example
If you need to style many of the rows or columns in a consistent manner, it usually makes sense to style the <TableBody /> component itself. For example if you want to stripe the rows, you can do something like this:
const table = useShadcnTable({
columns,
data,
stTableBodyProps: {
//stripe the rows, make odd rows a darker color
className: '[&_tr:nth-of-type(odd)>td]:bg-muted',
},
});
return <ShadcnTable table={table} />;Stripe Columns Example
Similarly, if you want to stripe the columns, you can do something like this:
const table = useShadcnTable({
columns,
data,
stTableBodyProps: {
//stripe the columns, make odd columns a darker color
className: '[&_td:nth-of-type(odd)]:bg-muted',
},
stTableBodyCellProps: {
className: 'border-r-2', //add a border between columns
},
});Customize No Rows overlay
As part of the customization options, we allow you to override the No Records overlay.
const table = useShadcnTable({
columns,
data,
renderEmptyRowsFallback: ({ table }) => (
<span>Customized No Rows Overlay</span>
),
});