Table Column Visibility
A free React table column visibility component for data tables in Next.js, React and Tailwind.
Choose the columns for this view
4 of 4 columns visible
Visible columns
| Record | Team | Status | Last service |
|---|---|---|---|
| 76084 Kirkstone | Traffic | In service | 12 Oct 2026 |
| 5643 Glyder | Engineering | Under overhaul | 28 Sep 2026 |
| 68011 Snowdon | Operations | In service | 04 Oct 2026 |
Customise
Code
const columns = [
{ id: "record", label: "Record" },
{ id: "team", label: "Team" },
{ id: "status", label: "Status" },
];
const rows = [
{ id: "76084", cells: { record: "76084 Kirkstone", team: "Traffic", status: "In service" } },
{ id: "5643", cells: { record: "5643 Glyder", team: "Engineering", status: "Under overhaul" } },
];
const [visibleColumnIds, setVisibleColumnIds] = useState<string[]>(columns.map(({ id }) => id));
<TableColumnVisibility
columns={columns}
rows={rows}
caption="Wear Valley Railway fleet records"
visibleColumnIds={visibleColumnIds}
onVisibleColumnIdsChange={setVisibleColumnIds}
/>Table Column Visibility is a free table component for Next.js and React, styled with Tailwind. It lets people choose which columns appear using a native disclosure and checkboxes while keeping the current records and their order in place.
Visible columns remain real table headers and cells, hidden columns leave the table and accessibility tree, and the last visible column stays protected. Use controlled IDs when your application owns the preference, or let the component manage the current view locally.
Install
Add the @te registry to your components.json once:
{
"registries": {
"@te": "https://templateempire.io/r/{name}.json"
}
}Then install the component:
npx shadcn@latest add @te/table-column-visibilityUsage
import { TableColumnVisibility } from "@/components/table-column-visibility";
const columns = [
{ id: "record", label: "Record" },
{ id: "team", label: "Team" },
{ id: "status", label: "Status" },
];
const rows = [
{ id: "76084", cells: { record: "76084 Kirkstone", team: "Traffic", status: "In service" } },
{ id: "5643", cells: { record: "5643 Glyder", team: "Engineering", status: "Under overhaul" } },
];
export default function Page() {
return <TableColumnVisibility caption="Fleet records" columns={columns} rows={rows} />;
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| columns | { id: string; label: string; align?: "left" | "center" | "right"; defaultVisible?: boolean }[] | required | Ordered table columns. Duplicate and empty IDs are ignored after validation. |
| rows | { id: string; cells: Record<string, ReactNode> }[] | required | Consumer-owned rows and cell content, rendered in supplied order. Duplicate or empty row IDs get deterministic fallback keys. |
| caption | string | required | Visible table caption. |
| visibleColumnIds | string[] | undefined | Controlled visible IDs, normalized to known column IDs in column order. Requires onVisibleColumnIdsChange. |
| defaultVisibleColumnIds | string[] | all columns | Initial visible IDs for uncontrolled use. Invalid or empty sets fall back to the first valid column. |
| onVisibleColumnIdsChange | (visibleColumnIds: string[]) => void | undefined | Called with the normalized visible IDs after a user change or Show all action. |
| className | string | undefined | Additional classes merged onto the component shell. |
Customisation
The table uses semantic surface, border, foreground, muted and focus tokens. Pass IDs to control visibility from application state, and scope theme tokens around this instance when it sits in a distinct panel:
<TableColumnVisibility
columns={columns}
rows={rows}
caption="Fleet records"
visibleColumnIds={visibleIds}
onVisibleColumnIdsChange={setVisibleIds}
className="max-w-5xl"
/>Frequently asked questions
- Is Table Column Visibility free for commercial use?
- Yes. Table Column Visibility is MIT licensed and can be used in personal and commercial projects.
- Are hidden columns still available to screen readers?
- No. Hidden columns are removed from the table markup, so they leave the visual table and its accessible representation together.
- Can I control which columns are shown?
- Yes. Pass visibleColumnIds with onVisibleColumnIdsChange for controlled state, or use defaultVisibleColumnIds for an initial local view. The component always keeps at least one valid column visible.