# sortable-table primitive

Drop-in click-to-sort for HTML tables. Companion to the `/dropzone/` primitive.

Live at: `https://assets-gf-cx.pages.dev/sortable-table/sortable-table.{js,css}`

## Embed

```html
<link rel="stylesheet" href="https://assets-gf-cx.pages.dev/sortable-table/sortable-table.css">
<script src="https://assets-gf-cx.pages.dev/sortable-table/sortable-table.js" defer></script>
```

## Apply

```html
<table data-sortable>
  <thead>
    <tr>
      <th data-sort="num">     <!-- $ amounts -->Claimed</th>
      <th data-sort="alpha">   Item</th>
      <th data-sort="date">    Order date</th>
      <th data-sort="status" data-sort-status-order="STRONG,MODERATE,NONE">Evidence</th>
      <th>                     <!-- not sortable -->Notes</th>
    </tr>
  </thead>
  <tbody>...</tbody>
</table>
```

## Types

| `data-sort` | Behaviour |
|---|---|
| `alpha` | case-insensitive string compare (default for empty `data-sort=""`) |
| `num` | parses numbers; strips `$`, `,`, `%`, whitespace; missing → `-Infinity` |
| `currency` | same as `num` |
| `date` | uses `Date.parse()`; ISO-8601 + most readable formats work |
| `status` | ranks badge text by predefined order |
| `custom` | reads `<td data-sort-key="X">` value |

## Per-cell overrides

If a cell's display text isn't the right sort value, supply `data-sort-value`:

```html
<td data-sort-value="2026-05-22T07:43">7:43 AM today</td>
```

## State

Sort direction persists per (page-path × table) in `sessionStorage`. Click cycles:
`original → asc → desc → original`.

## Accessibility

- `<th>` becomes `role="button"` with `tabindex="0"` + `aria-label="<header> — click to sort"`
- Enter / Space triggers sort
- `aria-sort="ascending|descending|none"` updates as user clicks
- `:focus-visible` outline in --st-accent

## Theming

Uses CSS variable `--st-accent` which defaults to the host page's `--accent` if defined, else falls back to `#444`. No other style overrides needed — the indicators are unicode glyphs (`⇅` `▲` `▼`).

## Browser support

Vanilla ES5+ syntax (no transpiling needed). Tested on Safari 17, Chrome 121+, Firefox 122+. No IE support.

## See also

- Source: [`xlab-co/toolkit/web-assets/sortable-table/`](https://github.com/xlab-co/toolkit/tree/main/web-assets/sortable-table)
- First use: pa.gf.cx/home-insurance/claims/_bulk-source/_affidavits/dashboard
- Lift candidate: reports.dare.co.uk catalog (currently has a one-column inline sort; can be replaced with this primitive)
