Add buttons, menus and the rest of M3 Expressive's actions
tests / browser (firefox, firefox) (push) Successful in 1m54s
tests / browser (safari, webkit) (push) Successful in 2m17s
tests / lint (push) Successful in 59s
tests / feature (8.4) (push) Successful in 1m7s
tests / feature (8.5) (push) Successful in 1m0s
tests / browser (chrome, chromium) (push) Successful in 1m49s
tests / browser (firefox, firefox) (push) Successful in 1m54s
tests / browser (safari, webkit) (push) Successful in 2m17s
tests / lint (push) Successful in 59s
tests / feature (8.4) (push) Successful in 1m7s
tests / feature (8.5) (push) Successful in 1m0s
tests / browser (chrome, chromium) (push) Successful in 1m49s
<x-button> (label buttons, icon buttons and toggles in five sizes, with filled, tonal, outlined, elevated and text variants in any colour role), <x-tooltip>, <x-menu> with items, groups and separators, <x-button-group>, <x-group> as a connected button group, <x-split-button>, <x-fab>, <x-fab-menu> and <x-loading>. Sizes, colours and shapes come from androidx Compose Material 3's tokens; the loading indicator ports its Morph into SVG + SMIL. Menus follow WAI-ARIA's menu button pattern on popovers placed by CSS anchor positioning. Browser tests run in Chromium, Firefox and WebKit. The showcase fetches the icon names on demand: inlined, they tripped Pest's test server into HTTP 431s under Firefox. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
co-authored by
Claude Opus 5
parent
b48e879254
commit
cd64f4f371
@@ -0,0 +1,139 @@
|
||||
@php
|
||||
$examples = [
|
||||
'Variants' => <<<'BLADE'
|
||||
<x-button label="Filled" variant="filled" />
|
||||
<x-button label="Tonal" variant="tonal" />
|
||||
<x-button label="Outlined" variant="outlined" />
|
||||
<x-button label="Elevated" variant="elevated" />
|
||||
<x-button label="Text" />
|
||||
BLADE,
|
||||
'Sizes, with an icon' => <<<'BLADE'
|
||||
<x-button label="Extra small" icon="upload" variant="filled" size="xs" />
|
||||
<x-button label="Small" icon="upload" variant="filled" />
|
||||
<x-button label="Medium" icon="upload" variant="filled" size="md" />
|
||||
<x-button label="Large" icon="upload" variant="filled" size="lg" />
|
||||
<x-button label="Extra large" icon="upload" variant="filled" size="xl" />
|
||||
BLADE,
|
||||
'Square, and pressed (hold the pointer down)' => <<<'BLADE'
|
||||
<x-button label="Round" variant="tonal" size="md" />
|
||||
<x-button label="Square" variant="tonal" size="md" shape="square" />
|
||||
BLADE,
|
||||
'Colours' => <<<'BLADE'
|
||||
<x-button label="Primary" primary />
|
||||
<x-button label="Secondary" variant="filled" color="secondary" />
|
||||
<x-button label="Tertiary" variant="filled" color="tertiary" />
|
||||
<x-button label="Delete" icon="delete" danger />
|
||||
<x-button label="Take down" caution />
|
||||
<x-button label="Success" variant="tonal" color="success" />
|
||||
<x-button label="Info" variant="outlined" color="info" />
|
||||
BLADE,
|
||||
'Toggle buttons' => <<<'BLADE'
|
||||
<x-button label="Filled" variant="filled" :selected="false" />
|
||||
<x-button label="Selected" variant="filled" :selected="true" />
|
||||
<x-button label="Tonal" variant="tonal" :selected="false" />
|
||||
<x-button label="Selected" variant="tonal" :selected="true" />
|
||||
<x-button label="Outlined" variant="outlined" :selected="false" />
|
||||
<x-button label="Selected" variant="outlined" :selected="true" />
|
||||
BLADE,
|
||||
'Icon buttons, and their tooltips' => <<<'BLADE'
|
||||
<x-button icon="favorite" tooltip="Standard" />
|
||||
<x-button icon="favorite" tooltip="Filled" variant="filled" />
|
||||
<x-button icon="favorite" tooltip="Tonal" variant="tonal" />
|
||||
<x-button icon="favorite" tooltip="Outlined" variant="outlined" />
|
||||
<x-button icon="favorite" tooltip="Selected" variant="filled" :selected="true" />
|
||||
<x-button icon="favorite" tooltip="Selected, square" variant="tonal" shape="square" :selected="true" />
|
||||
BLADE,
|
||||
'Icon button sizes and widths' => <<<'BLADE'
|
||||
<x-button icon="share" tooltip="XS narrow" variant="tonal" size="xs" width="narrow" />
|
||||
<x-button icon="share" tooltip="S" variant="tonal" />
|
||||
<x-button icon="share" tooltip="M wide" variant="tonal" size="md" width="wide" />
|
||||
<x-button icon="share" tooltip="L" variant="tonal" size="lg" />
|
||||
<x-button icon="share" tooltip="XL wide" variant="tonal" size="xl" width="wide" />
|
||||
BLADE,
|
||||
'Links and disabled' => <<<'BLADE'
|
||||
<x-button label="Opens a page" link="#buttons" variant="outlined" />
|
||||
<x-button label="Leaves the site" link="https://m3.material.io" external icon-right="open_in_new" />
|
||||
<x-button label="Disabled" variant="filled" disabled />
|
||||
<x-button label="Disabled link" link="#buttons" variant="tonal" disabled />
|
||||
<x-button icon="delete" tooltip="Disabled" variant="outlined" disabled />
|
||||
BLADE,
|
||||
'Loading indicator' => <<<'BLADE'
|
||||
<x-loading />
|
||||
<x-loading contained />
|
||||
<x-loading class="size-24 text-tertiary" label="Uploading" />
|
||||
<x-loading contained class="size-8" />
|
||||
BLADE,
|
||||
'Button groups: standard (press a button) and connected' => <<<'BLADE'
|
||||
<x-button-group label="Standard" size="md">
|
||||
<x-button label="Day" variant="tonal" size="md" />
|
||||
<x-button label="Week" variant="tonal" size="md" />
|
||||
<x-button label="Month" variant="tonal" size="md" />
|
||||
</x-button-group>
|
||||
|
||||
<x-button-group label="Formatting" connected>
|
||||
<x-button icon="format_bold" aria-label="Bold" variant="tonal" :selected="true" />
|
||||
<x-button icon="format_italic" aria-label="Italic" variant="tonal" :selected="false" />
|
||||
<x-button icon="format_underlined" aria-label="Underline" variant="tonal" :selected="false" />
|
||||
</x-button-group>
|
||||
BLADE,
|
||||
'A choice as a connected group (<x-group>)' => <<<'BLADE'
|
||||
<div x-data="{ theme: 'system', days: ['mon'] }" class="grid w-full gap-6 md:grid-cols-2">
|
||||
<x-group label="Theme" name="showcase-theme" x-model="theme" :options="[
|
||||
['id' => 'light', 'name' => 'Light', 'icon' => 'light_mode'],
|
||||
['id' => 'dark', 'name' => 'Dark', 'icon' => 'dark_mode'],
|
||||
['id' => 'system', 'name' => 'System', 'icon' => 'computer'],
|
||||
]" />
|
||||
|
||||
<x-group label="Days" name="showcase-days" x-model="days" multiple variant="outlined" hint="Choose any" :options="[
|
||||
['id' => 'mon', 'name' => 'Mon'],
|
||||
['id' => 'tue', 'name' => 'Tue'],
|
||||
['id' => 'wed', 'name' => 'Wed'],
|
||||
['id' => 'thu', 'name' => 'Thu', 'disabled' => true],
|
||||
]" />
|
||||
</div>
|
||||
BLADE,
|
||||
'Split buttons' => <<<'BLADE'
|
||||
<x-split-button label="Download all" icon="download" menu-label="Download options">
|
||||
<x-menu-item label="As a ZIP" icon="folder_zip" />
|
||||
<x-menu-item label="One by one" icon="download" />
|
||||
</x-split-button>
|
||||
|
||||
<x-split-button label="Share" variant="tonal" size="md" menu-label="Share options">
|
||||
<x-menu-item label="Copy link" icon="content_copy" />
|
||||
<x-menu-item label="Email" icon="mail" />
|
||||
</x-split-button>
|
||||
|
||||
<x-split-button label="Save" variant="outlined" size="xs" menu-label="Save options">
|
||||
<x-menu-item label="Save as draft" />
|
||||
</x-split-button>
|
||||
BLADE,
|
||||
'FABs and extended FABs' => <<<'BLADE'
|
||||
<x-fab icon="add" tooltip="New share" />
|
||||
<x-fab icon="edit" size="md" color="secondary" tooltip="Edit" />
|
||||
<x-fab icon="upload" size="lg" color="tertiary" tooltip="Upload" />
|
||||
<x-fab icon="add" label="New share" />
|
||||
<x-fab icon="upload" label="Upload" size="md" variant="filled" />
|
||||
BLADE,
|
||||
'FAB menu' => <<<'BLADE'
|
||||
<div class="flex h-72 w-full items-end justify-end">
|
||||
<x-fab-menu label="New">
|
||||
<x-fab-menu-item label="Upload files" icon="upload_file" />
|
||||
<x-fab-menu-item label="Upload a folder" icon="drive_folder_upload" />
|
||||
<x-fab-menu-item label="Paste text" icon="content_paste" />
|
||||
</x-fab-menu>
|
||||
</div>
|
||||
BLADE,
|
||||
];
|
||||
@endphp
|
||||
|
||||
<section id="buttons" class="scroll-mt-24 space-y-6">
|
||||
<h2 class="type-headline-md">Buttons</h2>
|
||||
|
||||
<p class="max-w-3xl type-body-md text-on-surface-variant">
|
||||
<code><x-button></code>: label buttons, icon buttons and toggles in M3 Expressive's five sizes.
|
||||
</p>
|
||||
|
||||
@foreach ($examples as $title => $code)
|
||||
<x-showcase::example :$title :$code />
|
||||
@endforeach
|
||||
</section>
|
||||
@@ -2,16 +2,19 @@
|
||||
id="icons"
|
||||
class="scroll-mt-24 space-y-6"
|
||||
x-data="{
|
||||
names: {{ json_encode(\NoNameWeb\LivewireMaterial\Support\SvgFile::symbolNames()) }},
|
||||
base: '{{ rtrim(route('livewire-material.showcase', [], false), '/') }}/symbols',
|
||||
names: [],
|
||||
query: '',
|
||||
filled: false,
|
||||
async load() {
|
||||
this.names = await (await fetch('{{ route('livewire-material.symbols', [], false) }}')).json();
|
||||
},
|
||||
get matches() {
|
||||
const query = this.query.trim().toLowerCase().replaceAll(' ', '_');
|
||||
|
||||
return (query === '' ? this.names : this.names.filter((name) => name.includes(query))).slice(0, 120);
|
||||
},
|
||||
}"
|
||||
x-intersect.once="load()"
|
||||
>
|
||||
<h2 class="type-headline-md">Icons</h2>
|
||||
|
||||
@@ -37,7 +40,7 @@
|
||||
<span
|
||||
class="size-6 bg-current"
|
||||
x-bind:style="{
|
||||
mask: `url('${base}/${filled ? 'filled' : 'outlined'}/${name}.svg') center / contain no-repeat`,
|
||||
mask: `url('{{ rtrim(route('livewire-material.showcase', [], false), '/') }}/symbols/${filled ? 'filled' : 'outlined'}/${name}.svg') center / contain no-repeat`,
|
||||
}"
|
||||
></span>
|
||||
<code class="w-full break-all type-label-sm text-on-surface-variant" x-text="name"></code>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
@php
|
||||
$examples = [
|
||||
'A menu' => <<<'BLADE'
|
||||
<x-menu label="Share actions">
|
||||
<x-slot:trigger>
|
||||
<x-button icon="more_vert" tooltip="More" />
|
||||
</x-slot:trigger>
|
||||
|
||||
<x-menu-item label="Copy link" icon="content_copy" shortcut="⌘C" />
|
||||
<x-menu-item label="Download" icon="download" />
|
||||
<x-menu-item label="Rename" icon="edit" description="Change what recipients see" />
|
||||
<x-menu-separator />
|
||||
<x-menu-item label="Delete" icon="delete" />
|
||||
</x-menu>
|
||||
|
||||
<x-menu label="Sort" position="bottom-end">
|
||||
<x-slot:trigger>
|
||||
<x-button label="Sort" icon-right="arrow_drop_down" variant="outlined" />
|
||||
</x-slot:trigger>
|
||||
|
||||
<x-menu-group label="Sort by">
|
||||
<x-menu-item label="Newest" :selected="true" keep-open />
|
||||
<x-menu-item label="Largest" :selected="false" keep-open />
|
||||
<x-menu-item label="Expiring soon" :selected="false" keep-open />
|
||||
</x-menu-group>
|
||||
<x-menu-separator />
|
||||
<x-menu-item label="Reset" icon="restart_alt" disabled />
|
||||
</x-menu>
|
||||
|
||||
<x-menu label="Vibrant" vibrant>
|
||||
<x-slot:trigger>
|
||||
<x-button label="Vibrant" variant="tonal" color="tertiary" />
|
||||
</x-slot:trigger>
|
||||
|
||||
<x-menu-item label="Upload files" icon="upload_file" />
|
||||
<x-menu-item label="Upload a folder" icon="drive_folder_upload" />
|
||||
</x-menu>
|
||||
BLADE,
|
||||
];
|
||||
@endphp
|
||||
|
||||
<section id="menus" class="scroll-mt-24 space-y-6">
|
||||
<h2 class="type-headline-md">Menus</h2>
|
||||
|
||||
<p class="max-w-3xl type-body-md text-on-surface-variant">
|
||||
<code><x-menu></code> with <code><x-menu-item></code>, <code><x-menu-group></code> and <code><x-menu-separator></code>.
|
||||
Open one with the keyboard too: arrows, Home, End, a letter, Escape.
|
||||
</p>
|
||||
|
||||
@foreach ($examples as $title => $code)
|
||||
<x-showcase::example :$title :$code />
|
||||
@endforeach
|
||||
</section>
|
||||
Reference in New Issue
Block a user