# Search

> Package `@umriss-ui/table`, version 0.40.0. Demo page: <https://romanhaendler.github.io/umriss-ui/table/search/>. 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).

A text field that narrows the table to the rows containing what the user types (also called a quick filter or global filter). Put it in the toolbar, or anywhere on the page.

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

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

It searches the columns whose value is text, and it searches the value, not its presentation; `searchable` on a column adds or removes one. A search term goes back to page one and counts as a restriction – the toolbar shows the matches and “Reset” – but it is not listed as a condition, since the field already shows it.

## Examples

### Find a person

Put a `Search` into the toolbar; it looks through every text column, and the toolbar shows how many rows still match.

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

interface Person {
  name: string;
  role: string;
  team: string;
  capacity: number;
}

const PEOPLE: Person[] = [
  { name: "Maya Lindgren", role: "Product manager", team: "Web", capacity: 32 },
  { name: "Arjun Mehta", role: "Developer", team: "Web", capacity: 40 },
  { name: "Noah Fischer", role: "Designer", team: "Web", capacity: 24 },
  { name: "Hana Sato", role: "Developer", team: "Apps", capacity: 40 },
  { name: "Freya Olsen", role: "Designer", team: "Apps", capacity: 40 },
];

export default function FindAPerson() {
  const { Table, Column } = useTable(PEOPLE, { rowKey: (p) => p.name });

  return (
    <Table ariaLabel="People">
      <Toolbar>
        <Search placeholder="Search people" />
      </Toolbar>
      <Column value="name" label="Name" rowHeader />
      <Column value="role" label="Role" />
      <Column value="team" label="Team" />
      <Column value="capacity" label="Hours a week" />
    </Table>
  );
}
```

### Leave a column out

Set `searchable={false}` on a text column the search should skip – here the team, so “Web” finds the web developer and not the whole team.

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

interface Person {
  name: string;
  role: string;
  team: string;
}

const PEOPLE: Person[] = [
  { name: "Maya Lindgren", role: "Product manager", team: "Web" },
  { name: "Chloe Durand", role: "Web developer", team: "Web" },
  { name: "Kofi Mensah", role: "App developer", team: "Apps" },
  { name: "David Kowalski", role: "QA engineer", team: "Apps" },
];

export default function LeaveAColumnOut() {
  const { Table, Column } = useTable(PEOPLE, { rowKey: (p) => p.name });

  return (
    <Table ariaLabel="People by role">
      <Toolbar>
        <Search placeholder="Search name or role" />
      </Toolbar>
      <Column value="name" label="Name" rowHeader />
      <Column value="role" label="Role" />
      <Column value="team" label="Team" searchable={false} />
    </Table>
  );
}
```

### Search from a card header

Pass the table as `of` and the search can stand anywhere; the match count and “Reset” still appear at the table.

```tsx
import { Card, CardBody, CardHeader } from "@umriss-ui/core";
import { Search, useTable } from "@umriss-ui/table";

interface Person {
  name: string;
  role: string;
}

const PEOPLE: Person[] = [
  { name: "Luis Moreno", role: "Product manager" },
  { name: "Hana Sato", role: "Developer" },
  { name: "Freya Olsen", role: "Designer" },
];

export default function SearchFromACardHeader() {
  const t = useTable(PEOPLE, { rowKey: (p) => p.name });
  const { Table, Column } = t;

  return (
    <Card>
      <CardHeader divider title="Apps team" actions={<Search of={t} placeholder="Search people" aria-label="Search the Apps team" />} />
      <CardBody>
        <Table ariaLabel="Apps team">
          <Column value="name" label="Name" rowHeader />
          <Column value="role" label="Role" />
        </Table>
      </CardBody>
    </Card>
  );
}
```

### Search takes the line

`<Search grow />` takes the rest of the toolbar's line; the column menu and the export stand at its end.

```tsx
import { ColumnMenu, Export, Search, Toolbar, useTable } from "@umriss-ui/table";

interface Person {
  name: string;
  role: string;
  city: string;
}

const PEOPLE: Person[] = [
  { name: "Luis Moreno", role: "Product manager", city: "Lisbon" },
  { name: "Hana Sato", role: "Developer", city: "Osaka" },
  { name: "Freya Olsen", role: "Designer", city: "Bergen" },
];

export default function SearchTakesTheLine() {
  const { Table, Column } = useTable(PEOPLE, { rowKey: (p) => p.name });

  return (
    <Table ariaLabel="Apps team">
      <Toolbar>
        <Search grow placeholder="Search people" />
        <ColumnMenu />
        <Export filename="people.csv" />
      </Toolbar>
      <Column value="name" label="Name" rowHeader />
      <Column value="role" label="Role" />
      <Column value="city" label="City" />
    </Table>
  );
}
```

## When to use something else

- Restrict one column to some of its values or to a range → Filter

## Keyboard

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

## API

### `SearchProps`

| Prop | Type | Default | Description |
|---|---|---|---|
| `placeholder` | `string` | the wording's "Search …" | The placeholder in the field.<br>Shown in: [Find a person](https://romanhaendler.github.io/umriss-ui/table/search/#find-a-person), [Leave a column out](https://romanhaendler.github.io/umriss-ui/table/search/#leave-a-column-out), [Search from a card header](https://romanhaendler.github.io/umriss-ui/table/search/#search-from-a-card-header) and 23 more |
| `size` | [`ToolbarSize`](https://romanhaendler.github.io/umriss-ui/table/search/#type-ToolbarSize)<br>`"sm" \| "md"` | the size of the toolbar it stands in, `"sm"` outside one | The size of the part: `sm` or `md`.<br>Shown in: [Parts outside a toolbar (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#parts-outside-a-toolbar) |
| `grow` | `boolean` | `false` | Take the rest of the toolbar's line: the parts after the search - column menu, export - stand at its end.<br>Shown in: [Search takes the line](https://romanhaendler.github.io/umriss-ui/table/search/#search-takes-the-line) |
| `of` | [`TableRef`](https://romanhaendler.github.io/umriss-ui/table/search/#type-TableRef) | — | The table, when the part does not stand inside it: the return value of `useTable`.<br>Shown in: [Search from a card header](https://romanhaendler.github.io/umriss-ui/table/search/#search-from-a-card-header), [Place it outside the table (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#place-it-outside), [Parts outside a toolbar (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#parts-outside-a-toolbar) and 1 more |

#### Accessibility

| Prop | Type | Default | Description |
|---|---|---|---|
| `aria-label` | `string` | the wording's "Search table" | Accessible name.<br>Shown in: [Search from a card header](https://romanhaendler.github.io/umriss-ui/table/search/#search-from-a-card-header) |

#### Styling

| Prop | Type | Default | Description |
|---|---|---|---|
| `className` | `string` | — | Classes on the field. |

### Types on this page

#### `ToolbarSize`

The size of a toolbar's controls.

```ts
type ToolbarSize = "sm" | "md";
```

#### `TableRef`

What a part without a row type needs from a table – for `of`.

```ts
type TableRef = Omit<TableSnapshot<unknown>, "setFilter" | "conditionOf"> & {
  readonly Table: unknown;
  /** Without a row kind: any id, any condition. */
  setFilter(column: string, condition: unknown): void;
};
```

## Known limits

- In [server mode](https://romanhaendler.github.io/umriss-ui/table/server-mode/) the table searches nothing itself; the term goes to the server in the request.

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