pin columns

This commit is contained in:
2025-11-25 13:39:19 -03:00
parent de340a6d46
commit 0278fca9f2
7 changed files with 65 additions and 32 deletions

View File

@@ -5,6 +5,7 @@ import {
getCoreRowModel,
useReactTable,
type ColumnDef,
type ColumnPinningState,
type ColumnSort,
type RowSelectionState,
type SortingState,
@@ -38,6 +39,7 @@ import { DataTablePagination } from './pagination'
interface DataTableProps<TData, TValue> {
children?: ReactNode
columns: ColumnDef<TData, TValue>[]
columnPinning?: ColumnPinningState
data: TData[]
setSelectedRows?: (selectedRows: TData[]) => void
pageIndex: number
@@ -67,6 +69,7 @@ export function DataTable<TData, TValue>({
data,
children,
columns,
columnPinning = { left: [], right: [] },
sort,
pageIndex,
pageSize,
@@ -192,10 +195,12 @@ export function DataTable<TData, TValue>({
sorting,
rowSelection,
columnVisibility,
columnPinning,
pagination: { pageIndex, pageSize }
},
manualSorting: true,
manualPagination: true,
enableColumnPinning: true,
enableRowSelection: true,
getRowId,
getCoreRowModel: getCoreRowModel(),
@@ -220,7 +225,7 @@ export function DataTable<TData, TValue>({
<CardContent>
{children}
<Table_ className="table-auto">
<Table_ className="table-auto w-full">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow
@@ -228,11 +233,18 @@ export function DataTable<TData, TValue>({
className="hover:bg-transparent"
>
{headerGroup.headers.map((header) => {
const isPinned = header.column.getIsPinned()
return (
<TableHead
key={header.id}
className={cn(
isPinned && 'z-1 lg:sticky bg-card',
isPinned === 'left' && 'left-0',
isPinned === 'right' && 'right-0',
'p-2.5',
// Override the shadcn class
'[&:has([role=checkbox])]:pr-2.5',
// @ts-ignore
header.column.columnDef.meta?.className
)}
@@ -252,29 +264,42 @@ export function DataTable<TData, TValue>({
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
className="has-data-[state=open]:bg-muted/50"
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
className={cn(
'p-2.5',
// @ts-ignore
cell.column.columnDef.meta?.className
)}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
))}
</TableRow>
))
table.getRowModel().rows.map((row) => {
const isSelected = row.getIsSelected()
return (
<TableRow
key={row.id}
data-state={isSelected && 'selected'}
className="group has-data-[state=open]:bg-muted transition-none hover:bg-muted relative z-5"
>
{row.getVisibleCells().map((cell) => {
const isPinned = cell.column.getIsPinned()
return (
<TableCell
key={cell.id}
className={cn(
isPinned &&
'lg:sticky z-1 bg-card group-hover:bg-muted group-has-data-[state=open]:bg-muted',
isPinned && isSelected && 'bg-muted',
isPinned === 'left' && 'left-0',
isPinned === 'right' && 'right-0',
'p-2.5',
// @ts-ignore
cell.column.columnDef.meta?.className
)}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
)
})}
</TableRow>
)
})
) : (
<TableRow>
<TableCell

View File

@@ -28,7 +28,9 @@ export const columns: ColumnDef<Enrollment>[] = [
return (
<div className="flex gap-2.5 items-center">
<Avatar className="size-10 hidden lg:block">
<AvatarFallback>{initials(user.name)}</AvatarFallback>
<AvatarFallback className="border">
{initials(user.name)}
</AvatarFallback>
</Avatar>
<ul>

View File

@@ -23,7 +23,7 @@ export const columns: ColumnDef<User>[] = [
return (
<div className="flex gap-2.5 items-center">
<Avatar className="size-10 hidden lg:block">
<AvatarFallback>{initials(name)}</AvatarFallback>
<AvatarFallback className="border">{initials(name)}</AvatarFallback>
</Avatar>
<ul>