---
title: Button Group
description: Button groups visually unite related actions so users perceive them as a single control cluster. Use them for segmented choices or paired operations.
---

import { meta as ButtonGroupMeta, Default } from '@/content/stories/button-group';
import Canvas from '@/components/component-docs/canvas';
import Demo from '@/components/component-docs/demo';

export const config = {
	dependencies: {
		components: [Canvas, Demo],
		scripts: [
			'../../../components/component-docs/demo.script.tsx',
			'../../../components/component-docs/canvas.script.tsx',
			'../../../components/component-docs/controls.script.tsx',
		],
	},
};


# Button Group

<p class="docs-lede">Button groups visually unite related actions so users perceive them as a single control cluster. Use them for segmented choices or paired operations.</p>

## Try it

<Demo of={Default} meta={ButtonGroupMeta} />

## Usage

Place `RuiButton` children inside `RuiButtonGroup`. Set `orientation` when stacking vertically in narrow layouts.

```tsx
import { RuiButtonGroup } from '@ecopages/radiant-ui/button-group';
import { RuiButton } from '@ecopages/radiant-ui/button';

<RuiButtonGroup orientation="horizontal">
  <RuiButton variant="outline">Cancel</RuiButton>
  <RuiButton variant="filled">Save</RuiButton>
</RuiButtonGroup>
```

## Group related actions only

<p>Keep actions logically connected, such as confirm/cancel pairs, view toggles, or formatting tools. Unrelated buttons should stand apart.</p>

## Orientation

<p>Use `horizontal` for toolbars and dialog footers. Switch to `vertical` in side panels or mobile layouts where width is constrained.</p>

## Theming

Button Group maps to **semantic spacing roles**, never Tailwind palette steps:

| Part | CSS roles |
| --- | --- |
| Group (`rui-button-group`) | `--space-inline` (item gap) |

The `horizontal` / `vertical` modifiers change flow layout only and add no color. Override at the theme layer, not in component CSS.

## API

`RuiButtonGroup` is a presentational JSX view over a `<div role="group">`, no custom element.

### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `orientation` | `horizontal` · `vertical` | `horizontal` | Layout direction. |
| `aria-label` | `string` | | Accessible name when the group has no visible label. |

### CSS classes

Public BEM classes on the rendered element (documented via `@cssclass` on `RuiButtonGroup`):

| Class | Description |
| --- | --- |
| `.rui-button-group` | Root group (`role="group"`). |
| `.rui-button-group--horizontal` | Side-by-side layout (default). |
| `.rui-button-group--vertical` | Stacked layout. |

### Theme roles

| Part | CSS variables consumed |
| --- | --- |
| Item gap | `--space-inline` |

## Accessibility

- Each button inside the group retains its own accessible name and keyboard focus.
- When buttons represent a single choice, consider `toggle` buttons with `aria-pressed` instead of separate submit actions.
- Maintain visible focus indicators on every button in the group.
