Skip to main contentSkip to docs navigation

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.

JSX
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>.

JSX
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.

JSX
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.

JSX
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.

JSX
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>
  )
}
JSX
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.

JSX
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.

@
@
JSX
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.



JSX
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.

JSX
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.

JSX
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>
  )
}
JSX
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>
  )
}
JSX
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

PropTypeDefault
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

PropTypeDefault
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—