BuildWithMatija
  1. Home
  2. Blog
  3. Payload
  4. Payload CMS Admin UI Components: Complete Glossary

Payload CMS Admin UI Components: Complete Glossary

Authoritative reference for @payloadcms/ui elements & fields (v3.6+). Props, imports, usage examples, and best…

13th November 2025·Updated on:3rd June 2026··
Payload
Payload CMS Admin UI Components: Complete Glossary

Need Help Making the Switch?

Moving to Next.js and Payload CMS? I offer advisory support on an hourly basis.

Book Hourly Advisory

📚 Comprehensive Payload CMS Guides

Detailed Payload guides with field configuration examples, custom components, and workflow optimization tips to speed up your CMS development process.

No spam. Unsubscribe anytime.

Related Posts:

  • •How to Create Dynamic Cross-Collection Dropdowns in Payload CMS v3
  • •Payload CMS Custom Admin Fields and Views: A Guide to @payloadcms/ui
  • •How to Dynamically Filter Payload CMS Relationship Fields Based on Sibling Data in Array Fields
📄View markdown version
0

Frequently Asked Questions

About the author

Matija Žiberna

Matija Žiberna

Full-stack developer, co-founder

AboutResume

Self-taught full-stack developer sharing lessons from building software and startups.

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.

You might be interested in

How to Create Dynamic Cross-Collection Dropdowns in Payload CMS v3
How to Create Dynamic Cross-Collection Dropdowns in Payload CMS v3

29th September 2025

Payload CMS Custom Admin Fields and Views: A Guide to @payloadcms/ui
Payload CMS Custom Admin Fields and Views: A Guide to @payloadcms/ui

16th October 2025

How to Dynamically Filter Payload CMS Relationship Fields Based on Sibling Data in Array Fields
How to Dynamically Filter Payload CMS Relationship Fields Based on Sibling Data in Array Fields

12th October 2025

Contents

  • Using This Reference
  • How to Explore `@payloadcms/ui`
  • Import Conventions
  • Elements
  • Button (`@payloadcms/ui/elements/Button`)
  • Card (`@payloadcms/ui/elements/Card`)
  • Collapsible (`@payloadcms/ui/elements/Collapsible`)
  • Drawer (`@payloadcms/ui/elements/Drawer`)
  • Modal (`@payloadcms/ui/elements/Modal`)
  • ReactSelect (`@payloadcms/ui/elements/ReactSelect`)
  • DatePickerField (`@payloadcms/ui/elements/DatePicker`)
  • DraggableSortable (`@payloadcms/ui/elements/DraggableSortable`)
  • Table (`@payloadcms/ui/elements/Table`)
  • Tooltip (`@payloadcms/ui/elements/Tooltip`)
  • Field Primitives
  • FieldLabel (`@payloadcms/ui/fields/FieldLabel`)
  • FieldDescription (`@payloadcms/ui/fields/FieldDescription`)
  • FieldError (`@payloadcms/ui/fields/FieldError`)
  • TextInput & TextField (`@payloadcms/ui/fields/Text`)
  • Textarea (`@payloadcms/ui/fields/Textarea`)
  • Select (`@payloadcms/ui/fields/Select`)
  • Relationship (`@payloadcms/ui/fields/Relationship`)
  • DateTime (`@payloadcms/ui/fields/DateTime`)
  • Checkbox (`@payloadcms/ui/fields/Checkbox`)
  • Array (`@payloadcms/ui/fields/Array`)
  • Blocks (`@payloadcms/ui/fields/Blocks`)
  • Upload (`@payloadcms/ui/fields/Upload`)
  • Patterns & Best Practices
On this page:
  • Using This Reference
  • How to Explore `@payloadcms/ui`
  • Import Conventions
  • Elements
  • Field Primitives
Build with Matija logo

Build with Matija

Modern websites, content systems, and AI workflows built for long-term growth.

Services

  • Headless CMS Websites
  • Next.js & Headless CMS Advisory
  • AI Systems & Automation
  • Website & Content Audit

Resources

  • Case Studies
  • How I Work
  • Blog
  • Topics
  • CMS Hub
  • E-commerce Hub
  • B2B Website Strategy
  • Dashboard

