Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Field intents and generated types

Field intents decide which values render, which values stay in the generated holder, and which values the application must supply during reconstruction. Every non-empty-form field must choose exactly one intent.

IntentGenerated componentStored in holderReconstruction
component(...)YesYesUses the holder value
hiddenNoYesUses the holder value
skipNoNoCaller supplies the source value

Component fields

Use component(...) for fields edited by a GPUI widget:

#[gpui_form(component(gpui_form_collection::input::Input::<_>))]
name: String,

The shape owns construction, rendering, value binding, and the storage policy used by the generated holder. A configured shape expression can customize construction:

#[gpui_form(
    component(gpui_form_collection::select::Select::<_>.searchable(true))
)]
country: Country,

Put default = ... inside component(...) when the holder should start with a field-specific value. A component shape also defines how a non-optional field stores an empty value; see Component shapes.

Hidden fields

Use hidden for values that participate in the holder and conversion without a component:

#[gpui_form(hidden(default = request_context()))]
context: RequestContext,

Hidden fields are useful for non-visual values that may still come from a structured client or application default. They do not create a FormFields member or a FormComponents constructor.

Skipped fields

Use skip for source fields the form does not own:

#[gpui_form(skip)]
created_by: UserId,

Reconstruct a skipped-field model by passing those values to holder.into_original(created_by, ...). If another field can fail conversion, the same method returns Result<Model, Error>. holder.present_fields() provides a typed snapshot of the editable fields for preview or diagnostic UI.

Do not combine skip with component or hidden on the same field.

Form-side value types

Use value(...) when a widget edits a type different from the source field:

#[gpui_form(component(
    gpui_form_collection::input::Input::<_>,
    value(
        type = String,
        from_source = format_account_id,
        try_into_source = parse_account_id,
    )
))]
account_id: AccountId,

Write the base form-side type in type = ...; source optionality determines whether the holder stores an optional value. Both from_source and one reverse conversion are required. Use into_source for an infallible reverse conversion or try_into_source for a function returning Result<Source, Error> where the error implements Debug.

For a struct-level #[koruma(newtype)], value(koruma_newtype) edits the inner value and reconstructs the validated wrapper through Koruma’s public newtype traits.

Generated types

For UserProfile, the generated types have distinct jobs:

TypeUse
UserProfileFormFieldIdentify component-backed fields; each variant’s name() returns the exact source field name.
UserProfileFormFieldsStore the GPUI entities owned by the form view.
UserProfileFormComponentsConstruct component state with methods named after source fields.
UserProfileFormValueHolderStore editable values and defaults, convert back to the model, and expose validation when Koruma integration is enabled.

Hidden and skipped fields do not produce UserProfileFormField variants.