+ "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\ninterface DataGridSelectCheckboxProps\n extends React.ComponentProps<typeof Checkbox> {\n rowNumber?: number;\n}\n\nfunction DataGridSelectCheckbox({\n rowNumber,\n checked,\n className,\n ...props\n}: DataGridSelectCheckboxProps) {\n if (rowNumber !== undefined) {\n return (\n <div className=\"group relative\">\n <div\n aria-hidden=\"true\"\n data-state={checked ? \"checked\" : \"unchecked\"}\n className=\"pointer-events-none absolute start-0 top-0 flex size-4 items-center justify-center text-muted-foreground text-xs tabular-nums transition-opacity group-hover:opacity-0 data-[state=checked]:opacity-0\"\n >\n {rowNumber}\n </div>\n <Checkbox\n className={cn(\n \"relative transition-[shadow,border,opacity] after:absolute after:-inset-2.5 after:content-[''] 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 </div>\n );\n }\n\n return (\n <Checkbox\n className={cn(\n \"relative transition-[shadow,border] after:absolute after:-inset-2.5 after:content-[''] hover:border-primary/40\",\n className,\n )}\n checked={checked}\n {...props}\n />\n );\n}\n\nfunction DataGridSelectHeader<TData>({\n table,\n}: Pick<HeaderContext<TData, unknown>, \"table\">) {\n const onCheckedChange = React.useCallback(\n (value: boolean) => table.toggleAllPageRowsSelected(value),\n [table],\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 />\n );\n}\n\ninterface DataGridSelectCellProps<TData>\n extends Pick<CellContext<TData, unknown>, \"row\" | \"table\"> {\n enableRowMarkers?: boolean;\n}\n\nfunction DataGridSelectCell<TData>({\n row,\n table,\n enableRowMarkers,\n}: DataGridSelectCellProps<TData>) {\n const onRowSelect = table.options.meta?.onRowSelect;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: rowNumber is memoized to avoid re-rendering the component when the row number changes\n const rowNumber = React.useMemo(() => {\n if (!enableRowMarkers) return undefined;\n\n const rows = table.getRowModel().rows;\n const visualIndex = rows.findIndex((r) => r.id === row.id);\n return visualIndex !== -1 ? visualIndex + 1 : row.index + 1;\n }, [enableRowMarkers, table.getRowModel().rows, row]);\n\n const onCheckedChange = React.useCallback(\n (value: boolean) => {\n if (onRowSelect) {\n onRowSelect(row.index, value, false);\n } else {\n row.toggleSelected(value);\n }\n },\n [onRowSelect, row],\n );\n\n const onClick = React.useCallback(\n (event: React.MouseEvent) => {\n if (event.shiftKey) {\n event.preventDefault();\n onRowSelect?.(row.index, !row.getIsSelected(), true);\n }\n },\n [onRowSelect, row],\n );\n\n return (\n <DataGridSelectCheckbox\n aria-label={`Select row ${rowNumber}`}\n checked={row.getIsSelected()}\n onCheckedChange={onCheckedChange}\n onClick={onClick}\n rowNumber={rowNumber}\n />\n );\n}\n\ninterface GetDataGridSelectColumnOptions<TData>\n extends Omit<Partial<ColumnDef<TData>>, \"id\" | \"header\" | \"cell\"> {\n enableRowMarkers?: boolean;\n}\n\nexport function getDataGridSelectColumn<TData>({\n size = 40,\n enableHiding = false,\n enableResizing = false,\n enableSorting = false,\n enableRowMarkers = false,\n ...props\n}: GetDataGridSelectColumnOptions<TData> = {}): ColumnDef<TData> {\n return {\n id: \"select\",\n header: ({ table }) => <DataGridSelectHeader table={table} />,\n cell: ({ row, table }) => (\n <DataGridSelectCell\n row={row}\n table={table}\n enableRowMarkers={enableRowMarkers}\n />\n ),\n size,\n enableHiding,\n enableResizing,\n enableSorting,\n ...props,\n };\n}\n",
0 commit comments