Layout from backend metadata
When a backend describes how fields are grouped, keep that description separate from the schema and translate it into a layout in the client:
import type { FormLayoutConfig } from "mlform/view";
type ApiLayout = { steps: { id: string; title: string; fields: string[] }[] };
const toLayout = (api: ApiLayout): FormLayoutConfig => ({ kind: "wizard", steps: api.steps.map((step) => ({ id: step.id, title: step.title, children: step.fields.map((field) => ({ kind: "field", field })), })),});The layout is validated when the form is created. A step that names an unknown field, misses a field, or repeats one throws, so creating the view is the check:
let layout: FormLayoutConfig | undefined;try { layout = toLayout(apiLayout); createFormView({ schema, transport, layout }).dispose();} catch (error) { console.warn("Ignoring invalid layout metadata", error); layout = undefined; // fall back to the default stacked layout}mountForm(container, { schema, transport, layout });Field references use exact runtime ids. Explicit ids stay unchanged; make sure the backend uses the same strings as the schema. See Layout config for every rule and error message.
