Marble UI
← Components

Button Group

Preview: Attached

Groups related buttons visually: attached, split button or spaced.

Import

import { ButtonGroup } from '@marbleui/ui'

Props

<ButtonGroup>

PropTypeDefaultDescription
orientation'vertical' | 'horizontal''horizontal'
variant'attached' | 'spaced''attached'attached: shared borders, one shape. spaced: separate buttons with a small gap.

Also accepts React Aria props (16) and HTML element props (269).

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: React Aria Group. Follow the primitive's docs for the full keyboard map.

Usage notes

Lays related buttons out as one connected unit, as a split button, or as a spaced row. For a selectable set use ToggleButtonGroup or SegmentedControl; for a toolbar with keyboard navigation use Toolbar.

<ButtonGroup aria-label="Merge">
  <Button>Merge pull request</Button>
  <IconButton variant="solid" aria-label="More merge options">
    <ChevronIcon />
  </IconButton>
</ButtonGroup>
  • variant: attached (default) shares borders and squares inner corners; spaced keeps separate buttons with a gap. orientation is horizontal or vertical.
  • It only styles its children and holds no selection state.
  • Pass aria-label so the group is named for assistive tech; it renders a React Aria Group.
  • Icon-only children need their own aria-label.
Example source · show
import { Button } from '../button'
import { IconButton } from '../icon-button'
import { ButtonGroup } from './button-group'

const Chevron = ({ d }: { d: string }) => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden>
    <path d={d} />
  </svg>
)

export const styles = {
  Attached: () => (
    <ButtonGroup aria-label="Text alignment">
      <Button variant="outline">Years</Button>
      <Button variant="outline">Months</Button>
      <Button variant="outline">Days</Button>
    </ButtonGroup>
  ),
  'Split button': () => (
    <ButtonGroup aria-label="Merge">
      <Button>Merge pull request</Button>
      <IconButton variant="solid" aria-label="More merge options" className="border-l border-accent-fg/20">
        <Chevron d="m6 9 6 6 6-6" />
      </IconButton>
    </ButtonGroup>
  ),
  Spaced: () => (
    <ButtonGroup variant="spaced" aria-label="Pagination">
      <IconButton variant="outline" aria-label="Previous"><Chevron d="m15 18-6-6 6-6" /></IconButton>
      <IconButton variant="outline" aria-label="Next"><Chevron d="m9 18 6-6-6-6" /></IconButton>
    </ButtonGroup>
  ),
}

Source: packages/ui/src/button-group/button-group.tsx

Catalog

Category
inputs
Priority
Core
Primitive
composed
React Aria
Group