Lay the scheme picker out as tiles and pass its attributes to the group
tests / lint (push) Successful in 1m6s
tests / feature (8.4) (push) Successful in 1m12s
tests / feature (8.5) (push) Successful in 1m16s
tests / browser (chrome, chromium) (push) Successful in 3m17s
tests / browser (firefox, firefox) (push) Successful in 4m43s
tests / browser (safari, webkit) (push) Successful in 5m22s

The check sat beside the name and truncated it at four columns; it now
sits in the tile's corner under the swatch dots. Attributes other than
the binding (data-test, class) reach the fieldset, and the dots' ring
follows the selected tile's colour.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
Andreas Reinhold / reini
2026-09-13 14:39:26 +02:00
co-authored by Claude Opus 5
parent fb42f004b1
commit d805dbc407
2 changed files with 16 additions and 5 deletions
@@ -29,7 +29,7 @@
@endphp @endphp
@if ($profiles !== []) @if ($profiles !== [])
<fieldset x-data data-scheme-picker {{ $attributes->only(['class', 'wire:key'])->class('min-w-0') }}> <fieldset x-data data-scheme-picker {{ $attributes->whereDoesntStartWith(['wire:model', 'x-model'])->except('name')->class('min-w-0') }}>
@if (filled($label)) @if (filled($label))
<legend class="mb-2 type-label-lg text-on-surface-variant">{{ $label }}</legend> <legend class="mb-2 type-label-lg text-on-surface-variant">{{ $label }}</legend>
@endif @endif
@@ -38,7 +38,7 @@
@foreach ($profiles as $profile => $scheme) @foreach ($profiles as $profile => $scheme)
<label <label
data-scheme-option="{{ $profile }}" data-scheme-option="{{ $profile }}"
class="state-layer flex min-w-0 cursor-pointer select-none items-center gap-3 rounded-corner-lg border border-outline-variant bg-surface-container-low p-3 text-on-surface transition-[background-color,border-color] duration-(--md-sys-motion-effects-fast-duration) ease-effects-fast has-checked:border-transparent has-checked:bg-secondary-container has-checked:text-on-secondary-container has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-secondary" class="state-layer flex min-w-0 cursor-pointer select-none flex-col items-start gap-2 rounded-corner-lg border border-outline-variant bg-surface-container-low p-3 text-on-surface transition-[background-color,border-color] duration-(--md-sys-motion-effects-fast-duration) ease-effects-fast has-checked:border-transparent has-checked:bg-secondary-container has-checked:text-on-secondary-container has-focus-visible:outline-3 has-focus-visible:outline-offset-2 has-focus-visible:outline-secondary"
> >
<input <input
{{ $attributes->whereStartsWith(['wire:model', 'x-model']) }} {{ $attributes->whereStartsWith(['wire:model', 'x-model']) }}
@@ -53,14 +53,17 @@
@foreach (['primary', 'secondary', 'tertiary'] as $role) @foreach (['primary', 'secondary', 'tertiary'] as $role)
<span <span
style="--swatch-light: {{ $scheme['light'][$role] }}; --swatch-dark: {{ $scheme['dark'][$role] }}" style="--swatch-light: {{ $scheme['light'][$role] }}; --swatch-dark: {{ $scheme['dark'][$role] }}"
class="size-5 rounded-full bg-(--swatch-light) ring-2 ring-surface-container-low dark:bg-(--swatch-dark)" class="size-5 rounded-full bg-(--swatch-light) ring-2 ring-surface-container-low in-has-checked:ring-secondary-container dark:bg-(--swatch-dark)"
></span> ></span>
@endforeach @endforeach
</span> </span>
<span class="min-w-0 flex-1 truncate type-label-lg">{{ __($scheme['label']) }}</span> <span class="w-full truncate pe-6 type-label-lg">{{ __($scheme['label']) }}</span>
<x-livewire-material::icon name="check" class="hidden size-5 shrink-0 peer-checked:block" /> {{-- In the corner, so a long name keeps its room. The wrapper carries the position. --}}
<span class="pointer-events-none absolute end-2 top-2 hidden peer-checked:block">
<x-livewire-material::icon name="check" class="size-5" />
</span>
</label> </label>
@endforeach @endforeach
</div> </div>
@@ -32,6 +32,14 @@ it('draws a radio per generated profile, bound, named and previewing on change',
->toContain('style="--swatch-light: #00897b; --swatch-dark: #80cbc4"'); ->toContain('style="--swatch-light: #00897b; --swatch-dark: #80cbc4"');
}); });
it('puts its other attributes on the group and the binding on the radios', function () {
$html = (string) $this->blade('<x-scheme-picker wire:model="colorProfile" data-test="color-profile" class="mt-4" />');
expect($html)->toMatch('/<fieldset x-data data-scheme-picker class="min-w-0 mt-4" data-test="color-profile">/')
->and(substr_count($html, 'wire:model="colorProfile"'))->toBe(2)
->and(substr_count($html, 'data-test="color-profile"'))->toBe(1);
});
it('keeps its inline styles to the scheme file\'s checked colours', function () { it('keeps its inline styles to the scheme file\'s checked colours', function () {
File::put($this->path, json_encode([ File::put($this->path, json_encode([
'default' => 'indigo', 'default' => 'indigo',