Table
A responsive table component.
Code
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow,} from "@falcon/ui-kit";
const invoices = [ { invoice: "ORD001", paymentStatus: "Paid", totalAmount: "$250.00", paymentMethod: "Credit Card", }, { invoice: "ORD002", paymentStatus: "Pending", totalAmount: "$150.00", paymentMethod: "ACH", }, { invoice: "ORD003", paymentStatus: "Unpaid", totalAmount: "$350.00", paymentMethod: "Bank Transfer", }, { invoice: "ORD004", paymentStatus: "Paid", totalAmount: "$450.00", paymentMethod: "Credit Card", }, { invoice: "ORD005", paymentStatus: "Paid", totalAmount: "$550.00", paymentMethod: "ACH", }, { invoice: "ORD006", paymentStatus: "Pending", totalAmount: "$200.00", paymentMethod: "Bank Transfer", }, { invoice: "ORD007", paymentStatus: "Unpaid", totalAmount: "$300.00", paymentMethod: "Credit Card", },];
export function Example() { return ( <Table> <TableCaption>A list of your recent orders.</TableCaption> <TableHeader> <TableRow> <TableHead className="tw:w-[100px]">Order</TableHead> <TableHead>Status</TableHead> <TableHead>Method</TableHead> <TableHead className="tw:text-right">Amount</TableHead> </TableRow> </TableHeader> <TableBody> {invoices.map((invoice) => ( <TableRow key={invoice.invoice}> <TableCell className="tw:font-medium">{invoice.invoice}</TableCell> <TableCell>{invoice.paymentStatus}</TableCell> <TableCell>{invoice.paymentMethod}</TableCell> <TableCell className="tw:text-right"> {invoice.totalAmount} </TableCell> </TableRow> ))} </TableBody> <TableFooter> <TableRow> <TableHead colSpan={3} scope="row"> Total </TableHead> <TableCell className="tw:text-right">$2,250.00</TableCell> </TableRow> </TableFooter> </Table> );}Composition
Section titled “Composition”Use the following composition to build a Table:
Table├── TableCaption├── TableHeader│ └── TableRow│ ├── TableHead│ ├── TableHead│ ├── TableHead│ └── TableHead├── TableBody│ ├── TableRow│ │ ├── TableCell│ │ ├── TableCell│ │ ├── TableCell│ │ └── TableCell│ └── TableRow│ ├── TableCell│ ├── TableCell│ ├── TableCell│ └── TableCell└── TableFooterSorting
Section titled “Sorting”Put TableHeadSortable inside a TableHead on a sortable column:
TableHead└── TableHeadSortableIt renders no <th> itself, so the enclosing TableHead still owns cell
concerns like aria-sort. Pass the column’s current sort direction to both —
TableHeadSortable for its chevrons, TableHead for aria-sort — and handle
the sort in onClick; the component owns none of the sorting logic itself.
Code
import { useState } from "react";import { Table, TableBody, TableCell, TableHead, TableHeadSortable, TableHeader, TableRow,} from "@falcon/ui-kit";
const accounts = [ { name: "Adams Ranch", syngentaId: "502081", location: "Abilene, KS" }, { name: "Albrecht Ag Inc", syngentaId: "1005", location: "Fayette, MO" }, { name: "Allen Farms", syngentaId: "502101", location: "Minot, ND" }, { name: "Bailey Agriculture", syngentaId: "502021", location: "Freeport, IL", },];
type Column = "name" | "syngentaId";
export function Example() { const [sort, setSort] = useState<{ column: Column; direction: "asc" | "desc"; }>({ column: "name", direction: "asc" });
const sorted = [...accounts].sort((a, b) => { const result = a[sort.column].localeCompare(b[sort.column]);
return sort.direction === "asc" ? result : -result; });
function toggleSort(column: Column) { setSort((current) => current.column === column ? { column, direction: current.direction === "asc" ? "desc" : "asc" } : { column, direction: "asc" }, ); }
const nameSorted = sort.column === "name" ? sort.direction : false; const syngentaIdSorted = sort.column === "syngentaId" ? sort.direction : false;
return ( <Table> <TableHeader> <TableRow> <TableHead sorted={nameSorted}> <TableHeadSortable sorted={nameSorted} onClick={() => toggleSort("name")} > Account </TableHeadSortable> </TableHead> <TableHead sorted={syngentaIdSorted}> <TableHeadSortable sorted={syngentaIdSorted} onClick={() => toggleSort("syngentaId")} > Syngenta ID </TableHeadSortable> </TableHead> <TableHead>Location</TableHead> </TableRow> </TableHeader> <TableBody> {sorted.map((account) => ( <TableRow key={account.name}> <TableCell className="tw:font-medium">{account.name}</TableCell> <TableCell>{account.syngentaId}</TableCell> <TableCell>{account.location}</TableCell> </TableRow> ))} </TableBody> </Table> );}Footer
Section titled “Footer”Use the <TableFooter /> component to add a footer to the table.
Code
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow,} from "@falcon/ui-kit";
const invoices = [ { invoice: "ORD001", paymentStatus: "Paid", totalAmount: "$250.00", paymentMethod: "Credit Card", }, { invoice: "ORD002", paymentStatus: "Pending", totalAmount: "$150.00", paymentMethod: "ACH", }, { invoice: "ORD003", paymentStatus: "Unpaid", totalAmount: "$350.00", paymentMethod: "Bank Transfer", }, { invoice: "ORD004", paymentStatus: "Paid", totalAmount: "$450.00", paymentMethod: "Credit Card", }, { invoice: "ORD005", paymentStatus: "Paid", totalAmount: "$550.00", paymentMethod: "ACH", }, { invoice: "ORD006", paymentStatus: "Pending", totalAmount: "$200.00", paymentMethod: "Bank Transfer", }, { invoice: "ORD007", paymentStatus: "Unpaid", totalAmount: "$300.00", paymentMethod: "Credit Card", },];
export function Example() { return ( <Table> <TableCaption>A list of your recent orders.</TableCaption> <TableHeader> <TableRow> <TableHead className="tw:w-[100px]">Order</TableHead> <TableHead>Status</TableHead> <TableHead>Method</TableHead> <TableHead className="tw:text-right">Amount</TableHead> </TableRow> </TableHeader> <TableBody> {invoices.slice(0, 3).map((invoice) => ( <TableRow key={invoice.invoice}> <TableCell className="tw:font-medium">{invoice.invoice}</TableCell> <TableCell>{invoice.paymentStatus}</TableCell> <TableCell>{invoice.paymentMethod}</TableCell> <TableCell className="tw:text-right"> {invoice.totalAmount} </TableCell> </TableRow> ))} </TableBody> <TableFooter> <TableRow> <TableHead colSpan={3} scope="row"> Total </TableHead> <TableCell className="tw:text-right">$750.00</TableCell> </TableRow> </TableFooter> </Table> );}Actions
Section titled “Actions”A table showing actions for each row using a <DropdownMenu /> component.
Code
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, MoreHorizontalIcon, Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from "@falcon/ui-kit";
export function Example() { return ( <Table> <TableHeader> <TableRow> <TableHead>Product</TableHead> <TableHead>Price</TableHead> <TableHead className="tw:text-right">Actions</TableHead> </TableRow> </TableHeader> <TableBody> <TableRow> <TableCell className="tw:font-medium">Soil Test Kit</TableCell> <TableCell>$29.99</TableCell> <TableCell className="tw:text-right"> <DropdownMenu> <DropdownMenuTrigger render={ <Button variant="ghost" size="icon" className="tw:size-8" /> } > <MoreHorizontalIcon /> <span className="tw: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="tw:font-medium"> Field Measuring Wheel </TableCell> <TableCell>$129.99</TableCell> <TableCell className="tw:text-right"> <DropdownMenu> <DropdownMenuTrigger render={ <Button variant="ghost" size="icon" className="tw:size-8" /> } > <MoreHorizontalIcon /> <span className="tw: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="tw:font-medium">Sprayer Nozzle Set</TableCell> <TableCell>$49.99</TableCell> <TableCell className="tw:text-right"> <DropdownMenu> <DropdownMenuTrigger render={ <Button variant="ghost" size="icon" className="tw:size-8" /> } > <MoreHorizontalIcon /> <span className="tw: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> );}Renders a <table> element and accepts standard table props.
TableBody
Section titled “TableBody”Contains the table’s data rows. Renders a <tbody> element and accepts
standard tbody props.
TableCaption
Section titled “TableCaption”Describes the table. Renders a <caption> element and accepts standard
caption props.
TableCell
Section titled “TableCell”Renders a <td> element and accepts standard td props.
TableFooter
Section titled “TableFooter”Contains summary rows. Renders a <tfoot> element and accepts standard tfoot
props.
TableHead
Section titled “TableHead”Renders a <th> element and accepts standard th props. Pass sorted for a
sortable column — give it the same value passed to the nested
TableHeadSortable’s own sorted prop, which drives its chevrons.
sorted
Section titled “sorted”sorted?: SortDirectionWhich direction the column is currently sorted by. Sets aria-sort to
"ascending", "descending", or (false) "none". Omit for a
non-sortable column to leave aria-sort unset.
TableHeadSortable
Section titled “TableHeadSortable”Sort toggle for a column heading. Wraps its label in a <button> and shows
the column’s current sort direction on the trailing chevrons. Place it as the
content of a TableHead, which renders no <th> itself; forwards standard
<button> props (e.g. onClick); type is fixed to "button" and can’t be
overridden. Pass the same value to the enclosing TableHead’s own sorted
prop to keep its aria-sort in sync.
sorted
Section titled “sorted”sorted?: SortDirection = falseWhich direction the column is currently sorted by, if any.
TableHeader
Section titled “TableHeader”Contains column headings. Renders a <thead> element and accepts standard
thead props.
TableRow
Section titled “TableRow”Renders a <tr> element and accepts standard tr props.