Button Group
Group a series of buttons into a single visual and semantic unit, with sizing, nesting, and toolbar composition.
Basic example
Wrap a series of <Button> components in <ButtonGroup> to render them as a single, connected unit.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Basic example">
<Button color="primary">Left</Button>
<Button color="primary">Middle</Button>
<Button color="primary">Right</Button>
</ButtonGroup>
)
}The same grouping works for a set of navigation links rendered as <Button> with href set, as an alternative to <Nav>.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Link group example">
<Button href="#" color="primary" className="active">
Active link
</Button>
<Button href="#" color="primary">
Link
</Button>
<Button href="#" color="primary">
Link
</Button>
</ButtonGroup>
)
}Style variants
<ButtonGroup> renders whatever color/variant combination each child <Button> sets, including a mix of colors within the same group.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Basic mixed styles example">
<Button color="danger">Left</Button>
<Button color="warning">Middle</Button>
<Button color="success">Right</Button>
</ButtonGroup>
)
}Every child can share variant="outline" the same way a standalone button does.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Basic outlined example">
<Button color="primary" variant="outline">
Left
</Button>
<Button color="primary" variant="outline">
Middle
</Button>
<Button color="primary" variant="outline">
Right
</Button>
</ButtonGroup>
)
}Toggle button groups
Combine Checkbox or Radio components with the button prop to render toggle-button-style controls, then wrap them in <ButtonGroup> for a seamless connected appearance.
import { ButtonGroup, Checkbox } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Basic checkbox toggle button group">
<Checkbox
button={{ color: 'primary', variant: 'outline' }}
id="btncheck1"
label="Checkbox 1"
/>
<Checkbox
button={{ color: 'primary', variant: 'outline' }}
id="btncheck2"
label="Checkbox 2"
/>
<Checkbox
button={{ color: 'primary', variant: 'outline' }}
id="btncheck3"
label="Checkbox 3"
/>
</ButtonGroup>
)
}import { ButtonGroup, Radio, RadioGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<RadioGroup aria-label="Basic radio toggle button group" defaultValue="btnradio1">
<ButtonGroup>
<Radio
button={{ color: 'primary', variant: 'outline' }}
value="btnradio1"
label="Radio 1"
/>
<Radio
button={{ color: 'primary', variant: 'outline' }}
value="btnradio2"
label="Radio 2"
/>
<Radio
button={{ color: 'primary', variant: 'outline' }}
value="btnradio3"
label="Radio 3"
/>
</ButtonGroup>
</RadioGroup>
)
}Button toolbar
Combine multiple <ButtonGroup>s into a <ButtonToolbar> for more complex compositions. Apply spacing utilities to <ButtonGroup> to separate the groups within the toolbar.
import { Button, ButtonGroup, ButtonToolbar } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonToolbar role="group" aria-label="Toolbar with button groups">
<ButtonGroup className="me-sm" role="group" aria-label="First group">
<Button color="primary">1</Button>
<Button color="primary">2</Button>
<Button color="primary">3</Button>
<Button color="primary">4</Button>
</ButtonGroup>
<ButtonGroup className="me-sm" role="group" aria-label="Second group">
<Button color="secondary">5</Button>
<Button color="secondary">6</Button>
<Button color="secondary">7</Button>
</ButtonGroup>
<ButtonGroup className="me-sm" role="group" aria-label="Third group">
<Button color="info">8</Button>
</ButtonGroup>
</ButtonToolbar>
)
}An <InputGroup> composes with button groups inside the same toolbar; spacing utilities keep the pieces apart.
import {
Button,
ButtonGroup,
ButtonToolbar,
InputGroup,
InputGroupAddon,
TextInput
} from '@chassis-ui/react'
export const Example = () => {
return (
<>
<ButtonToolbar className="mb-md" role="group" aria-label="Toolbar with button groups">
<ButtonGroup className="me-sm" role="group" aria-label="First group">
<Button color="secondary" variant="outline">
1
</Button>
<Button color="secondary" variant="outline">
2
</Button>
<Button color="secondary" variant="outline">
3
</Button>
<Button color="secondary" variant="outline">
4
</Button>
</ButtonGroup>
<InputGroup>
<InputGroupAddon id="btnGroupAddon">@</InputGroupAddon>
<TextInput
placeholder="Input group example"
aria-label="Input group example"
aria-describedby="btnGroupAddon"
/>
</InputGroup>
</ButtonToolbar>
<ButtonToolbar
className="justify-content-between"
role="group"
aria-label="Toolbar with button groups"
>
<ButtonGroup className="me-sm" role="group" aria-label="First group">
<Button color="secondary" variant="outline">
1
</Button>
<Button color="secondary" variant="outline">
2
</Button>
<Button color="secondary" variant="outline">
3
</Button>
<Button color="secondary" variant="outline">
4
</Button>
</ButtonGroup>
<InputGroup>
<InputGroupAddon id="btnGroupAddon2">@</InputGroupAddon>
<TextInput
placeholder="Input group example"
aria-label="Input group example"
aria-describedby="btnGroupAddon2"
/>
</InputGroup>
</ButtonToolbar>
</>
)
}Sizing
Set size on <ButtonGroup> to size every button inside it at once, instead of setting size on each <Button> individually — including on each group when nesting multiple groups.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<ButtonGroup size="lg" role="group" aria-label="Large button group">
<Button variant="outline">Left</Button>
<Button variant="outline">Middle</Button>
<Button variant="outline">Right</Button>
</ButtonGroup>
<br />
<ButtonGroup role="group" aria-label="Default button group">
<Button variant="outline">Left</Button>
<Button variant="outline">Middle</Button>
<Button variant="outline">Right</Button>
</ButtonGroup>
<br />
<ButtonGroup size="sm" role="group" aria-label="Small button group">
<Button variant="outline">Left</Button>
<Button variant="outline">Middle</Button>
<Button variant="outline">Right</Button>
</ButtonGroup>
</>
)
}Nesting
Nest a <ButtonGroup> inside another <ButtonGroup> to combine a dropdown menu with a series of buttons.
import {
Button,
ButtonGroup,
Menu,
MenuToggle,
MenuList,
MenuItem,
MenuDivider
} from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup role="group" aria-label="Button group with nested menu">
<Button color="primary">1</Button>
<Button color="primary">2</Button>
<Menu>
<MenuToggle color="primary">Menu</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
</ButtonGroup>
)
}Vertical variation
Set vertical to stack a group's buttons vertically instead of horizontally.
import { Button, ButtonGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup vertical role="group" aria-label="Vertical button group">
<Button color="black">Button</Button>
<Button color="black">Button</Button>
<Button color="black">Button</Button>
<Button color="black">Button</Button>
<Button color="black">Button</Button>
<Button color="black">Button</Button>
<Button color="black">Button</Button>
</ButtonGroup>
)
}import {
Button,
ButtonGroup,
Menu,
MenuToggle,
MenuList,
MenuItem,
MenuDivider
} from '@chassis-ui/react'
export const Example = () => {
return (
<ButtonGroup vertical role="group" aria-label="Vertical button group">
<Button color="primary">Button</Button>
<Button color="primary">Button</Button>
<Menu>
<MenuToggle color="primary">Menu</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<Button color="primary">Button</Button>
<Button color="primary">Button</Button>
<Menu>
<MenuToggle color="primary">Menu</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<Menu>
<MenuToggle color="primary">Menu</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
<Menu>
<MenuToggle color="primary">Menu</MenuToggle>
<MenuList>
<MenuItem href="#">Action</MenuItem>
<MenuItem href="#">Another action</MenuItem>
<MenuItem href="#">Something else here</MenuItem>
<MenuDivider />
<MenuItem href="#">Separated link</MenuItem>
</MenuList>
</Menu>
</ButtonGroup>
)
}import { ButtonGroup, Radio, RadioGroup } from '@chassis-ui/react'
export const Example = () => {
return (
<RadioGroup aria-label="Vertical radio toggle button group" defaultValue="vbtnradio1">
<ButtonGroup vertical>
<Radio
button={{ color: 'danger', variant: 'outline' }}
value="vbtnradio1"
label="Radio 1"
/>
<Radio
button={{ color: 'danger', variant: 'outline' }}
value="vbtnradio2"
label="Radio 2"
/>
<Radio
button={{ color: 'danger', variant: 'outline' }}
value="vbtnradio3"
label="Radio 3"
/>
</ButtonGroup>
</RadioGroup>
)
}Accessibility
Assistive technology only announces a set of buttons as grouped when the group carries an explicit role — role="group" for a button group, role="toolbar" for a <ButtonToolbar>. Every group and toolbar also needs an understandable label, since most assistive technologies don't otherwise announce the role attribute alone; aria-label is used throughout the examples above, though aria-labelledby works as well.
API
ButtonGroup
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the base component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
ref? | any | — |
size? | "sm" | "lg" | — |
| Size the component sm or lg. | ||
vertical? | boolean | — |
Create a set of buttons that appear vertically stacked rather than horizontally, with the
.button-group-vertical class in place of .button-group. Split button dropdowns are not
supported here, and size has no effect: chassis-css sizes the buttons of a horizontal group
only, so size the buttons of a vertical one themselves. | ||
ButtonToolbar
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the base component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
ref? | any | — |