From 573d94fe6e25aec45521406809e62323fedd7247 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold Date: Mon, 14 Sep 2026 06:00:12 +0200 Subject: [PATCH] Give the xs button M3's 16dp padding, and stop groups wrapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ButtonXSmallTokens puts 16dp either side of an xs label, where the button, the segment and --group-pad all wrote 12px; the variants table calls 16dp the Expressive value twice over. A standard button group also dropped onto a second line on a narrow window, which M3 forbids — and the press expansion only ever reaches a neighbour on the same line. Plan step 18, actions.md ACT-09, ACT-10. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/css/components/groups.css | 2 +- resources/views/components/button-group.blade.php | 5 ++++- resources/views/components/button.blade.php | 2 +- resources/views/components/group.blade.php | 2 +- tests/Feature/Components/ButtonGroupTest.php | 6 +++++- tests/Feature/Components/ButtonTest.php | 2 +- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/resources/css/components/groups.css b/resources/css/components/groups.css index 1251eb31..6058a39a 100644 --- a/resources/css/components/groups.css +++ b/resources/css/components/groups.css @@ -36,7 +36,7 @@ --group-full: 1.25rem; } -[data-button-group][data-size='xs'] { --group-pad: 0.75rem; --group-grow: 4px; --group-inner: var(--md-sys-shape-corner-xs); --group-inner-pressed: 2px; --group-full: 1rem; } +[data-button-group][data-size='xs'] { --group-pad: 1rem; --group-grow: 4px; --group-inner: var(--md-sys-shape-corner-xs); --group-inner-pressed: 2px; --group-full: 1rem; } [data-button-group][data-size='sm'] { --group-pad: 1rem; --group-grow: 6px; --group-full: 1.25rem; } [data-button-group][data-size='md'] { --group-pad: 1.5rem; --group-grow: 8px; --group-full: 1.75rem; } [data-button-group][data-size='lg'] { --group-pad: 3rem; --group-grow: 16px; --group-inner: var(--md-sys-shape-corner-lg); --group-inner-pressed: var(--md-sys-shape-corner-md); --group-full: 3rem; } diff --git a/resources/views/components/button-group.blade.php b/resources/views/components/button-group.blade.php index a38bed0b..8a670aa5 100644 --- a/resources/views/components/button-group.blade.php +++ b/resources/views/components/button-group.blade.php @@ -11,6 +11,10 @@ the size of the buttons inside, so the spacing and corners match. For a choice bound to a property, `` draws a connected group of radios. + 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. --}} @@ -32,7 +36,6 @@ {{ $attributes->class([ 'inline-flex items-center', 'gap-0.5' => $connected, - 'flex-wrap' => ! $connected, 'gap-[18px]' => ! $connected && $size === 'xs', 'gap-3' => ! $connected && $size === 'sm', 'gap-2' => ! $connected && in_array($size, ['md', 'lg', 'xl'], true), diff --git a/resources/views/components/button.blade.php b/resources/views/components/button.blade.php index 02eac82d..71ac4209 100644 --- a/resources/views/components/button.blade.php +++ b/resources/views/components/button.blade.php @@ -150,7 +150,7 @@ 'xl' => ['narrow' => 'h-34 w-26', 'default' => 'size-34', 'wide' => 'h-34 w-46'], ][$size][$width] : [ - 'xs' => 'h-8 gap-2 px-3 type-label-lg', + 'xs' => 'h-8 gap-2 px-4 type-label-lg', 'sm' => 'h-10 gap-2 px-4 type-label-lg', 'md' => 'h-14 gap-2 px-6 type-title-md', 'lg' => 'h-24 gap-3 px-12 type-headline-sm', diff --git a/resources/views/components/group.blade.php b/resources/views/components/group.blade.php index 22c5b4bb..8d8b5d01 100644 --- a/resources/views/components/group.blade.php +++ b/resources/views/components/group.blade.php @@ -51,7 +51,7 @@ $small = in_array($size, ['xs', 'sm'], true); $segment = [ - 'xs' => 'h-8 gap-2 px-3 type-label-lg', + 'xs' => 'h-8 gap-2 px-4 type-label-lg', 'sm' => 'h-10 gap-2 px-4 type-label-lg', 'md' => 'h-14 gap-2 px-6 type-title-md', 'lg' => 'h-24 gap-3 px-12 type-headline-sm', diff --git a/tests/Feature/Components/ButtonGroupTest.php b/tests/Feature/Components/ButtonGroupTest.php index 9cdd7986..fbf43af5 100644 --- a/tests/Feature/Components/ButtonGroupTest.php +++ b/tests/Feature/Components/ButtonGroupTest.php @@ -17,7 +17,11 @@ it('groups buttons with the spacing of their size', function () { it('connects buttons 2px apart', function () { expect((string) $this->blade('')) ->toContain('data-button-group="connected"') - ->toContain('gap-0.5') + ->toContain('gap-0.5'); +}); + +it('never wraps a group onto a second line', function () { + expect((string) $this->blade('')) ->not->toContain('flex-wrap'); }); diff --git a/tests/Feature/Components/ButtonTest.php b/tests/Feature/Components/ButtonTest.php index 9bf8930f..cdaff032 100644 --- a/tests/Feature/Components/ButtonTest.php +++ b/tests/Feature/Components/ButtonTest.php @@ -49,7 +49,7 @@ it('sizes a label button on Expressive\'s scale', function (string $size, string expect($html)->toContain($classes)->toContain($icon); })->with([ - 'xs' => ['xs', 'h-8 gap-2 px-3 type-label-lg', 'size-5'], + 'xs' => ['xs', 'h-8 gap-2 px-4 type-label-lg', 'size-5'], 'sm' => ['sm', 'h-10 gap-2 px-4 type-label-lg', 'size-5'], 'md' => ['md', 'h-14 gap-2 px-6 type-title-md', 'size-6'], 'lg' => ['lg', 'h-24 gap-3 px-12 type-headline-sm', 'size-8'],