pin columns
This commit is contained in:
@@ -47,12 +47,14 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
{
|
{
|
||||||
id: 'select',
|
id: 'select',
|
||||||
header: DataTableColumnHeaderSelect,
|
header: DataTableColumnHeaderSelect,
|
||||||
cell: DataTableColumnSelect
|
cell: DataTableColumnSelect,
|
||||||
|
meta: { className: 'w-9' }
|
||||||
},
|
},
|
||||||
...columns_,
|
...columns_,
|
||||||
{
|
{
|
||||||
id: 'actions',
|
id: 'action',
|
||||||
cell: ActionMenu
|
cell: ActionMenu,
|
||||||
|
meta: { className: 'w-12' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export default function Route({ loaderData: { data } }: Route.ComponentProps) {
|
|||||||
sort={[{ id: 'created_at', desc: true }]}
|
sort={[{ id: 'created_at', desc: true }]}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={hits as Enrollment[]}
|
data={hits as Enrollment[]}
|
||||||
|
columnPinning={{ left: ['select'], right: ['action'] }}
|
||||||
pageIndex={page - 1}
|
pageIndex={page - 1}
|
||||||
pageSize={hitsPerPage}
|
pageSize={hitsPerPage}
|
||||||
setSelectedRows={setSelectedRows}
|
setSelectedRows={setSelectedRows}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export const columns: ColumnDef<Order>[] = [
|
|||||||
{
|
{
|
||||||
id: 'select',
|
id: 'select',
|
||||||
header: DataTableColumnHeaderSelect,
|
header: DataTableColumnHeaderSelect,
|
||||||
cell: DataTableColumnSelect
|
cell: DataTableColumnSelect,
|
||||||
|
meta: { className: 'w-9' }
|
||||||
},
|
},
|
||||||
...columns_
|
...columns_
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -42,12 +42,14 @@ export const columns: ColumnDef<User>[] = [
|
|||||||
{
|
{
|
||||||
id: 'select',
|
id: 'select',
|
||||||
header: DataTableColumnHeaderSelect,
|
header: DataTableColumnHeaderSelect,
|
||||||
cell: DataTableColumnSelect
|
cell: DataTableColumnSelect,
|
||||||
|
meta: { className: 'w-9' }
|
||||||
},
|
},
|
||||||
...columns_,
|
...columns_,
|
||||||
{
|
{
|
||||||
id: 'actions',
|
id: 'actions',
|
||||||
cell: ActionMenu
|
cell: ActionMenu,
|
||||||
|
meta: { className: 'w-12' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
getCoreRowModel,
|
getCoreRowModel,
|
||||||
useReactTable,
|
useReactTable,
|
||||||
type ColumnDef,
|
type ColumnDef,
|
||||||
|
type ColumnPinningState,
|
||||||
type ColumnSort,
|
type ColumnSort,
|
||||||
type RowSelectionState,
|
type RowSelectionState,
|
||||||
type SortingState,
|
type SortingState,
|
||||||
@@ -38,6 +39,7 @@ import { DataTablePagination } from './pagination'
|
|||||||
interface DataTableProps<TData, TValue> {
|
interface DataTableProps<TData, TValue> {
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
columns: ColumnDef<TData, TValue>[]
|
columns: ColumnDef<TData, TValue>[]
|
||||||
|
columnPinning?: ColumnPinningState
|
||||||
data: TData[]
|
data: TData[]
|
||||||
setSelectedRows?: (selectedRows: TData[]) => void
|
setSelectedRows?: (selectedRows: TData[]) => void
|
||||||
pageIndex: number
|
pageIndex: number
|
||||||
@@ -67,6 +69,7 @@ export function DataTable<TData, TValue>({
|
|||||||
data,
|
data,
|
||||||
children,
|
children,
|
||||||
columns,
|
columns,
|
||||||
|
columnPinning = { left: [], right: [] },
|
||||||
sort,
|
sort,
|
||||||
pageIndex,
|
pageIndex,
|
||||||
pageSize,
|
pageSize,
|
||||||
@@ -192,10 +195,12 @@ export function DataTable<TData, TValue>({
|
|||||||
sorting,
|
sorting,
|
||||||
rowSelection,
|
rowSelection,
|
||||||
columnVisibility,
|
columnVisibility,
|
||||||
|
columnPinning,
|
||||||
pagination: { pageIndex, pageSize }
|
pagination: { pageIndex, pageSize }
|
||||||
},
|
},
|
||||||
manualSorting: true,
|
manualSorting: true,
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
|
enableColumnPinning: true,
|
||||||
enableRowSelection: true,
|
enableRowSelection: true,
|
||||||
getRowId,
|
getRowId,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
@@ -220,7 +225,7 @@ export function DataTable<TData, TValue>({
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<Table_ className="table-auto">
|
<Table_ className="table-auto w-full">
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
@@ -228,11 +233,18 @@ export function DataTable<TData, TValue>({
|
|||||||
className="hover:bg-transparent"
|
className="hover:bg-transparent"
|
||||||
>
|
>
|
||||||
{headerGroup.headers.map((header) => {
|
{headerGroup.headers.map((header) => {
|
||||||
|
const isPinned = header.column.getIsPinned()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableHead
|
<TableHead
|
||||||
key={header.id}
|
key={header.id}
|
||||||
className={cn(
|
className={cn(
|
||||||
|
isPinned && 'z-1 lg:sticky bg-card',
|
||||||
|
isPinned === 'left' && 'left-0',
|
||||||
|
isPinned === 'right' && 'right-0',
|
||||||
'p-2.5',
|
'p-2.5',
|
||||||
|
// Override the shadcn class
|
||||||
|
'[&:has([role=checkbox])]:pr-2.5',
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
header.column.columnDef.meta?.className
|
header.column.columnDef.meta?.className
|
||||||
)}
|
)}
|
||||||
@@ -252,16 +264,27 @@ export function DataTable<TData, TValue>({
|
|||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{table.getRowModel().rows?.length ? (
|
{table.getRowModel().rows?.length ? (
|
||||||
table.getRowModel().rows.map((row) => (
|
table.getRowModel().rows.map((row) => {
|
||||||
|
const isSelected = row.getIsSelected()
|
||||||
|
|
||||||
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && 'selected'}
|
data-state={isSelected && 'selected'}
|
||||||
className="has-data-[state=open]:bg-muted/50"
|
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
|
<TableCell
|
||||||
key={cell.id}
|
key={cell.id}
|
||||||
className={cn(
|
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',
|
'p-2.5',
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
cell.column.columnDef.meta?.className
|
cell.column.columnDef.meta?.className
|
||||||
@@ -272,9 +295,11 @@ export function DataTable<TData, TValue>({
|
|||||||
cell.getContext()
|
cell.getContext()
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
))}
|
)
|
||||||
|
})}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
)
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell
|
<TableCell
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export const columns: ColumnDef<Enrollment>[] = [
|
|||||||
return (
|
return (
|
||||||
<div className="flex gap-2.5 items-center">
|
<div className="flex gap-2.5 items-center">
|
||||||
<Avatar className="size-10 hidden lg:block">
|
<Avatar className="size-10 hidden lg:block">
|
||||||
<AvatarFallback>{initials(user.name)}</AvatarFallback>
|
<AvatarFallback className="border">
|
||||||
|
{initials(user.name)}
|
||||||
|
</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const columns: ColumnDef<User>[] = [
|
|||||||
return (
|
return (
|
||||||
<div className="flex gap-2.5 items-center">
|
<div className="flex gap-2.5 items-center">
|
||||||
<Avatar className="size-10 hidden lg:block">
|
<Avatar className="size-10 hidden lg:block">
|
||||||
<AvatarFallback>{initials(name)}</AvatarFallback>
|
<AvatarFallback className="border">{initials(name)}</AvatarFallback>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user