tests / feature (8.4) (push) Successful in 1m5s
tests / feature (8.5) (push) Successful in 1m4s
tests / lint (push) Successful in 59s
tests / browser (chrome, chromium) (push) Successful in 2m54s
tests / browser (firefox, firefox) (push) Successful in 3m3s
tests / browser (safari, webkit) (push) Successful in 4m13s
Outlined and filled text fields (input, password, auto-growing textarea, native select with the customizable select menu, file), checkbox with an indeterminate state, radio buttons, the M3 switch and form, ported from ReStride and extended. The first half of Phase 6. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
63 lines
2.7 KiB
PHP
63 lines
2.7 KiB
PHP
{{-- A checkbox, M3's: an 18px box that fills with primary when ticked, in a 40px state layer.
|
|
|
|
The label and its hint sit beside it and are its accessible name — the whole row is the
|
|
`<label>`, so either can be pressed. `right` puts the box at the end of the row, for a setting
|
|
read left to right. `indeterminate` shows the mixed state of a "select all" whose items are
|
|
partly ticked: HTML has no attribute for it, so the input is marked `data-indeterminate` and
|
|
resources/js/field.js keeps the property in step, on load and after every morph. Errors are
|
|
read from the bag under the `wire:model` name. Every other attribute reaches the `<input>`
|
|
(resources/css/components/selection.css). --}}
|
|
|
|
@props([
|
|
'label' => null,
|
|
'hint' => null,
|
|
'right' => false,
|
|
'indeterminate' => false,
|
|
])
|
|
|
|
@php
|
|
$model = $attributes->whereStartsWith('wire:model')->first();
|
|
$id = $attributes->get('id') ?? 'check-'.substr(md5($model.'|'.$label.'|'.$attributes->get('value')), 0, 12);
|
|
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
|
@endphp
|
|
|
|
<div {{ $attributes->only(['class', 'wire:key'])->class(['min-w-0']) }}>
|
|
<label for="{{ $id }}" data-selection @if ($messages !== []) data-invalid @endif @class([
|
|
'flex gap-4',
|
|
'items-start' => filled($hint),
|
|
'items-center' => blank($hint),
|
|
'flex-row-reverse justify-between' => $right,
|
|
])>
|
|
<span data-checkbox @class(['mt-[3px]' => filled($hint)])>
|
|
<input
|
|
{{ $attributes->except(['class', 'id', 'wire:key']) }}
|
|
id="{{ $id }}"
|
|
type="checkbox"
|
|
@if ($indeterminate) data-indeterminate @endif
|
|
@if ($messages !== []) aria-invalid="true" aria-describedby="{{ $id }}-support" @endif
|
|
/>
|
|
<x-icon name="check" class="size-4" data-check />
|
|
<x-icon name="remove" class="size-4" data-mixed />
|
|
</span>
|
|
|
|
@if (filled($label) || filled($hint))
|
|
<span class="min-w-0">
|
|
@if (filled($label))
|
|
<span class="block type-body-lg text-on-surface" data-selection-label>{{ $label }}</span>
|
|
@endif
|
|
@if (filled($hint))
|
|
<span class="mt-0.5 block type-body-sm text-on-surface-variant">{{ $hint }}</span>
|
|
@endif
|
|
</span>
|
|
@endif
|
|
</label>
|
|
|
|
@if ($messages !== [])
|
|
<div id="{{ $id }}-support" class="mt-1 type-body-sm text-error" role="alert">
|
|
@foreach ($messages as $message)
|
|
<p>{{ $message }}</p>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|