Thrive Design System

Components

ButtonGroup

A container component for grouping related buttons together with attached or detached styles and horizontal or vertical orientations

Installation

npm install @thrivecart/ui
yarn add @thrivecart/ui
pnpm add @thrivecart/ui
bun add @thrivecart/ui

Usage

Import the ButtonGroup component from the package:

import { ButtonGroup, Button, IconButton } from '@thrivecart/ui';

Examples

Basic Attached Group

Attached Buttons

Buttons visually connected with shared borders

<ButtonGroup attached>
<Button variant="secondary">Left</Button>
<Button variant="secondary">Center</Button>
<Button variant="secondary">Right</Button>
</ButtonGroup>

Two Button Toggle

Two Button Toggle

A pair of attached buttons with toggle state

Detached Group

Detached Buttons

Buttons separated with consistent spacing

<ButtonGroup attached={false}>
<Button variant="primary">Save</Button>
<Button variant="secondary">Cancel</Button>
</ButtonGroup>

Text Formatting Toolbar

Formatting Controls

Common text formatting button group

<ButtonGroup attached>
<IconButton variant="secondary" icon={<MdFormatBold />} aria-label="Bold" />
<IconButton variant="secondary" icon={<MdFormatItalic />} aria-label="Italic" />
<IconButton variant="secondary" icon={<MdFormatUnderlined />} aria-label="Underline" />
</ButtonGroup>

Alignment Controls

Text Alignment

Alignment button group

<ButtonGroup attached>
<IconButton variant="secondary" icon={<MdFormatAlignLeft />} aria-label="Align left" />
<IconButton variant="secondary" icon={<MdFormatAlignCenter />} aria-label="Align center" />
<IconButton variant="secondary" icon={<MdFormatAlignRight />} aria-label="Align right" />
</ButtonGroup>

View Switcher

View Options

Switch between different view modes with active state

Vertical Orientation

Vertical Layout

Stack buttons vertically

<div className="flex gap-8">
<ButtonGroup orientation="vertical" attached>
  <Button variant="secondary">Top</Button>
  <Button variant="secondary">Middle</Button>
  <Button variant="secondary">Bottom</Button>
</ButtonGroup>

<ButtonGroup orientation="vertical" attached={false}>
  <Button variant="primary">Primary Action</Button>
  <Button variant="secondary">Secondary Action</Button>
  <Button variant="ghost">Tertiary Action</Button>
</ButtonGroup>
</div>

Size Variants

All Sizes

Button groups in different sizes

<div className="flex flex-col gap-4 items-start">
<ButtonGroup size="xs">
  <Button variant="secondary">XS</Button>
  <Button variant="secondary">Size</Button>
  <Button variant="secondary">Group</Button>
</ButtonGroup>

<ButtonGroup size="sm">
  <Button variant="secondary">Small</Button>
  <Button variant="secondary">Size</Button>
  <Button variant="secondary">Group</Button>
</ButtonGroup>

<ButtonGroup size="md">
  <Button variant="secondary">Default</Button>
  <Button variant="secondary">Size</Button>
  <Button variant="secondary">Group</Button>
</ButtonGroup>

<ButtonGroup size="lg">
  <Button variant="secondary">Large</Button>
  <Button variant="secondary">Size</Button>
  <Button variant="secondary">Group</Button>
</ButtonGroup>
</div>

Overriding Size on Individual Children

A child can override the group's size by setting its own size prop directly. This is useful when one button in the group needs to differ — though use this sparingly since mixed sizes break visual rhythm.

Size Override

One child overrides the group size

<ButtonGroup size="sm" attached>
<Button variant="secondary">Normal</Button>
<Button variant="secondary" size="md">Overrideden</Button>
<Button variant="secondary">Normal</Button>
</ButtonGroup>

Toggle State

Interactive Toggle

Single and multi-select toggle groups

Text Alignment (Single Select)

Text Formatting (Multi Select)

Best Practices

Use attached for related actions

Use attached mode when buttons represent related options in a single control (e.g., text alignment).

Use detached for distinct actions

Use detached mode for action pairs like Save/Cancel where actions are distinct but related.

Provide clear active states

When using as toggle buttons, clearly indicate the active state using the primary variant.

Add aria-labels to icon buttons

Always provide accessible labels for icon-only buttons in the group.

Don't mix attached and detached

Use a consistent style within your application for similar use cases.

Don't group unrelated actions

Only group buttons that are contextually related or form a cohesive control.

Props

ButtonGroup

PropTypeDefaultDescription
attachedbooleantrueWhether buttons are visually connected
orientation'horizontal' | 'vertical''horizontal'Layout direction
size'xs' | 'sm' | 'md' | 'lg''md'Size propagated to all child buttons via context. Individual children can override with their own size prop.
childrenReactNode-Button or IconButton components
classNamestring-Additional className

Accessibility

ARIA Roles

ButtonGroup uses role="group" to indicate that the buttons are related. For toggle groups, consider using role="toolbar" or implementing a proper ARIA pattern.

  • Uses semantic grouping with role="group"
  • Supports keyboard navigation between buttons
  • Individual buttons maintain their accessibility features
  • Always provide aria-label for icon-only buttons
  • For exclusive selection, consider using aria-pressed to indicate state