Glin UI
Primitive / Moleculebeta

Button Group

Merges adjacent buttons into one segmented control with shared borders.

Edit on GitHub

Installation

Install from
pnpm dlx @glinui/cli@latest add button-group

Prefer the package?

Usage

Variants

import { Button, ButtonGroup } from "@glinui/ui"
export function Demo() {
return (
<div className="grid gap-3">
<ButtonGroup variant="glinr" aria-label="Glinr"><Button>One</Button><Button>Two</Button></ButtonGroup>
<ButtonGroup variant="solid" aria-label="Solid"><Button>One</Button><Button>Two</Button></ButtonGroup>
<ButtonGroup variant="plain" aria-label="Plain"><Button>One</Button><Button>Two</Button></ButtonGroup>
<ButtonGroup variant="outline" aria-label="Outline"><Button>One</Button><Button>Two</Button></ButtonGroup>
</div>
)
}

Glass (opt-in)

100%
import { Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from "@glinui/ui"
// Glass needs a colorful or photographic backdrop to read.
export function Demo() {
return (
<ButtonGroup variant="glass" aria-label="Zoom">
<Button>-</Button>
<ButtonGroupText>100%</ButtonGroupText>
<ButtonGroupSeparator />
<Button>+</Button>
</ButtonGroup>
)
}

Quantity stepper

Icon buttons around a live value make a compact stepper.

"use client"
import { useState } from "react"
import { Minus, Plus } from "@phosphor-icons/react"
import { Button, ButtonGroup } from "@glinui/ui"
export function ToggleStepper() {
const [qty, setQty] = useState(2)
return (
<ButtonGroup aria-label="Quantity" variant="outline">
<Button size="icon" aria-label="Decrease quantity" onClick={() => setQty((value) => Math.max(1, value - 1))}>
<Minus weight="bold" />
</Button>
<Button aria-live="polite" tabIndex={-1} className="min-w-12 tabular-nums">{qty}</Button>
<Button size="icon" aria-label="Increase quantity" onClick={() => setQty((value) => value + 1)}>
<Plus weight="bold" />
</Button>
</ButtonGroup>
)
}

Accessibility

  • Renders `role="group"`; give it an `aria-label` describing the set.
  • Each child keeps its own button semantics and focus ring (raised above neighbours).

Keyboard Interactions

KeyAction
TabMove through each button in order.

ARIA Attributes

  • `role="group"` with `aria-label`
  • `role="separator"` on ButtonGroupSeparator

Reduced Motion

Hover lift and press scale are disabled inside the group so merged edges stay aligned.

Affected properties

transform

API Reference

ButtonGroup

PropTypeRequiredDefaultDescription
orientation"horizontal" | "vertical"NohorizontalLayout direction. Adjacent buttons share borders; only outer ends are rounded.
variant"default" | "glass" | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient"NodefaultLook shared with every child Button that does not set its own. Glass also adds a blurred container and needs a backdrop.
toneSurfaceToneNo-Tone shared with child Buttons.
sizeButtonGroupContextValue["size"]No-Size shared with child Buttons.

ButtonGroupText

PropTypeRequiredDefaultDescription
asChildboolean-falseRender as the child element, for example a label.
orientation"horizontal" | "vertical"No"vertical"Variant option from buttonGroupVariants.
sizeButtonGroupContextValue["size"]No-Size applied to child Buttons that do not set their own.
toneSurfaceToneNo-Tone applied to child Buttons that do not set their own.
variant"default" | "glass" | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient"No"default"Variant option from buttonGroupVariants.

ButtonGroupSeparator

PropTypeRequiredDefaultDescription
orientation"horizontal" | "vertical"NoverticalDivider direction.
sizeButtonGroupContextValue["size"]No-Size applied to child Buttons that do not set their own.
toneSurfaceToneNo-Tone applied to child Buttons that do not set their own.
variant"default" | "glass" | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient"No"default"Variant option from buttonGroupVariants.

Source

Import directly from the package or browse the source on GitHub. Click any file to view it.

Import

import { ButtonGroup } from "@glinui/ui"

Source Files

Dependencies

@glinui/ui@radix-ui/react-slotclass-variance-authority

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/button-group.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

ButtonGroupProps

ButtonGroupProps

PropTypeRequiredDefaultDescription
orientation"horizontal" | "vertical"No"vertical"Variant option from buttonGroupVariants.
sizeButtonGroupContextValue["size"]No-Size applied to child Buttons that do not set their own.
toneSurfaceToneNo-Tone applied to child Buttons that do not set their own.
variant"default" | "glass" | "glinr" | "solid" | "plain" | "soft" | "outline" | "ghost" | "gradient"No"default"Variant option from buttonGroupVariants.

ButtonGroupTextProps

PropTypeRequiredDefaultDescription
asChildbooleanNofalse-