Button Group
Related buttons joined into one segmented control. For choosing between mutually exclusive options use ToggleGroup instead — a button group is a set of actions, not a value.
Added 14 October 2026
React
Codecomponents/react/button-group-demo.tsx
import {Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText} from '@stroeer-labs/design-library/react';
import {ChevronDownIcon, MinusIcon, PlusIcon} from 'lucide-react';
export function ButtonGroupDemo() {
return (
<div className="space-y-6">
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Horizontal</p>
<ButtonGroup aria-label="Date granularity">
<Button variant="outline">Day</Button>
<Button variant="outline">Week</Button>
<Button variant="outline">Month</Button>
</ButtonGroup>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Vertical</p>
<ButtonGroup orientation="vertical" aria-label="Row position">
<Button variant="outline">Top</Button>
<ButtonGroupSeparator />
<Button variant="outline">Middle</Button>
<Button variant="outline">Bottom</Button>
</ButtonGroup>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Split button (separator)</p>
<ButtonGroup aria-label="Export">
<Button variant="outline">Export</Button>
<ButtonGroupSeparator />
<Button variant="outline" size="icon" aria-label="More export options">
<ChevronDownIcon />
</Button>
</ButtonGroup>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">With text label</p>
<ButtonGroup aria-label="Slot count">
<Button variant="outline" size="icon" aria-label="Remove one slot">
<MinusIcon />
</Button>
<ButtonGroupText>12 slots</ButtonGroupText>
<Button variant="outline" size="icon" aria-label="Add one slot">
<PlusIcon />
</Button>
</ButtonGroup>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Filled variant</p>
<ButtonGroup aria-label="Save options">
<Button>Save</Button>
<Button>Save and close</Button>
</ButtonGroup>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Floating (map controls — bg-muted stands in for the map)</p>
<div className="flex items-start gap-4 rounded-lg bg-muted p-4">
<ButtonGroup orientation="vertical" aria-label="Map zoom">
<Button variant="floating" size="icon" aria-label="Zoom in">
<PlusIcon />
</Button>
<Button variant="floating" size="icon" aria-label="Zoom out">
<MinusIcon />
</Button>
</ButtonGroup>
<ButtonGroup aria-label="Map view">
<Button variant="floating">Satellite</Button>
<Button variant="floating">Fit all</Button>
</ButtonGroup>
<Button variant="floating">Expand map</Button>
</div>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Sizes</p>
<div className="flex flex-wrap items-center gap-3">
<ButtonGroup>
<Button variant="outline" size="sm">
Small
</Button>
<Button variant="outline" size="sm">
Group
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline">Default</Button>
<Button variant="outline">Group</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="lg">
Large
</Button>
<Button variant="outline" size="lg">
Group
</Button>
</ButtonGroup>
</div>
</div>
</div>
);
}Angular
Codecomponents/angular/button-group-demo.ts
import {Component} from '@angular/core';
import {HlmButtonGroupImports, HlmButtonImports} from '@stroeer-labs/design-library/angular';
import {NgIcon, provideIcons} from '@ng-icons/core';
import {lucideChevronDown, lucideMinus, lucidePlus} from '@ng-icons/lucide';
@Component({
selector: 'dl-button-group-demo',
standalone: true,
imports: [HlmButtonGroupImports, HlmButtonImports, NgIcon],
providers: [provideIcons({lucideChevronDown, lucideMinus, lucidePlus})],
template: `
<div class="space-y-6">
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Horizontal</p>
<div hlmButtonGroup aria-label="Date granularity">
<button hlmBtn variant="outline">Day</button>
<button hlmBtn variant="outline">Week</button>
<button hlmBtn variant="outline">Month</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Vertical</p>
<div hlmButtonGroup orientation="vertical" aria-label="Row position">
<button hlmBtn variant="outline">Top</button>
<hlm-button-group-separator />
<button hlmBtn variant="outline">Middle</button>
<button hlmBtn variant="outline">Bottom</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Split button (separator)</p>
<div hlmButtonGroup aria-label="Export">
<button hlmBtn variant="outline">Export</button>
<hlm-button-group-separator />
<button hlmBtn variant="outline" size="icon" aria-label="More export options">
<ng-icon name="lucideChevronDown" />
</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">With text label</p>
<div hlmButtonGroup aria-label="Slot count">
<button hlmBtn variant="outline" size="icon" aria-label="Remove one slot">
<ng-icon name="lucideMinus" />
</button>
<div hlmButtonGroupText>12 slots</div>
<button hlmBtn variant="outline" size="icon" aria-label="Add one slot">
<ng-icon name="lucidePlus" />
</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Filled variant</p>
<div hlmButtonGroup aria-label="Save options">
<button hlmBtn>Save</button>
<button hlmBtn>Save and close</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Floating (map controls — bg-muted stands in for the map)</p>
<div class="flex items-start gap-4 rounded-lg bg-muted p-4">
<div hlmButtonGroup orientation="vertical" aria-label="Map zoom">
<button hlmBtn variant="floating" size="icon" aria-label="Zoom in"><ng-icon name="lucidePlus" /></button>
<button hlmBtn variant="floating" size="icon" aria-label="Zoom out"><ng-icon name="lucideMinus" /></button>
</div>
<div hlmButtonGroup aria-label="Map view">
<button hlmBtn variant="floating">Satellite</button>
<button hlmBtn variant="floating">Fit all</button>
</div>
<button hlmBtn variant="floating">Expand map</button>
</div>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Sizes</p>
<div class="flex flex-wrap items-center gap-3">
<div hlmButtonGroup>
<button hlmBtn variant="outline" size="sm">Small</button>
<button hlmBtn variant="outline" size="sm">Group</button>
</div>
<div hlmButtonGroup>
<button hlmBtn variant="outline">Default</button>
<button hlmBtn variant="outline">Group</button>
</div>
<div hlmButtonGroup>
<button hlmBtn variant="outline" size="lg">Large</button>
<button hlmBtn variant="outline" size="lg">Group</button>
</div>
</div>
</div>
</div>
`,
})
export class ButtonGroupDemoComponent {}