column configuration

This commit is contained in:
Oliver Bryan
2025-12-14 18:31:02 +00:00
parent 9d7781d0a1
commit 52a7bdfe6d
2 changed files with 87 additions and 99 deletions

View File

@@ -1,25 +1,45 @@
import type { IssueRecord } from "@issue/shared"; import type { IssueRecord } from "@issue/shared";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
export function IssuesTable({ issues }: { issues: IssueRecord[] }) { export function IssuesTable({
issues,
columns = {},
}: {
issues: IssueRecord[];
columns?: { id?: boolean; title?: boolean; description?: boolean; assignee?: boolean };
}) {
return ( return (
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>ID</TableHead> {(columns.id == null || columns.id === true) && (
<TableHead>Title</TableHead> <TableHead className="w-[50px] border-r">ID</TableHead>
<TableHead>Description</TableHead> )}
{(columns.title == null || columns.title === true) && <TableHead>Title</TableHead>}
{(columns.description == null || columns.description === true) && (
<TableHead>Description</TableHead>
)}
{/* below is kept blank to fill the space, used as the "Assignee" column */} {/* below is kept blank to fill the space, used as the "Assignee" column */}
<TableHead></TableHead> {(columns.assignee == null || columns.assignee === true) && <TableHead></TableHead>}
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{issues.map((issue) => ( {issues.map((issue) => (
<TableRow key={issue.id}> <TableRow key={issue.id} className="cursor-pointer">
<TableCell className="font-medium">{issue.id}</TableCell> {(columns.id == null || columns.id === true) && (
<TableCell>{issue.title}</TableCell> <TableCell className="font-medium border-r">
<TableCell>{issue.description}</TableCell> {String(issue.id).padStart(3, "0")}
<TableCell>?</TableCell> </TableCell>
)}
{(columns.title == null || columns.title === true) && (
<TableCell>{issue.title}</TableCell>
)}
{(columns.description == null || columns.description === true) && (
<TableCell className="overflow-hide">{issue.description}</TableCell>
)}
{(columns.assignee == null || columns.assignee === true) && (
<TableCell className={"text-right"}>?</TableCell>
)}
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>

View File

@@ -1,114 +1,82 @@
import * as React from "react" import * as React from "react";
import { cn } from "@/lib/utils" import { cn } from "@/lib/utils";
function Table({ className, ...props }: React.ComponentProps<"table">) { function Table({ className, ...props }: React.ComponentProps<"table">) {
return ( return (
<div <div data-slot="table-container" className="relative w-full overflow-x-auto">
data-slot="table-container" <table data-slot="table" className={cn("w-full caption-bottom text-sm", className)} {...props} />
className="relative w-full overflow-x-auto" </div>
> );
<table
data-slot="table"
className={cn("w-full caption-bottom text-sm", className)}
{...props}
/>
</div>
)
} }
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
return ( return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />;
<thead
data-slot="table-header"
className={cn("[&_tr]:border-b", className)}
{...props}
/>
)
} }
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
return ( return (
<tbody <tbody data-slot="table-body" className={cn("[&_tr:last-child]:border-0", className)} {...props} />
data-slot="table-body" );
className={cn("[&_tr:last-child]:border-0", className)}
{...props}
/>
)
} }
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
return ( return (
<tfoot <tfoot
data-slot="table-footer" data-slot="table-footer"
className={cn( className={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", {...props}
className />
)} );
{...props}
/>
)
} }
function TableRow({ className, ...props }: React.ComponentProps<"tr">) { function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
return ( return (
<tr <tr
data-slot="table-row" data-slot="table-row"
className={cn( className={cn(
"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
className className,
)} )}
{...props} {...props}
/> />
) );
} }
function TableHead({ className, ...props }: React.ComponentProps<"th">) { function TableHead({ className, ...props }: React.ComponentProps<"th">) {
return ( return (
<th <th
data-slot="table-head" data-slot="table-head"
className={cn( className={cn(
"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
className className,
)} )}
{...props} {...props}
/> />
) );
} }
function TableCell({ className, ...props }: React.ComponentProps<"td">) { function TableCell({ className, ...props }: React.ComponentProps<"td">) {
return ( return (
<td <td
data-slot="table-cell" data-slot="table-cell"
className={cn( className={cn(
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
className className,
)} )}
{...props} {...props}
/> />
) );
} }
function TableCaption({ function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
className, return (
...props <caption
}: React.ComponentProps<"caption">) { data-slot="table-caption"
return ( className={cn("text-muted-foreground mt-4 text-sm", className)}
<caption {...props}
data-slot="table-caption" />
className={cn("text-muted-foreground mt-4 text-sm", className)} );
{...props}
/>
)
} }
export { export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
}