Skip to content

ButtonGroup ​

A button group joins related Buttons into a single control: the corners are rounded on the outside only, and the group sets the size and variant so the buttons cannot drift apart. Where the buttons also carry selection — pressed or not — you want a ToggleButtonGroup instead.

ts
import { Button, ButtonGroup, ButtonGroupSeparator } from "ropav";
variant
size
orientation
template
<ButtonGroup aria-label="History">
  <Button>Undo</Button>
  <Button>
    <ButtonGroupSeparator />
    Redo
  </Button>
</ButtonGroup>

size and variant on the group apply to every button in it, and any button may still set its own — which is how one destructive action sits in a row of ordinary ones.

The rule between buttons ​

ButtonGroupSeparator goes inside the button that follows the rule, not between the two. That is what keeps the line attached to the button as it moves, so a group can wrap or change orientation without the rules ending up somewhere else.

button-group-vertical.vue
vue
<script setup lang="ts">
import { Button, ButtonGroup, ButtonGroupSeparator } from "ropav";
</script>

<template>
  <ButtonGroup aria-label="File actions" orientation="vertical" variant="secondary">
    <Button>Duplicate</Button>
    <Button>
      <ButtonGroupSeparator />
      Rename
    </Button>
    <Button>
      <ButtonGroupSeparator />
      Archive
    </Button>
  </ButtonGroup>
</template>

Inside a Toolbar the group takes the toolbar's axis, so orientation only needs setting when the group stands on its own.

Accessibility ​

  • The group is a role="group" and every button inside keeps its own role, its own name and its own tab stop — joining controls visually does not make them one control to a screen reader.
  • That group has no name of its own, so pass an aria-label wherever the grouping is part of the meaning rather than only part of the picture.
  • is-disabled on the group disables every button in it. A group where only some actions are unavailable should disable those buttons rather than the group.
  • An icon-only button in a group still needs an aria-label — the shared frame gives it no name.

API ​

ButtonGroup

PropTypeDefaultDescription
fullWidthboolean—Stretches the group to the full width of its container.
isDisabledboolean—Disables every button in the group.
orientation"horizontal" | "vertical""horizontal"Direction the buttons are laid out in. Falls back to the axis of an enclosing Toolbar.
size"xs" | "sm" | "md" | "lg"—Size for every button in the group. Each button can still set its own.
variant"primary" | "secondary" | "tertiary" | "outline" | "ghost" | "danger" | "danger-soft"—Variant for every button in the group. Each button can still set its own.

Slots: default.

ButtonGroupSeparator

ButtonGroupSeparator takes nothing but class.