# Selection

> Package `@umriss-ui/table`, version 0.40.0. Demo page: <https://romanhaendler.github.io/umriss-ui/table/selection/>. Every page in one line: [llms.txt](https://romanhaendler.github.io/umriss-ui/table/llms.txt); every page in full: [llms-full.txt](https://romanhaendler.github.io/umriss-ui/table/llms-full.txt).

Tick rows to act on them together (also called row selection or multi-select).

```ts
import { useTable } from "@umriss-ui/table";
```

Demo page: https://romanhaendler.github.io/umriss-ui/table/selection/

“Select all” selects what search and filters leave, on every page.

## Examples

### Select rows

`selectable` adds the selection column; “select all” takes what the search leaves. Search “Oak”, select all, clear the search.

```tsx
import { Stack, Text } from "@umriss-ui/core";
import { Search, Toolbar, useTable } from "@umriss-ui/table";

interface Shipment {
  id: string;
  customer: string;
  tour: string;
}

const SHIPMENTS: Shipment[] = [
  { id: "FP-1004210", customer: "Holloway Garden Supplies", tour: "T-01" },
  { id: "FP-1004223", customer: "Oakridge Pharmacy", tour: "T-01" },
  { id: "FP-1004236", customer: "Brixley Cycles", tour: "T-02" },
  { id: "FP-1004249", customer: "Oakridge Pharmacy", tour: "T-02" },
  { id: "FP-1004262", customer: "Pellham Hardware", tour: "T-03" },
  { id: "FP-1004275", customer: "Oakridge Pharmacy", tour: "T-03" },
];

export default function Selection() {
  const t = useTable(SHIPMENTS, { rowKey: (s) => s.id });
  const { Table, Column } = t;
  const inTheSet = t.filtered.filter((s) => t.selection.isSelected(s.id)).length;

  return (
    <Stack gap={3}>
      <Table selectable ariaLabel="Shipments">
        <Toolbar>
          <Search placeholder="Search customer" />
        </Toolbar>
        <Column value="id" label="Shipment" rowHeader />
        <Column value="customer" label="Customer" />
        <Column value="tour" label="Tour" />
      </Table>
      <Text size="xs" tone="muted">
        {t.selection.count} selected, {inTheSet} of them in the filtered set.
      </Text>
    </Stack>
  );
}
```

### Hold the selection yourself

