# Table Cells

Source: https://payloadcms.com/docs/ui-components/table-cells

Payload's table-cell components format field values inside Admin Panel tables. Use `DefaultCell` when a custom table should follow Payload's built-in field formatting, or register a custom Cell Component when a column needs purpose-specific output.

This guide covers the table-cell primitives exported from `@payloadcms/ui`. The Field Config shown below is the registration point for a custom cell, not a general guide to Payload fields.

## Import

```tsx
import {
  DateCell,
  DefaultCell,
  RenderDefaultCell,
  useCellProps,
} from '@payloadcms/ui'
import type {
  DefaultCellComponentProps,
  DefaultServerCellComponentProps,
} from 'payload'
```

## Custom cell

A custom Cell Component receives the current value as `cellData` and the complete document as `rowData`. Use the value to apply a distinct visual treatment to each option your field supports.

**Implementation**

```tsx
'use client'

import type { DefaultCellComponentProps } from 'payload'
import { Pill } from '@payloadcms/ui'

const variantLabels = {
  alpha: 'Alpha',
  beta: 'Beta',
  gamma: 'Gamma',
  delta: 'Delta',
  epsilon: 'Epsilon',
} as const

type Variant = keyof typeof variantLabels

const isVariant = (value: unknown): value is Variant =>
  typeof value === 'string' && value in variantLabels

export const CustomCell = ({ cellData }: DefaultCellComponentProps) => {
  const variant = isVariant(cellData) ? cellData : 'other'
  const label = isVariant(cellData)
    ? variantLabels[cellData]
    : String(cellData ?? 'Other')

  return (
    <Pill className={['custom-cell', 'custom-cell--' + variant].join(' ')}>
      {label}
    </Pill>
  )
}
```

**Styling**

Use one shared cell rule and assign color tokens from a stable modifier class for each known value. Values without a modifier use the neutral fallback colors.

```css
.table .custom-cell {
  background: var(--cell-background, var(--theme-elevation-100));
  border: 1px solid var(--cell-border, var(--theme-elevation-250));
  border-radius: 999px;
  color: var(--cell-text, var(--theme-text));
  font-weight: 600;
}

.custom-cell--alpha {
  --cell-background: #eee8ff;
  --cell-border: #a99be8;
  --cell-text: #41317d;
}

.custom-cell--beta {
  --cell-background: #dff1ff;
  --cell-border: #78add1;
  --cell-text: #174d70;
}

.custom-cell--gamma {
  --cell-background: #ffe3f0;
  --cell-border: #d68eae;
  --cell-text: #71334f;
}

.custom-cell--delta {
  --cell-background: #dff5e8;
  --cell-border: #7eb996;
  --cell-text: #245d3b;
}

.custom-cell--epsilon {
  --cell-background: #fff0d9;
  --cell-border: #d2a25d;
  --cell-text: #704914;
}
```

- `--cell-background`: Surface color for a custom value.
- `--cell-text`: Text color for a custom value.
- `--cell-border`: Outline color for a custom value.
- `border-radius`: Shape of the custom value treatment.
- `font-weight`: Emphasis applied to the custom value.

This example derives a stable `custom-cell--{value}` modifier from an allowlist. A shared CSS rule defines the cell treatment, while each modifier supplies its background, text, and border colors. Unexpected values fall back to the neutral Payload theme colors.

Register the component through `admin.components.Cell` on the field whose column it replaces:

```ts
import type { Field } from 'payload'

export const variantField: Field = {
  name: 'variant',
  type: 'select',
  options: ['alpha', 'beta', 'gamma', 'delta', 'epsilon'],
  admin: {
    components: {
      Cell: '/components/CustomCell',
    },
  },
}
```

Use `DefaultCellComponentProps` for a Client Component and `DefaultServerCellComponentProps` for a Server Component. The prop types come from `payload`, while any visual primitives used by the cell—such as `Pill` in this example—come from `@payloadcms/ui`.

## Default field rendering

`DefaultCell` selects Payload's standard renderer for the supplied field type. For types without a specialized renderer, it displays the value directly.

**Implementation**

```tsx
<DefaultCell
  cellData={row.title}
  collectionSlug="posts"
  field={titleField}
  link={false}
  rowData={row}
/>
```

**Styling**

Target the column class generated from each accessor to adjust a built-in cell without replacing its value formatting.

```css
.table .cell-title {
  color: var(--theme-text);
  font-weight: 600;
}

.table .cell-publishedAt {
  color: var(--theme-elevation-600);
}
```

- `color`: Text color for a specific column.
- `font-weight`: Text emphasis for a specific column.

Pass the same field configuration and row data used to build the surrounding column. Set `link` when the value should navigate to the document, or provide `onClick` when the cell performs a custom selection action.

`DateCell` is the specialized date renderer used by `DefaultCell`. It applies the field's `admin.date.displayFormat`, the root Admin date format, and timezone data when configured. Most custom tables should use `DefaultCell` for a date field rather than call `DateCell` directly.

## Advanced cell composition

`RenderDefaultCell` is the lower-level wrapper used by Payload's List View. In addition to rendering `DefaultCell`, it coordinates linked cells with `TableColumnsProvider` and a List Drawer.

`useCellProps` reads the current `DefaultCellComponentProps` from that wrapper. It is useful when replacing Payload's linked-cell output, but it returns `null` outside `RenderDefaultCell`.

For an ordinary custom Cell Component, use the props passed directly to the component instead of adding either API.

## Common props

These are the props most commonly used with `DefaultCell`. See `DefaultCellComponentProps` from `payload` for the complete type.

| Prop              | Type          | Description                                              |
| ----------------- | ------------- | -------------------------------------------------------- |
| `cellData*`       | `unknown`     | Supplies the value for the current field and row.        |
| `collectionSlug*` | `string`      | Identifies the Collection represented by the table.      |
| `field*`          | `ClientField` | Selects Payload's renderer and formatting configuration. |
| `rowData*`        | `RowData`     | Supplies the complete document represented by the row.   |
| `link`            | `boolean`     | Wraps the displayed value in a document link.            |
| `linkURL`         | `string`      | Overrides the URL generated for a linked cell.           |
| `onClick`         | `function`    | Replaces linked behavior with a cell action.             |
| `customCellProps` | `object`      | Supplies project-specific data to a custom cell.         |

_\* An asterisk denotes that a prop is required._

## Accessibility

- Render text alongside color when a custom cell communicates status.
- Use a link only when the cell navigates and a button only when it performs an action.
- Keep custom output concise so the table remains readable at narrow widths.
- Preserve an understandable text value when adding icons or visual formatting.

## Provider requirements

`DefaultCell` and `DateCell` use the Config and Translation providers supplied by the Payload Admin Panel. `RenderDefaultCell` additionally expects Table Columns and List Drawer context. Custom Cell Components registered through a Field Config receive their props from Payload automatically.

See [Fields](/docs/v3/fields/overview.md#cell) for the complete Cell Component extension point and [Table](/docs/v3/ui-components/table.md) for composing rows and columns.
