Square a button group and the choice drawn as one

Plan step 22, actions.md § Missing (Square-by-default button groups): M3
lists "Default shape | Round, square" as a button-group configuration and
neither `<x-button-group>` nor `<x-group>` had a `shape` prop, so a group
of square buttons still drew round outer corners.

`shape="square"` passes the square corner scale to every child through
`data-shape` and two new variables in groups.css: `--group-outer` is what
the two ends of a group round to (half the height when round, the corner
its inner edges take when square — M3's square table, 4/8/8/16/20dp), and
`--group-square`/`--group-square-pressed` give a standard group's buttons
the scale `<x-button shape="square">` draws. The selected rules keep
`--group-full`, so a selected button in a square group rounds: M3 has a
toggle inside a group swap shape on selection either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:40:14 +02:00
co-authored by Claude Opus 5
parent 88c46001fb
commit 5d0e9bc12f
6 changed files with 96 additions and 11 deletions
@@ -20,6 +20,22 @@ it('connects buttons 2px apart', function () {
->toContain('gap-0.5');
});
it('squares a group, and a choice drawn as one', function () {
// M3 lists "Default shape | Round, square" as a button-group configuration; the shape covers
// every button in the group, so it need not be written on each one.
expect((string) $this->blade('<x-button-group shape="square"><x-button label="Day" /></x-button-group>'))
->toContain('data-shape="square"')
->and((string) $this->blade('<x-button-group connected shape="square"><x-button label="Day" /></x-button-group>'))
->toContain('data-button-group="connected"')
->toContain('data-shape="square"')
->and((string) $this->blade('<x-button-group><x-button label="Day" /></x-button-group>'))
->toContain('data-shape="round"')
->and((string) $this->blade('<x-group shape="square" name="x" :options="[[\'id\' => \'a\', \'name\' => \'A\']]" />'))
->toContain('data-shape="square"')
->and((string) $this->blade('<x-group name="x" :options="[[\'id\' => \'a\', \'name\' => \'A\']]" />'))
->toContain('data-shape="round"');
});
it('never wraps a group onto a second line', function () {
expect((string) $this->blade('<x-button-group><x-button label="Day" /></x-button-group>'))
->not->toContain('flex-wrap');