본문으로 건너뛰기
언어

Tablestandard

행과 열로 데이터를 보여 주는 표(table)입니다. shadcn base-nova 의 stock 아이템으로, 시맨틱 HTML 표 요소에 스타일만 입힌 얇은 부품입니다. 정렬·필터·페이지 같은 표 기능은 없으며 `@tanstack/react-table` 과 함께 쓸 수 있습니다.

설치

pnpm
pnpm dlx shadcn@4.23.0 add @uikit/table

Default

table-example.tsx
"use client"
import {  Example,  ExampleWrapper,} from "@/components/example"import { Button } from "@/components/ui/button"import {  DropdownMenu,  DropdownMenuContent,  DropdownMenuItem,  DropdownMenuSeparator,  DropdownMenuTrigger,} from "@/components/ui/dropdown-menu"import { Input } from "@/components/ui/input"import {  Select,  SelectContent,  SelectGroup,  SelectItem,  SelectTrigger,  SelectValue,} from "@/components/ui/select"import {  Table,  TableBody,  TableCaption,  TableCell,  TableFooter,  TableHead,  TableHeader,  TableRow,} from "@/components/ui/table"import { MoreHorizontalIcon } from "lucide-react"
const invoices = [  {    invoice: "INV001",    paymentStatus: "Paid",    totalAmount: "$250.00",    paymentMethod: "Credit Card",  },  {    invoice: "INV002",    paymentStatus: "Pending",    totalAmount: "$150.00",    paymentMethod: "PayPal",  },  {    invoice: "INV003",    paymentStatus: "Unpaid",    totalAmount: "$350.00",    paymentMethod: "Bank Transfer",  },  {    invoice: "INV004",    paymentStatus: "Paid",    totalAmount: "$450.00",    paymentMethod: "Credit Card",  },  {    invoice: "INV005",    paymentStatus: "Paid",    totalAmount: "$550.00",    paymentMethod: "PayPal",  },  {    invoice: "INV006",    paymentStatus: "Pending",    totalAmount: "$200.00",    paymentMethod: "Bank Transfer",  },  {    invoice: "INV007",    paymentStatus: "Unpaid",    totalAmount: "$300.00",    paymentMethod: "Credit Card",  },]
export default function TableExample() {  return (    <ExampleWrapper>      <TableBasic />      <TableWithFooter />      <TableSimple />      <TableWithBadges />      <TableWithActions />      <TableWithSelect />      <TableWithInput />    </ExampleWrapper>  )}
function TableBasic() {  return (    <Example title="Basic">      <Table>        <TableCaption>A list of your recent invoices.</TableCaption>        <TableHeader>          <TableRow>            <TableHead className="w-[100px]">Invoice</TableHead>            <TableHead>Status</TableHead>            <TableHead>Method</TableHead>            <TableHead className="text-right">Amount</TableHead>          </TableRow>        </TableHeader>        <TableBody>          {invoices.slice(0, 3).map((invoice) => (            <TableRow key={invoice.invoice}>              <TableCell className="font-medium">{invoice.invoice}</TableCell>              <TableCell>{invoice.paymentStatus}</TableCell>              <TableCell>{invoice.paymentMethod}</TableCell>              <TableCell className="text-right">                {invoice.totalAmount}              </TableCell>            </TableRow>          ))}        </TableBody>      </Table>    </Example>  )}
function TableWithFooter() {  return (    <Example title="With Footer">      <Table>        <TableCaption>A list of your recent invoices.</TableCaption>        <TableHeader>          <TableRow>            <TableHead className="w-[100px]">Invoice</TableHead>            <TableHead>Status</TableHead>            <TableHead>Method</TableHead>            <TableHead className="text-right">Amount</TableHead>          </TableRow>        </TableHeader>        <TableBody>          {invoices.slice(0, 3).map((invoice) => (            <TableRow key={invoice.invoice}>              <TableCell className="font-medium">{invoice.invoice}</TableCell>              <TableCell>{invoice.paymentStatus}</TableCell>              <TableCell>{invoice.paymentMethod}</TableCell>              <TableCell className="text-right">                {invoice.totalAmount}              </TableCell>            </TableRow>          ))}        </TableBody>        <TableFooter>          <TableRow>            <TableCell colSpan={3}>Total</TableCell>            <TableCell className="text-right">$2,500.00</TableCell>          </TableRow>        </TableFooter>      </Table>    </Example>  )}
function TableSimple() {  return (    <Example title="Simple">      <Table>        <TableHeader>          <TableRow>            <TableHead>Name</TableHead>            <TableHead>Email</TableHead>            <TableHead className="text-right">Role</TableHead>          </TableRow>        </TableHeader>        <TableBody>          <TableRow>            <TableCell className="font-medium">Sarah Chen</TableCell>            <TableCell className="break-all whitespace-normal">sarah.chen@acme.com</TableCell>            <TableCell className="text-right">Admin</TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Marc Rodriguez</TableCell>            <TableCell className="break-all whitespace-normal">marcus.rodriguez@acme.com</TableCell>            <TableCell className="text-right">User</TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Emily Watson</TableCell>            <TableCell className="break-all whitespace-normal">emily.watson@acme.com</TableCell>            <TableCell className="text-right">User</TableCell>          </TableRow>        </TableBody>      </Table>    </Example>  )}
function TableWithBadges() {  return (    <Example title="With Badges">      <Table>        <TableHeader>          <TableRow>            <TableHead>Task</TableHead>            <TableHead>Status</TableHead>            <TableHead className="text-right">Priority</TableHead>          </TableRow>        </TableHeader>        <TableBody>          <TableRow>            <TableCell className="font-medium">Design homepage</TableCell>            <TableCell>              <span className="inline-flex items-center rounded-full bg-green-500/10 px-2 py-1 text-xs font-medium text-green-700 dark:text-green-400">                Completed              </span>            </TableCell>            <TableCell className="text-right">              <span className="inline-flex items-center rounded-full bg-blue-500/10 px-2 py-1 text-xs font-medium text-blue-700 dark:text-blue-400">                High              </span>            </TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Implement API</TableCell>            <TableCell>              <span className="inline-flex items-center rounded-full bg-yellow-500/10 px-2 py-1 text-xs font-medium text-yellow-700 dark:text-yellow-400">                In Progress              </span>            </TableCell>            <TableCell className="text-right">              <span className="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 text-xs font-medium text-gray-700 dark:text-gray-400">                Medium              </span>            </TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Write tests</TableCell>            <TableCell>              <span className="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 text-xs font-medium text-gray-700 dark:text-gray-400">                Pending              </span>            </TableCell>            <TableCell className="text-right">              <span className="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-1 text-xs font-medium text-gray-700 dark:text-gray-400">                Low              </span>            </TableCell>          </TableRow>        </TableBody>      </Table>    </Example>  )}
function TableWithActions() {  return (    <Example title="With Actions">      <Table>        <TableHeader>          <TableRow>            <TableHead>Product</TableHead>            <TableHead>Price</TableHead>            <TableHead className="text-right">Actions</TableHead>          </TableRow>        </TableHeader>        <TableBody>          <TableRow>            <TableCell className="font-medium">Wireless Mouse</TableCell>            <TableCell>$29.99</TableCell>            <TableCell className="text-right">              <DropdownMenu>                <DropdownMenuTrigger                  render={                    <Button variant="ghost" size="icon" className="size-8" />                  }                >                  <MoreHorizontalIcon />                  <span className="sr-only">Open menu</span>                </DropdownMenuTrigger>                <DropdownMenuContent align="end">                  <DropdownMenuItem>Edit</DropdownMenuItem>                  <DropdownMenuItem>Duplicate</DropdownMenuItem>                  <DropdownMenuSeparator />                  <DropdownMenuItem variant="destructive">                    Delete                  </DropdownMenuItem>                </DropdownMenuContent>              </DropdownMenu>            </TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Mechanical Keyboard</TableCell>            <TableCell>$129.99</TableCell>            <TableCell className="text-right">              <DropdownMenu>                <DropdownMenuTrigger                  render={                    <Button variant="ghost" size="icon" className="size-8" />                  }                >                  <MoreHorizontalIcon />                  <span className="sr-only">Open menu</span>                </DropdownMenuTrigger>                <DropdownMenuContent align="end">                  <DropdownMenuItem>Edit</DropdownMenuItem>                  <DropdownMenuItem>Duplicate</DropdownMenuItem>                  <DropdownMenuSeparator />                  <DropdownMenuItem variant="destructive">                    Delete                  </DropdownMenuItem>                </DropdownMenuContent>              </DropdownMenu>            </TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">USB-C Hub</TableCell>            <TableCell>$49.99</TableCell>            <TableCell className="text-right">              <DropdownMenu>                <DropdownMenuTrigger                  render={                    <Button variant="ghost" size="icon" className="size-8" />                  }                >                  <MoreHorizontalIcon />                  <span className="sr-only">Open menu</span>                </DropdownMenuTrigger>                <DropdownMenuContent align="end">                  <DropdownMenuItem>Edit</DropdownMenuItem>                  <DropdownMenuItem>Duplicate</DropdownMenuItem>                  <DropdownMenuSeparator />                  <DropdownMenuItem variant="destructive">                    Delete                  </DropdownMenuItem>                </DropdownMenuContent>              </DropdownMenu>            </TableCell>          </TableRow>        </TableBody>      </Table>    </Example>  )}
const people = [  { value: "sarah", label: "Sarah Chen" },  { value: "marcus", label: "Marc Rodriguez" },  { value: "emily", label: "Emily Watson" },  { value: "david", label: "David Kim" },]
const tasks = [  {    task: "Design homepage",    assignee: "sarah",    status: "In Progress",  },  {    task: "Implement API",    assignee: "marcus",    status: "Pending",  },  {    task: "Write tests",    assignee: "emily",    status: "Not Started",  },]
function TableWithSelect() {  return (    <Example title="With Select">      <Table>        <TableHeader>          <TableRow>            <TableHead>Task</TableHead>            <TableHead>Assignee</TableHead>            <TableHead>Status</TableHead>          </TableRow>        </TableHeader>        <TableBody>          {tasks.map((item) => (            <TableRow key={item.task}>              <TableCell className="font-medium">{item.task}</TableCell>              <TableCell>                <Select                  items={people}                  defaultValue={people.find(                    (person) => person.value === item.assignee                  )}                  itemToStringValue={(item) => {                    return item.value                  }}                >                  <SelectTrigger aria-label="Status" className="w-40" size="sm">                    <SelectValue />                  </SelectTrigger>                  <SelectContent>                    <SelectGroup>                      {people.map((person) => (                        <SelectItem key={person.value} value={person}>                          {person.label}                        </SelectItem>                      ))}                    </SelectGroup>                  </SelectContent>                </Select>              </TableCell>              <TableCell>{item.status}</TableCell>            </TableRow>          ))}        </TableBody>      </Table>    </Example>  )}
function TableWithInput() {  return (    <Example title="With Input">      <Table>        <TableHeader>          <TableRow>            <TableHead>Product</TableHead>            <TableHead>Quantity</TableHead>            <TableHead>Price</TableHead>          </TableRow>        </TableHeader>        <TableBody>          <TableRow>            <TableCell className="font-medium">Wireless Mouse</TableCell>            <TableCell>              <Input aria-label="Quantity"                type="number"                defaultValue="1"                className="h-8 w-20"                min="0"              />            </TableCell>            <TableCell>$29.99</TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">Mechanical Keyboard</TableCell>            <TableCell>              <Input aria-label="Quantity"                type="number"                defaultValue="2"                className="h-8 w-20"                min="0"              />            </TableCell>            <TableCell>$129.99</TableCell>          </TableRow>          <TableRow>            <TableCell className="font-medium">USB-C Hub</TableCell>            <TableCell>              <Input aria-label="Quantity"                type="number"                defaultValue="1"                className="h-8 w-20"                min="0"              />            </TableCell>            <TableCell>$49.99</TableCell>          </TableRow>        </TableBody>      </Table>    </Example>  )}