Fields
Fields define behavior and data contracts. They do not render HTML, CSS, icons, or accessibility markup. Your Vue application chooses how every serialized field is presented.
Import fields from the Inertify\Form\Fields namespace and return them from Form::fields():
use Inertify\Form\Fields\TextInput;
TextInput::make('email', 'Email address')
->email()
->required()
->maxLength(255)
->precognitive();
The first argument is the canonical data path. Dotted names are supported. A missing label is generated from the last path segment.
Shared field API
Every class extending Field supports these methods.
| Concern | Methods | Effect |
|---|---|---|
| Content | label(), help(), placeholder() | Functional content exposed to the renderer. Each value may be a string, closure, or null. |
| Initial value | default() | Supplies a value only when binding and explicit data do not provide one. |
| Validation | required(), nullable(), rule(), rules() | Builds the server-side Laravel rule set. Boolean arguments may be closures. |
| Precognition | precognitive() | Marks the field for field-level Precognition validation in Vue. |
| State | disabled(), readonly(), autofocus() | Serializes semantic state. A disabled field is excluded from server validation. |
| Binding | withoutModelBinding(), without(), withModelBinding() | Controls whether Form::bind() reads this field. Password-like fields disable binding automatically. |
| Authorization | authorize(), authorizedWhen(), authorizedUnless() | Removes unauthorized fields from schema, initial data, and validation rules. |
| Visibility | visible(), hidden(), visibleWhen(), hiddenWhen(), visibleWhenIn(), hiddenWhenIn(), visibleWhenAll(), visibleWhenAny(), visibleWhenNot() | Defines server-evaluated and serializable visibility. |
| Hidden transitions | clearWhenHidden() | Tells the Vue engine to clear the value when a visible field becomes hidden. |
| Consumer metadata | dataAttribute(), dataAttributes(), meta() | Adds application-owned attributes or arbitrary serializable metadata. |
| Laravel fluency | when(), unless(), tap() | Comes from Laravel's Conditionable and Tappable traits. Field also supports macros. |
authorize() or application policies for sensitive fields, and always enforce authorization on the server.Visibility operators
visibleWhen() and hiddenWhen() accept =, !=, <, <=, >, >=, in, not_in, contains, empty, not_empty, truthy, and falsy.
Inside a repeater or block, an unqualified dependency first resolves against the current row. Prefix a path with $. to force lookup from the root form data:
TextInput::make('company')
->visibleWhen('employment_type', 'employed');
TextInput::make('tax_id')
->visibleWhen('$.country', 'US');
Build grouped conditions with associative arrays, condition tuples, or the visibility builder:
Textarea::make('details')->visibleWhenAll([
'kind' => 'business',
['employees', '>=', 10],
]);
Textarea::make('reason')->visibleWhenNot(
fn ($visibility) => $visibility->where('archived', true),
);
Multiple visibility calls are combined with and semantics.
Field catalog
The component value is the semantic frontend discriminator serialized to Vue and the key used by createFormRenderer(). It is intentionally independent of the PHP class name.
| PHP class | Serialized component | Submitted value | Field-specific configuration |
|---|---|---|---|
TextInput | Text | Scalar or null | type(), string(), email(), password(), number(), integer(), tel(), url(), color(), search(), date(), datetime(), time(), min(), max(), step(), minLength(), maxLength(), pattern(), mask(), phone(), creditCard(), clearable(), copyable(), viewable(), kbd(), currency(), numberFormat(), parseNumbers(), autocomplete(), enterKeyHint(), inputMode() |
Textarea | Textarea | String or null | minLength(), maxLength() |
Slug | Slug | String or null | All TextInput methods plus from(), separator(), lockOnManualEdit(), onlyWhenEmpty(), updateOnEdit(), lowercase() |
Link | Link | URL string, or { url, label?, target? } | plain(), structured(), withLabel(), withTarget(), requireScheme(), allowedSchemes() |
Hidden | Hidden | Any scalar value or null | Shared methods only |
OtpInput | Otp | String | length(), numeric(), alphanumeric(), password(), mask(), autoSubmit(), webOtp() |
Checkbox | Checkbox | Configured true or false value | trueValue(), falseValue(), indeterminate() |
Toggle | Toggle | Configured on or off value | Checkbox methods plus onValue(), offValue(), onLabel(), offLabel() |
Radio | Radio | One option value or null | Finite choice methods described below |
CheckboxGroup | CheckboxGroup | List of option values | Finite choice methods plus minSelected(), maxSelected() |
Combobox | Combobox | One value, or a list for multiple/tokens mode | Inline, query-backed, and endpoint-backed choice methods described below |
DatePicker | DatePicker | Date string, integer year, or a list for range/multiple mode | single(), multiple(), range(), month(), year(), displayFormat(), valueFormat(), timezone(), minDate(), maxDate(), disabledDates(), presets(), withTime(), use24HourTime(), openTo(), clearable(), firstDayOfWeek() |
TimePicker | TimePicker | Time string | displayFormat(), valueFormat(), minTime(), maxTime(), step(), hourStep(), minuteStep(), secondStep(), disabledValues(), disabledHours(), disabledMinutes(), disabledSeconds(), showSeconds(), use24HourTime(), clearable() |
ColorPicker | ColorPicker | Color string or null | format(), hex(), rgb(), hsl(), alpha(), formats(), swatches(), clearable(), eyedropper(), defaultColor() |
Slider | Slider | Number, or a two-number list in range mode | min(), max(), step(), range(), minStepsBetween(), unit(), marks(), lazy() |
File | File | Native file, secure token, existing-file object, or a list | Upload and file-rule methods described below |
Composer | Composer | String, or { text, attachments } | allowAttachments(), storeWithForm(), reorderable(), file constraints and upload strategy methods |
RichText | RichText | HTML string, optionally with a companion <name>_images token list | maxLength(), imageUploads() |
Repeater | Repeater | List of row objects | schema(), minItems(), maxItems(), addable(), deletable(), reorderable(), defaultItem(), itemLabel(), addButtonText() |
Blocks | Blocks | List of { type, data } objects | blocks(), sets(), set(), minItems(), maxItems(), reorderable() |
KeyValue | KeyValue | Object in keyed mode; list in single mode | keyed(), single(), mode(), keyRules(), valueRules(), keyLabel(), valueLabel(), addLabel(), minItems(), maxItems(), reorderable() |
Submit | Submit | Not included in form data | Submit::make($label, $name), name(), value() |
Presentation-only settings are deliberately absent. For example, textarea rows, grid widths, icons, visual variants, field wrappers, and character-count markup belong to the application renderer.
Choice fields
Radio and CheckboxGroup use finite choices. Their options() source may be an array, collection, traversable value, model class, Eloquent/query builder, or closure. Configure extraction and remapping with:
optionLabel(),optionValue(),optionDescription(),optionDisabled(), andoptionDisabledReason()mapAs(),mapValueAs(), andmapDescriptionAs()searchable(),clearable(), andmultiple()where the field supports them
Radio::make('plan')->options(
Plan::query()->where('active', true),
label: 'name',
value: 'id',
description: 'summary',
);
Finite values receive a Laravel Rule::in() constraint. CheckboxGroup applies it to every list item.
Combobox sources
Combobox supports three source styles:
// Finite options serialized with the field.
Combobox::make('country')->options([
'ua' => 'Ukraine',
'pl' => 'Poland',
]);
// Request-aware Eloquent options serialized into form metadata.
Combobox::make('person_id')->options(
Person::query()->where('active', true),
label: 'name',
value: 'id',
)->perPage(25)->searchable();
// Application-owned JSON endpoint.
Combobox::make('person_id')
->source(route('people.index', absolute: false))
->selectedSource(route('people.index', absolute: false))
->searchParam('search')
->valuesParam('values')
->pageParam('page')
->perPage(25)
->debounce(250)
->searchable();
Mapping includes optionImage(), optionAvatar(), optionBadge(), optionUrl(), optionMetadata(), optionSelectedSuffix(), their map...As() counterparts, groupBy(), mapGroupAs(), and mapOptionAs().
Selection and token behavior includes multiple(), minSelected(), maxSelected(), tokens(), delimiter(), allowDuplicates(), allowCustomValues(), pattern(), maxLength(), createOnBlur(), reorderable(), records(), selected(), exists(), distinct(), and ruleIn().
Endpoint behavior includes params(), filters(), scopes(), perPageParam(), minSearchLength(), preload(), status text methods, createRecordUsing(), createRecordText(), and canCreateRecord().
Nested fields
Repeaters
Repeater child names are relative to each row. The generated Vue path includes the row index, such as projects.0.title.
Repeater::make('projects')->schema([
TextInput::make('title')->required(),
Textarea::make('summary'),
])->defaultItem([
'title' => 'Untitled',
]);
Use a $. prefix when a nested field intentionally reads a root-level path. Defaults are merged into every initial row and into rows appended by the Vue collection controller.
Blocks
Each BlockSet has a stable type and its own schema:
use Inertify\Form\Fields\Blocks;
use Inertify\Form\Fields\BlockSet;
Blocks::make('content')->sets([
BlockSet::make('hero', 'Hero')
->description('A page heading and introduction.')
->schema([
TextInput::make('heading')->required(),
Textarea::make('lead'),
])
->default(['heading' => 'Welcome'])
->maxItems(1),
]);
BlockSet also supports authorization, data attributes, and metadata. Submitted rows use the canonical shape { "type": "hero", "data": { ... } }.
Fieldsets
Fieldset groups fields without adding a data path:
Fieldset::make('Contact details')
->id('contact')
->description('How we can reach you.')
->fields([
TextInput::make('email')->email(),
]);
It supports fields()/schema(), legend(), description(), id(), authorization, visibility, clearWhenHidden(), data attributes, and metadata.
File and content fields
Configure file constraints with image(), accept(), multiple(), minFiles(), maxFiles(), minSize(), maxSize(), dimensions(), minDimensions(), and maxDimensions(). Sizes passed to field constraint methods are in KiB.
Choose exactly one transport strategy:
File::make('document')->storeWithForm();
File::make('avatar')->image();
File::make('archive')->chunked(5 * 1024 * 1024);
File::make('video')->directToStorage('s3');
Additional upload methods include uploadDisk(), partSize(), multipartThreshold(), uploadRoutes(), requireValidatedUploads(), uploadRulesToken(), validateUploadsUsing(), existingFiles(), mediaCollection(), reorderable(), and the custom upload() descriptor hook.
Composer delegates attachment configuration to an internal File contract and exposes the corresponding public strategy and constraint methods. RichText::imageUploads() accepts true or a closure receiving UploadConfig:
RichText::make('body')->imageUploads(
fn (UploadConfig $images) => $images
->image()
->maxSize(2048)
->directToStorage('private'),
);
Custom fields
Extend Field and return a stable component discriminator. Add behavior as serializable metadata or options owned by the custom field:
use Inertify\Form\Fields\Field;
final class Money extends Field
{
public function getComponent(): string
{
return 'Money';
}
public function currency(string $currency): static
{
return $this->meta('currency', $currency);
}
}
Register the application renderer under the exact Money key or provide a type-money slot. No PHP presenter registry is required.