Atlas Forms
Building the ViewComponent
The ViewComponent renders in view mode — a read-only display of the stored value. It receives the raw value and should format it for human reading. If you omit ViewComponent, the framework falls back to rendering EditComponent with readOnly={true}.
Props Contract
interface ViewComponentProps {
control: FormControl; // Control config from schema (access settings via control.settings)
value: any; // The stored value to display
mode: FormOperatingMode; // Always 'view' when ViewComponent is used
}
When to Provide a ViewComponent
Provide a dedicated ViewComponent when:
- The raw value needs formatting for human reading (phone number:
15550001234→(555) 000-1234) - The view mode should look significantly different from edit mode (star rating as stars not buttons)
- The edit UI elements (dropdowns, pickers) are unnecessary in view mode and would be confusing
- You need richer display (address formatted as multi-line text block, not a grid of inputs)
Skip ViewComponent for simple controls where the edit component already renders acceptably with readOnly prop.
Phone View Example
import React from 'react';
import type { ViewComponentProps } from '@atlas-forms/types-js';
import { formatPhoneNumber } from '../utils/phoneFormatter';
export const PhoneViewComponent: React.FC<ViewComponentProps> = ({ control, value }) => {
if (!value) return <span className="empty-value">—</span>;
const settings = control.settings ?? {};
const format = settings.format ?? 'international';
const formatted = formatPhoneNumber(value, format);
return (
<div className="phone-view">
<a href={`tel:${value}`} aria-label={`Call ${formatted}`}>
{formatted}
</a>
</div>
);
};
Address View Example
export const AddressViewComponent: React.FC<ViewComponentProps> = ({ value }) => {
if (!value) return <span>—</span>;
const { street, city, state, zipCode } = value;
return (
<address style={{ fontStyle: 'normal' }}>
<div>{street}</div>
<div>{city}, {state} {zipCode}</div>
</address>
);
};
Empty State
Always handle null and undefined values gracefully in the view component. The recommended empty state is an em dash (—) in a muted style, consistent with Atlas Forms built-in display controls:
if (!value || value === '') {
return <span className="text-muted">—</span>;
}
Accessibility in View Mode
View components should still be accessible:
- Use semantic HTML (
<address>,<time>,<a href="tel:...">) - Ensure the label associated with the field in the form wrapper still provides context
- Avoid displaying raw database keys or IDs — resolve to human-readable values