Merge branch 'worktree-agent-a4fc1072037346c95'

This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:44:46 +02:00
26 changed files with 950 additions and 114 deletions
@@ -52,8 +52,9 @@
</x-chip-set>
BLADE,
'A set that scrolls' => <<<'BLADE'
{{-- M3 asks an overflowing chip row for a visible affordance: the edge it can still scroll towards fades, and on a mouse a button sits over it. --}}
<div class="w-full max-w-sm">
<x-chip-set label="Sort and filter" scroll>
<x-chip-set label="Sort and filter" hint="Drag, or use the arrow keys" scroll>
<x-chip type="filter" label="Newest" name="sort[]" value="newest" :selected="true" />
<x-chip type="filter" label="Largest" name="sort[]" value="largest" />
<x-chip type="filter" label="Expiring soon" name="sort[]" value="expiring" />
@@ -41,6 +41,24 @@
</div>
</div>
BLADE,
'Width at medium and above' => <<<'BLADE'
<div class="w-full space-y-4">
{{-- M3: never let a text field span the full width of a large screen. From medium it stops at 40rem. --}}
<x-input label="Bounded, the default" hint="No wider than 40rem from medium, however wide the pane is" />
<x-input label="Narrower" class="max-w-xs" hint="A max-w-* class from the call site wins" />
<x-input label="The width of the pane" full icon="search" hint="`full` takes the bound off — for a search row or an editor" />
</div>
BLADE,
'Character counter' => <<<'BLADE'
<div class="grid w-full gap-6 medium:grid-cols-2">
<div class="grid content-start gap-4">
<x-input label="Share name" maxlength="40" counter hint="Recipients see this name" />
<x-input variant="filled" label="Subject" maxlength="60" counter />
</div>
<x-textarea label="Message for recipients" maxlength="180" counter rows="3" hint="Sent with the link" />
</div>
BLADE,
'Textarea and select' => <<<'BLADE'
<div class="grid w-full gap-6 medium:grid-cols-2">
<div class="grid content-start gap-4">
@@ -74,6 +92,23 @@
</div>
</div>
BLADE,
'A checkbox group at expanded' => <<<'BLADE'
{{-- M3: from expanded (840px), gather related checkboxes into a contained region instead of one long column. --}}
<x-card variant="outlined" class="w-full max-w-2xl">
<fieldset>
<legend class="mb-4 type-title-sm text-on-surface">Tell me about</legend>
<div class="grid gap-4 expanded:grid-cols-2">
<x-checkbox label="Downloads" name="notify[]" value="downloads" checked />
<x-checkbox label="Comments" name="notify[]" value="comments" />
<x-checkbox label="Expiring shares" name="notify[]" value="expiring" checked />
<x-checkbox label="Failed uploads" name="notify[]" value="failed" />
<x-checkbox label="New team members" name="notify[]" value="members" />
<x-checkbox label="Weekly summary" name="notify[]" value="summary" />
</div>
</fieldset>
</x-card>
BLADE,
'Radio buttons' => <<<'BLADE'
<div class="grid w-full gap-6 medium:grid-cols-2">
<x-radio label="Who can open the link" name="showcase-audience" value="password" :options="[['id' => 'anyone', 'name' => 'Anyone with the link'], ['id' => 'password', 'name' => 'Anyone with the password', 'hint' => 'Share the password separately'], ['id' => 'team', 'name' => 'My team only', 'disabled' => true]]" />
@@ -134,6 +169,40 @@
</div>
</div>
BLADE,
'Search entry points and suggestions' => <<<'BLADE'
<div class="grid w-full gap-6 medium:grid-cols-2">
<div x-data="{ query: '' }">
<x-search x-model="query" placeholder="Search shares">
<x-slot:suggestions>
<x-list>
<x-list-item title="Recent: holiday photos" icon="history" link="#fields" />
<x-list-item title="Recent: contract" icon="history" link="#fields" />
<x-list-item title="Shares expiring this week" icon="trending_up" link="#fields" />
</x-list>
</x-slot:suggestions>
<x-list>
<x-list-item title="holiday-photos.zip" description="248 MB" icon="folder_zip" link="#fields" x-show="'holiday-photos.zip'.includes(query.toLowerCase())" />
<x-list-item title="contract.pdf" description="1.2 MB" icon="picture_as_pdf" link="#fields" x-show="'contract.pdf'.includes(query.toLowerCase())" />
</x-list>
</x-search>
</div>
{{-- M3's search icon button: search as a secondary action, expanding into the full-screen view. --}}
<div class="flex items-center gap-2 rounded-corner-full bg-surface-container-high px-2 py-1">
<x-button icon="menu" aria-label="Open the menu" />
<span class="grow type-title-md text-on-surface">Shares</span>
<x-search trigger="icon" label="Search shares">
<x-slot:suggestions>
<x-list>
<x-list-item title="Recent: design review" icon="history" link="#fields" />
</x-list>
</x-slot:suggestions>
<x-slot:empty>No shares match.</x-slot:empty>
</x-search>
</div>
</div>
BLADE,
'A form' => <<<'BLADE'
<x-card variant="outlined" class="w-full max-w-xl">
<x-form x-on:submit.prevent="materialToast('Share created', { type: 'success' })" separator>
@@ -27,6 +27,7 @@
</div>
BLADE,
'Range' => <<<'BLADE'
{{-- Narrow the window below 600px: a range picker becomes M3's full-screen one, with a close button, Save, and the months scrolled through. --}}
<div class="grid w-full gap-6 medium:grid-cols-2" x-data="{ trip: { start: '{{ now()->addDays(3)->format('Y-m-d') }}', end: '{{ now()->addDays(9)->format('Y-m-d') }}' }, leave: { start: null, end: null } }">
<div class="grid content-start gap-4">
<x-datepicker label="Trip" range x-model="trip" />
@@ -34,7 +35,7 @@
</div>
<div class="grid content-start gap-4">
<x-datepicker label="Leave" range mode="modal" x-model="leave" />
<x-datepicker label="Leave" range mode="modal" x-model="leave" hint="Full screen on a compact window" />
<p class="type-body-sm text-on-surface-variant">Bound value: <code x-text="JSON.stringify(leave)"></code></p>
</div>
</div>
@@ -22,6 +22,16 @@
<x-slider label="Balance" value="15" :min="-50" :max="50" centered />
</div>
BLADE,
'Vertical' => <<<'BLADE'
{{-- M3 Expressive's second orientation. A vertical slider needs a height: it is on the wrapper, which the label and hint share. --}}
<div class="flex flex-wrap items-end gap-10">
<x-slider label="Volume" orientation="vertical" value="40" class="h-64" hint="Up and Down" />
<x-slider label="Warmth" orientation="vertical" value="6" :max="10" ticks class="h-64" />
<x-slider label="Brightness" orientation="vertical" value="70" size="md" icon="light_mode" class="h-64" />
<x-slider label="Always labelled" orientation="vertical" value="55" value-label="always" color="tertiary" class="h-64" />
<x-slider label="Locked" orientation="vertical" value="25" disabled class="h-64" />
</div>
BLADE,
'Colours and value labels' => <<<'BLADE'
<div class="grid w-full gap-8 expanded:grid-cols-3">
<x-slider label="Always labelled" value="55" color="secondary" value-label="always" size="sm" />
@@ -48,7 +58,7 @@
<h2 class="type-headline-md">Sliders</h2>
<p class="max-w-3xl type-body-md text-on-surface-variant">
<code>&lt;x-slider&gt;</code>: M3 Expressive's slider on native range inputs standard, range and centred, five sizes, ticks, value labels and an inset icon.
<code>&lt;x-slider&gt;</code>: M3 Expressive's slider on native range inputs standard, range and centred, horizontal or vertical, five sizes, ticks, value labels and an inset icon.
</p>
@foreach ($examples as $title => $code)