General
Button Group
Usage#
import { WDS_BUTTON_GROUP } from '@wds/angular/button-group';Examples#
Default#
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
import { WdsDropdownComponent, WdsDropdownItemComponent, WdsDropdownSeparatorComponent } from '@wds/angular/dropdown';
@Component({
selector: 'app-button-group-default-demo',
imports: [WdsButtonGroupComponent, WdsButtonComponent, WdsDropdownComponent, WdsDropdownItemComponent, WdsDropdownSeparatorComponent],
template: `
<wds-button-group aria-label="Message actions">
<wds-button-group>
<wds-button variant="outline" size="icon" label="Go back">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 19-7-7 7-7" /><path d="M19 12H5" /></svg>
</wds-button>
</wds-button-group>
<wds-button-group>
<wds-button variant="outline">Archive</wds-button>
<wds-button variant="outline">Report</wds-button>
</wds-button-group>
<wds-button-group>
<wds-button variant="outline">Snooze</wds-button>
<wds-dropdown align="end">
<wds-button slot="trigger" variant="outline" size="icon" label="More options">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1" /><circle cx="19" cy="12" r="1" /><circle cx="5" cy="12" r="1" /></svg>
</wds-button>
<wds-dropdown-item value="read">Mark as read</wds-dropdown-item>
<wds-dropdown-item value="archive">Archive</wds-dropdown-item>
<wds-dropdown-separator></wds-dropdown-separator>
<wds-dropdown-item value="trash" variant="destructive">Trash</wds-dropdown-item>
</wds-dropdown>
</wds-button-group>
</wds-button-group>
`,
})
export class ButtonGroupDefaultDemo {}Orientation#
orientation="vertical" stacks the buttons.
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-orientation-demo',
imports: [WdsButtonGroupComponent, WdsButtonComponent],
template: `
<wds-button-group orientation="vertical" aria-label="Zoom">
<wds-button variant="outline" size="icon" label="Zoom in">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
<wds-button variant="outline" size="icon" label="Zoom out">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /></svg>
</wds-button>
</wds-button-group>
`,
})
export class ButtonGroupOrientationDemo {}Size#
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-size-demo',
imports: [WdsButtonGroupComponent, WdsButtonComponent],
template: `
<div class="flex flex-col items-center gap-4">
<wds-button-group aria-label="Small buttons">
<wds-button variant="outline" size="sm">Small</wds-button>
<wds-button variant="outline" size="sm">Button</wds-button>
<wds-button variant="outline" size="sm">Group</wds-button>
<wds-button variant="outline" size="icon-sm" label="Add">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
</wds-button-group>
<wds-button-group aria-label="Default buttons">
<wds-button variant="outline">Default</wds-button>
<wds-button variant="outline">Button</wds-button>
<wds-button variant="outline">Group</wds-button>
<wds-button variant="outline" size="icon" label="Add">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
</wds-button-group>
<wds-button-group aria-label="Large buttons">
<wds-button variant="outline" size="lg">Large</wds-button>
<wds-button variant="outline" size="lg">Button</wds-button>
<wds-button variant="outline" size="lg">Group</wds-button>
<wds-button variant="outline" size="icon-lg" label="Add">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
</wds-button-group>
</div>
`,
})
export class ButtonGroupSizeDemo {}Nested#
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-nested-demo',
imports: [WdsButtonGroupComponent, WdsButtonComponent],
template: `
<wds-button-group aria-label="Pagination">
<wds-button-group>
<wds-button variant="outline" size="sm">1</wds-button>
<wds-button variant="outline" size="sm">2</wds-button>
<wds-button variant="outline" size="sm">3</wds-button>
</wds-button-group>
<wds-button-group>
<wds-button variant="outline" size="icon-sm" label="Previous">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6" /></svg>
</wds-button>
<wds-button variant="outline" size="icon-sm" label="Next">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6" /></svg>
</wds-button>
</wds-button-group>
</wds-button-group>
`,
})
export class ButtonGroupNestedDemo {}Separator#
wds-button-group-separator draws a line between buttons without a border, e.g. secondary.
import { Component } from '@angular/core';
import { WdsButtonGroupComponent, WdsButtonGroupSeparatorComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-separator-demo',
imports: [WdsButtonGroupComponent, WdsButtonGroupSeparatorComponent, WdsButtonComponent],
template: `
<wds-button-group aria-label="Clipboard">
<wds-button variant="secondary" size="sm">Copy</wds-button>
<wds-button-group-separator></wds-button-group-separator>
<wds-button variant="secondary" size="sm">Paste</wds-button>
</wds-button-group>
`,
})
export class ButtonGroupSeparatorDemo {}Split#
import { Component } from '@angular/core';
import { WdsButtonGroupComponent, WdsButtonGroupSeparatorComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-split-demo',
imports: [WdsButtonGroupComponent, WdsButtonGroupSeparatorComponent, WdsButtonComponent],
template: `
<wds-button-group aria-label="Split button">
<wds-button variant="secondary">Button</wds-button>
<wds-button-group-separator></wds-button-group-separator>
<wds-button variant="secondary" size="icon" label="More">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
</wds-button-group>
`,
})
export class ButtonGroupSplitDemo {}Input#
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsInputComponent } from '@wds/angular/input';
import { WdsButtonComponent } from '@wds/angular/button';
@Component({
selector: 'app-button-group-input-demo',
imports: [WdsButtonGroupComponent, WdsInputComponent, WdsButtonComponent],
template: `
<wds-button-group class="w-full max-w-xs" aria-label="Search">
<wds-input placeholder="Search..." aria-label="Search"></wds-input>
<wds-button variant="outline" size="icon" label="Search">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21 21-4.34-4.34" /><circle cx="11" cy="11" r="8" /></svg>
</wds-button>
</wds-button-group>
`,
})
export class ButtonGroupInputDemo {}Input group#
import { Component, signal } from '@angular/core';
import { WdsButtonComponent } from '@wds/angular/button';
import { WDS_BUTTON_GROUP } from '@wds/angular/button-group';
import { WdsInputComponent } from '@wds/angular/input';
import { WDS_INPUT_GROUP } from '@wds/angular/input-group';
@Component({
selector: 'app-button-group-input-group-demo',
imports: [...WDS_BUTTON_GROUP, ...WDS_INPUT_GROUP, WdsButtonComponent, WdsInputComponent],
template: `
<wds-button-group class="w-sm max-w-full" aria-label="Message">
<wds-button-group>
<wds-button variant="outline" size="icon" label="Add attachment">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14" /><path d="M12 5v14" /></svg>
</wds-button>
</wds-button-group>
<wds-button-group class="flex-1">
<wds-input-group>
<wds-input [placeholder]="voice() ? 'Recording...' : 'Send a message...'" [disabled]="voice()" aria-label="Message" />
<wds-input-group-addon align="inline-end">
<wds-button [variant]="voice() ? 'default' : 'ghost'" size="icon-xs" shape="circle" label="Voice mode" [attr.aria-pressed]="voice()" (click)="voice.set(!voice())">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 10v3" /><path d="M6 6v11" /><path d="M10 3v18" /><path d="M14 8v7" /><path d="M18 5v13" /><path d="M22 10v3" /></svg>
</wds-button>
</wds-input-group-addon>
</wds-input-group>
</wds-button-group>
</wds-button-group>
`,
})
export class ButtonGroupInputGroupDemo {
protected readonly voice = signal(false);
}Dropdown#
wds-dropdown trigger joins the group like a button.
import { Component } from '@angular/core';
import { WdsButtonGroupComponent } from '@wds/angular/button-group';
import { WdsButtonComponent } from '@wds/angular/button';
import { WdsDropdownComponent, WdsDropdownItemComponent } from '@wds/angular/dropdown';
@Component({
selector: 'app-button-group-dropdown-demo',
imports: [WdsButtonGroupComponent, WdsButtonComponent, WdsDropdownComponent, WdsDropdownItemComponent],
template: `
<wds-button-group aria-label="Follow">
<wds-button variant="outline">Follow</wds-button>
<wds-dropdown align="end">
<wds-button slot="trigger" variant="outline" size="icon" label="Follow options">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6" /></svg>
</wds-button>
<wds-dropdown-item value="mute">Mute conversation</wds-dropdown-item>
<wds-dropdown-item value="read">Mark as read</wds-dropdown-item>
<wds-dropdown-item value="block" variant="destructive">Block user</wds-dropdown-item>
</wds-dropdown>
</wds-button-group>
`,
})
export class ButtonGroupDropdownDemo {}Text#
wds-button-group-text looks like an item of the group, e.g. a prefix.
import { Component } from '@angular/core';
import { WdsButtonGroupComponent, WdsButtonGroupTextComponent } from '@wds/angular/button-group';
import { WdsInputComponent } from '@wds/angular/input';
@Component({
selector: 'app-button-group-text-demo',
imports: [WdsButtonGroupComponent, WdsButtonGroupTextComponent, WdsInputComponent],
template: `
<wds-button-group class="w-full max-w-xs" aria-label="Website">
<wds-button-group-text>https://</wds-button-group-text>
<wds-input placeholder="example" aria-label="Domain"></wds-input>
<wds-button-group-text>.com</wds-button-group-text>
</wds-button-group>
`,
})
export class ButtonGroupTextDemo {}API References#
wds-button-group#
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| orientation | WdsButtonGroupOrientation | 'horizontal' |
Slots
| Slot | Description |
|---|---|
| (default) | wds-button, wds-input, wds-input-group, wds-dropdown, wds-button-group-text, wds-button-group-separator, nested wds-button-group. |
wds-button-group-separator#
orientation="horizontal".
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| orientation | 'horizontal' | 'vertical' | 'vertical' |
wds-button-group-text#
https:// prefix before a field.
Slots
| Slot | Description |
|---|---|
| (default) | <svg> icon. |
CSS parts (::part)
| Part | Description |
|---|---|
| base |
Accessibility#
Screen reader#
wds-button-group has role="group": give it a name with aria-label that says what the buttons do together. A nested group is also a group; name it when the name adds information.
wds-button needs a label.
wds-button-group-separator has role="separator" with aria-orientation. wds-button-group-text is plain text.