Button groups
A row of buttons or icon buttons that react to a press together.
Usage
Copy code
<ButtonGroup aria-label="Playback">
<IconButton variant="tonal" width="narrow" size="m" title="Previous">
<Icon>skip_previous</Icon>
</IconButton>
<IconButton variant="filled" width="wide" size="m" title="Play">
<Icon>play_arrow</Icon>
</IconButton>
<IconButton variant="tonal" width="narrow" size="m" title="Next">
<Icon>skip_next</Icon>
</IconButton>
</ButtonGroup> A group needs a name of its own, so pass an aria-label that says
what the buttons belong to. Connected
For selecting an option, switching a view or sorting a page. The buttons are toggle buttons, and
the group takes over the corners between them. The outer ends keep the round shape of the button,
so leave its buttons on shape="round".
Copy code
<script lang="ts">
let places = $state([
{ label: 'Work', icon: 'work', selected: true },
{ label: 'Restaurant', icon: 'restaurant', selected: false },
{ label: 'Coffee', icon: 'coffee', selected: false },
{ label: 'Home', icon: 'home', selected: false },
])
const choose = (index: number) => {
places.forEach((place, i) => (place.selected = i === index))
}
</script>
<ButtonGroup variant="connected" aria-label="Place">
{#each places as place, index (place.label)}
<Button variant="tonal" toggle bind:selected={place.selected} onclick={() => choose(index)}>
{#snippet start()}
<Icon>{place.icon}</Icon>
{/snippet}
{place.label}
</Button>
{/each}
</ButtonGroup>Multiple choice
Copy code
<ButtonGroup variant="connected" aria-label="Text style">
<Button variant="tonal" toggle bind:selected={styles.bold}>
{#snippet start()}
<Icon>format_bold</Icon>
{/snippet}
Bold
</Button>
<Button variant="tonal" toggle bind:selected={styles.italic}>
{#snippet start()}
<Icon>format_italic</Icon>
{/snippet}
Italic
</Button>
<Button variant="tonal" toggle bind:selected={styles.underline}>
{#snippet start()}
<Icon>format_underlined</Icon>
{/snippet}
Underline
</Button>
</ButtonGroup>Sizes
The buttons carry their own size, the group only holds them together.
Copy code
<ButtonGroup variant="connected" aria-label="Medium alignment">
<IconButton size="m" variant="tonal" title="Align left"><Icon>format_align_left</Icon></IconButton>
<IconButton size="m" variant="tonal" title="Align center">
<Icon>format_align_center</Icon>
</IconButton>
<IconButton size="m" variant="tonal" title="Align right">
<Icon>format_align_right</Icon>
</IconButton>
</ButtonGroup>Motion
expandedRatio is the share of its width a pressed button grows by, compressionLimit caps what a single neighbour gives up. Only standard groups change widths,
and reduced motion turns the motion off in both variants.
Copy code
<ButtonGroup expandedRatio={0.5} aria-label="Rating">
<Button variant="tonal">Bad</Button>
<Button variant="tonal">Fine</Button>
<Button variant="tonal">Great</Button>
</ButtonGroup>Theming
Tokens
| Token | Default value |
|---|---|
--np-button-group-space | 0.75rem, 0.125rem when connected |
--np-button-group-inner-corner | 0.5rem |
--np-button-group-pressed-inner-corner | 0.25rem |
The corner tokens only apply to a connected group.
Example
Copy code
<ButtonGroup
variant="connected"
aria-label="Custom button group"
--np-button-group-space="0.25rem"
--np-button-group-inner-corner="1rem"
>
<Button variant="tonal">Start</Button>
<Button variant="tonal">Middle</Button>
<Button variant="tonal">End</Button>
</ButtonGroup>API
Props
| Attribute | Type | Default | Description |
|---|---|---|---|
variant | 'standard' | 'connected' | 'standard' | A connected group moves its buttons together and shortens the corners between them. |
expandedRatio | number | 0.15 | Share of its width a pressed button grows by. Standard groups only. |
compressionLimit | number | 24 | Pixels a single neighbour gives up at most. Standard groups only. |
element | bind:HTMLElement | undefined | A reference to the root DOM element of the component. This variable is bound using bind:this, allowing direct access to the underlying HTML element for manipulation or querying within
the component's logic. |
...attributes | HTMLAttributes<HTMLDivElement> | Every other attribute is passed to the group element, a div. |