refactor: polish shadcn data table shell

This commit is contained in:
hailin
2026-07-02 15:44:46 +08:00
parent be7edae94f
commit a16e0be5b1

View File

@@ -1,6 +1,7 @@
import type * as React from 'react' import type * as React from 'react'
import { AppEmptyState } from '@/components/app/AppEmptyState' import { AppEmptyState } from '@/components/app/AppEmptyState'
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
@@ -35,41 +36,49 @@ export function AppDataTable<Row>({
onRowClick onRowClick
}: AppDataTableProps<Row>) { }: AppDataTableProps<Row>) {
return ( return (
<div className="overflow-hidden rounded-lg border border-border bg-card shadow-sm"> <Card className="gap-0 py-0">
{toolbar ? <div className="border-b border-border bg-muted/20 p-3">{toolbar}</div> : null} {toolbar ? <CardHeader className="border-b border-border bg-muted/20 p-3">{toolbar}</CardHeader> : null}
{rows.length === 0 ? ( <CardContent className="p-0">
<div className="p-4"> {rows.length === 0 ? (
<AppEmptyState title={emptyTitle} description={emptyDescription} /> <div className="p-3">
</div> <AppEmptyState title={emptyTitle} description={emptyDescription} />
) : ( </div>
<Table className={tableClassName}> ) : (
<TableHeader className="bg-muted/30"> <Table className={cn('min-w-[720px]', tableClassName)}>
<TableRow> <TableHeader className="bg-muted/40">
{columns.map((column) => ( <TableRow>
<TableHead key={column.key} className={column.className}>
{column.header}
</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{rows.map((row) => (
<TableRow
key={getRowKey(row)}
className={cn(onRowClick ? 'cursor-pointer' : undefined)}
onClick={() => onRowClick?.(row)}
>
{columns.map((column) => ( {columns.map((column) => (
<TableCell key={column.key} className={column.className}> <TableHead key={column.key} className={column.className}>
{column.cell(row)} {column.header}
</TableCell> </TableHead>
))} ))}
</TableRow> </TableRow>
))} </TableHeader>
</TableBody> <TableBody>
</Table> {rows.map((row) => (
)} <TableRow
{footer ? <div className="border-t border-border bg-muted/20 px-3 py-2">{footer}</div> : null} key={getRowKey(row)}
</div> tabIndex={onRowClick ? 0 : undefined}
className={cn(onRowClick ? 'cursor-pointer focus-visible:bg-muted focus-visible:outline-none' : undefined)}
onClick={() => onRowClick?.(row)}
onKeyDown={(event) => {
if (event.target !== event.currentTarget || !onRowClick || (event.key !== 'Enter' && event.key !== ' ')) return
event.preventDefault()
onRowClick(row)
}}
>
{columns.map((column) => (
<TableCell key={column.key} className={column.className}>
{column.cell(row)}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
)}
</CardContent>
{footer ? <CardFooter className="bg-muted/20 px-3 py-2 [&>*]:w-full">{footer}</CardFooter> : null}
</Card>
) )
} }