Primitives

Button Group

Visually-joined cluster of buttons sharing borders.

Preview
01 Installation

Install

Pull Button Group from the barrel for everyday use, or the granular path when you want a tighter bundle.

tsxBarrel1 line
import { ButtonGroup } from "@brika/clay";
tsxGranular1 line
import { ButtonGroup } from "@brika/clay/components/button-group";
02 Usage

A minimal example

Drop this into a page. Native HTML attributes pass through to the underlying primitive.

tsxButton Group.tsx13 lines
import { Button } from '@brika/clay/components/button';
import { ButtonGroup } from '@brika/clay/components/button-group';

/** Three related action buttons joined in a shared frame, each click fires once, no selection state. */
export default function ButtonGroupDefaultDemo() {
  return (
    <ButtonGroup>
      <Button variant="outline">Reply</Button>
      <Button variant="outline">Reply all</Button>
      <Button variant="outline">Forward</Button>
    </ButtonGroup>
  );
}
03 Examples

Button Group, every way

Filled

Filled default variant inside a group, good for primary action clusters.

Icons

Icon-only action buttons for a compact toolbar, every button needs an `aria-label`.

Split Button

Primary action plus a dropdown chevron for related variants.

Vertical

Vertical orientation stacks buttons top-to-bottom with shared dividers.

With Input

Input + trailing button, classic copy-URL pattern.

04 Accessibility

Accessibility

  • The wrapper carries role="group", add aria-label when the group's purpose is not clear from context.
  • Each button inside the group keeps its individual focus ring and keyboard behavior.
  • Icon-only buttons inside the group still require aria-label.
05 Tokens 4 theme-overridable

Theme tokens

Every CSS variable Button Group reads, with its default and the dotted path you'd write in a ThemeConfig JSON to override it. Set any of these in your theme to retune Button Group without touching component code.

Button Group tokens

4 tokens
ColorFill, border, and text colors.4
  • --button-group-frame-containercolorvar(--input-container)
    components.buttonGroup.frameContainer

    Background fill of the button-group frame. Defaults to the `--input-container` role so a group reads as a single grouped control matching other inputs.

  • --button-group-frame-bordercolorvar(--input-border)
    components.buttonGroup.frameBorder

    Border color of the button-group outer frame. Defaults to the `--input-border` role so the frame matches other input edges.

  • --button-group-divider-colorcolorvar(--input-border)
    components.buttonGroup.dividerColor

    Color of the 1px separator drawn between adjacent buttons in the group, and of the explicit `ButtonGroupSeparator` bar. Defaults to `--input-border` so dividers blend with the frame.

  • --button-group-text-colorcolorvar(--muted-foreground)
    components.buttonGroup.textColor

    Foreground color of the inline `ButtonGroupText` label slot. Defaults to the muted-foreground role so plain text inside a group reads as supporting content.

Override in a theme

Authoring a theme is plain JSON. Drop overrides under components.buttonGroup, the names are camelCase versions of the variable suffix.

jsonmy-theme.json12 lines
{
  "id": "my-theme",
  "name": "My Theme",
  "description": "...",
  "accentSwatches": ["#000"],

  "components": {
    "buttonGroup": {
      "frameContainer": "var(--input-container)"
    }
  }
}

Then apply with applyTheme(myTheme) (see the theming guide), scope it to a subtree with themeToCssVars(myTheme, mode), or consume any token directly in your own JSX with the matching Tailwind utility (e.g. bg-button-group-…) — see the chips on each token row.

06 API reference

API reference

Props specific to Button Group. Native HTML attributes pass through to the underlying primitive, see the component source on GitHub for the full type signature.

<ButtonGroup />

1 prop
  • 'horizontal' | 'vertical'
    Lay buttons out horizontally or vertically.

<ButtonGroupSeparator />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<ButtonGroupText />

1 prop
  • asChilddefault false
    boolean
    When true, render the child element instead of the default DOM node and merge props. Lets you compose with <a>, <Link>, or another primitive while keeping behavior and styling.