Table
Styled data tables with optional striping and hover effects.
Default
Preview
| Name | Status | |
|---|---|---|
| Jane Doe | jane@example.com | Active |
| John Smith | john@example.com | Pending |
| Bob Wilson | bob@example.com | Inactive |
<div class="nano-table-wrapper">
<table class="nano-table nano-table--striped nano-table--hoverable">
<thead class="nano-table__head">
<tr>
<th scope="col" class="nano-table__header">Name</th>
<th scope="col" class="nano-table__header">Email</th>
<th scope="col" class="nano-table__header">Status</th>
</tr>
</thead>
<tbody class="nano-table__body">
<tr class="nano-table__row">
<td class="nano-table__cell">Jane Doe</td>
<td class="nano-table__cell">jane@example.com</td>
<td class="nano-table__cell">
<span class="nano-badge nano-badge--success">Active</span>
</td>
</tr>
</tbody>
</table>
</div>
Variants
nano-table--striped– alternating row backgroundsnano-table--hoverable– highlight rows on hover
Sortable columns
Wrap a table with data-controller="nanoui-data-table" and mark sortable headers with --sortable + data-nanoui-data-table-target="header". The controller toggles aria-sort on click and (by default) sorts rows client-side. Set data-nanoui-data-table-server-value="true" to let the controller only dispatch a nanoui-data-table:sort event and leave actual sorting to the server (Turbo Frame, fetch, etc.).
Per-header options:
data-sort-key— the field name used in the dispatched eventdata-sort-type—string(default),number, ordatedata-sort-valueon cells — explicit sort value when the displayed text isn’t directly comparable
Preview
| Alice Anderson | $49.00 | Apr 15 |
| Carol Carver | $149.00 | Apr 10 |
| Bob Baker | $349.00 | Apr 12 |
<div class="nano-table-wrapper" data-controller="nanoui-data-table">
<table class="nano-table">
<thead class="nano-table__head">
<tr>
<th class="nano-table__header nano-table__header--sortable"
data-nanoui-data-table-target="header"
data-sort-key="amount"
data-sort-type="number"
data-action="click->nanoui-data-table#sort">
<button type="button" class="nano-table__sort">Amount</button>
</th>
</tr>
</thead>
<tbody class="nano-table__body" data-nanoui-data-table-target="body">
<tr class="nano-table__row" data-nanoui-data-table-target="row">
<td class="nano-table__cell" data-sort-value="49">$49.00</td>
</tr>
</tbody>
</table>
</div>
Pagination
Pair the table with .nano-table-pagination below. Pagination is a presentation-only component — you can wire it to Turbo, a fetch-and-replace handler, or server-rendered links.
Preview
<nav class="nano-table-pagination" aria-label="Table pagination">
<span class="nano-table-pagination__info">
Showing <strong>1–10</strong> of <strong>42</strong>
</span>
<span class="nano-table-pagination__controls">
<a class="nano-table-pagination__button" aria-current="page" href="?page=1">1</a>
<a class="nano-table-pagination__button" href="?page=2">2</a>
<span class="nano-table-pagination__ellipsis">…</span>
<a class="nano-table-pagination__button" href="?page=5">5</a>
</span>
</nav>
Data table Stimulus API
- Controller:
nanoui-data-table - Targets:
header,body,row - Values:
server(Boolean, defaultfalse) — whentrue, skip client-side sorting and only dispatch the event - Events:
nanoui-data-table:sortwith{ key, direction }in detail