Files
livewire-material/resources/views/components/toggle.blade.php
T
Andreas Reinhold / reiniandClaude Fable 5.1 da4952e684 Give an unlabelled checkbox, radio or switch a 48px target
A selection control with a label is pressed anywhere along its row, but
one without — a table's "select all", a row's tick — was only its 18, 20
or 32px box, because the 40px state layer is a ::before that catches no
pointer. The box now wears the shared touch-target utility, which M3 asks
for on all three (checkbox, radio and switch specs: target size 48dp).

Plan step 13, finding IN-03.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 05:52:23 +02:00

60 lines
2.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{-- A switch, M3's: a 52×32 track whose handle grows and slides across when it turns on.
On a real checkbox with `role="switch"`, so it is focusable, announced as on or off, and takes
Space from the keyboard; the handle is drawn beside it. `label` and `hint` sit beside it and are
its name — a switch without `label` needs an `aria-label`. `right` puts it at the end of the
row, where a setting's switch usually is. `icons` draws a check on the handle when on and a
cross when off; `icons="selected"` only the check. Every other attribute reaches the `<input>`
(resources/css/components/selection.css).
Without a label the row is only the 52×32 track, so the track carries `touch-target` and catches
presses over M3's 48px minimum. --}}
@props([
'label' => null,
'hint' => null,
'right' => false,
'icons' => false,
])
@php
$model = $attributes->whereStartsWith('wire:model')->first();
$id = $attributes->get('id') ?? 'switch-'.substr(md5($model.'|'.$label), 0, 12);
$icons = $icons === 'selected' ? 'selected' : ($icons ? 'both' : null);
@endphp
<div {{ $attributes->only(['class', 'wire:key'])->class(['min-w-0']) }}>
<label for="{{ $id }}" data-selection @class([
'flex gap-4',
'items-start' => filled($hint),
'items-center' => blank($hint),
'flex-row-reverse justify-between' => $right,
])>
<span data-switch @if ($icons) data-icons="{{ $icons }}" @endif @class(['touch-target' => blank($label) && blank($hint)])>
<input
{{ $attributes->except(['class', 'id', 'wire:key']) }}
id="{{ $id }}"
type="checkbox"
role="switch"
/>
<span data-handle>
@if ($icons)
<x-livewire-material::icon name="check" class="size-4" data-on />
<x-livewire-material::icon name="close" class="size-4" data-off />
@endif
</span>
</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>
</div>