eddev
ACF

Custom Enums

Register reusable typed ACF choice fields without writing a full custom field UI.

Custom enums are shorthand for semi-custom ACF fields. They create a named ACF field type backed by a normal ACF choice control, then expose that value to GraphQL as a generated TypeScript-friendly scalar.

Use them for repeated dropdowns like colour schemes, content tones, states, categories, or display modes.

Register An Enum Field

Put enum registrations in backend/fields/*.php.

<?php

ED()->registerEnumFieldType("content-tone", [
  "label" => "Content Tone",
  "type" => "select",
  "options" => [
    "neutral" => "Neutral",
    "festival" => "Festival",
    "urgent" => "Urgent",
  ],
]);

The enum field type slug is content-tone. Add that field type to any ACF field group where authors should choose one of those values.

type controls the underlying ACF editing control:

TypeUse It For
selectThe default choice for most dropdowns.
button_groupShort visual choices with only a few options.
radioChoices that should stay visible without opening a dropdown.
checkboxMultiple selected values.

checkbox returns a list of enum values in GraphQL. The other types return one value or null.

Query The Field

Once the field has been added to ACF, select it from the relevant view or block query.

query {
  block {
    content_callout {
      tone
    }
  }
}

eddev derives the generated type name from the field slug. content-tone becomes ContentToneOption.

import { defineBlock } from "eddev/blocks"
import type { ContentToneOption } from "@generated-types"

const toneClasses: Record<ContentToneOption, string> = {
  neutral: "theme-neutral",
  festival: "theme-festival",
  urgent: "theme-urgent",
}

export default defineBlock("content/callout", (props) => {
  const tone = props.tone ?? "neutral"

  return <section className={toneClasses[tone]}>...</section>
})

Keep the PHP options and React mapping together during review. If a new enum option is added, TypeScript should force the component to decide how that option renders.

For a more recipe-style dropdown example, see Type-Safe ACF Dropdowns.

On this page