165 lines
3.8 KiB
TypeScript
165 lines
3.8 KiB
TypeScript
import "./table.css";
|
||
|
||
import * as React from "react";
|
||
|
||
import { cn } from "../../lib/utils";
|
||
|
||
interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
|
||
variant?: "default" | "secondary" | "line";
|
||
caption?: string;
|
||
}
|
||
|
||
const Table = React.forwardRef<HTMLTableElement, TableProps>(
|
||
(
|
||
{
|
||
className,
|
||
variant = "default",
|
||
caption,
|
||
"aria-label": ariaLabel,
|
||
children,
|
||
...props
|
||
},
|
||
ref,
|
||
) => {
|
||
const captionText = caption ?? (ariaLabel ? `${ariaLabel} 표` : "테이블");
|
||
|
||
return (
|
||
<div className="relative w-full">
|
||
<table
|
||
ref={ref}
|
||
className={cn(
|
||
"table-ui w-full caption-bottom text-sm",
|
||
className,
|
||
variant,
|
||
)}
|
||
aria-label={ariaLabel}
|
||
{...props}
|
||
>
|
||
<caption className="sr-only">{captionText}</caption>
|
||
{children}
|
||
</table>
|
||
</div>
|
||
);
|
||
},
|
||
);
|
||
Table.displayName = "Table";
|
||
|
||
const TableHeader = React.forwardRef<
|
||
HTMLTableSectionElement,
|
||
React.HTMLAttributes<HTMLTableSectionElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<thead
|
||
ref={ref}
|
||
className={cn("sticky -top-3 z-10 bg-secondary [&_tr]:border-b", className)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableHeader.displayName = "TableHeader";
|
||
|
||
const TableBody = React.forwardRef<
|
||
HTMLTableSectionElement,
|
||
React.HTMLAttributes<HTMLTableSectionElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<tbody
|
||
ref={ref}
|
||
className={cn("[&_tr:last-child]:border-0", className)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableBody.displayName = "TableBody";
|
||
|
||
const TableFooter = React.forwardRef<
|
||
HTMLTableSectionElement,
|
||
React.HTMLAttributes<HTMLTableSectionElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<tfoot
|
||
ref={ref}
|
||
className={cn(
|
||
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
|
||
className,
|
||
)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableFooter.displayName = "TableFooter";
|
||
|
||
const TableRow = React.forwardRef<
|
||
HTMLTableRowElement,
|
||
React.HTMLAttributes<HTMLTableRowElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<tr
|
||
ref={ref}
|
||
className={cn(
|
||
"border-b bg-background transition-colors data-[state=selected]:bg-muted",
|
||
className,
|
||
)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableRow.displayName = "TableRow";
|
||
|
||
type TableHeadProps = React.ThHTMLAttributes<HTMLTableCellElement> & {
|
||
"data-required"?: boolean | string;
|
||
scope?: "col" | "row" | "colgroup" | "rowgroup";
|
||
};
|
||
|
||
const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
|
||
({ children, className, scope = "col", "data-required": dataRequired, ...props }, ref) => {
|
||
const isRequired =
|
||
dataRequired !== undefined && dataRequired !== false && dataRequired !== "false";
|
||
|
||
return (
|
||
<th
|
||
ref={ref}
|
||
scope={scope}
|
||
className={cn("align-middle", className)}
|
||
data-required={isRequired ? "" : undefined}
|
||
{...props}
|
||
>
|
||
{children}
|
||
{isRequired && (
|
||
<span className="table-required-marker" title="필수 항목">
|
||
{" "}(*)
|
||
</span>
|
||
)}
|
||
</th>
|
||
);
|
||
},
|
||
);
|
||
TableHead.displayName = "TableHead";
|
||
|
||
const TableCell = React.forwardRef<
|
||
HTMLTableCellElement,
|
||
React.TdHTMLAttributes<HTMLTableCellElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<td
|
||
ref={ref}
|
||
className={cn("align-middle text-foreground", className)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableCell.displayName = "TableCell";
|
||
|
||
const TableCaption = React.forwardRef<
|
||
HTMLTableCaptionElement,
|
||
React.HTMLAttributes<HTMLTableCaptionElement>
|
||
>(({ className, ...props }, ref) => (
|
||
<caption
|
||
ref={ref}
|
||
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
||
{...props}
|
||
/>
|
||
));
|
||
TableCaption.displayName = "TableCaption";
|
||
|
||
export {
|
||
Table,
|
||
TableHeader,
|
||
TableBody,
|
||
TableFooter,
|
||
TableHead,
|
||
TableRow,
|
||
TableCell,
|
||
TableCaption,
|
||
};
|