{{-- A choice of a few options as an M3 Expressive connected button group — the successor of the segmented button. Native radios under the segments (checkboxes with `multiple`), so `wire:model` and `x-model` bind as on any input, the arrow keys move the choice, and a screen reader announces a group. The chosen segment rounds fully and takes the selected colour; `variant` is `tonal` (the default), `filled` or `outlined`, as for toggle buttons. The segments share the row unless `inline`. An option with `'disabled' => true` greys its own segment. At `xs` and `sm` a segment carries `touch-target` and a 48px minimum width, which M3 asks for by name and tells you never to reduce. Corners move on the spatial spring and colours on the effects one (`state-transition-fast`). ReStride's props, kept: `label`, `hint`, `hint-class`, `name` (needed with `x-model`, which names no property), `options`, `option-value`, `option-label`; plus `option-icon`, `size`, `variant`, `multiple`, `inline`. A validation message for the bound property replaces the hint. `hint-class` adds classes to the hint, as on ``: a colour there paints it (`hint-class="text-warning"` for a hint that warns). The hint's own colour then carries no specificity, as the field's does in the components layer, because which of two colour utilities wins depends on the order Tailwind emits them. --}} @props([ 'label' => null, 'hint' => null, 'hintClass' => null, 'name' => null, 'options' => [], 'optionValue' => 'id', 'optionLabel' => 'name', 'optionIcon' => 'icon', 'size' => 'sm', 'variant' => 'tonal', 'multiple' => false, 'inline' => false, ]) @php $model = $attributes->whereStartsWith('wire:model')->first(); $name ??= $model; // 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)) : []; $size = in_array($size, ['xs', 'sm', 'md', 'lg', 'xl'], true) ? $size : 'sm'; // M3: an xs or sm connected segment keeps a 48px target and a 48px minimum width, whatever // its 32px/40px container measures. From md the segment is wider than that on its own. $small = in_array($size, ['xs', 'sm'], true); $segment = [ 'xs' => 'h-8 gap-2 px-4 type-label-lg', 'sm' => 'h-10 gap-2 px-4 type-label-lg', 'md' => 'h-14 gap-2 px-6 type-title-md', 'lg' => 'h-24 gap-3 px-12 type-headline-sm', 'xl' => 'h-34 gap-4 px-16 type-headline-lg', ][$size]; $hintClasses = filled($hintClass) ? \Illuminate\Support\Arr::toCssClasses(['mt-1 type-body-sm [:where(&)]:text-on-surface-variant', $hintClass]) : 'mt-1 type-body-sm text-on-surface-variant'; $iconSize = ['xs' => 'size-5', 'sm' => 'size-5', 'md' => 'size-6', 'lg' => 'size-8', 'xl' => 'size-10'][$size]; $colours = match ($variant) { 'filled' => 'bg-surface-container text-on-surface-variant has-checked:bg-primary has-checked:text-on-primary', 'outlined' => 'border border-outline-variant text-on-surface-variant has-checked:border-transparent has-checked:bg-inverse-surface has-checked:text-inverse-on-surface', default => 'bg-secondary-container text-on-secondary-container has-checked:bg-secondary has-checked:text-on-secondary', }; @endphp
only(['class', 'wire:key'])->class('min-w-0') }}> @if (filled($label)) {{ $label }} @endif
! $inline, 'w-fit' => $inline])> @foreach ($options as $option) @endforeach
@if ($messages !== []) @foreach ($messages as $message)

{{ $message }}

@endforeach @elseif (filled($hint))

{{ $hint }}

@endif