diff --git a/resources/css/components/groups.css b/resources/css/components/groups.css index b556acd3..1251eb31 100644 --- a/resources/css/components/groups.css +++ b/resources/css/components/groups.css @@ -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 (``): 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 (``): 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 { diff --git a/resources/views/components/split-button.blade.php b/resources/views/components/split-button.blade.php index 13f2ce37..ff430b88 100644 --- a/resources/views/components/split-button.blade.php +++ b/resources/views/components/split-button.blade.php @@ -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,