DataGrid

A grid with two halves: the sorting happens in the database, not in JavaScript.

**Server mode** takes the `grid` prop from `TGrid<M>` in Pascal. Sorting,
searching and paging happen in the database. The component owns no data logic:
it reports state through `onstate` and renders what it is given. This is the
default for Askr, because the database is already there, has the indexes, and
is faster than the network.

```pascal
G := TGrid<TCustomer>.New;
G.Read(Req)
 .Sortable('name', Customers.Name)
 .Searchable([Customers.Name, Customers.Email])
 .DefaultSort('name');

Result := Inertia('Customers/Index',
  ['rows', G.Rows(TQuery<TCustomer>.New), 'grid', G]);
```

**`Sortable` is an allowlist, and it is not a check somebody remembered to
write.** `TQuery.OrderBy` takes a typed column, not a string, so a key that
was never registered has nothing to sort by — `'ORDER BY ' + param` cannot be
written. There is a test that sends
`sort=email); DROP TABLE customers;--` and then counts the rows still in the
table.

**Client mode** — leave `grid` off and the grid sorts, filters and pages the
array itself. Fine for a few thousand rows, wrong beyond that.

**Virtualisation is opt-in.** It keeps the DOM small — 24 rows in the document
out of 10 000, measured — but it costs the browser's own Ctrl+F and printing.
`aria-rowcount` and `aria-rowindex` are set either way, and in server mode the
index is the row's place in the *whole* set. That is what lets a screen reader
say "row 4013 of 91000" when twenty rows exist.

Keyboard follows the WAI-ARIA grid pattern: one cell in the tab order, arrows
between cells, Home and End for the row, Ctrl with them for the grid, Enter to
activate. Arrow-up from the first row lands on the column header rather than
nowhere.

Select-all has three states, and only ever means *this page*.

**What it does not do**, on purpose: column reordering and pinning by drag,
grouping, cell editing, infinite scroll, export. Each is its own project, and
dragging with keyboard support is as hard as the rest put together.