Tessera UI

ButtonGroup

A group of pill buttons inside a rounded pill container, supporting horizontal and vertical orientations with configurable gap

Installation

pnpm add @tessinaui/ui

Usage

import { ButtonGroup, ButtonGroupItem } from "@tessinaui/ui";
<ButtonGroup variant="outline" size="md">
  <ButtonGroupItem leadingIcon={<Scissors />} label="Cut" />
  <ButtonGroupItem leadingIcon={<Copy />} label="Copy" />
  <ButtonGroupItem leadingIcon={<Clipboard />} label="Paste" />
</ButtonGroup>

Playground

Configure every property of the ButtonGroup component interactively:

Preview
Loading...

Showcase

All variants, intents, sizes, orientations, and states:

Preview
Loading...

API Reference

ButtonGroup Props

PropTypeDefaultDescription
variant"outline" | "ghost""outline"Visual style applied to all items
intent"none" | "error""none"Semantic color intent applied to all items
size"xs" | "sm" | "md" | "lg" | "xl""md"Size applied to all items
orientation"horizontal" | "vertical""horizontal"Layout direction of the group
gap"micro" | "none""micro"Gap between items — micro is 4px, none is 0px
disabledbooleanfalseDisables all items in the group at once
dir"ltr" | "rtl""ltr"Text direction — RTL reverses icon/label order

ButtonGroupItem Props

PropTypeDefaultDescription
labelstringVisible label text
leadingIconReact.ReactNodeIcon rendered before the label; replaced by a spinner when loading
trailingIconReact.ReactNodeIcon rendered after the label; hidden when loading
loadingbooleanfalseShows a spinner and disables this item
disabledbooleanfalseDisables this item individually
aria-labelstringAccessible label (required when no visible label is provided)
onClickMouseEventHandlerClick handler

Supported Combinations

VariantIntents
outlinenone, error
ghostnone, error

Sizes

SizeHeightUse case
xs40pxCompact toolbars
sm48pxSecondary actions
md56pxDefault, most use cases
lg64pxProminent toolbars
xl104pxHero / large controls

Accessibility

The ButtonGroup component:

  • Renders with role="group" on the wrapper for semantic grouping
  • Requires aria-label on icon-only ButtonGroupItem elements
  • focus-visible:ring-2 focus ring meets WCAG 2.1 AA on each item
  • Touch targets ≥ 44×44px for xs/sm; larger sizes exceed minimum
  • loading sets aria-busy="true" and disables the item
  • disabled (item or group) sets pointer-events-none and disabled attribute
  • RTL fully supported via the dir prop

On this page