Components

Data table

DataTable is composition, not a new recipe. table() dresses the markup, pagination() sits under the list, and a Select beside the nav owns rows-per-page when a dashboard needs it. TanStack Table (or any headless model) supplies sorting, selection and column state — later, in the app or ui-react.

Anatomy

Showing 1–20 of 412

EventReviewsScore
Harbor City Marathon4124.7
Seabridge Half Marathon893.2

What ships in @sportingscouter/ui

PieceExportOwns
Table visualstable({ hover, stickyHead, selectable, … })Classes only — no column model
Pagination visualspagination({ scale, layout })Classes only — no page math
Page windowpaginationWindow({ page, pageCount })Numbers and ellipsis markers
Row slicepaginationSlice({ page, pageSize, total })from, to, pageCount — summary copy stays in the app
Page sizeselect() composed beside navNot inside pagination()
Sort / select / columnsTanStack Table (app / ui-react)Out of scope for this package

Empty and error

Use table() empty and error slots — different shapes, same layout. Empty is neutral; error is destructive. Both need a recovery action in stateAction. No illustrations — the system has no imagery. See Empty, loading, error.

Structure

import { table, pagination, paginationWindow, paginationSlice } from '@sportingscouter/ui';

const { from, to, pageCount } = paginationSlice({ page, pageSize, total });
const items = paginationWindow({ page, pageCount });

<div class={tbl.wrap()}>
  <table class={tbl.root({ hover: true, stickyHead: true })}>…</table>
</div>
<nav class={pg.root()} aria-label="Pagination">
  <p class={pg.summary()} aria-live="polite">{/* app-owned: Showing {from}–{to} of {total} */}</p>
  <ul class={pg.list()}>{/* map items from paginationWindow */}</ul>
</nav>
<Select scale="sm" … /> {/* rows per page — beside nav, not inside it */}

Rules

  • No dataTable() recipe. Three APIs for one grid is three chances to diverge. Compose what exists.
  • Table does not grow a footer. Pagination and page-size live outside the <table>.
  • Missing score is —, not 0.0. Absence is a state — see Table.
  • Admin may keep TanStack on its own stack. It adopts these tokens and recipes when ready — this pass does not block it.

See also: Table · Pagination · Select

Sporting Scouter Design System
Every token on this site is generated from theme.css.