{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "data-grid-select-column",
  "title": "Data Grid Select Column",
  "description": "A reusable select column definition for the data grid with checkbox selection and shift-click support",
  "dependencies": [
    "@tanstack/react-table"
  ],
  "registryDependencies": [
    "checkbox"
  ],
  "files": [
    {
      "path": "src/components/data-grid/data-grid-select-column.tsx",
      "content": "\"use client\";\n\nimport type {\n  CellContext,\n  ColumnDef,\n  HeaderContext,\n} from \"@tanstack/react-table\";\nimport * as React from \"react\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { cn } from \"@/lib/utils\";\n\ntype HitboxSize = \"default\" | \"sm\" | \"lg\";\n\ninterface DataGridSelectHitboxProps {\n  htmlFor: string;\n  children: React.ReactNode;\n  size?: HitboxSize;\n  debug?: boolean;\n}\n\nfunction DataGridSelectHitbox({\n  htmlFor,\n  children,\n  size,\n  debug,\n}: DataGridSelectHitboxProps) {\n  return (\n    <div\n      className={cn(\n        \"group relative -my-1.5 h-[calc(100%+0.75rem)] py-1.5\",\n        size === \"default\" && \"-ms-3 -me-2 ps-3 pe-2\",\n        size === \"sm\" && \"-ms-3 -me-1.5 ps-3 pe-1.5\",\n        size === \"lg\" && \"-mx-3 px-3\",\n      )}\n    >\n      {children}\n      <label\n        htmlFor={htmlFor}\n        className={cn(\n          \"absolute inset-0 cursor-pointer\",\n          debug && \"border border-red-500 border-dashed bg-red-500/20\",\n        )}\n      />\n    </div>\n  );\n}\n\ninterface DataGridSelectCheckboxProps\n  extends Omit<React.ComponentProps<typeof Checkbox>, \"id\"> {\n  rowNumber?: number;\n  hitboxSize?: HitboxSize;\n  debug?: boolean;\n}\n\nfunction DataGridSelectCheckbox({\n  rowNumber,\n  hitboxSize,\n  debug,\n  checked,\n  className,\n  ...props\n}: DataGridSelectCheckboxProps) {\n  const id = React.useId();\n\n  if (rowNumber !== undefined) {\n    return (\n      <DataGridSelectHitbox htmlFor={id} size={hitboxSize} debug={debug}>\n        <div\n          aria-hidden=\"true\"\n          className={cn(\n            \"pointer-events-none absolute start-3 top-1.5 flex size-4 items-center justify-center text-muted-foreground text-xs tabular-nums transition-opacity group-hover:opacity-0\",\n            checked && \"opacity-0\",\n          )}\n        >\n          {rowNumber}\n        </div>\n        <Checkbox\n          id={id}\n          className={cn(\n            \"relative transition-[shadow,border,opacity] hover:border-primary/40\",\n            \"opacity-0 group-hover:opacity-100 data-[state=checked]:opacity-100\",\n            className,\n          )}\n          checked={checked}\n          {...props}\n        />\n      </DataGridSelectHitbox>\n    );\n  }\n\n  return (\n    <DataGridSelectHitbox htmlFor={id} size={hitboxSize} debug={debug}>\n      <Checkbox\n        id={id}\n        className={cn(\n          \"relative transition-[shadow,border] hover:border-primary/40\",\n          className,\n        )}\n        checked={checked}\n        {...props}\n      />\n    </DataGridSelectHitbox>\n  );\n}\n\ninterface DataGridSelectHeaderProps<TData>\n  extends Pick<HeaderContext<TData, unknown>, \"table\"> {\n  hitboxSize?: HitboxSize;\n  readOnly?: boolean;\n  debug?: boolean;\n}\n\nfunction DataGridSelectHeader<TData>({\n  table,\n  hitboxSize,\n  readOnly,\n  debug,\n}: DataGridSelectHeaderProps<TData>) {\n  const onCheckedChange = React.useCallback(\n    (value: boolean) => table.toggleAllPageRowsSelected(value),\n    [table],\n  );\n\n  if (readOnly) {\n    return (\n      <div className=\"mt-1 flex items-center ps-1 text-muted-foreground text-sm\">\n        #\n      </div>\n    );\n  }\n\n  return (\n    <DataGridSelectCheckbox\n      aria-label=\"Select all\"\n      checked={\n        table.getIsAllPageRowsSelected() ||\n        (table.getIsSomePageRowsSelected() && \"indeterminate\")\n      }\n      onCheckedChange={onCheckedChange}\n      hitboxSize={hitboxSize}\n      debug={debug}\n    />\n  );\n}\n\ninterface DataGridSelectCellProps<TData>\n  extends Pick<CellContext<TData, unknown>, \"row\" | \"table\"> {\n  hitboxSize?: HitboxSize;\n  enableRowMarkers?: boolean;\n  readOnly?: boolean;\n  debug?: boolean;\n}\n\nfunction DataGridSelectCell<TData>({\n  row,\n  table,\n  hitboxSize,\n  enableRowMarkers,\n  readOnly,\n  debug,\n}: DataGridSelectCellProps<TData>) {\n  const meta = table.options.meta;\n  const rowNumber = enableRowMarkers\n    ? (meta?.getVisualRowIndex?.(row.id) ?? row.index + 1)\n    : undefined;\n\n  const onCheckedChange = React.useCallback(\n    (value: boolean) => {\n      if (meta?.onRowSelect) {\n        meta.onRowSelect(row.id, value, false);\n      } else {\n        row.toggleSelected(value);\n      }\n    },\n    [meta, row],\n  );\n\n  const onClick = React.useCallback(\n    (event: React.MouseEvent<HTMLButtonElement>) => {\n      if (event.shiftKey) {\n        event.preventDefault();\n        meta?.onRowSelect?.(row.id, !row.getIsSelected(), true);\n      }\n    },\n    [meta, row],\n  );\n\n  if (readOnly) {\n    return (\n      <div className=\"flex items-center ps-1 text-muted-foreground text-xs tabular-nums\">\n        {rowNumber ?? row.index + 1}\n      </div>\n    );\n  }\n\n  return (\n    <DataGridSelectCheckbox\n      aria-label={rowNumber ? `Select row ${rowNumber}` : \"Select row\"}\n      checked={row.getIsSelected()}\n      onCheckedChange={onCheckedChange}\n      onClick={onClick}\n      rowNumber={rowNumber}\n      hitboxSize={hitboxSize}\n      debug={debug}\n    />\n  );\n}\n\ninterface GetDataGridSelectColumnOptions<TData>\n  extends Omit<Partial<ColumnDef<TData>>, \"id\" | \"header\" | \"cell\"> {\n  enableRowMarkers?: boolean;\n  readOnly?: boolean;\n  hitboxSize?: HitboxSize;\n  debug?: boolean;\n}\n\nexport function getDataGridSelectColumn<TData>({\n  size = 40,\n  hitboxSize = \"default\",\n  enableHiding = false,\n  enableResizing = false,\n  enableSorting = false,\n  enableRowMarkers = false,\n  readOnly = false,\n  debug = false,\n  ...props\n}: GetDataGridSelectColumnOptions<TData> = {}): ColumnDef<TData> {\n  return {\n    id: \"select\",\n    header: ({ table }) => (\n      <DataGridSelectHeader\n        table={table}\n        hitboxSize={hitboxSize}\n        readOnly={readOnly}\n        debug={debug}\n      />\n    ),\n    cell: ({ row, table }) => (\n      <DataGridSelectCell\n        row={row}\n        table={table}\n        enableRowMarkers={enableRowMarkers}\n        readOnly={readOnly}\n        hitboxSize={hitboxSize}\n        debug={debug}\n      />\n    ),\n    size,\n    enableHiding,\n    enableResizing,\n    enableSorting,\n    ...props,\n  };\n}\n",
      "type": "registry:component",
      "target": "src/components/data-grid/data-grid-select-column.tsx"
    }
  ],
  "type": "registry:component"
}