Viana Kitv0.1.4

Components

Table

A responsive data table built from semantic HTML. Supports captions, footers, and row selection states.

example.tsx
NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comUser

Import

tsx
import {
  AppTable,
  AppTableHeader,
  AppTableBody,
  AppTableFooter,
  AppTableHead,
  AppTableRow,
  AppTableCell,
  AppTableCaption,
} from "@/components/primitives/AppTable"

With caption

Place AppTableCaption as the first child of AppTable. It renders below the table body via the caption-bottom utility regardless of DOM order.

A list of your recent invoices.
InvoiceStatusAmount
INV-001Paid$250.00
INV-002Pending$150.00
INV-003Paid$350.00

With footer

Use AppTableFooter for summary rows — totals, counts, or aggregates. It renders with a top border and muted background automatically. Use colSpan on AppTableCell to span multiple columns.

InvoiceStatusAmount
INV-001Paid$250.00
INV-002Pending$150.00
INV-003Paid$350.00
Total$750.00

Selected row

Add data-state="selected" to an AppTableRow to apply the selection highlight. Control this via your own state — no built-in selection logic is included.

NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comUser
Bob Johnsonbob@example.comEditor

API Reference

AppTable

Extends all native <table> HTML attributes. Renders inside a overflow-auto wrapper — the className prop targets the inner <table>, not the wrapper.

PropTypeDefaultDescription
classNamestringAdditional Tailwind classes merged onto the <table> element via cn().

AppTableHeader

Extends all native <thead> HTML attributes. Default styling applies a bottom border to all child rows.

PropTypeDefaultDescription
classNamestringMerged onto <thead>. Default: [&_tr]:border-b.

AppTableBody

Extends all native <tbody> HTML attributes. Default styling removes the bottom border from the last row.

PropTypeDefaultDescription
classNamestringMerged onto <tbody>. Default: [&_tr:last-child]:border-0.

AppTableFooter

Extends all native <tfoot> HTML attributes. Renders with a top border, muted background, and medium font weight.

PropTypeDefaultDescription
classNamestringMerged onto <tfoot>. Default: border-t bg-muted/50 font-medium [&>tr]:last:border-b-0.

AppTableHead

Extends all native <th> HTML attributes. Used inside AppTableRow within AppTableHeader.

PropTypeDefaultDescription
classNamestringMerged onto <th>. Default: h-10 px-2 text-left align-middle font-medium text-muted-foreground.

AppTableRow

Extends all native <tr> HTML attributes. Includes hover and selection transitions by default.

PropTypeDefaultDescription
data-state"selected" | undefinedSet to "selected" to apply the selection highlight (bg-muted). Controlled by your state — no built-in selection logic.
classNamestringMerged onto <tr>. Default: border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted.

AppTableCell

Extends all native <td> HTML attributes. Used inside AppTableRow within AppTableBody or AppTableFooter.

PropTypeDefaultDescription
colSpannumberSpan multiple columns. Common in footer summary rows.
classNamestringMerged onto <td>. Default: p-2 align-middle.

AppTableCaption

Extends all native <caption> HTML attributes. Always place as the first child of AppTable. Renders below the table body via caption-bottom.

PropTypeDefaultDescription
classNamestringMerged onto <caption>. Default: mt-4 text-sm text-muted-foreground. Renders below body via caption-bottom.

Source

src/components/primitives/AppTable.tsx
"use client"

import * as React from "react"
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "../ui/table"

type AppTableProps = React.ComponentProps<typeof Table>
function AppTable(props: AppTableProps) {
  return <Table {...props} />
}

type AppTableHeaderProps = React.ComponentProps<typeof TableHeader>
function AppTableHeader(props: AppTableHeaderProps) {
  return <TableHeader {...props} />
}

type AppTableBodyProps = React.ComponentProps<typeof TableBody>
function AppTableBody(props: AppTableBodyProps) {
  return <TableBody {...props} />
}

type AppTableFooterProps = React.ComponentProps<typeof TableFooter>
function AppTableFooter(props: AppTableFooterProps) {
  return <TableFooter {...props} />
}

type AppTableHeadProps = React.ComponentProps<typeof TableHead>
function AppTableHead(props: AppTableHeadProps) {
  return <TableHead {...props} />
}

type AppTableRowProps = React.ComponentProps<typeof TableRow>
function AppTableRow(props: AppTableRowProps) {
  return <TableRow {...props} />
}

type AppTableCellProps = React.ComponentProps<typeof TableCell>
function AppTableCell(props: AppTableCellProps) {
  return <TableCell {...props} />
}

type AppTableCaptionProps = React.ComponentProps<typeof TableCaption>
function AppTableCaption(props: AppTableCaptionProps) {
  return <TableCaption {...props} />
}

export {
  AppTable, type AppTableProps,
  AppTableHeader, type AppTableHeaderProps,
  AppTableBody, type AppTableBodyProps,
  AppTableFooter, type AppTableFooterProps,
  AppTableHead, type AppTableHeadProps,
  AppTableRow, type AppTableRowProps,
  AppTableCell, type AppTableCellProps,
  AppTableCaption, type AppTableCaptionProps,
}