---
title: "Payload CMS Admin UI Components: Complete Glossary"
slug: "payload-admin-ui-components-glossary-v3-6"
published: "2025-11-13"
updated: "2025-12-25"
categories:
  - "Payload"
tags:
  - "Payload CMS admin UI components"
  - "@payloadcms/ui"
  - "Payload admin components"
  - "admin UI components glossary"
  - "custom admin UI"
  - "Next.js App Router"
  - "useField hook"
  - "DraggableSortable"
  - "react-select"
  - "Payload v3.6"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "payload@3.6+"
  - "next@13+ (App Router / src/app)"
  - "react@18+"
  - "typescript@4.8+"
status: "stable"
llm-purpose: "Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…"
llm-prereqs:
  - "Access to @payloadcms/ui"
  - "Access to Payload CMS"
  - "Access to Next.js"
  - "Access to React"
  - "Access to TypeScript"
llm-outputs:
  - "Completed outcome: Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…"
---

**Summary Triples**
- (@payloadcms/ui elements, are located under, node_modules/@payloadcms/ui/elements/<Component>)
- (Field primitives, are located under, node_modules/@payloadcms/ui/fields/<Component>)
- (Hooks (e.g., useField), should be imported from, '@payloadcms/ui' (package root))
- (Type definitions, can be inspected at, node_modules/@payloadcms/ui/dist/elements/*.d.ts and dist/fields/*.d.ts)
- (Source inspection, recommended action, open nearby index.js files to confirm transitions, context requirements, and composed children)
- (CSS classes shipped with package, should be reused, copy class names from the package's .scss files (e.g., array-field, pill, tooltip) instead of inventing new selectors)
- (Import conventions, for elements, import { Component } from '@payloadcms/ui/elements/Component')
- (Import conventions, for fields, import { Field } from '@payloadcms/ui/fields/Field')
- (Most components, are, safe to use in client and server components when used appropriately in Next.js App Router)
- (Custom admin extensions, should live in, Next.js (payload) routes under src/app to integrate with Payload admin chrome)
- (Maintenance rule, when bumping Payload, update version notes and component prop docs in the glossary)
- (Local examples, demonstrate composition, check src/components/fields/InventoryBatchBulkTable.tsx for real-world usage)

### {GOAL}
Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…

### {PREREQS}
- Access to @payloadcms/ui
- Access to Payload CMS
- Access to Next.js
- Access to React
- Access to TypeScript

### {STEPS}
1. Follow the detailed walkthrough in the article content below.

<!-- llm:goal="Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…" -->
<!-- llm:prereq="Access to @payloadcms/ui" -->
<!-- llm:prereq="Access to Payload CMS" -->
<!-- llm:prereq="Access to Next.js" -->
<!-- llm:prereq="Access to React" -->
<!-- llm:prereq="Access to TypeScript" -->
<!-- llm:output="Completed outcome: Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…" -->

# Payload CMS Admin UI Components: Complete Glossary
> Complete glossary of Payload CMS admin UI components with props, imports & code examples. Find @payloadcms/ui field types, hooks & custom admin solutions fast.
Matija Žiberna · 2025-11-13

This living reference catalogues the high-usage UI primitives exposed by `@payloadcms/ui` so custom admin extensions can look native. It complements the walkthrough in `docs/guides/building-custom-admin-ui-payload-cms-v3.md` and will grow as we document additional components.

## Using This Reference
- Scope: v3.6+ Payload projects using the Next.js App Router in `src/app` with custom admin extensions in `(payload)` routes.
- Audience: developers building bespoke field types, layout chrome, and admin embeds who need parity with Payload styles and behavior.
- Maintenance: update version notes and props when bumping Payload; add new components as they enter regular use.

## How to Explore `@payloadcms/ui`
- **Type definitions:** Browse `node_modules/@payloadcms/ui/dist/elements/*` and `dist/fields/*` for `.d.ts` files that declare props, default behaviors, and helper exports.
- **Source inspection:** Many components re-export JSX from nearby `index.js` files—quickly open them to confirm transitions, context requirements, or composed children.
- **CSS classes:** Each folder ships a matching `.scss` file. Copy class names (e.g., `array-field`, `pill`, `tooltip`) instead of inventing new selectors.
- **Local examples:** The bulk inventory table component at `src/components/fields/InventoryBatchBulkTable.tsx` shows how these pieces fit together in production.

## Import Conventions
- Elements live under `@payloadcms/ui/elements/<Component>`.
- Field primitives live under `@payloadcms/ui/fields/<Component>`.
- Hooks such as `useField` come from the package root: `import { useField } from '@payloadcms/ui'`.
- Most components are safe in both client and server components, but anything that depends on browser APIs (e.g., drag-and-drop, drawers) must be marked `'use client'` at the file top.

---

## Elements

### Button (`@payloadcms/ui/elements/Button`)
**Role:** Primary action trigger with design-system variants and optional icons.

**Import**
```tsx
import { Button } from '@payloadcms/ui/elements/Button'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `buttonStyle` | `'primary' | 'secondary' | 'error' | 'subtle' | 'pill' | 'tab' | 'icon-label' | 'transparent' | 'none'` | Matches Payload button palette; defaults to subtle secondary styling. |
| `size` | `'xsmall' | 'small' | 'medium' | 'large'` | Controls height/padding. |
| `icon` | `'chevron' | 'edit' | 'plus' | 'x'` or `ReactNode` | Use built-in glyphs for consistency. |
| `iconPosition` | `'left' | 'right'` | Place bundled icon before/after text. |
| `programmaticSubmit` | `boolean` | Forces form submission for detached buttons. |
| `secondaryActions` | `secondaryAction | secondaryAction[]` | Renders kebab menu-style sub actions. |

**Usage**
```tsx
<Button
  buttonStyle="primary"
  size="medium"
  icon="plus"
  iconPosition="left"
  onClick={onAddRow}
>
  Add another row
</Button>
```

**Tips**
- Prefer `buttonStyle="primary"` for a single dominant action per block.
- Use the `tooltip` prop for icon-only buttons to preserve accessibility.

### Card (`@payloadcms/ui/elements/Card`)
**Role:** Clickable summary tile with title and optional CTA area.

**Import**
```tsx
import { Card } from '@payloadcms/ui/elements/Card'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `title` | `string` | Required heading text. |
| `actions` | `ReactNode` | Slot for buttons/pills on the right. |
| `href` / `onClick` | `string` / `() => void` | Make entire card interactive. |
| `titleAs` | `ElementType` | Override rendered heading element (e.g., `h3`). |

**Usage**
```tsx
<Card
  title="Inventory batches"
  actions={<Button buttonStyle="secondary">Open</Button>}
  onClick={() => router.push('/admin/inventory')}
/>
```

**Tips**
- Cards inherit spacing from `index.scss`; avoid extra padding wrappers unless necessary.

### Collapsible (`@payloadcms/ui/elements/Collapsible`)
**Role:** Expandable section wrapper used inside array rows and grouped forms.

**Import**
```tsx
import { Collapsible } from '@payloadcms/ui/elements/Collapsible'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `header` | `ReactNode` | Always-visible summary content. |
| `initCollapsed` | `boolean` | Initial toggle state; defaults to collapsed. |
| `isCollapsed` | `boolean` | Control state externally. |
| `onToggle` | `(collapsed: boolean) => void` | Sync external state or analytics. |
| `collapsibleStyle` | `'default' | 'error'` | Applies red border for validation states. |

**Usage**
```tsx
<Collapsible
  className="array-field__row"
  initCollapsed={false}
  header={<span>{rowTitle}</span>}
>
  {children}
</Collapsible>
```

**Tips**
- Combine with `dragHandleProps` from `DraggableSortable` to make rows draggable while preserving toggles.

### Drawer (`@payloadcms/ui/elements/Drawer`)
**Role:** Right-side overlay for nested editing (mirrors Payload relationship drawers).

**Import**
```tsx
import { Drawer, DrawerToggler } from '@payloadcms/ui/elements/Drawer'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `slug` | `string` | Required unique identifier per drawer instance. |
| `title` | `string` | Header text; shown next to close icon. |
| `Header` | `ReactNode` | Replace the standard header entirely. |
| `gutter` | `boolean` | Adds internal padding. |

**Usage**
```tsx
<Drawer slug="product-selector" title="Select product" gutter>
  <ProductList onSelect={handleSelect} />
</Drawer>

<DrawerToggler slug="product-selector">
  <Button buttonStyle="secondary">Open drawer</Button>
</DrawerToggler>
```

**Tips**
- Wrap component file with `'use client'`; drawers rely on window APIs.
- Use `formatDrawerSlug` when nesting drawers to avoid collisions.

### Modal (`@payloadcms/ui/elements/Modal`)
**Role:** Faceless UI modal re-export for global overlays.

**Import**
```tsx
import { Modal, useModal } from '@payloadcms/ui/elements/Modal'
```

**Usage**
```tsx
const { toggleModal } = useModal()

<Modal slug="confirm-reset">
  <div className="modal__content">
    <h2>Reset filters?</h2>
    <Button buttonStyle="primary" onClick={onConfirm}>Confirm</Button>
  </div>
</Modal>

<Button onClick={() => toggleModal('confirm-reset', true)}>Reset filters</Button>
```

**Tips**
- Register modals once near the layout root to ensure portal context matches Payload’s admin shell.

### ReactSelect (`@payloadcms/ui/elements/ReactSelect`)
**Role:** Styled `react-select` adapter used across select and relationship fields.

**Import**
```tsx
import { ReactSelect, type Option } from '@payloadcms/ui/elements/ReactSelect'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `options` | `Option[] | OptionGroup[]` | Required choices with `label` + `value`. |
| `isMulti` | `boolean` | Enable multi-value selection; returns `Option[]`. |
| `isCreatable` | `boolean` | Allow creating ad-hoc options. |
| `customProps` | `CustomSelectProps` | Hook into Payload’s document drawers for relationships. |
| `value` | `Option | Option[]` | Controlled value(s). |

**Usage**
```tsx
<ReactSelect
  options={products}
  value={selectedProduct}
  isSearchable
  isClearable
  onChange={(option) => setSelectedProduct(option as Option<number>)}
/>
```

**Tips**
- Pass `placeholder` strings or `LabelFunction` to localize.
- For full relationship behavior (create/edit drawers), prefer the Relationship field wrapper.

### DatePickerField (`@payloadcms/ui/elements/DatePicker`)
**Role:** Calendar and time input matching Payload’s date fields.

**Import**
```tsx
import { DatePickerField } from '@payloadcms/ui/elements/DatePicker'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `value` | `Date | string` | Controlled value; ISO strings auto-parsed. |
| `onChange` | `(date: Date) => void` | Emits JS `Date` objects. |
| `readOnly` | `boolean` | Prevent user edits but keep styling. |
| `placeholder` | `string` | Ghost text when empty. |
| Day/Time picker props | Inherits from Payload’s `DayPickerProps` and `TimePickerProps`. |

**Usage**
```tsx
<DatePickerField
  value={row.receivedDate}
  onChange={(date) => updateDate(format(date))}
  placeholder="Select received date"
/>
```

**Tips**
- Combine with `DateTimeField` when you need server-managed validation and localization.

### DraggableSortable (`@payloadcms/ui/elements/DraggableSortable`)
**Role:** Drag-and-drop wrapper for reorderable lists tied to `@dnd-kit`.

**Import**
```tsx
import { DraggableSortable } from '@payloadcms/ui/elements/DraggableSortable'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `ids` | `string[]` | Array of unique IDs matching child order. |
| `onDragEnd` | `({ moveFromIndex, moveToIndex }) => void` | Required reorder logic. |
| `onDragStart` | `({ id }) => void` | Optional analytics/feedback. |
| `className` | `string` | Apply Payload spacing helpers (`array-field__draggable-rows`). |

**Usage**
```tsx
<DraggableSortable
  ids={rows.map((row) => row.id)}
  className="array-field__draggable-rows"
  onDragEnd={({ moveFromIndex, moveToIndex }) => reorderRows(moveFromIndex, moveToIndex)}
>
  {rows.map(renderRow)}
</DraggableSortable>
```

**Tips**
- Children should render `data-id` attributes via the `DraggableSortable` item helpers (see existing array field source) for smooth dragging.

### Table (`@payloadcms/ui/elements/Table`)
**Role:** Minimal data table for list-style summaries.

**Import**
```tsx
import { Table } from '@payloadcms/ui/elements/Table'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `columns` | `Column[]` | Use Payload’s column definition shape (`accessor`, `Header`, etc.). |
| `data` | `Record<string, unknown>[]` | Array of row objects keyed by column `accessor`. |
| `appearance` | `'default' | 'condensed'` | Adjust row height. |
| `BeforeTable` | `ReactNode` | Render filters/action bars above the table. |

**Usage**
```tsx
<Table
  appearance="condensed"
  columns={columns}
  data={rows}
/>
```

**Tips**
- For orderable tables, use the companion `OrderableTable` export in the same folder.

### Tooltip (`@payloadcms/ui/elements/Tooltip`)
**Role:** Hover/focus tooltip used for icon buttons and status pills.

**Import**
```tsx
import { Tooltip } from '@payloadcms/ui/elements/Tooltip'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `show` | `boolean` | Control visibility manually; defaults to hover trigger. |
| `delay` | `number` | Milliseconds before showing. |
| `position` | `'top' | 'bottom'` | Placement relative to trigger. |
| `alignCaret` | `'left' | 'center' | 'right'` | Align pointer.

**Usage**
```tsx
<Tooltip position="top" delay={150}>
  <Button buttonStyle="icon-label" icon="info" aria-label="More info" />
</Tooltip>
```

**Tips**
- Wrap only the trigger element; Tooltip clones its child and wires up events.

---

## Field Primitives

### FieldLabel (`@payloadcms/ui/fields/FieldLabel`)
**Role:** Standardized label element with required indicator support.

**Import**
```tsx
import { FieldLabel } from '@payloadcms/ui/fields/FieldLabel'
```

**Usage**
```tsx
<FieldLabel
  htmlFor="bulkRows"
  label="Bulk inventory batches"
/>
```

**Notes**
- Accepts Payload’s `GenericLabelProps`, including `localized` and `required` flags.
- Pair with `FieldDescription` for helper text.

### FieldDescription (`@payloadcms/ui/fields/FieldDescription`)
**Role:** Helper text block with consistent spacing and subdued color.

**Import**
```tsx
import { FieldDescription } from '@payloadcms/ui/fields/FieldDescription'
```

**Usage**
```tsx
<FieldDescription
  path="bulkRows"
  description="Add one row per product variant."
/>
```

**Notes**
- The `path` is used by Payload tooling for error linking; keep it stable.

### FieldError (`@payloadcms/ui/fields/FieldError`)
**Role:** Inline error message styled to match Payload validations.

**Import**
```tsx
import { FieldError } from '@payloadcms/ui/fields/FieldError'
```

**Usage**
```tsx
<FieldError
  message="Quantity must be greater than zero"
/>
```

**Notes**
- Render conditionally when `showError` flags trigger within field components.

### TextInput & TextField (`@payloadcms/ui/fields/Text`)
**Role:** Single-line input primitive and full field wrapper tied to form state.

**Import**
```tsx
import { TextInput } from '@payloadcms/ui/fields/Text'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `path` | `string` | Required unique path for Payload tracking. |
| `value` | `string` | Controlled input value. |
| `onChange` | `(event) => void` | Standard change handler (or `ReactSelect` change when `hasMany`). |
| `AfterInput` / `BeforeInput` | `ReactNode` | Slots for adornments. |
| `localized` | `boolean` | Adjusts layout when translating. |
| `placeholder` | `string | Record<string, string>` | Supports localized placeholders. |

**Usage (controlled input)**
```tsx
<TextInput
  path={`${row.id}-totalStock`}
  value={row.totalStock ?? ''}
  onChange={(event) => updateRow(row.id, event.target.value)}
  placeholder="Enter quantity"
  required
/>
```

**Tips**
- When building full custom fields, use `useField` to sync values with Payload and pass the `path` consistently.

### Textarea (`@payloadcms/ui/fields/Textarea`)
**Role:** Multi-line text area with Payload typography.

**Import**
```tsx
import { TextareaInput } from '@payloadcms/ui/fields/Textarea'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `rows` | `number` | Default row count; expand with CSS if needed. |
| `value` | `string` | Controlled text. |
| `onChange` | `(ChangeEvent<HTMLTextAreaElement>) => void` | Update state. |

**Usage**
```tsx
<TextareaInput
  path="notes"
  value={notes}
  onChange={(event) => setNotes(event.target.value)}
  placeholder="Optional notes"
/>
```

### Select (`@payloadcms/ui/fields/Select`)
**Role:** Payload-managed select field leveraging `ReactSelect` styles.

**Import**
```tsx
import { SelectInput } from '@payloadcms/ui/fields/Select'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `options` | `OptionObject[]` | Usually from collection config. |
| `hasMany` | `boolean` | Enables multi-select; returns `string[]`. |
| `isSortable` | `boolean` | Exposes drag handles for multi values. |
| `placeholder` | `LabelFunction | string` | Mirror config placeholders. |

**Usage**
```tsx
<SelectInput
  path="deliveryDate"
  name="deliveryDate"
  options={dateOptions}
  value={currentDateId}
  onChange={(option) => setCurrentDate(option?.value)}
/>
```

### Relationship (`@payloadcms/ui/fields/Relationship`)
**Role:** Fetch-on-demand relation picker with optional drawer editing.

**Import**
```tsx
import { RelationshipField } from '@payloadcms/ui/fields/Relationship'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `relationTo` | `string[]` | Collection slugs supported (mono or poly). |
| `appearance` | `'select' | 'drawer'` | Inline dropdown vs. open drawer. |
| `allowCreate` / `allowEdit` | `boolean` | Enables “Create new” and “Edit” buttons. |
| `hasMany` | `boolean` | Multi-relation mode; returns arrays. |
| `filterOptions` | `FilterOptionsResult` | Pre-filter server results. |

**Usage**
```tsx
<RelationshipField
  path="product"
  field={fieldConfig}
  relationTo={['products']}
  hasMany={false}
  allowEdit
  allowCreate
  value={currentProduct}
  onChange={setCurrentProduct}
/>
```

**Tips**
- Use `maxResultsPerRequest` to balance performance when large collections exist.

### DateTime (`@payloadcms/ui/fields/DateTime`)
**Role:** Full Payload date field wrapper including timezone + validation.

**Import**
```tsx
import { DateTimeField } from '@payloadcms/ui/fields/DateTime'
```

**Usage**
```tsx
<DateTimeField
  path="receivedDate"
  field={fieldConfig}
  value={valueFromForm}
  onChange={setValue}
/>
```

**Notes**
- Automatically wires `DatePickerField`; rely on it when you need Payload’s default min/max validation and timezone handling baked in.

### Checkbox (`@payloadcms/ui/fields/Checkbox`)
**Role:** Styled checkbox with tri-state support.

**Import**
```tsx
import { CheckboxField } from '@payloadcms/ui/fields/Checkbox'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `checked` | `boolean` | Controlled value. |
| `partialChecked` | `boolean` | Show indeterminate state (e.g., bulk toggles). |
| `onChange` | `(value: boolean) => void` | Emit selection state. |

**Usage**
```tsx
<CheckboxField
  path="confirm"
  checked={isConfirmed}
  onChange={setConfirmed}
  field={fieldConfig}
/>
```

### Array (`@payloadcms/ui/fields/Array`)
**Role:** Native array field wrapper with add/remove controls and draggable rows.

**Import**
```tsx
import { ArrayField } from '@payloadcms/ui/fields/Array'
```

**Usage**
```tsx
<ArrayField
  path="bulkRows"
  field={fieldConfig}
  value={valueFromForm}
  validate={fieldConfig.validate}
/>
```

**Notes**
- Combine with `DraggableSortable` classes (`array-field`, `array-field__header`, `array-field__draggable-rows`) when creating bespoke layouts that still resemble core arrays.

### Blocks (`@payloadcms/ui/fields/Blocks`)
**Role:** Stackable content blocks with drawer-based block chooser.

**Import**
```tsx
import { BlocksField } from '@payloadcms/ui/fields/Blocks'
```

**Usage**
```tsx
<BlocksField
  path="contentBlocks"
  field={fieldConfig}
/>
```

**Notes**
- Components such as `BlocksDrawer` and `BlockRow` live in the same folder if you need deeper customization.

### Upload (`@payloadcms/ui/fields/Upload`)
**Role:** File upload picker with thumbnail preview, relationship drawer, and server-driven validation.

**Import**
```tsx
import { UploadField } from '@payloadcms/ui/fields/Upload'
```

**Key props**
| prop | type | notes |
| --- | --- | --- |
| `field` | `UploadFieldClient` | Use the config passed into custom components. |
| `path` | `string` | Unique identifier for form state. |
| `onChange` | Provided via Payload; typically not replaced manually. |

**Usage**
```tsx
<UploadField
  path="galleryHero"
  field={fieldConfig}
/>
```

**Tips**
- Access the exported `UploadInput` directly for lightweight file pickers without the full field chrome.

---

## Patterns & Best Practices
- **Sync with `useField`:** For bespoke components, call `const { value, setValue, showError } = useField({ path })` and pass `showError` to inputs that support it.
- **Respect `path`:** Payload’s form state, localization, and validation rely on consistent `path` strings; do not reuse them across siblings.
- **Leverage CSS utilities:** Copy existing class names (`pill`, `gutter--left`, `toolbar`, etc.) from `.scss` files to inherit spacing without bespoke CSS.
- **Accessibility:** All elements supply ARIA hooks. Keep `aria-label`/`htmlFor`/`aria-describedby` attributes wired when wrapping components.
- **Live updates:** When upgrading Payload, re-run `pnpm install` and diff `node_modules/@payloadcms/ui/dist` to spot new components or prop changes to mirror here.

## LLM Response Snippet
```json
{
  "goal": "Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…",
  "responses": [
    {
      "question": "What does the article \"Payload CMS Admin UI Components: Complete Glossary\" cover?",
      "answer": "Payload CMS admin UI components: quick reference of @payloadcms/ui elements and field primitives (v3.6+). Learn props, imports, and best practices — read…"
    }
  ]
}
```