Plan step 38: every two-column layout moves onto <x-grid> with <x-stack> columns; the checkbox group's card, its legend and the two search demos' bespoke geometry (an avatar chip, the compact search-icon-button bar) move to data-md-showcase-* hooks. The two small demo controls and the "Narrower" field's override move to .showcase-w-sm/-xs/-narrow — plain, unlayered classes, since <x-input> and <x-datepicker> forward only class and style to the element that needs sizing, never a data attribute. "Narrower"'s hint is reworded from "A max-w-* class" to "An unlayered rule from the call site wins", since that is now the mechanism being shown. FieldsTest's Chromium selectors run against an isolated fieldProbe fixture, not this page, so nothing there is at risk; #fields and every id (showcase-error, showcase-error-filled, showcase-audience, showcase-radio-theme) is unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
236 lines
16 KiB
PHP
236 lines
16 KiB
PHP
@php
|
|
$examples = [
|
|
'Outlined and filled text fields' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-input label="Share name" hint="Recipients see this name" />
|
|
<x-input label="Recipient" icon="mail" type="email" placeholder="name@example.com" clearable value="anna@example.com" />
|
|
<x-input label="Price" prefix="CHF" suffix="per month" type="number" value="12" />
|
|
<x-input label="Share link" value="https://sealshare.test/s/8f3k2" readonly copyable />
|
|
<x-password label="Password" hint="At least 12 characters" />
|
|
<x-input label="Disabled" value="Not editable" disabled />
|
|
</x-livewire-material::stack>
|
|
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-input variant="filled" label="Share name" hint="Recipients see this name" />
|
|
<x-input variant="filled" label="Recipient" icon="mail" type="email" placeholder="name@example.com" clearable value="anna@example.com" />
|
|
<x-input variant="filled" label="Price" prefix="CHF" suffix="per month" type="number" value="12" />
|
|
<x-input variant="filled" label="Search" icon="search" icon-right="mic" />
|
|
<x-password variant="filled" label="Password" hint="At least 12 characters" />
|
|
<x-input variant="filled" label="Disabled" value="Not editable" disabled />
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Errors, required and sizes' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-input label="Email" required />
|
|
<x-field id="showcase-error" label="Expiry" :messages="['Choose a date in the future.']">
|
|
<input id="showcase-error" data-md-field-control value="2020-01-01" aria-invalid="true" />
|
|
</x-field>
|
|
</x-livewire-material::stack>
|
|
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-field id="showcase-error-filled" variant="filled" label="Expiry" :messages="['Choose a date in the future.']">
|
|
<input id="showcase-error-filled" data-md-field-control value="2020-01-01" aria-invalid="true" />
|
|
</x-field>
|
|
<x-livewire-material::row gap="space125" wrap align="center">
|
|
<x-input size="sm" icon="search" placeholder="Filter" aria-label="Filter" class="showcase-w-sm" />
|
|
<x-input size="xs" placeholder="Find" aria-label="Find" class="showcase-w-xs" />
|
|
</x-livewire-material::row>
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Width at medium and above' => <<<'BLADE'
|
|
<x-livewire-material::stack gap="space200">
|
|
{{-- 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="showcase-w-narrow" hint="An unlayered rule 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" />
|
|
</x-livewire-material::stack>
|
|
BLADE,
|
|
'Character counter' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-input label="Share name" maxlength="40" counter hint="Recipients see this name" />
|
|
<x-input variant="filled" label="Subject" maxlength="60" counter />
|
|
</x-livewire-material::stack>
|
|
|
|
<x-textarea label="Message for recipients" maxlength="180" counter rows="3" hint="Sent with the link" />
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Textarea and select' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-textarea label="Message" hint="Grows as you type, up to six lines" rows="2" max-rows="6" />
|
|
<x-select label="Expires after" :options="[['id' => 1, 'name' => '1 hour'], ['id' => 24, 'name' => '1 day'], ['id' => 168, 'name' => '7 days'], ['id' => 720, 'name' => '30 days', 'disabled' => true]]" />
|
|
<x-file label="Attachments" multiple hint="Up to 2 GB" />
|
|
</x-livewire-material::stack>
|
|
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-textarea variant="filled" label="Message" hint="Grows as you type, up to six lines" rows="2" max-rows="6" />
|
|
<x-select variant="filled" label="Expires after" icon="schedule" placeholder="Choose…" :options="[['id' => 1, 'name' => '1 hour'], ['id' => 24, 'name' => '1 day'], ['id' => 168, 'name' => '7 days']]" />
|
|
<x-file variant="filled" label="Attachments" multiple />
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Checkboxes' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'expanded' => 3]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-checkbox label="Notify me on download" checked />
|
|
<x-checkbox label="Select all files" indeterminate />
|
|
<x-checkbox label="Burn after reading" hint="The share is deleted after its first download" />
|
|
</x-livewire-material::stack>
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-checkbox label="Disabled" disabled />
|
|
<x-checkbox label="Disabled and ticked" checked disabled />
|
|
<x-checkbox label="Disabled, partly ticked" indeterminate disabled />
|
|
</x-livewire-material::stack>
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-checkbox label="Show in the dashboard" right />
|
|
<x-checkbox aria-label="Unlabelled" />
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
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" data-md-showcase-demo-card data-md-showcase-size="lg">
|
|
<fieldset>
|
|
<legend class="md-type-title-sm md-ink" data-md-showcase-legend>Tell me about</legend>
|
|
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'expanded' => 2]" gap="space200">
|
|
<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" />
|
|
</x-livewire-material::grid>
|
|
</fieldset>
|
|
</x-card>
|
|
BLADE,
|
|
'Radio buttons' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<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]]" />
|
|
<x-radio label="Theme" name="showcase-radio-theme" value="system" inline :options="[['id' => 'light', 'name' => 'Light'], ['id' => 'dark', 'name' => 'Dark'], ['id' => 'system', 'name' => 'System']]" hint="Inline from sm" />
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Switches' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'expanded' => 3]" gap="space300">
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-toggle label="Email notifications" checked />
|
|
<x-toggle label="Weekly summary" />
|
|
</x-livewire-material::stack>
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-toggle label="With icons" icons checked />
|
|
<x-toggle label="With icons, off" icons />
|
|
<x-toggle label="Only the check" icons="selected" checked />
|
|
</x-livewire-material::stack>
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-toggle label="Disabled" disabled />
|
|
<x-toggle label="Disabled, on" checked disabled icons />
|
|
<x-toggle label="Public link" hint="Anyone with the link can open it" right />
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Choices' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<x-livewire-material::stack gap="space300">
|
|
<x-choices label="Days you are free" hint="Filter chips: any number" :value="[1, 3]" :options="[['id' => 1, 'name' => 'Mon'], ['id' => 2, 'name' => 'Tue'], ['id' => 3, 'name' => 'Wed'], ['id' => 4, 'name' => 'Thu'], ['id' => 5, 'name' => 'Fri'], ['id' => 6, 'name' => 'Sat', 'disabled' => true]]" />
|
|
<x-choices label="Expires after" single :value="24" :options="[['id' => 1, 'name' => '1 hour'], ['id' => 24, 'name' => '1 day'], ['id' => 168, 'name' => '7 days']]" />
|
|
</x-livewire-material::stack>
|
|
|
|
<x-livewire-material::stack gap="space200">
|
|
<x-choices label="Time zone" searchable icon="public" value="Europe/Zurich" :options="collect(timezone_identifiers_list())->map(fn ($zone) => ['id' => $zone, 'name' => str_replace('_', ' ', $zone)])->all()" />
|
|
<x-choices label="Language" searchable variant="filled" placeholder="Type a language" :options="[['id' => 'de', 'name' => 'Deutsch'], ['id' => 'en', 'name' => 'English'], ['id' => 'fr', 'name' => 'Français'], ['id' => 'it', 'name' => 'Italiano'], ['id' => 'rm', 'name' => 'Rumantsch', 'disabled' => true]]" />
|
|
</x-livewire-material::stack>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Search' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<div x-data="{ query: '' }">
|
|
<x-search x-model="query" placeholder="Search shares">
|
|
<x-list>
|
|
<x-list-item title="holiday-photos.zip" description="248 MB · 3 days left" icon="folder_zip" link="#fields" x-show="'holiday-photos.zip'.includes(query.toLowerCase())" />
|
|
<x-list-item title="contract.pdf" description="1.2 MB · 1 hour left" icon="picture_as_pdf" link="#fields" x-show="'contract.pdf'.includes(query.toLowerCase())" />
|
|
<x-list-item title="design-review.mp4" description="3.4 GB · 7 days left" icon="movie" link="#fields" x-show="'design-review.mp4'.includes(query.toLowerCase())" />
|
|
</x-list>
|
|
<x-slot:trailing>
|
|
<span class="md-type-label-lg" data-md-showcase-avatar>AR</span>
|
|
</x-slot:trailing>
|
|
</x-search>
|
|
</div>
|
|
|
|
{{-- M3's resting bar is 360px and grows to 720 while focused; --search-width sets the resting one. --}}
|
|
<div style="--search-width: 22.5rem">
|
|
<x-search placeholder="Search in settings" docked>
|
|
<x-slot:empty>Type to search your settings.</x-slot:empty>
|
|
</x-search>
|
|
</div>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'Search entry points and suggestions' => <<<'BLADE'
|
|
<x-livewire-material::grid :columns="['compact' => 1, 'medium' => 2]" gap="space300">
|
|
<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 data-md-showcase-search-bar>
|
|
<x-button icon="menu" aria-label="Open the menu" />
|
|
<span class="md-type-title-md md-ink" data-md-showcase-search-bar-title>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>
|
|
</x-livewire-material::grid>
|
|
BLADE,
|
|
'A form' => <<<'BLADE'
|
|
<x-card variant="outlined" data-md-showcase-demo-card data-md-showcase-size="md">
|
|
<x-form x-on:submit.prevent="materialToast('Share created', { type: 'success' })" separator>
|
|
<x-input label="Share name" required />
|
|
<x-textarea label="Message for recipients" />
|
|
<x-select label="Expires after" :options="[['id' => 24, 'name' => '1 day'], ['id' => 168, 'name' => '7 days']]" />
|
|
<x-toggle label="Protect with a password" right />
|
|
|
|
<x-slot:actions>
|
|
<x-button label="Cancel" type="reset" />
|
|
<x-button label="Create share" variant="filled" type="submit" />
|
|
</x-slot:actions>
|
|
</x-form>
|
|
</x-card>
|
|
BLADE,
|
|
];
|
|
@endphp
|
|
|
|
<x-livewire-material::stack as="section" id="fields" gap="space300">
|
|
<h2 class="md-type-headline-md">Text fields and selection</h2>
|
|
|
|
<p class="md-type-body-md md-ink-variant">
|
|
<code><x-input></code>, <code><x-password></code>, <code><x-textarea></code>, <code><x-select></code>, <code><x-file></code>
|
|
(all on <code><x-field></code>, outlined or filled), <code><x-checkbox></code>, <code><x-radio></code>, <code><x-toggle></code>, <code><x-choices></code>, <code><x-search></code> and <code><x-form></code>.
|
|
</p>
|
|
|
|
@foreach ($examples as $title => $code)
|
|
<x-showcase::example :$title :$code />
|
|
@endforeach
|
|
</x-livewire-material::stack>
|