Skip to content

Commit 1533348

Browse files
committed
docs: update field type customization reference
Expand documentation on field type customization, covering settings, multi-value support, unique constraints, table filters, and import handling.
1 parent 38e988d commit 1533348

1 file changed

Lines changed: 113 additions & 6 deletions

File tree

docs/content/2.essentials/3.field-types.md

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,120 @@ FieldSchema::multiChoice() // For MULTI_CHOICE data type
191191
->priority(50) // Sort order (lower = first)
192192
->formComponent($component) // Form field component
193193
->tableColumn($column) // Table column component
194+
->tableFilter($filter) // Table filter component
194195
->infolistEntry($entry) // Read-only display component
195-
->availableValidationRules($rules) // User-selectable validation rules
196-
->defaultValidationRules($rules) // Always-applied validation rules
197-
->searchable() // Enable table search
198-
->sortable() // Enable table sorting
199-
->filterable() // Enable table filtering
200-
->encryptable() // Allow field encryption
196+
->availableValidationRules($rules) // Validation rules users can toggle per field
197+
->defaultValidationRules($rules) // Validation rules always applied to this field type
198+
->searchable() // Enable globally-searchable in tables (default: true)
199+
->sortable() // Enable column sorting in tables (default: true)
200+
->filterable() // Enable table filter for this field type (default: false)
201+
->encryptable() // Allow users to enable encryption for this field
202+
```
203+
204+
::callout{type="info"}
205+
A field type needs **both** `filterable()` and `tableFilter()` for filters to appear in tables. `filterable()` enables the capability; `tableFilter()` provides the filter component.
206+
::
207+
208+
### Settings
209+
210+
Add type-specific configuration options that appear in the field editor when your field type is selected. Settings are stored per custom field instance.
211+
212+
`withSettings()` takes two arguments:
213+
1. A [Spatie Laravel Data](https://spatie.be/docs/laravel-data/v4/introduction) class defining the settings structure
214+
2. An array of Filament form components (or a `Closure` returning them) for the settings UI
215+
216+
```php
217+
use Spatie\LaravelData\Data;
218+
use Filament\Forms\Components\TextInput;
219+
220+
class CurrencySettings extends Data
221+
{
222+
public function __construct(
223+
public string $currencySymbol = '$',
224+
public int $decimalPlaces = 2,
225+
) {}
226+
}
227+
228+
// In your field type's configure() method:
229+
return FieldSchema::float()
230+
->key('acme-currency')
231+
->label('Currency')
232+
->withSettings(CurrencySettings::class, [
233+
TextInput::make('currency_symbol')
234+
->label('Currency Symbol')
235+
->default('$'),
236+
TextInput::make('decimal_places')
237+
->label('Decimal Places')
238+
->numeric()
239+
->default(2),
240+
]);
241+
```
242+
243+
The settings form components are automatically shown/hidden based on the selected field type. Access stored settings via `$customField->settings` in your component closures.
244+
245+
### Multi-Value & Constraints
246+
247+
Control whether users can store multiple values in a single field and enforce uniqueness.
248+
249+
```php
250+
->supportsMultiValue()
251+
->supportsUniqueConstraint()
252+
->defaultItemValidationRules($rules)
253+
->requiresLookupType()
254+
```
255+
256+
**`supportsMultiValue()`** -- Shows an "Allow Multiple Values" toggle in the field editor. When enabled by the user, the field accepts multiple values (e.g., multiple emails or phone numbers) and a "Max Values" input appears. Used by Email, Phone, Link, and Record field types.
257+
258+
**`supportsUniqueConstraint()`** -- Shows a "Unique per Entity Type" toggle in the field editor. When enabled by the user, a `UniqueCustomFieldValue` validation rule is applied to prevent duplicate values across records of the same entity type. Used by Email, Phone, Link, Text, Textarea, and Number field types.
259+
260+
**`defaultItemValidationRules(array $rules)`** -- Validation rules automatically applied to **each individual item** in a multi-value field. These are not user-configurable -- they are hardcoded per field type. Only available for `MULTI_CHOICE` data types; throws `InvalidArgumentException` otherwise.
261+
262+
**`requiresLookupType()`** -- Replaces the user-defined options UI with an entity type selector. The field stores references to records of the selected entity type instead of static option values. Import/export treats these as entity references. Currently used by the Record field type.
263+
264+
Example -- the Email field type combines these to support multiple unique emails with per-item validation:
265+
266+
```php
267+
return FieldSchema::multiChoice()
268+
->key('email')
269+
->supportsMultiValue()
270+
->supportsUniqueConstraint()
271+
->withArbitraryValues()
272+
->withoutUserOptions()
273+
->defaultItemValidationRules(['email', 'max:254']);
274+
```
275+
276+
### Import Customization
277+
278+
Control how field values appear in import templates and how raw import data is transformed before storage.
279+
280+
```php
281+
->importExample('99.99')
282+
->importTransformer(function (mixed $state): ?float {
283+
// Transform raw import value into the correct storage format
284+
})
285+
```
286+
287+
**`importExample(string $example)`** -- Displayed as a sample value in the import template UI, helping users understand the expected format for this field type.
288+
289+
**`importTransformer(Closure $transformer)`** -- Receives the raw value from the import file and returns the transformed value for storage. Without a transformer, the raw value is stored as-is. The closure signature is `function (mixed $state): mixed`.
290+
291+
Example -- the Currency field type strips formatting characters on import:
292+
293+
```php
294+
return FieldSchema::float()
295+
->key('currency')
296+
->importExample('99.99')
297+
->importTransformer(function (mixed $state): ?float {
298+
if (blank($state)) {
299+
return null;
300+
}
301+
302+
if (is_string($state)) {
303+
$state = preg_replace('/[^0-9.-]/', '', $state);
304+
}
305+
306+
return round(floatval($state), 2);
307+
});
201308
```
202309

203310
### Component Types

0 commit comments

Comments
 (0)