{{-- A text field: M3's outlined or filled one (resources/views/components/field.blade.php).
`label`, `hint`, leading `icon`, trailing `icon-right`, `prefix` and `suffix` (text beside the
value, such as a currency or a unit), `variant`, `size` for unlabelled controls in toolbars,
and `mono` for a field that holds code. `clearable` adds a trailing button that empties the
field once it holds something; `copyable` one that copies its value and says so in a snackbar
(a share link, a token). `counter` counts the characters used against `maxlength`, at the end of
the supporting-text row. Every other attribute reaches the ``: `type`, `min`, `step`,
`readonly`, `wire:model` and the rest. Errors are read from the bag under the `wire:model` name.
The placeholder is a single space when none is given, because the label can only tell an
empty field from a filled one through `:placeholder-shown`. With a label, a real placeholder
shows only while the field has focus — until then the label stands where it would be. --}}
@props([
'label' => null,
'hint' => null,
'hintClass' => null,
'icon' => null,
'iconRight' => null,
'prefix' => null,
'suffix' => null,
'clearable' => false,
'copyable' => false,
'counter' => false,
'size' => 'md',
'variant' => null,
'mono' => false,
])
@php
$model = $attributes->whereStartsWith('wire:model')->first();
$placeholder = filled($attributes->get('placeholder')) ? $attributes->get('placeholder') : ' ';
$id = $attributes->get('id') ?? 'field-'.substr(md5($model.'|'.$label.'|'.$placeholder), 0, 12);
// A plain form's field is named, not bound: its errors are under its name (`files[]` → `files`, `a[b]` → `a.b`).
$errorKey = $model ?? (filled($attributes->get('name')) ? str_replace(['[]', '[', ']'], ['', '.', ''], (string) $attributes->get('name')) : null);
$messages = $errorKey !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($errorKey)) : [];
// M3's counter needs a maximum to count against: without `maxlength` there is nothing to show.
$max = $counter ? $attributes->get('maxlength') : null;
@endphp
except(['class', 'id', 'placeholder'])->merge(['type' => 'text']) }}
id="{{ $id }}"
placeholder="{{ $placeholder }}"
@if ($messages !== []) aria-invalid="true" @endif
@if ($messages !== [] || filled($hint)) aria-describedby="{{ $id }}-support" @endif
class="field-control"
/>
@if ($clearable || $copyable || $iconRight)
@if ($clearable)
@endif
@if ($copyable)
@endif
@if ($iconRight)
@endif
@endif