Make it with [`useTableSelection`](https://romanhaendler.github.io/umriss-ui/table/api/#useTableSelection) and pass it to [`useTable`](https://romanhaendler.github.io/umriss-ui/table/api/#useTable) as `selection`: the application counts it, fills it and clears it from controls of its own.

```tsx
import { Button, Stack, Text } from "@umriss-ui/core";
import { useTable, useTableSelection } from "@umriss-ui/table";

interface Shipment {
  id: string;
  customer: string;
  tour: string;
}

const SHIPMENTS: Shipment[] = [
  { id: "FP-1004210", customer: "Holloway Garden Supplies", tour: "T-01" },
  { id: "FP-1004223", customer: "Oakridge Pharmacy", tour: "T-01" },
  { id: "FP-1004236", customer: "Brixley Cycles", tour: "T-02" },
  { id: "FP-1004249", customer: "Oakridge Pharmacy", tour: "T-02" },
  { id: "FP-1004262", customer: "Pellham Hardware", tour: "T-03" },
];

const IDS = SHIPMENTS.map((s) => s.id);
const OAKRIDGE = SHIPMENTS.filter((s) => s.customer === "Oakridge Pharmacy").map((s) => s.id);

export default function HoldTheSelectionYourself() {
  const selection = useTableSelection(IDS);
  const { Table, Column } = useTable(SHIPMENTS, { rowKey: (s) => s.id, selection });

  return (
    <Stack gap={3}>
      <Stack direction="row" gap={2} align="center" wrap>
        <Button size="sm" variant="secondary" onClick={() => OAKRIDGE.filter((id) => !selection.isSelected(id)).forEach(selection.toggle)}>
          Select Oakridge Pharmacy
        </Button>
        <Button size="sm" variant="secondary" onClick={selection.clear} disabled={selection.count === 0}>
          Clear
        </Button>
        <Text size="xs" tone="muted">
          {selection.count} of {SHIPMENTS.length} to load
        </Text>
      </Stack>
      <Table selectable ariaLabel="Shipments">
        <Column value="id" label="Shipment" rowHeader />
        <Column value="customer" label="Customer" />
        <Column value="tour" label="Tour" />
      </Table>
    </Stack>
  );
}
```

## When to use something else

- Actions that act on the ticked rows → RowActions

## Keyboard

The keys of [First table](https://romanhaendler.github.io/umriss-ui/table/first-table/#keyboard-first-table), [Checkbox](https://romanhaendler.github.io/umriss-ui/core/checkbox/#keyboard-checkbox) and [Input](https://romanhaendler.github.io/umriss-ui/core/input/#keyboard-input) apply here.

## Props on this page

From `TableProps` — the full table stands on [First table](https://romanhaendler.github.io/umriss-ui/table/first-table/#type-TableProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`selectable`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableProps-selectable) | `boolean` | — | Adds the selection column. "All" means: the filtered set. |
| [`children`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableProps-children) | `ReactNode` | — | Columns, `RowDetail`, `RowActions` and the unbound parts. |

#### Accessibility

| Prop | Type | Default | Description |
|---|---|---|---|
| [`ariaLabel`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableProps-ariaLabel) | `string` | — | Accessible name of the table (not of the outer frame). |

From `TableOptions` — the full table stands on [First table](https://romanhaendler.github.io/umriss-ui/table/first-table/#type-TableOptions).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`rowKey`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableOptions-rowKey) *required* | `(row: Z) => string` | — | A stable key per row – the basis of selection and expansion. |
| [`selection`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableOptions-selection) | [`TableSelection`](https://romanhaendler.github.io/umriss-ui/table/first-table/#type-TableSelection)`<string>` | — | A selection from outside instead of its own – when the application holds it. |

From `TableSnapshot` — the full table stands on [First table](https://romanhaendler.github.io/umriss-ui/table/first-table/#type-TableSnapshot).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`filtered`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableSnapshot-filtered) *required* | `readonly Z[]` | — | The filtered set: what the pre-filter admits and search and filters leave, across all pages. |
| [`selection`](https://romanhaendler.github.io/umriss-ui/table/first-table/#TableSnapshot-selection) *required* | [`TableSelection`](https://romanhaendler.github.io/umriss-ui/table/first-table/#type-TableSelection)`<string>` | — | The selection – its own or the one handed in through `selection`. |

From `FieldColumn` — the full table stands on [Column](https://romanhaendler.github.io/umriss-ui/table/column/#type-FieldColumn).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`value`](https://romanhaendler.github.io/umriss-ui/table/column/#FieldColumn-value) *required* | `K` | — | A field of the row. Supplies the column's `id` at the same time. |

From `ColumnBase` — the full table stands on [Column](https://romanhaendler.github.io/umriss-ui/table/column/#type-ColumnBase).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`label`](https://romanhaendler.github.io/umriss-ui/table/column/#ColumnBase-label) *required* | `string` | — | Names the column in its header, in the column menu and in the header row of the export. |
| [`rowHeader`](https://romanhaendler.github.io/umriss-ui/table/column/#ColumnBase-rowHeader) | `boolean` | — | This column names the row: row header cells, never hideable, the column `stickyRowHeader` pins, and the name by which the row's selection, expander and actions are read out. At most one per table. |

From `SearchProps` — the full table stands on [Search](https://romanhaendler.github.io/umriss-ui/table/search/#type-SearchProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`placeholder`](https://romanhaendler.github.io/umriss-ui/table/search/#SearchProps-placeholder) | `string` | the wording's "Search …" | The placeholder in the field. |

From `ToolbarProps` — the full table stands on [Toolbar](https://romanhaendler.github.io/umriss-ui/table/toolbar/#type-ToolbarProps).

| Prop | Type | Default | Description |
|---|---|---|---|
| [`children`](https://romanhaendler.github.io/umriss-ui/table/toolbar/#ToolbarProps-children) | `ReactNode` | — | Search, column menu, export – on the left in the table toolbar, before the conditions. |

## Known limits

- In [server mode](https://romanhaendler.github.io/umriss-ui/table/server-mode/) “select all” selects the page the table holds.

What umriss deliberately does not build, and why: [ADR-0032](https://romanhaendler.github.io/umriss-ui/what-umriss-ui-is-not/).
