Presentations
Page, inline, modal, and drawer surfaces, and the overlay primitives behind them.
A presentation is a named bundle controlling how a form surfaces: in the page flow, or as an overlay, and whether it dismisses on success. Four ship by default:
| Name | Surface | Behavior |
|---|---|---|
page | In flow (default) | Renders inline in the page. |
inline | Embedded | Same as page, semantically scoped to an embedded slot. |
modal | Overlay | Centered dialog; dismisses on success. |
drawer | Overlay | Side panel; dismisses on success. |
Choosing a presentation
Presentation is a rendering concern, decided by the code that renders the form, not stored on the form document. Pass the presentation prop, as a registered name or an inline object (page is the default when omitted):
<Form form={form} presentation="modal" onClose={() => setOpen(false)} title="Contact us" />onClose is forwarded to the presentation's Wrapper so the host controls closing; title becomes the overlay's accessible name.
Custom presentations
Register at render time through the presentations prop, following the opt-in convention (false removes a built-in, an object adds or replaces one). An overlay presentation is a full FormPresentation with the React Wrapper it needs:
import { DialogSurface, type FormPresentation } from '@10x-media/form-builder/react'
const fullscreen: FormPresentation = {
name: 'fullscreen',
label: 'Fullscreen',
surface: 'overlay',
density: 'comfortable',
dismissOnSuccess: true,
Wrapper: ({ open, onClose, title, children }) => (
<DialogSurface open={open} onClose={onClose} label={title} surface="fullscreen">
{children}
</DialogSurface>
),
}
<Form form={form} presentations={{ fullscreen }} presentation="fullscreen" onClose={close} />Overlay primitives
The built-in modal and drawer are thin compositions of exported primitives; take exactly the pieces you need:
import {
DialogSurface, // backdrop + role=dialog/aria-modal + focus trap + scroll lock + dismiss
Backdrop, // full-viewport scrim with a data-fb-backdrop hook
useFocusTrap, // keep Tab/Shift-Tab inside a container
useScrollLock, // lock body scroll while open
useDismiss, // wire Escape and outside-click to a callback
} from '@10x-media/form-builder/react'DialogSurface ships the accessible baseline: role="dialog" with aria-modal, initial focus on open and focus restore on close, scroll lock, Escape and outside-click dismiss (both configurable), and a labelled close button. The drawer variant adds a surface="drawer" data hook for CSS positioning. Overlays use position: fixed (no portal yet).
Planned: a portal for overlays, popover and exit-intent triggers, and styled shadcn wrappers.