Skip to the content
BooleanPress UI

Button

Button group

Joins related buttons, or a button and an input, into one connected control.

Import

import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from "@booleanpress/ui/button-group"

Usage

ButtonGroup removes the inner borders and corner radii of its children, so they read as one control. It lays out; it does not select. For a choice that stays pressed, use a toggle group.

import { Button } from "@booleanpress/ui/button"
import { ButtonGroup } from "@booleanpress/ui/button-group"

export function Period() {
  return (
    <ButtonGroup aria-label="Log period">
      <Button variant="outline">Today</Button>
      <Button variant="outline">7 days</Button>
    </ButtonGroup>
  )
}

The parts are ButtonGroup, ButtonGroupText (a label or prefix drawn like a button), and ButtonGroupSeparator (a divider between two buttons that share a fill, as in a split button). A child can be a Button, an Input or a select trigger. Nest groups to space them apart. orientation is horizontal (default) or vertical.

Examples

Basic

Three related buttons as one control, named by aria-label.

Vertical

orientation="vertical" stacks the buttons and joins them top to bottom.

Split button

A main action and a menu button, divided by ButtonGroupSeparator.

With text and input

ButtonGroupText and an Input join a button in one row.

Disabled

Disable one button; the others keep working and the group keeps its shape.

Accessibility

Semantics
A div with role="group". data-orientation is set when you pass orientation. The separator is decorative and hidden from assistive technology.
Labels
Name the group with aria-label or aria-labelledby when the buttons need shared context ("Log period"). Name every icon-only button and every Input inside it.
Focus
Each child keeps its own tab stop. The focused child is raised above its neighbours, so its focus ring is not cut off by the next button.
Known limits
  • The group adds no arrow-key navigation. If you want the toolbar pattern (one tab stop, arrow keys between buttons), use a toolbar or a toggle group instead.
  • It does not track a selected button. Mark a current choice yourself, for example with aria-pressed.

Keyboard

Keyboard
KeyBehaviour

API

ButtonGroup

Renders a div and passes it every other prop.

ButtonGroupSeparator

ButtonGroupSeparator props
PropTypeDefaultDescription
asChildboolean
decorativebooleanWhether or not the component is purely decorative. When true, accessibility-related attributes are updated so that that the rendered element is removed from the accessibility tree.
orientation"horizontal" | "vertical"verticalEither vertical or horizontal. Defaults to horizontal.

ButtonGroupText

Renders a div and passes it every other prop.

ButtonGroupText props
PropTypeDefaultDescription
asChildbooleanfalseRender the child element instead, with this part's classes merged onto it, for a Label that sits in the group.

Also exported: buttonGroupVariants, the class names of ButtonGroup's variants and sizes (cva), to give another element the same look.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="button-group" (ButtonGroup), data-slot="button-group-separator" (ButtonGroupSeparator), and data-orientation.

Theming

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--inputbackground
--mutedbackground