{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "table-18",
  "title": "Row selection",
  "description": "TanStack Table, row checkboxes with a bulk actions toolbar showing count, clear, and delete.",
  "dependencies": [
    "@tanstack/react-table"
  ],
  "registryDependencies": [
    "table",
    "checkbox",
    "button"
  ],
  "files": [
    {
      "path": "registry/patterns/table/table-18.tsx",
      "content": "'use client'\n\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '@/components/ui/table'\nimport {\n  type ColumnDef,\n  type RowSelectionState,\n  flexRender,\n  getCoreRowModel,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Trash2Icon } from 'lucide-react'\nimport { useState } from 'react'\n\ntype Subscriber = {\n  id: string\n  email: string\n  plan: string\n  joined: string\n}\n\nconst data: Subscriber[] = [\n  { id: 's1', email: 'ava@example.com', plan: 'Pro', joined: 'Jan 2025' },\n  { id: 's2', email: 'ben@example.com', plan: 'Free', joined: 'Feb 2025' },\n  { id: 's3', email: 'cara@example.com', plan: 'Pro', joined: 'Mar 2025' },\n  { id: 's4', email: 'dan@example.com', plan: 'Team', joined: 'Apr 2025' },\n]\n\nconst columns: ColumnDef<Subscriber>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => (\n      <Checkbox\n        aria-label=\"Select all\"\n        checked={table.getIsAllPageRowsSelected()}\n        indeterminate={table.getIsSomePageRowsSelected()}\n        onCheckedChange={(value) =>\n          table.toggleAllPageRowsSelected(value === true)\n        }\n      />\n    ),\n    cell: ({ row }) => (\n      <Checkbox\n        aria-label=\"Select row\"\n        checked={row.getIsSelected()}\n        onCheckedChange={(value) => row.toggleSelected(value === true)}\n      />\n    ),\n    enableSorting: false,\n  },\n  {\n    accessorKey: 'email',\n    header: 'Email',\n    cell: ({ row }) => (\n      <span className=\"font-medium\">{row.getValue('email')}</span>\n    ),\n  },\n  { accessorKey: 'plan', header: 'Plan' },\n  {\n    accessorKey: 'joined',\n    header: () => <div className=\"text-right\">Joined</div>,\n    cell: ({ row }) => (\n      <div className=\"text-muted-foreground text-right\">\n        {row.getValue('joined')}\n      </div>\n    ),\n  },\n]\n\nexport function Table18() {\n  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})\n\n  const table = useReactTable({\n    data,\n    columns,\n    state: { rowSelection },\n    onRowSelectionChange: setRowSelection,\n    getCoreRowModel: getCoreRowModel(),\n  })\n\n  const selectedCount = table.getSelectedRowModel().rows.length\n\n  return (\n    <div className=\"flex w-full max-w-xl flex-col gap-3\">\n      <div className=\"flex h-9 items-center justify-between\">\n        {selectedCount > 0 ? (\n          <>\n            <span className=\"text-sm font-medium\">\n              {selectedCount} selected\n            </span>\n            <div className=\"flex items-center gap-2\">\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                onClick={() => table.resetRowSelection()}\n              >\n                Clear\n              </Button>\n              <Button variant=\"destructive\" size=\"sm\">\n                <Trash2Icon data-icon=\"inline-start\" />\n                Delete\n              </Button>\n            </div>\n          </>\n        ) : (\n          <span className=\"text-muted-foreground text-sm\">\n            Select rows to act on them.\n          </span>\n        )}\n      </div>\n      <div className=\"overflow-hidden rounded-lg border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => (\n                  <TableHead key={header.id} className=\"first:w-10\">\n                    {flexRender(\n                      header.column.columnDef.header,\n                      header.getContext(),\n                    )}\n                  </TableHead>\n                ))}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows.map((row) => (\n              <TableRow\n                key={row.id}\n                data-state={row.getIsSelected() ? 'selected' : undefined}\n              >\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))}\n          </TableBody>\n        </Table>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/flx/patterns/table/table-18.tsx"
    }
  ],
  "type": "registry:block"
}