Headless CMS

  • Payload CMS Developer
  • CMS Migration
  • Multi-Tenant CMS
  • Payload vs Sanity
  • Payload vs WordPress
  • Payload vs Contentful

Get in Touch

Ready to modernize your stack? Let's talk about what you're building.

Book a discovery callContact me →
© 2026Build with Matija•All rights reserved•Privacy Policy•Terms of Service
BuildWithMatija
Get In Touch

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

proptypenotes
buttonStyle`'primary''secondary'
size`'xsmall''small'
icon`'chevron''edit'
iconPosition`'left''right'`
programmaticSubmitbooleanForces form submission for detached buttons.
secondaryActions`secondaryActionsecondaryAction[]`

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

proptypenotes
titlestringRequired heading text.
actionsReactNodeSlot for buttons/pills on the right.
href / onClickstring / () => voidMake entire card interactive.
titleAsElementTypeOverride 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

proptypenotes
headerReactNodeAlways-visible summary content.
initCollapsedbooleanInitial toggle state; defaults to collapsed.
isCollapsedbooleanControl state externally.
onToggle(collapsed: boolean) => voidSync external state or analytics.
collapsibleStyle`'default''error'`

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

proptypenotes
slugstringRequired unique identifier per drawer instance.
titlestringHeader text; shown next to close icon.
HeaderReactNodeReplace the standard header entirely.
gutterbooleanAdds 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

proptypenotes
options`Option[]OptionGroup[]`
isMultibooleanEnable multi-value selection; returns Option[].
isCreatablebooleanAllow creating ad-hoc options.
customPropsCustomSelectPropsHook into Payload’s document drawers for relationships.
value`OptionOption[]`

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

proptypenotes
value`Datestring`
onChange(date: Date) => voidEmits JS Date objects.
readOnlybooleanPrevent user edits but keep styling.
placeholderstringGhost text when empty.
Day/Time picker propsInherits 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

proptypenotes
idsstring[]Array of unique IDs matching child order.
onDragEnd({ moveFromIndex, moveToIndex }) => voidRequired reorder logic.
onDragStart({ id }) => voidOptional analytics/feedback.
classNamestringApply 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

proptypenotes
columnsColumn[]Use Payload’s column definition shape (accessor, Header, etc.).
dataRecord<string, unknown>[]Array of row objects keyed by column accessor.
appearance`'default''condensed'`
BeforeTableReactNodeRender 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

proptypenotes
showbooleanControl visibility manually; defaults to hover trigger.
delaynumberMilliseconds before showing.
position`'top''bottom'`
alignCaret`'left''center'

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

proptypenotes
pathstringRequired unique path for Payload tracking.
valuestringControlled input value.
onChange(event) => voidStandard change handler (or ReactSelect change when hasMany).
AfterInput / BeforeInputReactNodeSlots for adornments.
localizedbooleanAdjusts layout when translating.
placeholder`stringRecord<string, string>`

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

proptypenotes
rowsnumberDefault row count; expand with CSS if needed.
valuestringControlled text.
onChange(ChangeEvent<HTMLTextAreaElement>) => voidUpdate 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

proptypenotes
optionsOptionObject[]Usually from collection config.
hasManybooleanEnables multi-select; returns string[].
isSortablebooleanExposes drag handles for multi values.
placeholder`LabelFunctionstring`

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

proptypenotes
relationTostring[]Collection slugs supported (mono or poly).
appearance`'select''drawer'`
allowCreate / allowEditbooleanEnables “Create new” and “Edit” buttons.
hasManybooleanMulti-relation mode; returns arrays.
filterOptionsFilterOptionsResultPre-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

proptypenotes
checkedbooleanControlled value.
partialCheckedbooleanShow indeterminate state (e.g., bulk toggles).
onChange(value: boolean) => voidEmit 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

proptypenotes
fieldUploadFieldClientUse the config passed into custom components.
pathstringUnique identifier for form state.
onChangeProvided 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.

This glossary is a reference companion to the Payload CMS custom admin UI components guide, which walks through the full workflow of discovering, importing, and building custom fields from scratch. To see these components in production on real Payload projects, explore the Payload CMS live demos.