Noctis

ButtonGroup

Weld related buttons into one control. Wrap any number of Buttons — icon, label, or icon-only — and the group squares their touching corners and draws a clearly visible divider between each.

Toolbar

Group icon buttons into a compact toolbar. Each stays a real Button with its own hover, focus, and aria-label; the group attaches them, separates them with a strong full-height divider, and shares one variant so they read as a set.

Shared size & variant

Set variant and size on the group and every child Button inherits them — that's the point of a group, so you set the look once instead of repeating it. A child that sets its own variant/size still wins, and inheritance flows through render, so a Menu.Trigger rendered as a Button (the split button below) matches too.

With labels

Buttons with labels work the same — a segmented set of related actions reads as one unit.

Split button

The split-button pattern — a primary action welded to a caret that opens more options — is just a ButtonGroup with a Menu: the action is a Button, and the caret is a Menu.Trigger rendered as an icon-only Button. No bespoke component; compose the two primitives.

Anatomy

ButtonGroup is a thin wrapper — it owns the shared look and attaches its children. Compose it from the Button primitive (and, for the split pattern, Menu):

  • Set variant and size on the group; each child Button inherits them unless it sets its own (an explicit child prop wins). Inheritance reaches buttons rendered through render too.
  • Each child stays a regular Button — its iconOnly, icons, aria-label, and handlers work as usual.
  • The group squares the inner corners (each end keeps its own button's outer radius) and pulls segments together so adjacent borders collapse to a single seam.
  • The divider at each seam is a full-height line in the high-contrast strong token — drawn in CSS, not as a separate element — so it stays legible across button variants. Everything is logical, so it mirrors under RTL.

The wrapper carries data-slot="button-group"; target the child buttons by their own data-slot="button".

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root
elevated
menu
sunken

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every group in that region retunes — e.g. .toolbar { --noctis-button-group-seam-color: var(--noctis-color-border); } softens the divider between buttons. Knobs that aren't minted are reached through the part's data-slot. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source.

Prop

AttributeDescription
data-slotMarks the group wrapper.