# ColumnMenu

> Package `@umriss-ui/table`, version 0.40.0. Demo page: <https://romanhaendler.github.io/umriss-ui/table/columnmenu/>. 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 menu in which the user shows, hides, reorders and pins the table's columns and picks a grouping (also called a column chooser). Offer it where the table has more columns than everyone needs.

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

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

Every change applies to header, body and footer together. The row header cannot be hidden. A column moves only within its block – pinned at the start, unpinned, pinned at the end – and after a move the focus stays on the button that was pressed.

Where the table can be grouped, the menu offers its groupable columns too, up to three levels ([Grouping](https://romanhaendler.github.io/umriss-ui/table/grouping/)).

## Examples

### Show, hide and arrange

Put a `ColumnMenu` into the toolbar; hiding or moving a column changes header, body and footer together.

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

interface CostCentre {
  name: string;
  owner: string;
  budget: number;
  actual: number;
  forecast: number;
}

/* Thousands of euros, for March. */
const CENTRES: CostCentre[] = [
  { name: "Sales", owner: "Helen Marsh", budget: 142, actual: 138, forecast: 144 },
  { name: "Marketing", owner: "Rafael Ortiz", budget: 68, actual: 79, forecast: 83 },
  { name: "Engineering", owner: "Anika Sørensen", budget: 188, actual: 181, forecast: 186 },
];

export default function ShowHideAndArrange() {
  const { Table, Column } = useTable(CENTRES, { rowKey: (c) => c.name });

  return (
    <Table stickyRowHeader ariaLabel="Cost centres in March">
      <Toolbar>
        <ColumnMenu />
      </Toolbar>
      <Column value="name" label="Cost centre" rowHeader />
      <Column value="owner" label="Owner" />
      <Column value="budget" label="Budget (k€)" />
      <Column value="actual" label="Actual (k€)" aggregate="sum" />
      <Column value="forecast" label="Forecast (k€)" />
    </Table>
  );
}
```

### Pin a column

The pin keys in the menu hold a column at the start or the end while the months scroll sideways – try pinning the year.

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

interface CostCentre {
  name: string;
  months: number[];
}

const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

/* Thousands of euros per month. */
const CENTRES: CostCentre[] = [
  { name: "Sales", months: [141, 139, 138, 144, 142, 140, 136, 131, 143, 145, 147, 150] },
  { name: "Marketing", months: [66, 71, 79, 83, 70, 68, 64, 60, 74, 77, 81, 90] },
  { name: "Customer service", months: [60, 61, 59, 62, 61, 63, 60, 58, 61, 62, 60, 64] },
];

export default function PinAColumn() {
  const { Table, Column } = useTable(CENTRES, { rowKey: (c) => c.name });

  return (
    <Table ariaLabel="Cost centres by month">
      <Toolbar>
        <ColumnMenu />
      </Toolbar>
      <Column value="name" label="Cost centre" rowHeader width={180} />
      {MONTHS.map((month, i) => (
        <Column key={month} id={month} label={month} value={(c) => c.months[i] ?? null} width={80} />
      ))}
      <Column id="year" label="Year" value={(c) => c.months.reduce((a, b) => a + b, 0)} width={90} />
    </Table>
  );
}
```

## Keyboard

| Key | Action |
|---|---|
| `Enter / Space` | On “Columns”: open or close the menu. Inside: tick a column, move it or pin it. |
| `Tab` | Move through the columns' boxes and buttons. |
| `Escape` | Close the menu; the focus returns to “Columns”. |

## API

### `ColumnMenuProps`

| Prop | Type | Default | Description |
|---|---|---|---|
| `size` | [`ToolbarSize`](https://romanhaendler.github.io/umriss-ui/table/columnmenu/#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) |
| `of` | [`TableRef`](https://romanhaendler.github.io/umriss-ui/table/columnmenu/#type-TableRef) | — | The table, when the part does not stand inside it: the return value of `useTable`.<br>Shown in: [Parts outside a toolbar (Toolbar)](https://romanhaendler.github.io/umriss-ui/table/toolbar/#parts-outside-a-toolbar) |

### 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;
};
```
