Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Integrate and customize shadcn/ui components—discovery, installation, theming, and Radix/Base UI best practices
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
examples/data-table.tsx
1// Example: Data Table with Sorting and Filtering2// Demonstrates: Table composition, TanStack Table integration, responsive design34"use client"56import {7ColumnDef,8ColumnFiltersState,9flexRender,10getCoreRowModel,11getFilteredRowModel,12getPaginationRowModel,13getSortedRowModel,14SortingState,15useReactTable,16} from "@tanstack/react-table"17import { ArrowUpDown, ChevronDown, MoreHorizontal } from "lucide-react"18import * as React from "react"1920import { Button } from "@/components/ui/button"21import {22DropdownMenu,23DropdownMenuCheckboxItem,24DropdownMenuContent,25DropdownMenuItem,26DropdownMenuLabel,27DropdownMenuSeparator,28DropdownMenuTrigger,29} from "@/components/ui/dropdown-menu"30import { Input } from "@/components/ui/input"31import {32Table,33TableBody,34TableCell,35TableHead,36TableHeader,37TableRow,38} from "@/components/ui/table"3940// Define data type41export type User = {42id: string43name: string44email: string45role: "admin" | "user" | "viewer"46status: "active" | "inactive"47}4849// Sample data50const data: User[] = [51{52id: "1",53name: "Alice Johnson",54email: "[email protected]",55role: "admin",56status: "active",57},58{59id: "2",60name: "Bob Smith",61email: "[email protected]",62role: "user",63status: "active",64},65{66id: "3",67name: "Carol White",68email: "[email protected]",69role: "viewer",70status: "inactive",71},72]7374// Define columns75export const columns: ColumnDef<User>[] = [76{77accessorKey: "name",78header: ({ column }) => {79return (80<Button81variant="ghost"82onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}83>84Name85<ArrowUpDown className="ml-2 h-4 w-4" />86</Button>87)88},89cell: ({ row }) => <div className="capitalize">{row.getValue("name")}</div>,90},91{92accessorKey: "email",93header: ({ column }) => {94return (95<Button96variant="ghost"97onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}98>99100<ArrowUpDown className="ml-2 h-4 w-4" />101</Button>102)103},104cell: ({ row }) => <div className="lowercase">{row.getValue("email")}</div>,105},106{107accessorKey: "role",108header: "Role",109cell: ({ row }) => (110<div className="capitalize">{row.getValue("role")}</div>111),112},113{114accessorKey: "status",115header: "Status",116cell: ({ row }) => (117<div className="capitalize">{row.getValue("status")}</div>118),119},120{121id: "actions",122enableHiding: false,123cell: ({ row }) => {124const user = row.original125126return (127<DropdownMenu>128<DropdownMenuTrigger asChild>129<Button variant="ghost" className="h-8 w-8 p-0">130<span className="sr-only">Open menu</span>131<MoreHorizontal className="h-4 w-4" />132</Button>133</DropdownMenuTrigger>134<DropdownMenuContent align="end">135<DropdownMenuLabel>Actions</DropdownMenuLabel>136<DropdownMenuItem137onClick={() => navigator.clipboard.writeText(user.id)}138>139Copy user ID140</DropdownMenuItem>141<DropdownMenuSeparator />142<DropdownMenuItem>View user</DropdownMenuItem>143<DropdownMenuItem>Edit user</DropdownMenuItem>144</DropdownMenuContent>145</DropdownMenu>146)147},148},149]150151export function DataTableExample() {152const [sorting, setSorting] = React.useState<SortingState>([])153const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])154const [columnVisibility, setColumnVisibility] = React.useState({})155const [rowSelection, setRowSelection] = React.useState({})156157const table = useReactTable({158data,159columns,160onSortingChange: setSorting,161onColumnFiltersChange: setColumnFilters,162getCoreRowModel: getCoreRowModel(),163getPaginationRowModel: getPaginationRowModel(),164getSortedRowModel: getSortedRowModel(),165getFilteredRowModel: getFilteredRowModel(),166onColumnVisibilityChange: setColumnVisibility,167onRowSelectionChange: setRowSelection,168state: {169sorting,170columnFilters,171columnVisibility,172rowSelection,173},174})175176return (177<div className="w-full">178<div className="flex items-center py-4">179<Input180placeholder="Filter names..."181value={(table.getColumn("name")?.getFilterValue() as string) ?? ""}182onChange={(event) =>183table.getColumn("name")?.setFilterValue(event.target.value)184}185className="max-w-sm"186/>187<DropdownMenu>188<DropdownMenuTrigger asChild>189<Button variant="outline" className="ml-auto">190Columns <ChevronDown className="ml-2 h-4 w-4" />191</Button>192</DropdownMenuTrigger>193<DropdownMenuContent align="end">194{table195.getAllColumns()196.filter((column) => column.getCanHide())197.map((column) => {198return (199<DropdownMenuCheckboxItem200key={column.id}201className="capitalize"202checked={column.getIsVisible()}203onCheckedChange={(value) =>204column.toggleVisibility(!!value)205}206>207{column.id}208</DropdownMenuCheckboxItem>209)210})}211</DropdownMenuContent>212</DropdownMenu>213</div>214<div className="rounded-md border">215<Table>216<TableHeader>217{table.getHeaderGroups().map((headerGroup) => (218<TableRow key={headerGroup.id}>219{headerGroup.headers.map((header) => {220return (221<TableHead key={header.id}>222{header.isPlaceholder223? null224: flexRender(225header.column.columnDef.header,226header.getContext()227)}228</TableHead>229)230})}231</TableRow>232))}233</TableHeader>234<TableBody>235{table.getRowModel().rows?.length ? (236table.getRowModel().rows.map((row) => (237<TableRow238key={row.id}239data-state={row.getIsSelected() && "selected"}240>241{row.getVisibleCells().map((cell) => (242<TableCell key={cell.id}>243{flexRender(244cell.column.columnDef.cell,245cell.getContext()246)}247</TableCell>248))}249</TableRow>250))251) : (252<TableRow>253<TableCell254colSpan={columns.length}255className="h-24 text-center"256>257No results.258</TableCell>259</TableRow>260)}261</TableBody>262</Table>263</div>264<div className="flex items-center justify-end space-x-2 py-4">265<div className="flex-1 text-sm text-muted-foreground">266{table.getFilteredSelectedRowModel().rows.length} of{" "}267{table.getFilteredRowModel().rows.length} row(s) selected.268</div>269<div className="space-x-2">270<Button271variant="outline"272size="sm"273onClick={() => table.previousPage()}274disabled={!table.getCanPreviousPage()}275>276Previous277</Button>278<Button279variant="outline"280size="sm"281onClick={() => table.nextPage()}282disabled={!table.getCanNextPage()}283>284Next285</Button>286</div>287</div>288</div>289)290}291292/**293* Key Patterns Demonstrated:294*295* 1. TanStack Table Integration: Using @tanstack/react-table with shadcn/ui296* 2. Sorting: Click headers to sort ascending/descending297* 3. Filtering: Text input to filter table data298* 4. Column Visibility: Toggle columns via dropdown menu299* 5. Pagination: Built-in pagination controls300* 6. Row Actions: Dropdown menu per row for context actions301* 7. Responsive Design: Table adapts to different screen sizes302*303* Required Dependencies:304* - @tanstack/react-table305* - lucide-react306*307* Installation:308* npx shadcn@latest add table309* npx shadcn@latest add button310* npx shadcn@latest add input311* npx shadcn@latest add dropdown-menu312* npm install @tanstack/react-table lucide-react313*/314