Skip to main content

Display Fields

Display fields show content without collecting user input. Use them for headings, dividers, informational text, computed metrics, and alerts. See Display Fields in the Forma Spec for the specification-level reference.

ComponentMap Setup

componentMap.tsx
import type { ComponentMap } from "@fogpipe/forma-react";

const components: ComponentMap = {
text: TextInput,
number: NumberInput,
// ... other field types
display: DisplayField,
};

Component Props

Display field components receive DisplayComponentProps:

PropertyTypeDescription
contentstring | undefinedStatic text content from the field definition
sourceValueunknown | undefinedResolved value from a computed field referenced by source
formatstring | undefinedFormat hint for displaying numeric values
variantstring | undefinedPresentation variant (e.g., "heading", "divider", "metric")
variantConfigRecord<string, unknown>Variant-specific configuration
valueneverNot available on display fields
onChangeneverNot available on display fields
labelstringDisplay label
visiblebooleanWhether the field is visible
namestringField path/identifier

Static Display

Display fields with content render text defined in the Forma spec:

{
"fields": {
"welcome_message": {
"type": "display",
"label": "Welcome",
"content": "Please fill out this form to complete your registration.",
"variant": "text"
}
}
}

Computed Display

Display fields can reference computed values using the source property. The library resolves the value and passes it as field.sourceValue:

{
"fields": {
"total_display": {
"type": "display",
"label": "Total",
"source": "total",
"format": "currency",
"variant": "metric"
}
},
"computed": {
"total": { "expression": "quantity * price" }
}
}

Currency formatting respects meta.locale and meta.currency when set. You can also override formatting at the renderer level via the formatOptions prop on FormRenderer.

Variant Routing

Use field.variant to render different presentations:

VariantPurposevariantConfig Keys
textBody text or paragraphs (default)-
headingSection headingslevel (2-5)
dividerVisual separator between sections-
metricLarge numeric display with optional unitunit (e.g., "kg", "USD")
alertContextual alert with severityseverity ("info", "warning", "error", "success")
calloutInformational callout with optional iconicon (e.g., "info", "lightbulb", "shield")
summaryCard-based summary display-

Implementation

Route to sub-components based on variant, with a fallback to the default text display:

DisplayField.tsx
import type { DisplayComponentProps } from "@fogpipe/forma-react";

function DisplayField({ field }: DisplayComponentProps) {
if (!field.visible) return null;

switch (field.variant ?? "text") {
case "heading": {
const level = (field.variantConfig?.level as number) ?? 3;
const Tag = `h${Math.min(Math.max(level, 2), 5)}` as
| "h2"
| "h3"
| "h4"
| "h5";
return <Tag>{field.content ?? field.label ?? ""}</Tag>;
}
case "divider":
return <hr />;
case "metric": {
const value =
field.sourceValue != null ? String(field.sourceValue) : "\u2014";
return (
<div>
{field.label && <p className="text-sm text-muted">{field.label}</p>}
<p className="text-2xl font-semibold">{value}</p>
</div>
);
}
default: {
const body =
field.sourceValue != null ? String(field.sourceValue) : field.content;
return (
<div>
{field.label && <p className="font-medium">{field.label}</p>}
{body && <p>{body}</p>}
</div>
);
}
}
}