---
id: "packages/active-grid/api/cells"
title: "Cells"
description: "BadgeCell, DateCell, ExpanderCell, getExpanderColumn and 5 more: generated from the source of active-grid."
url: "/packages/active-grid/api/cells"
locale: "en"
revision: "g0mvjxwj5c-88bdbe1c:cells"
---

# Cells

Exported by `@workspace/active-grid`. Generated from the package source; part of [the index of every export](/packages/active-grid/api).

## `BadgeCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `value` | `CategoricalCellValue` | yes | The categorical value: a string, number or boolean, exactly as broad as what `body-cell.tsx` passes through.  `labelMap` is looked up on the **text key** (`String(value)`), so a boolean column keys on `'true'` / `'false'` -- the same shape `meta.filterOptions` and `meta.statusTones` already use. |
| `className` | `string` | no |  |
| `labelMap` | `Record<string, string>` | no |  |

## `DateCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `value` | `string \| number \| Date \| null \| undefined` | yes |  |
| `className` | `string` | no |  |
| `locale` | `Locale` | no | date-fns locale object. Omitted? Then the cell follows the language of the grid itself (`locale`/`calendarLocale` on `<ActiveGrid>`), just like the date filter in the column header. |
| `preset` | `DatePreset` | no | The preset name, or nothing to inherit the **ordinary human date form** of the grid's presentation. Without a resolved form the platform fallback `SHORT_TEXTUAL` applies.  A preset, never a free date-fns pattern. The default is the same resolved form `formatSemanticDate` uses, so the `date` column type and this cell cannot render one semantics in two forms. |
| `semantic` | `"date-only" \| "datetime"` | no | What the value means, and therefore how it is read.  - `'date-only'` (default): a **calendar fact** -- date of birth, start date, contract, policy or pension date. The cell shows the same day in every time zone. - `'datetime'`: a **moment** -- `createdAt`, an audit or execution moment. The cell shows that in the zone of the reader, because that is what a moment is supposed to do.  Date-only is the default because that is what this cell gets in practice: `body-cell.tsx` renders it for columns with `meta.filterType: 'date'`, and a column that really shows a moment goes through the `dateTime` preset, which brings its own `valueFormatter` and therefore never reaches this cell.  Never read a date-only value with `new Date(value)`: an ISO date-only string is UTC midnight, and west of UTC it formats as the previous day. |

## `ExpanderCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `row` | `Row<TData>` | yes |  |

## `LinkCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `href` | `string \| ((value: string) => string)` | yes |  |
| `value` | `string \| null \| undefined` | yes | The link text, and at the same time the argument of an `href` function.  Stays `string`: a link carries text. The guard below is however the same as in `BadgeCell`, so that a cast-in `0` does not silently remove a cell. |
| `className` | `string` | no |  |
| `isExternal` | `boolean` | no |  |

## `SelectionCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `checked` | `boolean` | yes |  |
| `onCheckedChange` | `(checked: boolean) => void` | yes |  |
| `className` | `string` | no |  |

## `StatusCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `tone` | `GridStatusTone` | yes | The generic UI tone. Mandatory: a status cell without a tone is a categorical badge, and `BadgeCell` exists for that.  The mapping from domain value to tone belongs to the caller — in the column configuration through `meta.statusTones`, or here at the call site when the cell value is not a stable key (a derived or translated value). |
| `value` | `string \| null \| undefined` | yes | The already resolved status label.  **Deliberately `string` and not broader.** The key of a status column is `String(value)`, and the mapping key → tone lives in `meta.statusTones`; `body-cell.tsx` resolves that pair together and passes the outcome on here. Widening this type would invite a call site to pass a raw domain value, and thereby put a second key derivation next to the existing one.  The emptiness guard below is nevertheless the same as in `BadgeCell`, as defence in depth: a call site that does push a `false` or `0` through a cast does not lose a cell by it. |
| `className` | `string` | no |  |
| `labelMap` | `Record<string, string>` | no |  |

## `TextCell`

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `value` | `string \| number \| null \| undefined` | yes |  |
| `className` | `string` | no |  |
| `kind` | `GridTextKind` | no | What the text is, for the bidi policy: free text (`text`, the default) takes its direction from its first strong character, a formatted value (`value`) and the grid's own words (`ui`) inherit. |
| `textDirection` | `GridTextDirection` | no | The column's declared `meta.textDirection`; wins for `text` and `value`. |
| `truncate` | `boolean` | no |  |

## Functions, hooks and constants

**getExpanderColumn**: `<TData>() => GridDisplayColumnDef<TData>`

**getSelectionColumn**: `<TData>() => GridDisplayColumnDef<TData>`
