VayuUI

ButtonGroup

Groups multiple buttons together with connected borders and consistent sizing for cohesive action layouts.

Installation

npx vayu-ui-cli@latest add buttongroup

Usage

Button Group Examples
Horizontal (Outline)

Default horizontal layout with outline variant buttons.

Primary

Grouped primary buttons for related actions.

Vertical

Stack buttons vertically using the orientation prop.

Full Width

Buttons stretch to fill the full container width.

Mixed Variants

Combine different button variants in a single group.

With Icons

Icon-only buttons grouped together as a toolbar.

Radius Variants

Control the border radius using design token scales.

Control

Surface

Overlay

Full

<ButtonGroup aria-label="Text alignment">
  <Button variant="outline">
    <Button.Text>Left</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Center</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Right</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup aria-label="Save options">
  <Button variant="primary">
    <Button.Text>Save</Button.Text>
  </Button>
  <Button variant="primary">
    <Button.Text>Save &amp; Close</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup orientation="vertical" aria-label="Vertical actions">
  <Button variant="outline">
    <Button.Text>Top</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Middle</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Bottom</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup fullWidth aria-label="Confirmation actions">
  <Button variant="secondary">
    <Button.Text>Cancel</Button.Text>
  </Button>
  <Button variant="primary">
    <Button.Text>Confirm</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup aria-label="Mixed action buttons">
  <Button variant="outline">
    <Button.Text>Back</Button.Text>
  </Button>
  <Button variant="secondary">
    <Button.Text>Save Draft</Button.Text>
  </Button>
  <Button variant="primary">
    <Button.Text>Submit</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup radius="surface" aria-label="Formatted radius">
  <Button variant="outline">
    <Button.Text>A</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>B</Button.Text>
  </Button>
</ButtonGroup>

<ButtonGroup aria-label="Formatting options">
  <Button variant="outline">
    <Button.Icon>
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>
        <path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/>
      </svg>
    </Button.Icon>
  </Button>
  <Button variant="outline">
    <Button.Icon>
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <line x1="19" x2="10" y1="4" y2="4"/>
        <line x1="14" x2="15" y1="20" y2="4"/>
        <line x1="5" x2="19" y1="20" y2="20"/>
      </svg>
    </Button.Icon>
  </Button>
  <Button variant="outline">
    <Button.Icon>
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M10 4h8a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4h-8"/>
        <path d="M14 12H6"/>
        <path d="M10 8l-4 4 4 4"/>
      </svg>
    </Button.Icon>
  </Button>
</ButtonGroup>

Anatomy

import { ButtonGroup, Button } from 'vayu-ui';

<ButtonGroup aria-label="Group label">
  <Button variant="outline">
    <Button.Text>Button 1</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Button 2</Button.Text>
  </Button>
  <Button variant="outline">
    <Button.Text>Button 3</Button.Text>
  </Button>
</ButtonGroup>;
  • ButtonGroup — Root container with role="group". Manages orientation, sizing, radius, and focus stacking for child buttons via CSS.
  • Button — Individual action buttons rendered as children of the group. Supports all variants and subcomponents (Button.Text, Button.Icon).

Accessibility

  • Keyboard Support:
    • Tab — Move focus to the next focusable button.
    • Shift + Tab — Move focus to the previous focusable button.
    • Enter / Space — Activate the focused button.
  • ARIA Attributes:
    • role="group" on ButtonGroup indicates a related set of buttons.
    • aria-label or aria-labelledby provides the accessible group name. At least one is required.
  • Focus Behavior:
    • Focused and hovered buttons receive z-10 so the focus ring is fully visible over adjacent siblings (WCAG 2.4.11).
    • Focus follows natural DOM tab order through child buttons.

Screen reader behavior

When a screen reader encounters a ButtonGroup, it announces the group label (via aria-label or aria-labelledby) followed by the individual button labels in sequence. Each button is announced as a standard push button with its text content. Users navigate between buttons using Tab and Shift + Tab, and the screen reader announces each button as it receives focus. No additional state information is conveyed since button groups do not manage selection state.

Component Folder Structure

ButtonGroup/
├── ButtonGroup.tsx    # Component with CSS-based sizing, radius, and focus management
├── types.ts           # TypeScript type definitions (ButtonGroupProps, ButtonGroupRadius)
├── index.ts           # Re-exports ButtonGroup and types
└── README.md          # Component usage reference

Props

ButtonGroup

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Stack direction of buttons.
size"small" | "medium" | "large""medium"Size applied to all child buttons via CSS.
radius"control" | "surface" | "overlay" | "full""control"Border radius variant using semantic design tokens.
fullWidthbooleanfalseStretch to fill container width.
aria-labelstringAccessible label for the button group.
aria-labelledbystringID of element that labels this group.
classNamestringAdditional CSS classes.
childrenReactNodeButton elements to group.

On this page