Skills

Webiny Form Model

Building forms with the FormModel system, field types, renderers, layout, validation...

Install

npx skills add webiny/webiny-js --skill webiny-form-model -g -a claude-code -y
Repository
webiny/webiny-js8.1k
Category
Engineering
Updated
5d ago
License
See repository
Context cost
Mediumabout 3,000 tokens
Runs scripts
No, instructions only

What it does

Building forms with the FormModel system, field types, renderers, layout, validation, conditional rules, computed fields, and dynamic zones. Use this skill when the developer needs to define form fields with the builder API, choose renderers, build layouts with tabs/rows/separators, add validation (Zod or imperative), use conditional visibility/disable rules, create computed fields, or work with object fields and templates (dynamic zones).

Form Model

TL;DR

The Form Model is Webiny's declarative form system. Define fields with a fluent builder API (fields.text(), fields.datetime(), etc.), arrange them with a layout builder (layout.row(), layout.tabs(), etc.), and validate with Zod schemas or imperative rules. Fields support conditional visibility, computed values, reactive context from other fields (.context()), and deeply nested object/list structures with templates (dynamic zones).

Field Types

All fields are created via the fields registry callback. Each builder method returns a chainable builder.

Text

fields.text();

Default renderer: textInput. Value: string | null.

fields.text().label("Title").placeholder("Enter title").required("Title is required")
fields.text().renderer("textarea", { rows: 4 })
fields.text().list().renderer("tags").defaultValue([])
fields.text().list().renderer("textInputs", { addItemLabel: "Add text" })
fields.text().list().renderer("textareas", { addItemLabel: "Add description" })
fields.text().renderer("codeEditor", { language: "html", height: 300 })
fields.text().options([
    { label: "Option A", value: "a" },
    { label: "Option B", value: "b" }
])  // auto-switches to "select" renderer
fields.text().options([...]).renderer("radioButtons")
fields.text().list().options([...]).renderer("checkboxes")

// Dynamic options, callback receives { field, form }, re-evaluated reactively
fields.text().options(({ form }) => {
    const type = form.field("general.type").getValue();
    return getOptionsForType(type);
})

Number

fields.number();

Default renderer: numberInput. Value: number | null. Auto-normalizes to number.

fields.number().label("Count").placeholder("0").required();
fields.number().list().renderer("numberInputs", { addItemLabel: "Add number" });
fields.number().options([
  { label: "Tier 1", value: 100 },
  { label: "Tier 2", value: 200 }
]);
Read the whole SKILL.md on GitHub

More in Engineering