Put the split button on its own geometry
It borrowed the connected group's corner variables, so its inner corners were wrong at four of five sizes and shrank under the finger where SplitButton*Tokens grows them; its chevron took the icon-button table's size at every step, sat dead centre, and turned over on the expressive spring. groups.css now carries --split-inner, --split-icon and --split-nudge per size, and the rotation uses M3's standard scheme. Plan step 18, actions.md ACT-06, ACT-07, ACT-29, ACT-30. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
e4de067350
commit
d560e7449c
@@ -13,8 +13,15 @@
|
||||
* full, the inner corners small, smaller still while pressed, and a selected segment fully round
|
||||
* (ConnectedButtonGroupSmallTokens and the M3 Expressive connected button group spec).
|
||||
*
|
||||
* Split button (`<x-split-button>`): the same idea for two halves; the trailing half turns
|
||||
* round and its chevron turns over while its menu is open (SplitButton*Tokens).
|
||||
* Split button (`<x-split-button>`): the same idea for two halves, on its own corner scale —
|
||||
* SplitButton*Tokens gives the inner corner 4/4/4/8/12px at rest and *grows* it to 8/12/12/20/20px
|
||||
* under the finger, the opposite of a connected group, so `--split-inner*` is separate from
|
||||
* `--group-inner*`. The trailing half turns round and its chevron turns over while its menu is
|
||||
* open, on M3's standard scheme rather than the expressive springs (the site: "the trailing
|
||||
* button uses the standard motion scheme, not expressive, when rotating"), and the chevron sits
|
||||
* a little towards the leading half so the pair reads as one control (`--split-nudge`:
|
||||
* 1/1/2/3/6px). `--split-icon` is the trailing icon's own size, 22/22/26/38/50px, which the
|
||||
* icon-button table does not know about.
|
||||
*
|
||||
* "Full" here is half the size's height (`--group-full`), never `--md-sys-shape-corner-full`'s
|
||||
* 9999px. One element mixes full outer corners with small inner ones, and when a box's radii
|
||||
@@ -47,6 +54,12 @@
|
||||
padding-inline-start: calc(var(--group-pad) - var(--group-grow));
|
||||
}
|
||||
|
||||
[data-button-group='split'] { --split-inner: var(--md-sys-shape-corner-xs); --split-inner-pressed: var(--md-sys-shape-corner-md); --split-icon: 22px; --split-nudge: 1px; }
|
||||
[data-button-group='split'][data-size='xs'] { --split-inner-pressed: var(--md-sys-shape-corner-sm); }
|
||||
[data-button-group='split'][data-size='md'] { --split-icon: 26px; --split-nudge: 2px; }
|
||||
[data-button-group='split'][data-size='lg'] { --split-inner: var(--md-sys-shape-corner-sm); --split-inner-pressed: var(--md-sys-shape-corner-lg-increased); --split-icon: 38px; --split-nudge: 3px; }
|
||||
[data-button-group='split'][data-size='xl'] { --split-inner: var(--md-sys-shape-corner-md); --split-inner-pressed: var(--md-sys-shape-corner-lg-increased); --split-icon: 50px; --split-nudge: 6px; }
|
||||
|
||||
/*
|
||||
* A connected segment at the two smallest sizes is 32px or 40px tall, and an icon-only one is as
|
||||
* narrow as it is tall. M3 names both numbers and tells you not to reduce them: "XS and S
|
||||
@@ -65,18 +78,28 @@
|
||||
*/
|
||||
[data-button-group='connected'] > *,
|
||||
[data-split] {
|
||||
--group-corner: var(--group-inner);
|
||||
border-start-start-radius: var(--group-corner);
|
||||
border-end-start-radius: var(--group-corner);
|
||||
border-start-end-radius: var(--group-corner);
|
||||
border-end-end-radius: var(--group-corner);
|
||||
}
|
||||
|
||||
[data-button-group='connected'] > :active,
|
||||
[data-split]:active {
|
||||
[data-button-group='connected'] > * {
|
||||
--group-corner: var(--group-inner);
|
||||
}
|
||||
|
||||
[data-button-group='connected'] > :active {
|
||||
--group-corner: var(--group-inner-pressed);
|
||||
}
|
||||
|
||||
[data-split] {
|
||||
--group-corner: var(--split-inner);
|
||||
}
|
||||
|
||||
[data-split]:active {
|
||||
--group-corner: var(--split-inner-pressed);
|
||||
}
|
||||
|
||||
[data-button-group='connected'] > :is([aria-pressed='true'], :has(:checked)),
|
||||
[data-split='trailing'][aria-expanded='true'] {
|
||||
--group-corner: var(--group-full);
|
||||
@@ -94,8 +117,17 @@
|
||||
border-end-end-radius: var(--group-full);
|
||||
}
|
||||
|
||||
/*
|
||||
* The trailing chevron: its own size, and `--split-nudge` off centre towards the leading half —
|
||||
* equal and opposite margins move it by exactly that much inside a centred flex row, in whichever
|
||||
* direction the writing mode runs.
|
||||
*/
|
||||
[data-split='trailing'] svg {
|
||||
transition: rotate var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);
|
||||
width: var(--split-icon);
|
||||
height: var(--split-icon);
|
||||
margin-inline-start: calc(-1 * var(--split-nudge));
|
||||
margin-inline-end: var(--split-nudge);
|
||||
transition: rotate var(--md-sys-motion-duration-short) var(--md-sys-motion-easing-standard);
|
||||
}
|
||||
|
||||
[data-split='trailing'][aria-expanded='true'] svg {
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
|
||||
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. The corners are resources/css/components/groups.css. --}}
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user