| name | moonshine-fields-v3 |
| description | Use when working with any MoonShine v3 field type, relationship fields, field validation, field lifecycle, custom apply logic, field modes, or creating custom fields. |
MoonShine v3 Fields
Field Concept
Fields are the core building blocks of the MoonShine admin panel. They are used in:
FormBuilder for building forms
TableBuilder for creating tables
ModelResource for filters
- Custom pages and Blade views
Every field is created via the static make() method:
use MoonShine\UI\Fields\Text;
Text::make('Title')
Text::make('Title', 'title')
Text::make('Title', 'first_name', fn($item) => $item->first_name . ' ' . $item->last_name)
Constructor signature for all fields:
make(Closure|string|null $label = null, ?string $column = null, ?Closure $formatted = null)
Fields in MoonShine are NOT tied to a model (except Slug and relationship fields).
Field Modes
Every field has three visual states:
| Mode | Method | When Used | Description |
|---|
| Default | defaultMode() | Forms | Renders as HTML form element (<input>, <select>, etc.) |
| Preview | previewMode() | Tables, detail views | Displays formatted value (images as thumbnails, dates formatted, etc.) |
| Raw | rawMode() | Export | Outputs the original unmodified value |
Text::make('Title')->defaultMode()
Text::make('Title')->previewMode()
Text::make('Title')->rawMode()
Field Lifecycle
In FormBuilder (saving)
- Field declared in resource
- Field enters FormBuilder
- FormBuilder fills the field (
fill())
- FormBuilder renders the field
- On submit:
beforeApply() -> apply() -> model save() -> afterApply()
In TableBuilder (display)
- Field enters TableBuilder in preview mode
- TableBuilder iterates data, fills each field
- TableBuilder renders rows with field previews
In Export
- Field enters Handler in raw mode
- Handler iterates data, fills fields, generates table from raw values
Apply Lifecycle
Fields modify incoming data during the "apply" phase. For model saving:
Text::make('Thumbnail by link', 'thumbnail')
->onApply(function(Model $item, $value, Text $field) {
if ($value) {
$item->thumbnail = Storage::put('thumbnail.jpg', file_get_contents($value));
}
return $item;
})
For filters (QueryBuilder):
Text::make('Title')
->onApply(function(Builder $query, mixed $value, Text $field) {
$query->where('title', $value);
})
Related methods: onBeforeApply(), onAfterApply(), canApply().
Quick Reference: All Field Types
Basic Input Fields
| Field | Namespace | Description |
|---|
Text | MoonShine\UI\Fields\Text | Text input (<input type="text">) |
Textarea | MoonShine\UI\Fields\Textarea | Multi-line text |
Number | MoonShine\UI\Fields\Number | Numeric input with min/max/step |
Password | MoonShine\UI\Fields\Password | Password input (auto-hashes on apply) |
PasswordRepeat | MoonShine\UI\Fields\PasswordRepeat | Confirmation field (no apply) |
Email | MoonShine\UI\Fields\Email | Email input |
Phone | MoonShine\UI\Fields\Phone | Phone input with mask support |
Url | MoonShine\UI\Fields\Url | URL input with link preview |
Color | MoonShine\UI\Fields\Color | Color picker |
Date | MoonShine\UI\Fields\Date | Date/datetime input |
DateRange | MoonShine\UI\Fields\DateRange | Date range (from/to) |
Range | MoonShine\UI\Fields\Range | Numeric range (from/to) |
RangeSlider | MoonShine\UI\Fields\RangeSlider | Range with slider UI |
Slug | MoonShine\Laravel\Fields\Slug | Auto-generated slug (model-dependent) |
ID | MoonShine\UI\Fields\ID | Primary key (hidden in forms) |
Hidden | MoonShine\UI\Fields\Hidden | Hidden input |
HiddenIds | MoonShine\UI\Fields\HiddenIds | Collects selected IDs for bulk actions |
Position | MoonShine\UI\Fields\Position | Row numbering in repeating elements |
Preview | MoonShine\UI\Fields\Preview | Read-only display (badge, boolean, link, image) |
Template | MoonShine\UI\Fields\Template | Empty field built via fluent interface |
Selection Fields
| Field | Namespace | Description |
|---|
Select | MoonShine\UI\Fields\Select | Dropdown (options, async, searchable, multiple) |
Enum | MoonShine\UI\Fields\Enum | Select from PHP Enum |
Checkbox | MoonShine\UI\Fields\Checkbox | Checkbox (on/off values) |
Switcher | MoonShine\UI\Fields\Switcher | Toggle switch (extends Checkbox) |
File & Editor Fields
| Field | Namespace | Description |
|---|
File | MoonShine\UI\Fields\File | File upload (disk, dir, extensions, multiple) |
Image | MoonShine\UI\Fields\Image | Image upload with preview |
Code | Package moonshine/ace | Code editor (Ace) |
Markdown | Package moonshine/easymde | Markdown editor (EasyMDE) |
TinyMCE | Package moonshine/tinymce | WYSIWYG editor |
Structural Fields
| Field | Namespace | Description |
|---|
Json | MoonShine\UI\Fields\Json | JSON data (fields, keyValue, onlyValue, object) |
Fieldset | MoonShine\UI\Fields\Fieldset | Groups fields visually |
Relationship Fields
| Field | Namespace | Laravel Relation |
|---|
BelongsTo | MoonShine\Laravel\Fields\Relationships\BelongsTo | BelongsTo |
BelongsToMany | MoonShine\Laravel\Fields\Relationships\BelongsToMany | BelongsToMany |
HasOne | MoonShine\Laravel\Fields\Relationships\HasOne | HasOne |
HasMany | MoonShine\Laravel\Fields\Relationships\HasMany | HasMany |
HasOneThrough | MoonShine\Laravel\Fields\Relationships\HasOneThrough | HasOneThrough |
HasManyThrough | MoonShine\Laravel\Fields\Relationships\HasManyThrough | HasManyThrough |
MorphOne | MoonShine\Laravel\Fields\Relationships\MorphOne | MorphOne |
MorphMany | MoonShine\Laravel\Fields\Relationships\MorphMany | MorphMany |
MorphTo | MoonShine\Laravel\Fields\Relationships\MorphTo | MorphTo |
MorphToMany | MoonShine\Laravel\Fields\Relationships\MorphToMany | MorphToMany |
RelationRepeater | MoonShine\Laravel\Fields\Relationships\RelationRepeater | HasMany/HasOne inline |
Relationship Fields Overview
All relationship fields require a registered ModelResource. Constructor:
BelongsTo::make(
Closure|string $label,
?string $relationName = null, // auto-detected from label via camelCase
Closure|string|null $formatted = null, // display column or closure
ModelResource|string|null $resource = null, // auto-detected from relation name
)
Key patterns across relationship fields:
asyncSearch() - async search with custom query, formatted output, limit
creatable() - create related object via modal
valuesQuery() - modify the query that fetches dropdown values
withImage() - add images to dropdown items
searchable() - enable search in dropdown
selectMode() - display BelongsToMany as dropdown instead of checkboxes
relatedLink() - show as a link with count instead of full list
tabMode() / modalMode() - display HasOne/HasMany in tabs or modals
disableOutside() - render inside the main form instead of separately
Common Field Methods (All Fields)
Display & Attributes
->setLabel('New Label')
->translatable('ui')
->hint('Helper text')
->badge('success')
->horizontal()
->withoutWrapper()
->sortable()
->required()
->disabled()
->readonly()
->customAttributes(['class' => 'my-class'])
->customWrapperAttributes(['class' => 'mt-8'])
Value Modification
->default('value')
->nullable()
->fill('value')
->changeFill(fn($data, $ctx) => ...)
->afterFill(fn($ctx) => ...)
->changePreview(fn($value, $ctx) => ...)
->changeRender(fn($value, $ctx) => ...)
->modifyRawValue(fn($raw, $data, $ctx) => ...)
->fromRaw(fn($raw, $ctx) => ...)
Apply Lifecycle
->onApply(fn($item, $value, $field) => $item)
->onBeforeApply(fn($item, $value, $field) => $item)
->onAfterApply(fn($item, $value, $field) => $item)
->canApply(fn() => false)
Conditional Display
->canSee(fn($field) => true)
->when(fn() => true, fn($field) => $field->locked())
->showWhen('other_field', '=', 'value')
->showWhenDate('created_at', '>', '2024-01-01')
Inline Editing (Preview Mode)
->updateOnPreview()
->withUpdateRow('table-name')
->updateInPopover('table-name')
Reactivity
->reactive(function(Fields $fields, ?string $value): Fields {
return tap($fields, fn($f) => $f->findByColumn('slug')?->setValue(str($value)->slug()->value()));
})
Creating a Custom Field
php artisan moonshine:field
This generates a field class with its own Blade view. Override resolvePreview(), resolveOnApply(), and the view to customize behavior.
Cross-References
- For how fields are used in resources, see the
moonshine-resources-v3 skill
- Relationship fields require registered
ModelResource instances
- Fields work with
FormBuilder and TableBuilder components
- Filters use the same field classes with filter-specific apply logic
Reference Files
references/basic-fields.md - Text, Number, Date, Slug, ID, and other basic input fields
references/selection-fields.md - Select, Enum, Checkbox, Switcher
references/file-fields.md - File, Image, Code, Markdown, TinyMCE editors
references/relationship-fields.md - All relationship field types with patterns
references/field-display-attributes.md - Display methods, view modes, and attribute configuration
references/field-values-lifecycle.md - Value methods, fill logic, and apply lifecycle
references/field-interactive.md - Conditional display, showWhen, inline editing, onChange, reactivity, custom fields