YA Table
Responsive table component with rounded container, muted header, and row dividers for displaying structured data.
The YaTable is a composable table component in the YaVendio Design System. It wraps HTML native table elements with YaVendio styling: rounded container with border, muted header background, consistent cell padding, and hover states on rows.
Quick Start
pnpm dlx shadcn@latest add @yavendio/ya-tablenpx shadcn@latest add @yavendio/ya-tableyarn dlx shadcn@latest add @yavendio/ya-tableimport {
YaTable,
YaTableBody,
YaTableCell,
YaTableHead,
YaTableHeader,
YaTableRow,
} from '@/components/ui/ya-table'
export default function Example() {
return (
<YaTable>
<YaTableHeader>
<YaTableRow>
<YaTableHead>Name</YaTableHead>
<YaTableHead>Status</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
<YaTableRow>
<YaTableCell>Item 1</YaTableCell>
<YaTableCell>Active</YaTableCell>
</YaTableRow>
</YaTableBody>
</YaTable>
)
}Basic
A standard table with header and body rows.
| Factura | Estado | Método | Monto |
|---|---|---|---|
| INV001 | Pagado | Tarjeta de crédito | $250.00 |
| INV002 | Pendiente | PayPal | $150.00 |
| INV003 | No pagado | Transferencia | $350.00 |
| INV004 | Pagado | Tarjeta de crédito | $450.00 |
| INV005 | Pagado | PayPal | $550.00 |
<YaTable>
<YaTableHeader>
<YaTableRow>
<YaTableHead className="w-[120px]">Factura</YaTableHead>
<YaTableHead>Estado</YaTableHead>
<YaTableHead>Método</YaTableHead>
<YaTableHead className="text-right">Monto</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
<YaTableRow>
<YaTableCell className="font-medium">INV001</YaTableCell>
<YaTableCell>Pagado</YaTableCell>
<YaTableCell>Tarjeta de crédito</YaTableCell>
<YaTableCell className="text-right">$250.00</YaTableCell>
</YaTableRow>
</YaTableBody>
</YaTable>Footer
Use the YaTableFooter component to add a summary row at the bottom.
| Factura | Estado | Método | Monto |
|---|---|---|---|
| INV001 | Pagado | Tarjeta de crédito | $250.00 |
| INV002 | Pendiente | PayPal | $150.00 |
| INV003 | No pagado | Transferencia | $350.00 |
| Total | $750.00 | ||
<YaTable>
<YaTableHeader>
<YaTableRow>
<YaTableHead>Factura</YaTableHead>
<YaTableHead>Estado</YaTableHead>
<YaTableHead>Método</YaTableHead>
<YaTableHead className="text-right">Monto</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
{/* ...rows */}
</YaTableBody>
<YaTableFooter>
<YaTableRow>
<YaTableCell colSpan={3}>Total</YaTableCell>
<YaTableCell className="text-right">$750.00</YaTableCell>
</YaTableRow>
</YaTableFooter>
</YaTable>Caption
Use YaTableCaption for an accessible description of the table contents.
| Factura | Estado | Método | Monto |
|---|---|---|---|
| INV001 | Pagado | Tarjeta de crédito | $250.00 |
| INV002 | Pendiente | PayPal | $150.00 |
| INV003 | No pagado | Transferencia | $350.00 |
<YaTable>
<YaTableCaption>Lista de facturas recientes.</YaTableCaption>
<YaTableHeader>
<YaTableRow>
<YaTableHead>Factura</YaTableHead>
<YaTableHead>Estado</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
{/* ...rows */}
</YaTableBody>
</YaTable>Empty State
Show a message when the table has no data.
| Factura | Estado | Método | Monto |
|---|---|---|---|
| Sin resultados. | |||
<YaTable>
<YaTableHeader>
<YaTableRow>
<YaTableHead>Factura</YaTableHead>
<YaTableHead>Estado</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
<YaTableRow>
<YaTableCell colSpan={2} className="h-24 text-center text-muted-foreground">
Sin resultados.
</YaTableCell>
</YaTableRow>
</YaTableBody>
</YaTable>Composing with Other Components
YaTable cells accept any React content, making it easy to compose with other YaVendio components.
With Checkbox Selection
Use YaCheckbox for row selection. Set data-state="selected" on the YaTableRow to highlight selected rows.
| Producto | Categoría | Estado | Precio | |
|---|---|---|---|---|
| Camiseta básica | Ropa | Activo | $29.99 | |
| Taza personalizada | Accesorios | Borrador | $12.50 | |
| Poster A3 | Impresión | Activo | $18.00 | |
| Gorra bordada | Ropa | Archivado | $24.99 | |
| Sticker pack | Accesorios | Activo | $5.00 |
import { YaCheckbox } from '@/components/ui/ya-checkbox'
import { YaBadge } from '@/components/ui/ya-badge'
const [selected, setSelected] = useState<Set<string>>(new Set())
<YaTable>
<YaTableHeader>
<YaTableRow>
<YaTableHead className="w-[50px]">
<YaCheckbox
checked={allSelected}
indeterminate={someSelected}
onCheckedChange={handleToggleAll}
aria-label="Seleccionar todo"
/>
</YaTableHead>
<YaTableHead>Producto</YaTableHead>
<YaTableHead>Estado</YaTableHead>
<YaTableHead className="text-right">Precio</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
<YaTableRow data-state={selected.has(id) ? 'selected' : undefined}>
<YaTableCell>
<YaCheckbox checked={selected.has(id)} onCheckedChange={handleToggle} />
</YaTableCell>
<YaTableCell>Product name</YaTableCell>
<YaTableCell>
<YaBadge appearance="forest" size="sm">Activo</YaBadge>
</YaTableCell>
<YaTableCell className="text-right">$29.99</YaTableCell>
</YaTableRow>
</YaTableBody>
</YaTable>With Badges
Use YaBadge for category tags and status indicators inside cells.
| Producto | Categorías | Estado | Precio |
|---|---|---|---|
| Camiseta básica | Ropa Nuevo | Activo | $29.99 |
| Taza personalizada | Accesorios Nuevo | Borrador | $12.50 |
| Poster A3 | Impresión Nuevo | Activo | $18.00 |
| Gorra bordada | Ropa Nuevo | Archivado | $24.99 |
| Sticker pack | Accesorios Nuevo | Activo | $5.00 |
import { YaBadge } from '@/components/ui/ya-badge'
<YaTableCell>
<div className="flex items-center gap-1">
<YaBadge appearance="neutral" size="sm">Ropa</YaBadge>
<YaBadge appearance="indigo" size="sm">Nuevo</YaBadge>
</div>
</YaTableCell>With Actions
Use YaButton icon-only buttons for row-level actions like delete, copy, and more.
| Producto | Categoría | Precio | Acciones |
|---|---|---|---|
| Camiseta básica | Ropa | $29.99 | |
| Taza personalizada | Accesorios | $12.50 | |
| Poster A3 | Impresión | $18.00 | |
| Gorra bordada | Ropa | $24.99 | |
| Sticker pack | Accesorios | $5.00 |
import { YaButton } from '@/components/ui/ya-button'
import { Trash2, Copy, MoreHorizontal } from 'lucide-react'
<YaTableCell>
<div className="flex items-center gap-1">
<YaButton variant="ghost" size="icon-sm" className="text-destructive hover:text-destructive" aria-label="Eliminar">
<Trash2 />
</YaButton>
<YaButton variant="ghost" size="icon-sm" className="text-muted-foreground" aria-label="Copiar">
<Copy />
</YaButton>
<YaButton variant="ghost" size="icon-sm" className="text-muted-foreground" aria-label="Más opciones">
<MoreHorizontal />
</YaButton>
</div>
</YaTableCell>Rich Cells (Full Composition)
Combine checkboxes, text with description, badges, actions, and footer in a single table.
| Producto | Categorías | Estado | Precio | Acciones | |
|---|---|---|---|---|---|
Camiseta básicaPRD001 | Ropa | Activo | $29.99 | ||
Taza personalizadaPRD002 | Accesorios | Borrador | $12.50 | ||
Poster A3PRD003 | Impresión | Activo | $18.00 | ||
Gorra bordadaPRD004 | Ropa | Archivado | $24.99 | ||
Sticker packPRD005 | Accesorios | Activo | $5.00 | ||
| 0 de 5 seleccionados | $90.48 | ||||
Sticky Header
For tables with many rows, make the header sticky so it remains visible while scrolling. Use wrapperClassName to set a max height on the scroll container.
<YaTable wrapperClassName="max-h-[400px]">
<YaTableHeader className="sticky top-0 z-10">
<YaTableRow>
<YaTableHead>Producto</YaTableHead>
<YaTableHead>Precio</YaTableHead>
</YaTableRow>
</YaTableHeader>
<YaTableBody>
{/* Many rows... */}
</YaTableBody>
</YaTable>The wrapperClassName prop applies classes to the outer scroll container div, while className applies to the inner table element.
Responsive Behavior
The table wrapper has overflow-auto built in. On small screens, wide tables scroll horizontally inside the rounded container. No additional configuration is needed.
Subcomponents
| Component | HTML Element | Description |
|---|---|---|
YaTable | <div> + <table> | Scrollable wrapper with rounded border and inner table |
YaTableHeader | <thead> | Groups header rows |
YaTableBody | <tbody> | Groups body rows |
YaTableFooter | <tfoot> | Groups footer/summary rows |
YaTableRow | <tr> | A table row with hover state and bottom border |
YaTableHead | <th> | Header cell with muted background and medium font |
YaTableCell | <td> | Body cell with standard padding |
YaTableCaption | <caption> | Accessible table description |
Props
All subcomponents extend the native HTML element props they wrap:
| Component | Extends | Key Props |
|---|---|---|
YaTable | React.ComponentProps<'table'> | className, wrapperClassName |
YaTableHeader | React.ComponentProps<'thead'> | className |
YaTableBody | React.ComponentProps<'tbody'> | className |
YaTableFooter | React.ComponentProps<'tfoot'> | className |
YaTableRow | React.ComponentProps<'tr'> | className |
YaTableHead | React.ComponentProps<'th'> | className |
YaTableCell | React.ComponentProps<'td'> | className |
YaTableCaption | React.ComponentProps<'caption'> | className |
Accessibility
Data Table
You can use YaTable with @tanstack/react-table to build complex data tables with sorting, filtering, and pagination. See the shadcn Data Table documentation for a comprehensive guide.