Table

A composable, accessible table built from primitives. Compose nana-table with header, body, footer, row, head, cell and caption elements. Built on the CSS table model and surface tokens, so it lays out natively, scrolls on small screens, and follows the light/dark theme. Data-grid features (pagination, filtering, selection) compose around these primitives.

Anatomy

Name Email Status Amount John Doe john@example.com Active KSh 120.00 Jane Roe jane@example.com Pending KSh 80.00 Sam Poe sam@example.com Active KSh 240.00 Recent transactions
table.html
html
1 <nana-table variant="striped" hoverable>
2 <nana-table-header>
3 <nana-table-row>
4 <nana-table-head>Name</nana-table-head>
5 <nana-table-head>Email</nana-table-head>
6 <nana-table-head>Status</nana-table-head>
7 <nana-table-head align="right">Amount</nana-table-head>
8 </nana-table-row>
9 </nana-table-header>
10
11 <nana-table-body>
12 <nana-table-row>
13 <nana-table-cell>John Doe</nana-table-cell>
14 <nana-table-cell>john@example.com</nana-table-cell>
15 <nana-table-cell>Active</nana-table-cell>
16 <nana-table-cell align="right">KSh 120.00</nana-table-cell>
17 </nana-table-row>
18 </nana-table-body>
19
20 <nana-table-caption>Recent transactions</nana-table-caption>
21 </nana-table>

Variants

variant="default"

NameEmailStatusAmount John Doe john@example.com Active KSh 120.00 Jane Roe jane@example.com Pending KSh 80.00 Sam Poe sam@example.com Active KSh 240.00

variant="bordered"

NameEmailStatusAmount John Doe john@example.com Active KSh 120.00 Jane Roe jane@example.com Pending KSh 80.00 Sam Poe sam@example.com Active KSh 240.00

variant="striped"

NameEmailStatusAmount John Doe john@example.com Active KSh 120.00 Jane Roe jane@example.com Pending KSh 80.00 Sam Poe sam@example.com Active KSh 240.00

variant="minimal"

NameEmailStatusAmount John Doe john@example.com Active KSh 120.00 Jane Roe jane@example.com Pending KSh 80.00 Sam Poe sam@example.com Active KSh 240.00
variant.html
html
1 <nana-table variant="bordered">…</nana-table>

Density

density="compact"

Name Email Amount John Doe john@example.com KSh 120.00 Jane Roe jane@example.com KSh 80.00

density="normal"

Name Email Amount John Doe john@example.com KSh 120.00 Jane Roe jane@example.com KSh 80.00

density="comfortable"

Name Email Amount John Doe john@example.com KSh 120.00 Jane Roe jane@example.com KSh 80.00
density.html
html
1 <nana-table density="compact">…</nana-table>

Sortable Headers

Mark a nana-table-head as sortable. It renders the indicator and emits nana-sort on activation — the consumer owns the sort state and updates the sort attribute.

Name Email Amount John Doe john@example.com KSh 120.00 Jane Roe jane@example.com KSh 80.00
sortable.html
html
1 <nana-table-head sortable sort="asc">Name</nana-table-head>
2
3 <!-- The header only renders state and emits an event; the consumer sorts: -->
4 <nana-table @nana-sort=${onSort}> … </nana-table>

Customization

variant and density set the look and spacing. These variables tune the palette, and the parts let you reach internals.

Q2 revenue by region Region Owner Revenue North America Ada Lovelace $420,000 Europe Alan Turing $318,500 Asia Pacific Grace Hopper $265,200
report-table.html
html
1 <nana-table class="report" variant="striped" hoverable>
2 <nana-table-caption>Q2 revenue by region</nana-table-caption>
3 <nana-table-header>
4 <nana-table-row>
5 <nana-table-head>Region</nana-table-head>
6 <nana-table-head>Owner</nana-table-head>
7 <nana-table-head align="right">Revenue</nana-table-head>
8 </nana-table-row>
9 </nana-table-header>
10 <nana-table-body>
11 <nana-table-row>
12 <nana-table-cell>North America</nana-table-cell>
13 <nana-table-cell>Ada Lovelace</nana-table-cell>
14 <nana-table-cell align="right">$420,000</nana-table-cell>
15 </nana-table-row>
16 <!-- …more rows… -->
17 </nana-table-body>
18 </nana-table>
table.css
css
1 /* variant + density handle the common looks; these tune the palette */
2 nana-table.report {
3 --nana-table-border-color: #e2e8f0;
4 --nana-table-row-hover: #eef2ff;
5 --nana-table-stripe: #f8fafc;
6 --nana-table-header-bg: #0b1220;
7 --nana-table-header-color: #e5edff;
8 }
CSS Variable Description
--nana-table-border-colorGrid / divider colour
--nana-table-row-hoverRow hover background
--nana-table-stripeZebra-stripe background (striped variant)
--nana-table-header-bgHeader background colour
--nana-table-header-colorHeader text colour
Part Description
containerThe scroll container
tableThe native <table> element
cellA header or body cell
captionThe table caption

Import

A single import registers every table element.

main.ts
ts
1 import "@nana-tec/ui-components/table";

Elements

Element Maps to Description
nana-table <table> Container, scroll region, and design vars (variant/density/hoverable/sticky-header)
nana-table-header <thead> Header group
nana-table-body <tbody> Body group
nana-table-footer <tfoot> Footer group (totals/summary)
nana-table-row <tr> Row (handles stripe and hover)
nana-table-head <th> Header cell — optionally sortable
nana-table-cell <td> Data cell — supports align
nana-table-caption <caption> Accessible table description

Props (nana-table)

Attribute Type Default Description
variant default | bordered | striped | minimal default Visual style
density compact | normal | comfortable normal Cell padding
hoverable boolean false Highlight rows on hover
sticky-header boolean false Keep the header visible while scrolling

Props (nana-table-head / nana-table-cell)

Attribute Type Description
align left | center | right Cell text alignment (head & cell)
sortable boolean Head only — shows indicator and emits nana-sort
sort none | asc | desc Head only — current sort direction (controlled)