pin columns
This commit is contained in:
@@ -47,12 +47,14 @@ export const columns: ColumnDef<Enrollment>[] = [
|
||||
{
|
||||
id: 'select',
|
||||
header: DataTableColumnHeaderSelect,
|
||||
cell: DataTableColumnSelect
|
||||
cell: DataTableColumnSelect,
|
||||
meta: { className: 'w-9' }
|
||||
},
|
||||
...columns_,
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ActionMenu
|
||||
id: 'action',
|
||||
cell: ActionMenu,
|
||||
meta: { className: 'w-12' }
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export default function Route({ loaderData: { data } }: Route.ComponentProps) {
|
||||
sort={[{ id: 'created_at', desc: true }]}
|
||||
columns={columns}
|
||||
data={hits as Enrollment[]}
|
||||
columnPinning={{ left: ['select'], right: ['action'] }}
|
||||
pageIndex={page - 1}
|
||||
pageSize={hitsPerPage}
|
||||
setSelectedRows={setSelectedRows}
|
||||
|
||||
@@ -14,7 +14,8 @@ export const columns: ColumnDef<Order>[] = [
|
||||
{
|
||||
id: 'select',
|
||||
header: DataTableColumnHeaderSelect,
|
||||
cell: DataTableColumnSelect
|
||||
cell: DataTableColumnSelect,
|
||||
meta: { className: 'w-9' }
|
||||
},
|
||||
...columns_
|
||||
]
|
||||
|
||||
@@ -42,12 +42,14 @@ export const columns: ColumnDef<User>[] = [
|
||||
{
|
||||
id: 'select',
|
||||
header: DataTableColumnHeaderSelect,
|
||||
cell: DataTableColumnSelect
|
||||
cell: DataTableColumnSelect,
|
||||
meta: { className: 'w-9' }
|
||||
},
|
||||
...columns_,
|
||||
{
|
||||
id: 'actions',
|
||||
cell: ActionMenu
|
||||
cell: ActionMenu,
|
||||
meta: { className: 'w-12' }
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -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,16 +264,27 @@ export function DataTable<TData, TValue>({
|
||||
|
||||
<TableBody>
|
||||
{table.getRowModel().rows?.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
table.getRowModel().rows.map((row) => {
|
||||
const isSelected = row.getIsSelected()
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
key={row.id}
|
||||
data-state={row.getIsSelected() && 'selected'}
|
||||
className="has-data-[state=open]:bg-muted/50"
|
||||
data-state={isSelected && 'selected'}
|
||||
className="group has-data-[state=open]:bg-muted transition-none hover:bg-muted relative z-5"
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
{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
|
||||
@@ -272,9 +295,11 @@ export function DataTable<TData, TValue>({
|
||||
cell.getContext()
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</TableRow>
|
||||
))
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user