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
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:
| Property | Type | Description |
|---|---|---|
content | string | undefined | Static text content from the field definition |
sourceValue | unknown | undefined | Resolved value from a computed field referenced by source |
format | string | undefined | Format hint for displaying numeric values |
variant | string | undefined | Presentation variant (e.g., "heading", "divider", "metric") |
variantConfig | Record<string, unknown> | Variant-specific configuration |
value | never | Not available on display fields |
onChange | never | Not available on display fields |
label | string | Display label |
visible | boolean | Whether the field is visible |
name | string | Field 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:
| Variant | Purpose | variantConfig Keys |
|---|---|---|
text | Body text or paragraphs (default) | - |
heading | Section headings | level (2-5) |
divider | Visual separator between sections | - |
metric | Large numeric display with optional unit | unit (e.g., "kg", "USD") |
alert | Contextual alert with severity | severity ("info", "warning", "error", "success") |
callout | Informational callout with optional icon | icon (e.g., "info", "lightbulb", "shield") |
summary | Card-based summary display | - |
Implementation
Route to sub-components based on variant, with a fallback to the default text display:
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>
);
}
}
}