{{-- An M3 Expressive button group: related ``s in a row. Standard (the default): the buttons stand apart, and pressing a label button widens it while its neighbours give way. `connected`: 2px apart with small inner corners, the shape that replaced M3's segmented button; a selected (aria-pressed) button rounds fully. Give `size` the size of the buttons inside, so the spacing and corners match. `selection` is M3's third button-group configuration — `single`, `multi`, and either of them with `required` ("selection-required"): The group owns `aria-pressed` from then on: pressing a button writes the pressed one's `value` (an array with `multi`) to `wire:model` or `x-model`, deselects the others in `single`, and with `required` refuses the press that would leave nothing selected. Without a model it reads the buttons' own `aria-pressed` once and takes it from there. A button with no `value` is known by its label. The group manages state and shape, not colour: each `` draws its own selected colours from its own `:selected`, which is why the example binds both from one property. This is where `` and `` part, and neither absorbs the other — `` is for a choice whose options are *data*: it renders real radios or checkboxes from an `options` array, so it posts in a plain form, takes the browser's own keyboard, and paints its own segments. `` is for buttons you write yourself — icons, tooltips, mixed content, a `wire:click` of their own — and never becomes a form control. Reach for `` first. `shape` is M3's "Default shape | Round, square" configuration, and covers every button in the group so it need not be written on each one: `square` squares a connected group's two ends to the corner its inner edges take (M3's square table, 4/8/8/16/20dp by size) and gives a standard group's buttons the square corner scale `` draws. Selection still morphs the other way — M3 has a toggle inside a group "swap shape square/round on selection" — so a selected button in a square group rounds. A group never wraps to a second line — M3's rule, and the press expansion only reaches a neighbour on the same line anyway. Where a row is too long for its window the answer is a smaller `size` or fewer buttons, or two groups stacked. Spacing from the M3 Expressive spec (ButtonGroupSmallTokens: 12px at the small size). The shapes are resources/css/components/groups.css. --}} @props([ 'connected' => false, 'size' => 'sm', 'label' => null, 'shape' => 'round', 'selection' => null, 'required' => false, ]) @php $size = in_array($size, ['xs', 'sm', 'md', 'lg', 'xl'], true) ? $size : 'sm'; $shape = $shape === 'square' ? 'square' : 'round'; $selection = in_array($selection, ['single', 'multi'], true) ? $selection : null; $multiple = $selection === 'multi'; $wire = $attributes->wire('model'); $model = $selection !== null && $wire->value() !== false; // `wire:model` is entangled into the Alpine state below, so it must not also reach the div, // where Livewire would find no input to bind. `x-model` stays: `x-modelable` pairs with it. $attributes = $model ? $attributes->whereDoesntStartWith('wire:model') : $attributes; @endphp
class([ 'inline-flex items-center', 'gap-0.5' => $connected, 'gap-[18px]' => ! $connected && $size === 'xs', 'gap-3' => ! $connected && $size === 'sm', 'gap-2' => ! $connected && in_array($size, ['md', 'lg', 'xl'], true), ]) }} > {{ $slot }}