Skip to Content
Delmare Digital
Components

Custom fields

Puck fields for Payload media, colours, backgrounds, spacing, alignment and animation, plus CSS helpers and sidebar layout.

The plugin ships custom Puck fields for the things page components usually need: Payload media, colours, backgrounds, spacing and alignment. Each field has a factory (createMediaField()) that returns a Puck field definition, and a CSS helper that turns its value into styles. Everything here is imported from @delmaredigital/payload-puck/fields.

Field reference

FactoryWhat it edits
createMediaField()An image from the Payload media library
createRichTextField()Puck's native rich text, with colours, font sizes and highlights
createColorPickerField()A colour, with opacity and presets
createBackgroundField()Solid colours, gradients and images
createPaddingField() / createMarginField()Spacing on four sides, linked or unlinked
createBorderField()Border width, style, colour and radius
createDimensionsField()Width and height with constraints
createAlignmentField()Text alignment (left, center, right)
createContentAlignmentField()Position on a visual 3×3 grid
createJustifyContentField() / createAlignItemsField()Flexbox main-axis and cross-axis alignment
createVerticalAlignmentField()An item's alignment within its grid or flex cell
createSizeField()Preset sizes (sm, default, lg) with a custom mode
createWidthField()Full, contained or custom width
createTransformField()Rotate, scale, skew and translate
createAnimationField()Entrance animations
createResponsiveVisibilityField()Show or hide per breakpoint
createResponsiveField()Per-breakpoint overrides (xs, sm, md, lg, xl) for any field
createFolderPickerField()A folder from the page-tree hierarchy
createPageSegmentField()A page's URL segment, slugified
createSlugPreviewField()The computed slug, read-only

The last three are for page-tree. The field components themselves (MediaField, ColorPickerField, BackgroundField and so on) are exported too, for use in your own custom fields.

createMediaField() takes label and apiEndpoint (default '/api/media'). createColorPickerField() takes showOpacity and presets; without presets it uses the theme's colour presets. createPaddingField() takes showUnits.

Usage

components/Hero.tsx
import {
  createMediaField,
  createBackgroundField,
  backgroundValueToCSS,
} from '@delmaredigital/payload-puck/fields'

const HeroConfig = {
  fields: {
    image: createMediaField({ label: 'Background Image' }),
    background: createBackgroundField({ label: 'Overlay' }),
  },
  render: ({ image, background }) => (
    <section style={backgroundValueToCSS(background)}>
      {/* content */}
    </section>
  ),
}

CSS helpers

The helpers turn field values into CSS strings, style objects or class names. Empty-value results depend on the helper: alignmentToFlexCSS() and alignmentToGridCSS() return an empty object ({}), so you can spread them into a style object.

import {
  backgroundValueToCSS,
  paddingValueToCSS,
  marginValueToCSS,
  borderValueToCSS,
  dimensionsValueToCSS,
  colorValueToCSS,
  animationValueToCSS,
  visibilityValueToCSS,
  transformValueToCSS,
  alignmentToFlexCSS,
  alignmentToGridCSS,
  sizeValueToCSS,
  getSizeClasses,
} from '@delmaredigital/payload-puck/fields'

const style = {
  ...backgroundValueToCSS(props.background),
  padding: paddingValueToCSS(props.padding),
  ...dimensionsValueToCSS(props.dimensions),
  ...alignmentToFlexCSS(props.contentAlignment),
  ...sizeValueToCSS(props.size),
}

For email components there are colorValueToEmailCSS, paddingValueToEmailCSS and backgroundValueToEmailCSS; see Email builder. The cn() class-name helper and the value types (ColorValue, PaddingValue, BackgroundValue and so on) are exported from the same entry point.

Content alignment

createContentAlignmentField() gives a visual 3×3 grid, like a d-pad, for positioning content:

components/Banner.tsx
import {
  createContentAlignmentField,
  alignmentToFlexCSS,
} from '@delmaredigital/payload-puck/fields'

const BannerConfig = {
  fields: {
    contentPosition: createContentAlignmentField({ label: 'Content Position' }),
  },
  render: ({ contentPosition }) => (
    <div style={{
      display: 'flex',
      minHeight: '400px',
      ...alignmentToFlexCSS(contentPosition),
    }}>
      <div>Positioned content</div>
    </div>
  ),
}

Pick the helper for the container you render:

  • alignmentToFlexCSS(): for flexbox containers (justify-content and align-items).
  • alignmentToGridCSS(): for grid containers (justify-content and align-content).
  • alignmentToPlaceSelfCSS(): for individual grid items (place-self).
  • alignmentToTailwind(): returns Tailwind classes (justify-* and items-*).

Field layout

createFieldLayout() arranges a component's sidebar fields into Puck 0.24 tabs and groups. It only changes the editor sidebar: props, saved data and rendering are untouched. Fields the layout doesn't mention are added to the first tab rather than hidden. Use the same tab labels across components and the open tab stays selected as editors move between them.

components/Hero.tsx
import { createFieldLayout } from '@delmaredigital/payload-puck/fields'

const HeroConfig = {
  fields: { /* _reset, heading, image, background, border, margin, ... */ },
  renderFields: createFieldLayout({
    pinned: ['_reset'], // shown above the tabs
    tabs: [
      { label: 'General', fields: ['heading', 'image'] },
      { label: 'Style', fields: [{ group: 'Box', fields: ['background', 'border'] }] },
      { label: 'Layout', fields: ['margin'] },
    ],
  }),
  render: /* ... */,
}

Prop

Type

Edit this page on GitHub

On this page