Plan step 36. <x-button> renders data-md-button with its variant, colour, size, shape, icon-button width, selected state and compact FAB as data-md-* attributes, and passes the glyph's size to <x-icon>. button.css draws Button*Tokens' geometry per size, the colour roles through custom properties that the disabled treatment replaces, the state layer, focus ring and 48px target, and the compact FAB below 600px. Its corner rules carry no specificity (:where), so a group's stylesheet reshapes the buttons inside it with any selector; the split button no longer passes an empty corners prop, which is gone. data-icon-button becomes data-md-icon-button, also in groups.css, toolbar.css and theme-toggle's own button (navigation group), and the AppBarTest assertions follow the new hooks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
74 lines
3.1 KiB
PHP
74 lines
3.1 KiB
PHP
{{-- An M3 Expressive split button: an action, and a menu of its alternatives.
|
|
|
|
<x-split-button label="Download all" icon="download" wire:click="downloadZip" menu-label="Download options">
|
|
<x-menu-item label="Download as ZIP" wire:click="downloadZip" />
|
|
<x-menu-item label="Download files one by one" wire:click="downloadEach" />
|
|
</x-split-button>
|
|
|
|
Attributes (wire:click, spinner…) go to the leading button; the slot is the menu. `variant` is
|
|
`filled` (the default), `tonal`, `outlined` or `elevated` — a text split button does not exist
|
|
in M3 — with `color` and `size` as on `<x-button>`. The halves sit 2px apart; the trailing
|
|
one rounds fully and turns its chevron over while the menu is open. `menu-label` names the
|
|
trailing button and the menu for screen readers.
|
|
|
|
Padding from SplitButton*Tokens (androidx Compose Material 3, Apache-2.0): the leading button
|
|
keeps less room on its inner side at the two smallest sizes, and the trailing button is 48px
|
|
wide there. resources/css/components/groups.css carries the rest of the spec, which is all
|
|
geometry: the inner corners (4/4/4/8/12px, growing under the finger, not shrinking as a
|
|
connected group's do), the trailing icon's own size (22/22/26/38/50px, which the icon-button
|
|
table has no entry for), the 1/1/2/3/6px nudge that sits the chevron towards the leading half,
|
|
and the standard motion scheme M3 asks for while it turns over. --}}
|
|
|
|
@props([
|
|
'label' => null,
|
|
'icon' => null,
|
|
'variant' => 'filled',
|
|
'color' => 'primary',
|
|
'size' => 'sm',
|
|
'disabled' => false,
|
|
'spinner' => null,
|
|
'menuLabel' => null,
|
|
'position' => 'bottom-end',
|
|
])
|
|
|
|
@php
|
|
$variant = in_array($variant, ['filled', 'tonal', 'outlined', 'elevated'], true) ? $variant : 'filled';
|
|
$size = in_array($size, ['xs', 'sm', 'md', 'lg', 'xl'], true) ? $size : 'sm';
|
|
$menuLabel ??= __('More options');
|
|
|
|
$leadingPadding = ['xs' => 'pe-2.5', 'sm' => 'pe-3', 'md' => '', 'lg' => '', 'xl' => ''][$size];
|
|
$trailingWidth = ['xs' => 'w-12', 'sm' => 'w-12', 'md' => '', 'lg' => '', 'xl' => ''][$size];
|
|
@endphp
|
|
|
|
<div data-button-group="split" data-size="{{ $size }}" {{ $attributes->only('class')->class('inline-flex items-center gap-0.5') }}>
|
|
<x-livewire-material::button
|
|
{{ $attributes->except('class') }}
|
|
:label="$label"
|
|
:icon="$icon"
|
|
:variant="$variant"
|
|
:color="$color"
|
|
:size="$size"
|
|
:disabled="$disabled"
|
|
:spinner="$spinner"
|
|
data-split="leading"
|
|
:class="$leadingPadding"
|
|
/>
|
|
|
|
<x-livewire-material::menu :position="$position" :label="$menuLabel">
|
|
<x-slot:trigger>
|
|
<x-livewire-material::button
|
|
icon="keyboard_arrow_down"
|
|
:aria-label="$menuLabel"
|
|
:variant="$variant"
|
|
:color="$color"
|
|
:size="$size"
|
|
:disabled="$disabled"
|
|
data-split="trailing"
|
|
:class="$trailingWidth"
|
|
/>
|
|
</x-slot:trigger>
|
|
|
|
{{ $slot }}
|
|
</x-livewire-material::menu>
|
|
</div>
|