{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "comparison-table",
  "title": "Comparison Table",
  "description": "Pricing plans as columns in an ordinary bordered table, with dynamically generated columns and the recommended plan tinted.",
  "dependencies": [
    "@tanstack/react-table"
  ],
  "registryDependencies": [
    "table",
    "button"
  ],
  "files": [
    {
      "path": "src/components/comparison/comparison.ts",
      "content": "export type Plan = {\n  id: string\n  name: string\n  price: string\n  period: string\n  highlighted?: boolean\n  cta: string\n}\n\nexport type FeatureValue = boolean | string\n\nexport type Feature = {\n  id: string\n  label: string\n  values: Record<string, FeatureValue>\n}\n",
      "type": "registry:component",
      "target": "@components/tables/comparison-table/comparison.ts"
    },
    {
      "path": "src/components/comparison/data.ts",
      "content": "import type { Feature, Plan } from './comparison'\n\nexport const plans: Plan[] = [\n  { id: 'basic', name: 'Basic', price: '$9', period: '/month', cta: 'Get started' },\n  {\n    id: 'pro',\n    name: 'Pro',\n    price: '$29',\n    period: '/month',\n    highlighted: true,\n    cta: 'Start free trial',\n  },\n  { id: 'enterprise', name: 'Enterprise', price: '$99', period: '/month', cta: 'Contact sales' },\n]\n\nexport const features: Feature[] = [\n  {\n    id: 'users',\n    label: 'Team members',\n    values: { basic: '5', pro: '20', enterprise: 'Unlimited' },\n  },\n  {\n    id: 'storage',\n    label: 'Storage',\n    values: { basic: '10 GB', pro: '100 GB', enterprise: '1 TB' },\n  },\n  {\n    id: 'api',\n    label: 'API access',\n    values: { basic: false, pro: true, enterprise: true },\n  },\n  {\n    id: 'support',\n    label: 'Priority support',\n    values: { basic: false, pro: true, enterprise: true },\n  },\n  {\n    id: 'domain',\n    label: 'Custom domain',\n    values: { basic: false, pro: true, enterprise: true },\n  },\n  {\n    id: 'sso',\n    label: 'Single sign-on',\n    values: { basic: false, pro: false, enterprise: true },\n  },\n]\n",
      "type": "registry:component",
      "target": "@components/tables/comparison-table/data.ts"
    },
    {
      "path": "src/components/comparison/data-table.tsx",
      "content": "'use client'\n\nimport { useMemo } from 'react'\nimport {\n  flexRender,\n  getCoreRowModel,\n  useReactTable,\n} from '@tanstack/react-table'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Check, X } from 'lucide-react'\n\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '#/components/ui/table'\nimport { Button } from '#/components/ui/button'\nimport { cn } from '#/lib/utils.ts'\nimport type { Feature, FeatureValue, Plan } from './comparison'\n\ninterface ComparisonTableProps {\n  plans: Plan[]\n  features: Feature[]\n}\n\nfunction renderValue(value: FeatureValue) {\n  if (typeof value === 'boolean') {\n    return value ? (\n      <Check className=\"mx-auto h-4 w-4 text-emerald-600 dark:text-emerald-500\" />\n    ) : (\n      <X className=\"mx-auto h-4 w-4 text-muted-foreground/40\" />\n    )\n  }\n  return value\n}\n\nexport function ComparisonTable({ plans, features }: ComparisonTableProps) {\n  const columns = useMemo<ColumnDef<Feature>[]>(\n    () => [\n      {\n        id: 'feature',\n        header: '',\n        accessorKey: 'label',\n        cell: ({ getValue }) => (\n          <span className=\"text-sm text-muted-foreground\">\n            {getValue() as string}\n          </span>\n        ),\n      },\n      ...plans.map(\n        (plan): ColumnDef<Feature> => ({\n          id: plan.id,\n          header: plan.name,\n          accessorFn: (feature) => feature.values[plan.id],\n          cell: ({ getValue }) => (\n            <div className=\"text-center\">\n              {renderValue(getValue() as FeatureValue)}\n            </div>\n          ),\n        }),\n      ),\n    ],\n    [plans],\n  )\n\n  const table = useReactTable({\n    data: features,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n  })\n\n  return (\n    <div className=\"overflow-hidden rounded-md border\">\n      <Table>\n        <TableHeader>\n          <TableRow>\n            <TableHead />\n            {plans.map((plan) => (\n              <TableHead\n                key={plan.id}\n                className={cn(\n                  'py-4 align-bottom text-center',\n                  plan.highlighted && 'bg-primary/5',\n                )}\n              >\n                <div className=\"space-y-1\">\n                  <p className=\"text-sm font-semibold text-foreground\">\n                    {plan.name}\n                  </p>\n                  <p className=\"text-2xl font-bold text-foreground\">\n                    {plan.price}\n                    <span className=\"text-sm font-normal text-muted-foreground\">\n                      {plan.period}\n                    </span>\n                  </p>\n                  <Button\n                    type=\"button\"\n                    size=\"sm\"\n                    variant={plan.highlighted ? 'default' : 'outline'}\n                    className=\"mt-2 w-full\"\n                  >\n                    {plan.cta}\n                  </Button>\n                </div>\n              </TableHead>\n            ))}\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {table.getRowModel().rows.map((row) => (\n            <TableRow key={row.id}>\n              {row.getVisibleCells().map((cell) => {\n                const plan = plans.find((p) => p.id === cell.column.id)\n                return (\n                  <TableCell\n                    key={cell.id}\n                    className={cn(plan?.highlighted && 'bg-primary/5')}\n                  >\n                    {flexRender(\n                      cell.column.columnDef.cell,\n                      cell.getContext(),\n                    )}\n                  </TableCell>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableBody>\n      </Table>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "@components/tables/comparison-table/data-table.tsx"
    },
    {
      "path": "src/components/comparison/index.tsx",
      "content": "import { features, plans } from './data'\nimport { ComparisonTable } from './data-table'\n\nexport function ComparisonTableDemo() {\n  return <ComparisonTable plans={plans} features={features} />\n}\n",
      "type": "registry:component",
      "target": "@components/tables/comparison-table/index.tsx"
    }
  ],
  "type": "registry:block"
}