141 lines
4.5 KiB
TypeScript
141 lines
4.5 KiB
TypeScript
import * as React from "react"
|
|
|
|
import { cn } from "~/lib/utils"
|
|
|
|
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
return (
|
|
<div
|
|
data-slot="table-container"
|
|
className="relative w-full overflow-x-auto"
|
|
>
|
|
<table
|
|
data-slot="table"
|
|
// Subframe Table root layout: full-width, fit height, collapsed border with
|
|
// outer border-default frame (TableRoot: "h-fit w-full border border-solid
|
|
// border-border-default ... border-collapse").
|
|
className={cn(
|
|
"h-fit w-full caption-bottom border-collapse border border-solid border-border-default text-sm",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
return (
|
|
<thead
|
|
data-slot="table-header"
|
|
// Subframe layout: <thead> carries no border; the header/body divider comes
|
|
// from the first body row's top rule (TableRow border-t), so no border-b here
|
|
// to avoid a doubled rule.
|
|
className={cn(className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
return (
|
|
<tbody
|
|
data-slot="table-body"
|
|
// Subframe tbody layout: bottom rule under the body block
|
|
// (tbody: "border-b border-solid border-border-default").
|
|
className={cn("border-b border-solid border-border-default", className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
return (
|
|
<tfoot
|
|
data-slot="table-footer"
|
|
// No Subframe footer counterpart; kept shadcn behaviour but normalized the top
|
|
// rule to Subframe's explicit border style. Surface already matches the Row
|
|
// surface (bg-surface-neutral-secondary).
|
|
className={cn(
|
|
"bg-surface-neutral-secondary border-t border-solid border-border-default font-medium [&>tr]:last:border-b-0",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
return (
|
|
<tr
|
|
data-slot="table-row"
|
|
// Subframe Row layout: top rule between rows (Row: "border-t border-solid
|
|
// border-border-default"). Hover/selected colors kept from shadcn.
|
|
className={cn(
|
|
"hover:bg-surface-neutral-secondary data-[state=selected]:bg-surface-neutral-secondary border-t border-solid border-border-default transition-colors",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
return (
|
|
<th
|
|
data-slot="table-head"
|
|
// Subframe HeaderCell layout: h-10 row, px-4 cell padding, per-cell right
|
|
// divider that drops on the last cell, left-aligned, vertically centered, and
|
|
// the extra-small medium header typography from Subframe's HeaderCell label.
|
|
// (HeaderCell <th> "h-10"; inner "flex items-center gap-1 border-r ... px-4
|
|
// text-left last:border-r-0"; label "text-body-extra-small-medium-0
|
|
// font-body-extra-small-medium-0 text-text-neutral-secondary").
|
|
className={cn(
|
|
"text-text-neutral-secondary text-body-extra-small-medium-0 font-body-extra-small-medium-0 h-10 border-r border-solid border-border-default px-4 text-left align-middle whitespace-nowrap last:border-r-0 [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
return (
|
|
<td
|
|
data-slot="table-cell"
|
|
// Subframe Cell layout: 48px minimum row height, px-4 py-1 cell padding,
|
|
// vertically centered, per-cell right divider that drops on the last cell.
|
|
// (Cell inner "flex h-full min-h-[48px] items-center border-r ... px-4 py-1";
|
|
// min-h maps to h-12 on the <td> which acts as a row min-height.)
|
|
className={cn(
|
|
"h-12 border-r border-solid border-border-default px-4 py-1 align-middle whitespace-nowrap last:border-r-0 [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function TableCaption({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<"caption">) {
|
|
return (
|
|
<caption
|
|
data-slot="table-caption"
|
|
className={cn("text-text-neutral-tertiary mt-4 text-sm", className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export {
|
|
Table,
|
|
TableHeader,
|
|
TableBody,
|
|
TableFooter,
|
|
TableHead,
|
|
TableRow,
|
|
TableCell,
|
|
TableCaption,
|
|
}
|