An over-engineering audit of the whole tree, applied in five reviewed batches. Behaviour stays the same except where UPGRADE.md says otherwise. PHP: the showcase and error-page stylesheets are prebuilt into resources/dist by bin/stylesheets.mjs, through Vite's own postcss-import (first occurrence kept, the order an application's build gives), instead of Stylesheets::bundle() inlining imports on every request; only the import walk DesignGuard needs stays. SchemeStylesheet::withProfiles() replaces three copies of the scheme-plus-profiles loop, material:scheme leaves spec and contrast checks to the node script that already made them, and the error page's scheme cache, the hashed view namespace, the translations path with no lang/ folder and DesignGuard's 1.x-name hints are gone. JS: the androidx shape port progress.js and both bin scripts each carried lives once in resources/js/shapes.js (the generated SVGs are unchanged); util.js holds ringIndex(), ms(), reopenGuard() and remember(), which were written out several times; listeners are released through AbortController; tooltip.js's hoverPopover() serves the rich tooltip too. CSS: every rule for an element inside the navigation rail queries `--md-navigation-rail-value` instead of repeating the seven collapsed conditions under five media branches; badge, alert, progress, slider and button read one non-inheriting colour-role table (components/color.css); the dialog chrome, the submenu's popover chrome, the chip's state layer and touch target, and the visually-hidden inputs use the shared rules they copied; foundation/tokens.css is folded into foundation.css. Views: Support\Field and Support\Link replace the error-key, bound-value and link-attribute blocks copied into the fields and link components; the timepicker period group, the menu filter and the showcase head are partials; the datepicker's steppers and entry fields are loops; component docblocks no longer restate SKILL.md. Tests and tooling: one dataset-driven ComponentStylesheetsTest replaces four per-group files, DesignGuardTest and the layout-component tests use datasets, browser tests share one ready() helper, CSS parsing lives in ComponentStylesheet alone. docs/audits and the finding IDs citing it are removed, as are pestphp/pest-plugin-laravel, the unused composer scripts and check:font; the lint job runs in the feature job, which now installs node packages so the prebuilt-stylesheet staleness test runs in CI. Feature suite 1177 passed, Chrome browser suite 299 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
71 lines
3.5 KiB
PHP
71 lines
3.5 KiB
PHP
{{-- A checkbox, M3's: an 18px box that fills with primary when ticked, in a 40px state layer. The
|
|
tick and the dash fill the box at CheckboxTokens' 18px icon size, drawn from the 20 optical cut.
|
|
|
|
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-md-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>`.
|
|
The drawing is resources/css/components/checkbox.css, on the row the three selection controls
|
|
share (resources/css/components/selection.css).
|
|
|
|
Without a label — a "select all" in a table header, a row's tick — the row is only the 18px box,
|
|
so the box carries `md-touch-target` and catches presses over M3's 48px minimum.
|
|
|
|
Grouping is the caller's, not this component's: M3 asks that from `expanded` (840px) a set of
|
|
related checkboxes be gathered into a contained region rather than left as one long column
|
|
(docs/reference/m3/components-navigation-selection-inputs.md § Checkbox, Behaviour). Lay the
|
|
group out yourself — a grid of one column that takes two from `expanded`, or an `<x-card>` or
|
|
side sheet holding them — and give the group a heading that names what it asks. --}}
|
|
|
|
@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);
|
|
$field = \NoNameWeb\LivewireMaterial\Support\Field::class;
|
|
$errorKey = $field::key($model, $attributes->get('name'));
|
|
$messages = $field::messages($errors ?? null, $errorKey);
|
|
@endphp
|
|
|
|
<div data-md-checkbox {{ $attributes->only(['class', 'style', 'wire:key']) }}>
|
|
<label for="{{ $id }}" data-md-selection-row @if ($right) data-md-right @endif @if ($messages !== []) data-md-invalid @endif>
|
|
<span data-md-checkbox-box @if (blank($label) && blank($hint)) class="md-touch-target" @endif>
|
|
<input
|
|
{{ $attributes->except(['class', 'style', 'id', 'wire:key']) }}
|
|
id="{{ $id }}"
|
|
type="checkbox"
|
|
@if ($indeterminate) data-md-indeterminate @endif
|
|
@if ($messages !== []) aria-invalid="true" aria-describedby="{{ $id }}-support" @endif
|
|
/>
|
|
<x-livewire-material::icon name="check" size="18" data-md-checkbox-check />
|
|
<x-livewire-material::icon name="remove" size="18" data-md-checkbox-mixed />
|
|
</span>
|
|
|
|
@if (filled($label) || filled($hint))
|
|
<span data-md-selection-text>
|
|
@if (filled($label))
|
|
<span data-md-selection-label>{{ $label }}</span>
|
|
@endif
|
|
@if (filled($hint))
|
|
<span data-md-selection-hint>{{ $hint }}</span>
|
|
@endif
|
|
</span>
|
|
@endif
|
|
</label>
|
|
|
|
@if ($messages !== [])
|
|
<div id="{{ $id }}-support" data-md-selection-support role="alert">
|
|
@foreach ($messages as $message)
|
|
<p>{{ $message }}</p>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|