Form fields
Add ordered fields to a form and place related fields on one line.
A form-fields block is one ordered run of fields inside a form. Each field submits its value under its resource-field name. The action schema checks the available names and value types at compile time.
Create this block through form.fields. It has no separate factory.
API
form.fields(...fields: FieldBuilderContract[]): FormFieldsBuilder
| Method | Input | Result |
|---|---|---|
peers |
...FieldName[][] |
Replaces the sets of fields that share a line. |
A field that is not in a peer set stands alone. The renderer controls field width and responsive placement.
Basic fields
Pass fields in display order. Use resource.pick to select existing resource
fields without declaring them again.
import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'
const orders = defineResource('orders', [
fields.text('customerName', { label: 'Customer' }),
fields.number('quantity', { label: 'Quantity' }),
fields.date('placedAt', { label: 'Order date' }),
fields.boolean('expedited', { label: 'Expedited' }),
])
const createOrder = orders.action(
'create',
z.object({
customerName: z.string(),
quantity: z.number(),
placedAt: z.string(),
expedited: z.boolean(),
}),
() => {}
)
orders.view('create', () => {
const formBuilder = form(createOrder)
return formBuilder.setContent([
formBuilder.fields(
...orders.pick(
'customerName',
'quantity',
'placedAt',
'expedited'
)
),
])
})
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "create",
"slots": {
"content": [
{
"kind": "form",
"target": {
"resource": "orders",
"action": "create"
},
"slots": {
"content": [
{
"kind": "form-fields",
"fields": [
{
"kind": "text",
"name": "customerName",
"label": "Customer"
},
{
"kind": "number",
"name": "quantity",
"label": "Quantity"
},
{
"kind": "date",
"name": "placedAt",
"label": "Order date"
},
{
"kind": "boolean",
"name": "expedited",
"label": "Expedited"
}
]
}
]
}
}
]
}
}
}Peer fields
Call peers with one set of related field names. Other fields in the block
remain on separate lines.
import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'
const orders = defineResource('orders', [
fields.text('firstName', { label: 'First name' }),
fields.text('lastName', { label: 'Last name' }),
fields.text('email', { label: 'Email' }),
])
const createOrder = orders.action(
'create',
z.object({
firstName: z.string(),
lastName: z.string(),
email: z.email(),
}),
() => {}
)
orders.view('create', () => {
const formBuilder = form(createOrder)
return formBuilder.setContent([
formBuilder
.fields(
...orders.pick('firstName', 'lastName', 'email')
)
.peers(['firstName', 'lastName']),
])
})
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "create",
"slots": {
"content": [
{
"kind": "form",
"target": {
"resource": "orders",
"action": "create"
},
"slots": {
"content": [
{
"kind": "form-fields",
"fields": [
{
"kind": "text",
"name": "firstName",
"label": "First name"
},
{
"kind": "text",
"name": "lastName",
"label": "Last name"
},
{
"kind": "text",
"name": "email",
"label": "Email"
}
],
"peers": [
[
"firstName",
"lastName"
]
]
}
]
}
}
]
}
}
}Multiple peer sets
Pass more than one set to create multiple peer rows. Calling peers again
replaces all previous sets.
import { form, defineResource, fields } from '@backlit/sdk'
import { z } from 'zod'
const orders = defineResource('orders', [
fields.text('firstName', { label: 'First name' }),
fields.text('lastName', { label: 'Last name' }),
fields.text('email', { label: 'Email' }),
fields.text('phone', { label: 'Phone' }),
fields.text('note', { label: 'Order note' }),
])
const createOrder = orders.action(
'create',
z.object({
firstName: z.string(),
lastName: z.string(),
email: z.email(),
phone: z.string(),
note: z.string(),
}),
() => {}
)
orders.view('create', () => {
const formBuilder = form(createOrder)
return formBuilder.setContent([
formBuilder
.fields(
...orders.pick(
'firstName',
'lastName',
'email',
'phone',
'note'
)
)
.peers(['firstName', 'lastName'], ['email', 'phone']),
])
})
export default orders{
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "orders",
"name": "create",
"slots": {
"content": [
{
"kind": "form",
"target": {
"resource": "orders",
"action": "create"
},
"slots": {
"content": [
{
"kind": "form-fields",
"fields": [
{
"kind": "text",
"name": "firstName",
"label": "First name"
},
{
"kind": "text",
"name": "lastName",
"label": "Last name"
},
{
"kind": "text",
"name": "email",
"label": "Email"
},
{
"kind": "text",
"name": "phone",
"label": "Phone"
},
{
"kind": "text",
"name": "note",
"label": "Order note"
}
],
"peers": [
[
"firstName",
"lastName"
],
[
"email",
"phone"
]
]
}
]
}
}
]
}
}
}Wrap a form-fields block in a panel or section when the fields need a heading, description, or visible surface. See Form for form composition and initial values.
Field roles
setRoles({ fieldName: role }) selects roles for individual fields and replaces
the previous selections. The default role is display in tables and datalists,
and input in form field blocks. See Field roles.
revealWhen(condition) controls the complete block. See Form conditions.