md-button-group spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
A set of related buttons that behave as one control. It wraps
md-button / md-icon-button
children, forces them into toggle mode, and owns selection, roving tabindex,
arrow-key navigation and — in connected mode — the fused container shape.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-button-group variant="connected" selection-mode="single-select" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
<md-icon-button value="justify" icon="format_align_justify" aria-label="Justify"></md-icon-button>
</md-button-group>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdButtonGroup variant="connected" selectionMode="single-select" required aria-label="Text alignment">
<MdIconButton value="left" icon="format_align_left" aria-label="Align left" selected></MdIconButton>
<MdIconButton value="center" icon="format_align_center" aria-label="Align center"></MdIconButton>
<MdIconButton value="right" icon="format_align_right" aria-label="Align right"></MdIconButton>
<MdIconButton value="justify" icon="format_align_justify" aria-label="Justify"></MdIconButton>
</MdButtonGroup>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-button-group variant="connected" selection-mode="single-select" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
<md-icon-button value="justify" icon="format_align_justify" aria-label="Justify"></md-icon-button>
</md-button-group><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<md-button-group variant="connected" selection-mode="single-select" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
<md-icon-button value="justify" icon="format_align_justify" aria-label="Justify"></md-icon-button>
</md-button-group>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<md-button-group variant="connected" selection-mode="single-select" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
<md-icon-button value="justify" icon="format_align_justify" aria-label="Justify"></md-icon-button>
</md-button-group>
Already installed? See the
Installation guide for one-time package setup
(core + tokens, fonts). Each tab below shows two patterns for using
md-button-group in your project: Option A registers every AWC UI
component at once (simplest), Option B imports only this component for
tree-shake-friendly bundles.
<!-- ─── Option A: global registration (all components) ─── -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- ─── Option B: single import (tree-shake only md-button-group) ─── -->
<script type="module">
import '@awc-ui/core/components/md-button-group';
</script>
<md-button-group></md-button-group>// ─── Option A: typed React wrapper (registers all components) ───
// Importing from '@awc-ui/react' calls defineCustomElements() as a
// side effect, so every md-* element becomes available in the browser.
import { MdButtonGroup } from '@awc-ui/react';
export function Example() {
return <MdButtonGroup></MdButtonGroup>;
}
// ─── Option B: single import (tree-shake to only md-button-group) ───
// Skip the wrapper and use the raw custom element. Smallest bundle,
// but you lose typed props/events on JSX.
import '@awc-ui/core/components/md-button-group';
export function ExampleTreeShaken() {
return <md-button-group></md-button-group>;
}// ─── Option A: schema module (any md-* element accepted) ───
// Pair with `defineCustomElements(window)` in main.ts.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<md-button-group></md-button-group>`,
})
export class ExampleComponent {}
// ─── Option B: typed directive (tree-shake friendly) ───
// Pair with `import '@awc-ui/core/components/md-button-group'` in main.ts.
import { Component } from '@angular/core';
import { MdButtonGroup } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [MdButtonGroup],
template: `<md-button-group></md-button-group>`,
})
export class ExampleTreeShakenComponent {}<!-- ─── Option A: typed Vue wrapper (registers all components) ─── -->
<script setup lang="ts">
import { MdButtonGroup } from '@awc-ui/vue';
</script>
<template>
<MdButtonGroup></MdButtonGroup>
</template>
<!-- ─── Option B: single import (tree-shake to only md-button-group) ─── -->
<script setup lang="ts">
import '@awc-ui/core/components/md-button-group';
</script>
<template>
<md-button-group></md-button-group>
</template><!-- ─── Option A: global registration (done once in main entry) ─── -->
<!-- main.ts: -->
<!-- import { defineCustomElements } from '@awc-ui/svelte'; -->
<!-- defineCustomElements(window); -->
<md-button-group></md-button-group>
<!-- ─── Option B: single import (tree-shake to only md-button-group) ─── -->
<script lang="ts">
import '@awc-ui/core/components/md-button-group';
</script>
<md-button-group></md-button-group>connected).| Situation | Use instead |
|---|---|
| Choosing between 2–5 exclusive view/mode options with labels | md-segmented-button |
| A default action plus variations of it | md-split-button |
| Unrelated actions that happen to sit near each other | Separate md-buttons |
Form field selection bound to a <form> | md-radio / md-checkbox |
| Many options, or options that need a menu | md-menu, md-select |
| Navigating between destinations | md-tabs, md-navigation-bar |
| A single action | md-button |
This is the part that surprises people.
toggle = true on every child — you never set it yourself.connectedLeft, connectedRight, groupTabindex and value
positioning. Setting those by hand breaks the roving tabindex and the border
trimming.value. It is the identity carried in values,
added and removed.single-select it deselects the others; with required it re-selects the
clicked button if the click would have emptied the selection.md-button and md-icon-button children are discovered. Anything else
is ignored.<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">loose</span>
<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b">Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">grouped</span>
<md-button-group selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b" selected>Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>loose</span>
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdButton variant="tonal" value="a">Day</MdButton>
<MdButton variant="tonal" value="b">Week</MdButton>
<MdButton variant="tonal" value="c">Month</MdButton>
</div>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>grouped</span>
<MdButtonGroup selectionMode="single-select" aria-label="Range">
<MdButton variant="tonal" value="a">Day</MdButton>
<MdButton variant="tonal" value="b" selected>Week</MdButton>
<MdButton variant="tonal" value="c">Month</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">loose</span>
<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b">Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">grouped</span>
<md-button-group selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b" selected>Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">loose</span>
<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b">Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">grouped</span>
<md-button-group selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b" selected>Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">loose</span>
<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center;">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b">Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">grouped</span>
<md-button-group selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="a">Day</md-button>
<md-button variant="tonal" value="b" selected>Week</md-button>
<md-button variant="tonal" value="c">Month</md-button>
</md-button-group>
</div>The markup for the children is the same in both rows. Grouping is what makes them toggle, share one tab stop, and coordinate their selection. Tab into each row to feel the difference: the loose row has three tab stops, the grouped row has one.
standard spaces the children with a gap. connected fuses them into one
container and drives the inner corner radii.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group variant="standard" aria-label="Standard view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Connected view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
<MdButtonGroup variant="standard" aria-label="Standard view mode">
<MdButton value="day">Day</MdButton>
<MdButton value="week" selected>Week</MdButton>
<MdButton value="month">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="connected" aria-label="Connected view mode">
<MdButton value="day">Day</MdButton>
<MdButton value="week" selected>Week</MdButton>
<MdButton value="month">Month</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group variant="standard" aria-label="Standard view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Connected view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group variant="standard" aria-label="Standard view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Connected view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group variant="standard" aria-label="Standard view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Connected view mode">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>single-select (the default) behaves like a radio group — role radiogroup,
one selection at a time. multi-select allows several at once and uses role
group.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group selection-mode="single-select" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<md-button-group selection-mode="multi-select" variant="connected" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold" selected></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic"></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline" selected></md-icon-button>
</md-button-group>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
<MdButtonGroup selectionMode="single-select" variant="connected" required aria-label="Text alignment">
<MdIconButton value="left" icon="format_align_left" aria-label="Align left" selected></MdIconButton>
<MdIconButton value="center" icon="format_align_center" aria-label="Align center"></MdIconButton>
<MdIconButton value="right" icon="format_align_right" aria-label="Align right"></MdIconButton>
</MdButtonGroup>
<MdButtonGroup selectionMode="multi-select" variant="connected" aria-label="Text style">
<MdIconButton value="bold" icon="format_bold" aria-label="Bold" selected></MdIconButton>
<MdIconButton value="italic" icon="format_italic" aria-label="Italic"></MdIconButton>
<MdIconButton value="underline" icon="format_underlined" aria-label="Underline" selected></MdIconButton>
</MdButtonGroup>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group selection-mode="single-select" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<md-button-group selection-mode="multi-select" variant="connected" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold" selected></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic"></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline" selected></md-icon-button>
</md-button-group>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group selection-mode="single-select" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<md-button-group selection-mode="multi-select" variant="connected" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold" selected></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic"></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline" selected></md-icon-button>
</md-button-group>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group selection-mode="single-select" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<md-button-group selection-mode="multi-select" variant="connected" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold" selected></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic"></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline" selected></md-icon-button>
</md-button-group>
</div>required prevents the selection from ever emptying — the right choice for a
mode switch where “nothing selected” is meaningless.
Set size on the group. It assigns that size to every child on load and on
every change — the same five rungs as md-button, and
the same trap: the default is sm, not md. A per-child size does not
survive; see Group-owned child props.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 16px; align-items: flex-start;">
<md-button-group size="xs" variant="connected" aria-label="Extra small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="sm" variant="connected" aria-label="Small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="md" variant="connected" aria-label="Medium">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="lg" variant="connected" aria-label="Large">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', alignItems: 'flex-start' }}>
<MdButtonGroup size="xs" variant="connected" aria-label="Extra small">
<MdButton value="a" selected>Day</MdButton>
<MdButton value="b">Week</MdButton>
<MdButton value="c">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup size="sm" variant="connected" aria-label="Small">
<MdButton value="a" selected>Day</MdButton>
<MdButton value="b">Week</MdButton>
<MdButton value="c">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup size="md" variant="connected" aria-label="Medium">
<MdButton value="a" selected>Day</MdButton>
<MdButton value="b">Week</MdButton>
<MdButton value="c">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup size="lg" variant="connected" aria-label="Large">
<MdButton value="a" selected>Day</MdButton>
<MdButton value="b">Week</MdButton>
<MdButton value="c">Month</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display: flex; flex-direction: column; gap: 16px; align-items: flex-start;">
<md-button-group size="xs" variant="connected" aria-label="Extra small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="sm" variant="connected" aria-label="Small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="md" variant="connected" aria-label="Medium">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="lg" variant="connected" aria-label="Large">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 16px; align-items: flex-start;">
<md-button-group size="xs" variant="connected" aria-label="Extra small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="sm" variant="connected" aria-label="Small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="md" variant="connected" aria-label="Medium">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="lg" variant="connected" aria-label="Large">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 16px; align-items: flex-start;">
<md-button-group size="xs" variant="connected" aria-label="Extra small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="sm" variant="connected" aria-label="Small">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="md" variant="connected" aria-label="Medium">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
<md-button-group size="lg" variant="connected" aria-label="Large">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
</div>shape is set on the group and assigned to every child, exactly like
size — so a group is always one shape throughout. That matches M3, which
reserves shape variation for genuinely key interactions, not decoration.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group shape="round" variant="standard" aria-label="Round standard">
<md-button value="a" selected>Round</md-button>
<md-button value="b">Round</md-button>
<md-button value="c">Round</md-button>
</md-button-group>
<md-button-group shape="square" variant="standard" aria-label="Square standard">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
<md-button-group shape="square" variant="connected" aria-label="Square connected">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
<MdButtonGroup shape="round" variant="standard" aria-label="Round standard">
<MdButton value="a" selected>Round</MdButton>
<MdButton value="b">Round</MdButton>
<MdButton value="c">Round</MdButton>
</MdButtonGroup>
<MdButtonGroup shape="square" variant="standard" aria-label="Square standard">
<MdButton value="a" selected>Square</MdButton>
<MdButton value="b">Square</MdButton>
<MdButton value="c">Square</MdButton>
</MdButtonGroup>
<MdButtonGroup shape="square" variant="connected" aria-label="Square connected">
<MdButton value="a" selected>Square</MdButton>
<MdButton value="b">Square</MdButton>
<MdButton value="c">Square</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group shape="round" variant="standard" aria-label="Round standard">
<md-button value="a" selected>Round</md-button>
<md-button value="b">Round</md-button>
<md-button value="c">Round</md-button>
</md-button-group>
<md-button-group shape="square" variant="standard" aria-label="Square standard">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
<md-button-group shape="square" variant="connected" aria-label="Square connected">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group shape="round" variant="standard" aria-label="Round standard">
<md-button value="a" selected>Round</md-button>
<md-button value="b">Round</md-button>
<md-button value="c">Round</md-button>
</md-button-group>
<md-button-group shape="square" variant="standard" aria-label="Square standard">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
<md-button-group shape="square" variant="connected" aria-label="Square connected">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display: flex; flex-direction: column; gap: 20px;">
<md-button-group shape="round" variant="standard" aria-label="Round standard">
<md-button value="a" selected>Round</md-button>
<md-button value="b">Round</md-button>
<md-button value="c">Round</md-button>
</md-button-group>
<md-button-group shape="square" variant="standard" aria-label="Square standard">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
<md-button-group shape="square" variant="connected" aria-label="Square connected">
<md-button value="a" selected>Square</md-button>
<md-button value="b">Square</md-button>
<md-button value="c">Square</md-button>
</md-button-group>
</div>full-width stretches the group to its container and splits the space equally
between the children (flex: 1 1 0). It keeps a connected group tidy when
translated labels change width.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; display: flex; flex-direction: column; gap: 20px;">
<md-button-group full-width variant="connected" aria-label="Full width range">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
<md-button value="year">Year</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Capped width range" style="--md-button-group-max-width: 320px;">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ inlineSize: '100%', display: 'flex', flexDirection: 'column', gap: '20px' }}>
<MdButtonGroup fullWidth variant="connected" aria-label="Full width range">
<MdButton value="day">Day</MdButton>
<MdButton value="week" selected>Week</MdButton>
<MdButton value="month">Month</MdButton>
<MdButton value="year">Year</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="connected" aria-label="Capped width range" style={{ '--md-button-group-max-width': '320px' }}>
<MdButton value="day">Day</MdButton>
<MdButton value="week" selected>Week</MdButton>
<MdButton value="month">Month</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="inline-size: 100%; display: flex; flex-direction: column; gap: 20px;">
<md-button-group full-width variant="connected" aria-label="Full width range">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
<md-button value="year">Year</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Capped width range" style="--md-button-group-max-width: 320px;">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="inline-size: 100%; display: flex; flex-direction: column; gap: 20px;">
<md-button-group full-width variant="connected" aria-label="Full width range">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
<md-button value="year">Year</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Capped width range" style="--md-button-group-max-width: 320px;">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="inline-size: 100%; display: flex; flex-direction: column; gap: 20px;">
<md-button-group full-width variant="connected" aria-label="Full width range">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
<md-button value="year">Year</md-button>
</md-button-group>
<md-button-group variant="connected" aria-label="Capped width range" style="--md-button-group-max-width: 320px;">
<md-button value="day">Day</md-button>
<md-button value="week" selected>Week</md-button>
<md-button value="month">Month</md-button>
</md-button-group>
</div>md-button and md-icon-button can sit in the same group. Every icon-only
child needs its own aria-label.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-button-group variant="connected" selection-mode="multi-select" aria-label="Editor tools">
<md-button value="preview" icon="visibility">Preview</md-button>
<md-icon-button value="grid" icon="grid_on" aria-label="Show grid"></md-icon-button>
<md-icon-button value="ruler" icon="straighten" aria-label="Show rulers"></md-icon-button>
</md-button-group>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdButton, MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdButtonGroup variant="connected" selectionMode="multi-select" aria-label="Editor tools">
<MdButton value="preview" icon="visibility">Preview</MdButton>
<MdIconButton value="grid" icon="grid_on" aria-label="Show grid"></MdIconButton>
<MdIconButton value="ruler" icon="straighten" aria-label="Show rulers"></MdIconButton>
</MdButtonGroup>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-button-group variant="connected" selection-mode="multi-select" aria-label="Editor tools">
<md-button value="preview" icon="visibility">Preview</md-button>
<md-icon-button value="grid" icon="grid_on" aria-label="Show grid"></md-icon-button>
<md-icon-button value="ruler" icon="straighten" aria-label="Show rulers"></md-icon-button>
</md-button-group><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<md-button-group variant="connected" selection-mode="multi-select" aria-label="Editor tools">
<md-button value="preview" icon="visibility">Preview</md-button>
<md-icon-button value="grid" icon="grid_on" aria-label="Show grid"></md-icon-button>
<md-icon-button value="ruler" icon="straighten" aria-label="Show rulers"></md-icon-button>
</md-button-group>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<md-button-group variant="connected" selection-mode="multi-select" aria-label="Editor tools">
<md-button value="preview" icon="visibility">Preview</md-button>
<md-icon-button value="grid" icon="grid_on" aria-label="Show grid"></md-icon-button>
<md-icon-button value="ruler" icon="straighten" aria-label="Show rulers"></md-icon-button>
</md-button-group>| Event | Cancelable | Detail | Fires |
|---|---|---|---|
mdSelectionChange | no | MdButtonGroupChangeDetail | Every user activation that lands on a discovered child |
The group does not compare the new selection with the old one before
emitting. Re-pressing the already-selected child of a required
single-select group still fires, with added: [] and removed: [] — guard
on the diff, not on the event, if a no-op should be ignored.
interface MdButtonGroupChangeDetail { values: string[]; // full selection snapshot AFTER the change added: string[]; // newly selected (usually 0–1) removed: string[]; // newly deselected (usually 0–1) originalEvent: MouseEvent;}The event bubbles and is composed. Listen on the group — not on each
child’s mdClick, which fires before the group reconciles.
press a button to see the detail
<md-button-group id="style" selection-mode="multi-select" aria-label="Text style">
<md-button variant="tonal" value="bold" icon="format_bold">Bold</md-button>
<md-button variant="tonal" value="italic" icon="format_italic" selected>Italic</md-button>
<md-button variant="tonal" value="underline" icon="format_underlined">Underline</md-button>
</md-button-group>
<script type="module">
document.getElementById('style').addEventListener('mdSelectionChange', (e) => {
const { values, added, removed } = e.detail;
applyStyles(values); // full snapshot after the change
});
</script>import { MdButtonGroup, MdButton } from '@awc-ui/react';
export function TextStyleGroup({ onStyles }) {
return (
<MdButtonGroup
selectionMode="multi-select"
aria-label="Text style"
onMdSelectionChange={(e) => onStyles(e.detail.values)}
>
<MdButton variant="tonal" value="bold" icon="format_bold">Bold</MdButton>
<MdButton variant="tonal" value="italic" icon="format_italic" selected>Italic</MdButton>
<MdButton variant="tonal" value="underline" icon="format_underlined">Underline</MdButton>
</MdButtonGroup>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-text-style-group',
template: `
<md-button-group
selection-mode="multi-select"
aria-label="Text style"
(mdSelectionChange)="onStyles($event)"
>
<md-button variant="tonal" value="bold" icon="format_bold">Bold</md-button>
<md-button variant="tonal" value="italic" icon="format_italic" selected>Italic</md-button>
<md-button variant="tonal" value="underline" icon="format_underlined">Underline</md-button>
</md-button-group>
`,
})
export class TextStyleGroupComponent {
onStyles(e: CustomEvent) {
const { values, added, removed } = e.detail;
this.applyStyles(values); // full snapshot after the change
}
}<script setup lang="ts">
function onStyles(e: CustomEvent) {
const { values, added, removed } = e.detail;
applyStyles(values); // full snapshot after the change
}
</script>
<template>
<md-button-group
selection-mode="multi-select"
aria-label="Text style"
@mdSelectionChange="onStyles"
>
<md-button variant="tonal" value="bold" icon="format_bold">Bold</md-button>
<md-button variant="tonal" value="italic" icon="format_italic" selected>Italic</md-button>
<md-button variant="tonal" value="underline" icon="format_underlined">Underline</md-button>
</md-button-group>
</template><script lang="ts">
function onStyles(e: CustomEvent) {
const { values, added, removed } = e.detail;
applyStyles(values); // full snapshot after the change
}
</script>
<md-button-group
selection-mode="multi-select"
aria-label="Text style"
on:mdSelectionChange={onStyles}
>
<md-button variant="tonal" value="bold" icon="format_bold">Bold</md-button>
<md-button variant="tonal" value="italic" icon="format_italic" selected>Italic</md-button>
<md-button variant="tonal" value="underline" icon="format_underlined">Underline</md-button>
</md-button-group>values is the full snapshot after the change, not a delta — apply it
wholesale rather than reconciling added/removed yourself. Those two are
there for the cases where the transition matters, such as animating the button
that just turned off.
The group puts its children in toggle mode, so a single press produces a
cascade. All three bubble and are composed, so a listener on the group
receives every one of them — which is what you see in Storybook’s Actions panel:
| Order | Event | Target | Detail |
|---|---|---|---|
| 1 | mdClick | the child | { value, toggle, selected, href, target, originalEvent } |
| 2 | mdChange | the child | { selected, value } |
| 3 | mdSelectionChange | the group | { values, added, removed, originalEvent } |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-button-group id="range" variant="connected" selection-mode="single-select" required aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<output id="range-log">Press a button you have not selected — one press, three events.</output>
<script type="module">
var group = document.getElementById('range');
var log = document.getElementById('range-log');
var lines = [];
function push(line) {
lines.push(line);
log.textContent = lines.join(String.fromCharCode(10));
}
// One listener per event, all three on the GROUP: the child events bubble
// and are composed, so they reach it too.
group.addEventListener('mdClick', function (e) {
lines = [];
push('1 mdClick (child) value=' + e.detail.value + ' selected(next)=' + e.detail.selected);
});
group.addEventListener('mdChange', function (e) {
push('2 mdChange (child) value=' + e.detail.value + ' selected=' + e.detail.selected);
});
group.addEventListener('mdSelectionChange', function (e) {
var d = e.detail;
push('3 mdSelectionChange (group) values=[' + d.values.join(', ') +
'] added=[' + d.added.join(', ') + '] removed=[' + d.removed.join(', ') + ']');
});
</script>import { useEffect, useRef } from 'react';
import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
const groupRef = useRef(null);
const logRef = useRef(null);
useEffect(() => {
const group = groupRef.current;
const log = logRef.current;
var lines = [];
function push(line) {
lines.push(line);
log.textContent = lines.join(String.fromCharCode(10));
}
// One listener per event, all three on the GROUP: the child events bubble
// and are composed, so they reach it too.
group.addEventListener('mdClick', function (e) {
lines = [];
push('1 mdClick (child) value=' + e.detail.value + ' selected(next)=' + e.detail.selected);
});
group.addEventListener('mdChange', function (e) {
push('2 mdChange (child) value=' + e.detail.value + ' selected=' + e.detail.selected);
});
group.addEventListener('mdSelectionChange', function (e) {
var d = e.detail;
push('3 mdSelectionChange (group) values=[' + d.values.join(', ') +
'] added=[' + d.added.join(', ') + '] removed=[' + d.removed.join(', ') + ']');
});
}, []);
return (
<>
<MdButtonGroup id="range" ref={groupRef} variant="connected" selectionMode="single-select" required aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<output id="range-log" ref={logRef}>Press a button you have not selected — one press, three events.</output>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
// app.component.ts
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'app-demo',
templateUrl: './app.component.html',
})
export class DemoComponent implements AfterViewInit {
@ViewChild('group') groupRef!: ElementRef;
@ViewChild('log') logRef!: ElementRef;
ngAfterViewInit() {
const group = this.groupRef.nativeElement;
const log = this.logRef.nativeElement;
var lines = [];
function push(line) {
lines.push(line);
log.textContent = lines.join(String.fromCharCode(10));
}
// One listener per event, all three on the GROUP: the child events bubble
// and are composed, so they reach it too.
group.addEventListener('mdClick', function (e) {
lines = [];
push('1 mdClick (child) value=' + e.detail.value + ' selected(next)=' + e.detail.selected);
});
group.addEventListener('mdChange', function (e) {
push('2 mdChange (child) value=' + e.detail.value + ' selected=' + e.detail.selected);
});
group.addEventListener('mdSelectionChange', function (e) {
var d = e.detail;
push('3 mdSelectionChange (group) values=[' + d.values.join(', ') +
'] added=[' + d.added.join(', ') + '] removed=[' + d.removed.join(', ') + ']');
});
}
}
<!-- app.component.html -->
<md-button-group id="range" #group variant="connected" selection-mode="single-select" required aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<output id="range-log" #log>Press a button you have not selected — one press, three events.</output><script setup>
import { onMounted, ref } from 'vue';
import '@awc-ui/core/define';
const groupRef = ref(null);
const logRef = ref(null);
onMounted(() => {
const group = groupRef.value;
const log = logRef.value;
var lines = [];
function push(line) {
lines.push(line);
log.textContent = lines.join(String.fromCharCode(10));
}
// One listener per event, all three on the GROUP: the child events bubble
// and are composed, so they reach it too.
group.addEventListener('mdClick', function (e) {
lines = [];
push('1 mdClick (child) value=' + e.detail.value + ' selected(next)=' + e.detail.selected);
});
group.addEventListener('mdChange', function (e) {
push('2 mdChange (child) value=' + e.detail.value + ' selected=' + e.detail.selected);
});
group.addEventListener('mdSelectionChange', function (e) {
var d = e.detail;
push('3 mdSelectionChange (group) values=[' + d.values.join(', ') +
'] added=[' + d.added.join(', ') + '] removed=[' + d.removed.join(', ') + ']');
});
});
</script>
<template>
<md-button-group id="range" ref="groupRef" variant="connected" selection-mode="single-select" required aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<output id="range-log" ref="logRef">Press a button you have not selected — one press, three events.</output>
</template><script>
import { onMount } from 'svelte';
import '@awc-ui/core/define';
let groupRef;
let logRef;
onMount(() => {
const group = groupRef;
const log = logRef;
var lines = [];
function push(line) {
lines.push(line);
log.textContent = lines.join(String.fromCharCode(10));
}
// One listener per event, all three on the GROUP: the child events bubble
// and are composed, so they reach it too.
group.addEventListener('mdClick', function (e) {
lines = [];
push('1 mdClick (child) value=' + e.detail.value + ' selected(next)=' + e.detail.selected);
});
group.addEventListener('mdChange', function (e) {
push('2 mdChange (child) value=' + e.detail.value + ' selected=' + e.detail.selected);
});
group.addEventListener('mdSelectionChange', function (e) {
var d = e.detail;
push('3 mdSelectionChange (group) values=[' + d.values.join(', ') +
'] added=[' + d.added.join(', ') + '] removed=[' + d.removed.join(', ') + ']');
});
});
</script>
<md-button-group id="range" bind:this={groupRef} variant="connected" selection-mode="single-select" required aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<output id="range-log" bind:this={logRef}>Press a button you have not selected — one press, three events.</output>Listen to the child events only when you genuinely care about the press itself.
On an md-button child mdClick is cancelable, so that is where you veto
an activation before the group reconciles. On an md-icon-button child it
is not — the group below is icon-only, so nothing here can be vetoed; it just
reads the group’s own selection.
A button group is one control, so it reports one selection. Press an alignment and this paragraph follows it.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-button-group id="align" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<p id="align-sample">A button group is one control, so it reports one selection.</p>
<script type="module">
var group = document.getElementById('align');
var sample = document.getElementById('align-sample');
group.addEventListener('mdSelectionChange', function (e) {
// values is the snapshot; single-select means it holds at most one entry.
sample.style.textAlign = e.detail.values[0] || 'left';
});
</script>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { useEffect, useRef } from 'react';
import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
const groupRef = useRef(null);
const sampleRef = useRef(null);
useEffect(() => {
const group = groupRef.current;
const sample = sampleRef.current;
group.addEventListener('mdSelectionChange', function (e) {
// values is the snapshot; single-select means it holds at most one entry.
sample.style.textAlign = e.detail.values[0] || 'left';
});
}, []);
return (
<>
<MdButtonGroup id="align" ref={groupRef} variant="connected" required aria-label="Text alignment">
<MdIconButton value="left" icon="format_align_left" aria-label="Align left" selected></MdIconButton>
<MdIconButton value="center" icon="format_align_center" aria-label="Align center"></MdIconButton>
<MdIconButton value="right" icon="format_align_right" aria-label="Align right"></MdIconButton>
</MdButtonGroup>
<p id="align-sample" ref={sampleRef}>A button group is one control, so it reports one selection.</p>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
// app.component.ts
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'app-demo',
templateUrl: './app.component.html',
})
export class DemoComponent implements AfterViewInit {
@ViewChild('group') groupRef!: ElementRef;
@ViewChild('sample') sampleRef!: ElementRef;
ngAfterViewInit() {
const group = this.groupRef.nativeElement;
const sample = this.sampleRef.nativeElement;
group.addEventListener('mdSelectionChange', function (e) {
// values is the snapshot; single-select means it holds at most one entry.
sample.style.textAlign = e.detail.values[0] || 'left';
});
}
}
<!-- app.component.html -->
<md-button-group id="align" #group variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<p id="align-sample" #sample>A button group is one control, so it reports one selection.</p><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { onMounted, ref } from 'vue';
import '@awc-ui/core/define';
const groupRef = ref(null);
const sampleRef = ref(null);
onMounted(() => {
const group = groupRef.value;
const sample = sampleRef.value;
group.addEventListener('mdSelectionChange', function (e) {
// values is the snapshot; single-select means it holds at most one entry.
sample.style.textAlign = e.detail.values[0] || 'left';
});
});
</script>
<template>
<md-button-group id="align" ref="groupRef" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<p id="align-sample" ref="sampleRef">A button group is one control, so it reports one selection.</p>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { onMount } from 'svelte';
import '@awc-ui/core/define';
let groupRef;
let sampleRef;
onMount(() => {
const group = groupRef;
const sample = sampleRef;
group.addEventListener('mdSelectionChange', function (e) {
// values is the snapshot; single-select means it holds at most one entry.
sample.style.textAlign = e.detail.values[0] || 'left';
});
});
</script>
<md-button-group id="align" bind:this={groupRef} variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<p id="align-sample" bind:this={sampleRef}>A button group is one control, so it reports one selection.</p><md-button-group id="align" variant="connected" required aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<script type="module">
document.getElementById('align').addEventListener('mdSelectionChange', (e) => {
const { values, added, removed } = e.detail;
applyAlignment(values[0]);
});
</script>import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function AlignmentGroup({ onChange }) {
return (
<MdButtonGroup
variant="connected"
required
aria-label="Text alignment"
onMdSelectionChange={(e) => onChange(e.detail.values[0])}
>
<MdIconButton value="left" icon="format_align_left" aria-label="Align left" selected />
<MdIconButton value="center" icon="format_align_center" aria-label="Align center" />
<MdIconButton value="right" icon="format_align_right" aria-label="Align right" />
</MdButtonGroup>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-alignment-group',
template: `
<md-button-group
variant="connected"
required
aria-label="Text alignment"
(mdSelectionChange)="onChange($event)"
>
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align center"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
`,
})
export class AlignmentGroupComponent {
onChange(e: CustomEvent) {
const { values, added, removed } = e.detail;
this.applyAlignment(values[0]);
}
}<script setup lang="ts">
function onChange(e: CustomEvent) {
const { values, added, removed } = e.detail;
applyAlignment(values[0]);
}
</script>
<template>
<md-button-group
variant="connected"
required
aria-label="Text alignment"
@mdSelectionChange="onChange"
>
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected />
<md-icon-button value="center" icon="format_align_center" aria-label="Align center" />
<md-icon-button value="right" icon="format_align_right" aria-label="Align right" />
</md-button-group>
</template><script lang="ts">
function onChange(e: CustomEvent) {
const { values, added, removed } = e.detail;
applyAlignment(values[0]);
}
</script>
<md-button-group
variant="connected"
required
aria-label="Text alignment"
on:mdSelectionChange={onChange}
>
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected />
<md-icon-button value="center" icon="format_align_center" aria-label="Align center" />
<md-icon-button value="right" icon="format_align_right" aria-label="Align right" />
</md-button-group>| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
variant | variant | 'standard' | 'connected' | 'standard' | — |
size | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'sm' | — |
shape | shape | 'round' | 'square' | 'round' | — |
selectionMode | selection-mode | 'single-select' | 'multi-select' | 'single-select' | — |
required | required | boolean | false | — |
fullWidth | full-width | boolean | false | Yes |
density | density | 0 | -1 | -2 | -3 | -4 | 0 | Yes |
| Slot | Description |
|---|---|
(default) | — |
Override on the host element for per-instance theming:
| Property | Description |
|---|---|
--md-button-group-gap | Override default gap |
--md-button-group-width | Explicit inline-size (defaults to auto) |
--md-button-group-min-width | Minimum inline-size |
--md-button-group-max-width | Maximum inline-size |
--md-button-group-height | Explicit block-size (defaults to auto) |
--md-button-group-min-height | Minimum block-size |
--md-button-group-max-height | Maximum block-size |
--md-button-group-_unset | — |
radiogroup in single-select and group in multi-select.
Children expose aria-pressed through their own toggle mode.single-select
the selected child is the tab stop.ArrowLeft / ArrowRight move focus, Home / End jump to the ends.aria-label describing what it controls
(“Text alignment”), and every icon-only child its own aria-label.required prevents an empty selection, which keeps the radiogroup
semantics honest.<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">radiogroup</span>
<md-button-group selection-mode="single-select" aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align centre"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">group</span>
<md-button-group selection-mode="multi-select" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold"></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic" selected></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline"></md-icon-button>
</md-button-group>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>radiogroup</span>
<MdButtonGroup selectionMode="single-select" aria-label="Text alignment">
<MdIconButton value="left" icon="format_align_left" aria-label="Align left" selected></MdIconButton>
<MdIconButton value="center" icon="format_align_center" aria-label="Align centre"></MdIconButton>
<MdIconButton value="right" icon="format_align_right" aria-label="Align right"></MdIconButton>
</MdButtonGroup>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>group</span>
<MdButtonGroup selectionMode="multi-select" aria-label="Text style">
<MdIconButton value="bold" icon="format_bold" aria-label="Bold"></MdIconButton>
<MdIconButton value="italic" icon="format_italic" aria-label="Italic" selected></MdIconButton>
<MdIconButton value="underline" icon="format_underlined" aria-label="Underline"></MdIconButton>
</MdButtonGroup>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">radiogroup</span>
<md-button-group selection-mode="single-select" aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align centre"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">group</span>
<md-button-group selection-mode="multi-select" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold"></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic" selected></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline"></md-icon-button>
</md-button-group>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">radiogroup</span>
<md-button-group selection-mode="single-select" aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align centre"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">group</span>
<md-button-group selection-mode="multi-select" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold"></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic" selected></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline"></md-icon-button>
</md-button-group>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">radiogroup</span>
<md-button-group selection-mode="single-select" aria-label="Text alignment">
<md-icon-button value="left" icon="format_align_left" aria-label="Align left" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="Align centre"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="Align right"></md-icon-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">group</span>
<md-button-group selection-mode="multi-select" aria-label="Text style">
<md-icon-button value="bold" icon="format_bold" aria-label="Bold"></md-icon-button>
<md-icon-button value="italic" icon="format_italic" aria-label="Italic" selected></md-icon-button>
<md-icon-button value="underline" icon="format_underlined" aria-label="Underline"></md-icon-button>
</md-button-group>
</div>Both rows above are one tab stop each. Tab moves you into the group and
straight out again; ArrowLeft / ArrowRight move within it and Home / End
jump to the ends — the composite-widget pattern, not three separate stops.
The role changes with the mode: single-select is a radiogroup, multi-select
is a plain group. Every child here is icon-only, so each carries its own
aria-label, and the group carries one describing what it controls.
RTL — arrow direction follows reading order, not screen order. Under
dir="rtl", ArrowRight moves toward the start of the group. Connected corner
rounding flips with the layout. Directional child icons still need their own
mirror-icon handling. See RTL.
<div dir="rtl"> <md-button-group variant="connected" required aria-label="محاذاة النص">…</md-button-group></div><!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ltr</span>
<div dir="ltr">
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
</div>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rtl</span>
<div dir="rtl">
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Range">
<MdButton variant="tonal" value="day">يوم</MdButton>
<MdButton variant="tonal" value="week" selected>أسبوع</MdButton>
<MdButton variant="tonal" value="month">شهر</MdButton>
</MdButtonGroup>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div>The connected corner rounding flips too: the first child keeps the leading corners rounded in both directions, so the group never looks inside-out.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="inline-size: 100%;">
<md-button-group variant="connected" required aria-label="محاذاة النص">
<md-icon-button value="left" icon="format_align_left" aria-label="محاذاة لليسار" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="توسيط"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="محاذاة لليمين"></md-icon-button>
</md-button-group>
</div>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdButtonGroup, MdIconButton } from '@awc-ui/react';
export function Demo() {
return (
<>
<div dir="rtl" style={{ inlineSize: '100%' }}>
<MdButtonGroup variant="connected" required aria-label="محاذاة النص">
<MdIconButton value="left" icon="format_align_left" aria-label="محاذاة لليسار" selected></MdIconButton>
<MdIconButton value="center" icon="format_align_center" aria-label="توسيط"></MdIconButton>
<MdIconButton value="right" icon="format_align_right" aria-label="محاذاة لليمين"></MdIconButton>
</MdButtonGroup>
</div>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div dir="rtl" style="inline-size: 100%;">
<md-button-group variant="connected" required aria-label="محاذاة النص">
<md-icon-button value="left" icon="format_align_left" aria-label="محاذاة لليسار" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="توسيط"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="محاذاة لليمين"></md-icon-button>
</md-button-group>
</div><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<div dir="rtl" style="inline-size: 100%;">
<md-button-group variant="connected" required aria-label="محاذاة النص">
<md-icon-button value="left" icon="format_align_left" aria-label="محاذاة لليسار" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="توسيط"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="محاذاة لليمين"></md-icon-button>
</md-button-group>
</div>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="inline-size: 100%;">
<md-button-group variant="connected" required aria-label="محاذاة النص">
<md-icon-button value="left" icon="format_align_left" aria-label="محاذاة لليسار" selected></md-icon-button>
<md-icon-button value="center" icon="format_align_center" aria-label="توسيط"></md-icon-button>
<md-icon-button value="right" icon="format_align_right" aria-label="محاذاة لليمين"></md-icon-button>
</md-button-group>
</div>Arrow keys follow reading order, not screen order. In RTL, ArrowLeft moves
to the next button because next is to the left. The component already handles
that, so writing the children in reverse order for RTL flips them twice: the
group reads Month → Day, and Home lands on Month.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, logical order">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, hand-reversed">
<md-button variant="tonal" value="month">Month</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="day">Day</md-button>
</md-button-group>
</div>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>correct</span>
<div dir="rtl">
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Range, logical order">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
</div>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>wrong</span>
<div dir="rtl">
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Range, hand-reversed">
<MdButton variant="tonal" value="month">Month</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="day">Day</MdButton>
</MdButtonGroup>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, logical order">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, hand-reversed">
<md-button variant="tonal" value="month">Month</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="day">Day</md-button>
</md-button-group>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, logical order">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, hand-reversed">
<md-button variant="tonal" value="month">Month</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="day">Day</md-button>
</md-button-group>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, logical order">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range, hand-reversed">
<md-button variant="tonal" value="month">Month</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="day">Day</md-button>
</md-button-group>
</div>
</div><!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-button-group variant="connected" selection-mode="single-select" density="-1" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-button-group variant="connected" selection-mode="single-select" density="-2" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-button-group variant="connected" selection-mode="single-select" density="-4" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>0</span>
<MdButtonGroup variant="connected" selectionMode="single-select" density="0" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-1</span>
<MdButtonGroup variant="connected" selectionMode="single-select" density="-1" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-2</span>
<MdButtonGroup variant="connected" selectionMode="single-select" density="-2" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-3</span>
<MdButtonGroup variant="connected" selectionMode="single-select" density="-3" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<span style={{ inlineSize: '4rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-4</span>
<MdButtonGroup variant="connected" selectionMode="single-select" density="-4" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-button-group variant="connected" selection-mode="single-select" density="-1" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-button-group variant="connected" selection-mode="single-select" density="-2" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-button-group variant="connected" selection-mode="single-select" density="-4" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-button-group variant="connected" selection-mode="single-select" density="-1" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-button-group variant="connected" selection-mode="single-select" density="-2" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-button-group variant="connected" selection-mode="single-select" density="-4" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-button-group variant="connected" selection-mode="single-select" density="-1" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-button-group variant="connected" selection-mode="single-select" density="-2" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<span style="inline-size:4rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-button-group variant="connected" selection-mode="single-select" density="-4" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>Set density on the group, not on each child — it cascades, and mixing the
two is how you get a connected group whose segments no longer line up.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · 0</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · 0</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · -3</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · -3</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '5.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ltr · 0</span>
<div dir="ltr">
<MdButtonGroup variant="connected" selectionMode="single-select" density="0" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
</div>
<span style={{ inlineSize: '5.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rtl · 0</span>
<div dir="rtl">
<MdButtonGroup variant="connected" selectionMode="single-select" density="0" aria-label="النطاق">
<MdButton variant="tonal" value="day">يوم</MdButton>
<MdButton variant="tonal" value="week" selected>أسبوع</MdButton>
<MdButton variant="tonal" value="month">شهر</MdButton>
</MdButtonGroup>
</div>
<span style={{ inlineSize: '5.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ltr · -3</span>
<div dir="ltr">
<MdButtonGroup variant="connected" selectionMode="single-select" density="-3" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
</div>
<span style={{ inlineSize: '5.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rtl · -3</span>
<div dir="rtl">
<MdButtonGroup variant="connected" selectionMode="single-select" density="-3" aria-label="النطاق">
<MdButton variant="tonal" value="day">يوم</MdButton>
<MdButton variant="tonal" value="week" selected>أسبوع</MdButton>
<MdButton variant="tonal" value="month">شهر</MdButton>
</MdButtonGroup>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · 0</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · 0</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · -3</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · -3</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · 0</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · 0</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · -3</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · -3</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · 0</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · 0</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="0" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr · -3</span>
<div dir="ltr">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
</div>
<span style="inline-size:5.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl · -3</span>
<div dir="rtl">
<md-button-group variant="connected" selection-mode="single-select" density="-3" aria-label="النطاق">
<md-button variant="tonal" value="day">يوم</md-button>
<md-button variant="tonal" value="week" selected>أسبوع</md-button>
<md-button variant="tonal" value="month">شهر</md-button>
</md-button-group>
</div>
</div><!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" aria-label="Zeitraum">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" full-width aria-label="Zeitraum, full width">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', flexDirection: 'column', gap: '14px', alignItems: 'flex-start' }}>
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Range">
<MdButton variant="tonal" value="day">Day</MdButton>
<MdButton variant="tonal" value="week" selected>Week</MdButton>
<MdButton variant="tonal" value="month">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="connected" selectionMode="single-select" aria-label="Zeitraum">
<MdButton variant="tonal" value="day">Tag</MdButton>
<MdButton variant="tonal" value="week" selected>Woche</MdButton>
<MdButton variant="tonal" value="month">Monat</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="connected" selectionMode="single-select" fullWidth aria-label="Zeitraum, full width">
<MdButton variant="tonal" value="day">Tag</MdButton>
<MdButton variant="tonal" value="week" selected>Woche</MdButton>
<MdButton variant="tonal" value="month">Monat</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" aria-label="Zeitraum">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" full-width aria-label="Zeitraum, full width">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" aria-label="Zeitraum">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" full-width aria-label="Zeitraum, full width">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group variant="connected" selection-mode="single-select" aria-label="Range">
<md-button variant="tonal" value="day">Day</md-button>
<md-button variant="tonal" value="week" selected>Week</md-button>
<md-button variant="tonal" value="month">Month</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" aria-label="Zeitraum">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" full-width aria-label="Zeitraum, full width">
<md-button variant="tonal" value="day">Tag</md-button>
<md-button variant="tonal" value="week" selected>Woche</md-button>
<md-button variant="tonal" value="month">Monat</md-button>
</md-button-group>
</div>The third row shows the fix when translation makes a connected group ragged:
full-width divides the container evenly, so segment widths stop depending on
label length.
Density — density="-1…-4" on the group cascades to every child, tapering
the gap in standard and the child height in both variants. See
Density.
i18n — child labels and aria-labels come from your dictionary; the group
needs its own aria-label too. Translated labels change width, so reach for
full-width when a connected group has to stay even.
| Custom property | Purpose | Default |
|---|---|---|
--md-button-group-gap | Spacing between children | standard, per size: 18px (xs), 12px (sm — the default), 8px (md/lg/xl), each tapering to roughly half across the density range. connected: a fixed 2px seam that does not taper |
--md-button-group-width / -min-width / -max-width | Inline-size bounds | auto / auto / none |
--md-button-group-height / -min-height / -max-height | Block-size bounds | auto / auto / none |
Per-button appearance is themed with the children’s own --md-button-* /
--md-icon-button-* properties — the group exposes no CSS parts.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-button-group variant="standard" aria-label="Wide gap" style="--md-button-group-gap: 20px;">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdButtonGroup variant="standard" aria-label="Wide gap" style={{ '--md-button-group-gap': '20px' }}>
<MdButton value="a" selected>Day</MdButton>
<MdButton value="b">Week</MdButton>
<MdButton value="c">Month</MdButton>
</MdButtonGroup>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-button-group variant="standard" aria-label="Wide gap" style="--md-button-group-gap: 20px;">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-button-group variant="standard" aria-label="Wide gap" style="--md-button-group-gap: 20px;">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>
</template><script>
import '@awc-ui/core/define';
</script>
<md-button-group variant="standard" aria-label="Wide gap" style="--md-button-group-gap: 20px;">
<md-button value="a" selected>Day</md-button>
<md-button value="b">Week</md-button>
<md-button value="c">Month</md-button>
</md-button-group>The group owns layout; colour still comes from the children, so a themed
group is a themed set of md-buttons inside a sized container:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.bg-brand md-button:not(.md-button--selected) {
--md-button-container-color: #1B5E20;
--md-button-label-color: #FFFFFF;
}
.bg-brand md-button.md-button--selected {
--md-button-container-color: #A5D6A7;
--md-button-label-color: #0B3D0F;
}
</style>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group class="bg-brand" variant="connected" selection-mode="single-select" aria-label="Brand-themed">
<md-button variant="filled" value="a">Day</md-button>
<md-button variant="filled" value="b" selected>Week</md-button>
<md-button variant="filled" value="c">Month</md-button>
</md-button-group>
<md-button-group variant="standard" selection-mode="single-select" style="--md-button-group-gap: 2px;" aria-label="Tight gap">
<md-button variant="tonal" value="a">Tight</md-button>
<md-button variant="tonal" value="b" selected>2px</md-button>
<md-button variant="tonal" value="c">gap</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" style="--md-button-group-width: 420px;" aria-label="Fixed width">
<md-button variant="tonal" value="a">Fixed</md-button>
<md-button variant="tonal" value="b" selected>420px</md-button>
<md-button variant="tonal" value="c">wide</md-button>
</md-button-group>
</div>import { MdButton, MdButtonGroup } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.bg-brand md-button:not(.md-button--selected) {
--md-button-container-color: #1B5E20;
--md-button-label-color: #FFFFFF;
}
.bg-brand md-button.md-button--selected {
--md-button-container-color: #A5D6A7;
--md-button-label-color: #0B3D0F;
}
</style>
<div style={{ display: 'flex', flexDirection: 'column', gap: '14px', alignItems: 'flex-start' }}>
<MdButtonGroup className="bg-brand" variant="connected" selectionMode="single-select" aria-label="Brand-themed">
<MdButton variant="filled" value="a">Day</MdButton>
<MdButton variant="filled" value="b" selected>Week</MdButton>
<MdButton variant="filled" value="c">Month</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="standard" selectionMode="single-select" style={{ '--md-button-group-gap': '2px' }} aria-label="Tight gap">
<MdButton variant="tonal" value="a">Tight</MdButton>
<MdButton variant="tonal" value="b" selected>2px</MdButton>
<MdButton variant="tonal" value="c">gap</MdButton>
</MdButtonGroup>
<MdButtonGroup variant="connected" selectionMode="single-select" style={{ '--md-button-group-width': '420px' }} aria-label="Fixed width">
<MdButton variant="tonal" value="a">Fixed</MdButton>
<MdButton variant="tonal" value="b" selected>420px</MdButton>
<MdButton variant="tonal" value="c">wide</MdButton>
</MdButtonGroup>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.bg-brand md-button:not(.md-button--selected) {
--md-button-container-color: #1B5E20;
--md-button-label-color: #FFFFFF;
}
.bg-brand md-button.md-button--selected {
--md-button-container-color: #A5D6A7;
--md-button-label-color: #0B3D0F;
}
</style>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group class="bg-brand" variant="connected" selection-mode="single-select" aria-label="Brand-themed">
<md-button variant="filled" value="a">Day</md-button>
<md-button variant="filled" value="b" selected>Week</md-button>
<md-button variant="filled" value="c">Month</md-button>
</md-button-group>
<md-button-group variant="standard" selection-mode="single-select" style="--md-button-group-gap: 2px;" aria-label="Tight gap">
<md-button variant="tonal" value="a">Tight</md-button>
<md-button variant="tonal" value="b" selected>2px</md-button>
<md-button variant="tonal" value="c">gap</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" style="--md-button-group-width: 420px;" aria-label="Fixed width">
<md-button variant="tonal" value="a">Fixed</md-button>
<md-button variant="tonal" value="b" selected>420px</md-button>
<md-button variant="tonal" value="c">wide</md-button>
</md-button-group>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<style>
.bg-brand md-button:not(.md-button--selected) {
--md-button-container-color: #1B5E20;
--md-button-label-color: #FFFFFF;
}
.bg-brand md-button.md-button--selected {
--md-button-container-color: #A5D6A7;
--md-button-label-color: #0B3D0F;
}
</style>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group class="bg-brand" variant="connected" selection-mode="single-select" aria-label="Brand-themed">
<md-button variant="filled" value="a">Day</md-button>
<md-button variant="filled" value="b" selected>Week</md-button>
<md-button variant="filled" value="c">Month</md-button>
</md-button-group>
<md-button-group variant="standard" selection-mode="single-select" style="--md-button-group-gap: 2px;" aria-label="Tight gap">
<md-button variant="tonal" value="a">Tight</md-button>
<md-button variant="tonal" value="b" selected>2px</md-button>
<md-button variant="tonal" value="c">gap</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" style="--md-button-group-width: 420px;" aria-label="Fixed width">
<md-button variant="tonal" value="a">Fixed</md-button>
<md-button variant="tonal" value="b" selected>420px</md-button>
<md-button variant="tonal" value="c">wide</md-button>
</md-button-group>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<style>
.bg-brand md-button:not(.md-button--selected) {
--md-button-container-color: #1B5E20;
--md-button-label-color: #FFFFFF;
}
.bg-brand md-button.md-button--selected {
--md-button-container-color: #A5D6A7;
--md-button-label-color: #0B3D0F;
}
</style>
<div style="display:flex;flex-direction:column;gap:14px;align-items:flex-start;">
<md-button-group class="bg-brand" variant="connected" selection-mode="single-select" aria-label="Brand-themed">
<md-button variant="filled" value="a">Day</md-button>
<md-button variant="filled" value="b" selected>Week</md-button>
<md-button variant="filled" value="c">Month</md-button>
</md-button-group>
<md-button-group variant="standard" selection-mode="single-select" style="--md-button-group-gap: 2px;" aria-label="Tight gap">
<md-button variant="tonal" value="a">Tight</md-button>
<md-button variant="tonal" value="b" selected>2px</md-button>
<md-button variant="tonal" value="c">gap</md-button>
</md-button-group>
<md-button-group variant="connected" selection-mode="single-select" style="--md-button-group-width: 420px;" aria-label="Fixed width">
<md-button variant="tonal" value="a">Fixed</md-button>
<md-button variant="tonal" value="b" selected>420px</md-button>
<md-button variant="tonal" value="c">wide</md-button>
</md-button-group>
</div>/* Geometry on the group, colour on the children. */.toolbar-range { --md-button-group-gap: 2px; --md-button-group-max-width: 420px;}
/* The host class tracks the selection; the `selected` attribute does not. */.toolbar-range md-button.md-button--selected { --md-button-container-color: var(--md-sys-color-secondary-container); --md-button-label-color: var(--md-sys-color-on-secondary-container);}md-button ·
md-icon-button ·
md-segmented-button ·
md-split-button ·
md-toolbar ·
md-tabs
md-button-groupTwo artefacts to give your AI agent so it generates correct UI with this component. The per-component spec answers "how do I use this exact tag?". The main-llm spec answers "which tag should I pick in the first place?".
md-button-group spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
System-prompt preamble · decision matrix · token reference · page recipes · anti-patterns. Paste into the system prompt at the start of a piece of work.