Skip to content
Glint UI

ButtonGroup

A cluster of buttons that assistive technology announces as one thing before it reads them.

Usage

import { ButtonGroup } from "@glint/components/button-group.slint";
import { Button, ButtonVariant } from "@glint/components/button.slint";
import { Tokens } from "@glint/theme/tokens.slint";
export component AppWindow inherits Window {
width: 420px;
height: 140px;
background: Tokens.color-background;
VerticalLayout {
padding: 24px;
alignment: center;
HorizontalLayout {
alignment: center;
ButtonGroup {
accessible-label: "Alignment";
Button { variant: ButtonVariant.outline; text: "Left"; }
Button { variant: ButtonVariant.outline; text: "Center"; }
Button { variant: ButtonVariant.outline; text: "Right"; }
}
}
}
}

Drop two or more Buttons into the group’s slot. The group is layout and a name: it lays them out in a single row with no gap between them, and publishes one node for the cluster so a screen reader says what the buttons belong to before it reads them. Naming it is the call site’s — accessible-label, the way every Glint control is named.

Each button keeps its own variant and its own rounded corners — the group is not a style override. Pair the cluster with variant: ButtonVariant.outline for the classic segmented look.

ButtonGroup is not a selection. It is a row of independent actions, each with its own clicked. Reach for ToggleGroup when one of the buttons has to stay pressed, and for Tabs when picking one switches what is on screen.

Examples

The stacked cluster, and the weld

ButtonGroupColumn is the same cluster standing on end. It is a component of its own rather than an orientation on ButtonGroup, because a @children slot is written once and never inside an if (ADR-0027) — a group cannot pick between two layouts at runtime, so the axis is structural. Sheet and Drawer make the same move for the same reason.

The column is what welds. Stacked buttons overlap by the hairline they share, so two bordered neighbours draw one line instead of two, and the corners where they meet are squared. Squaring them is each button’s own join — Slint gives a parent no way to reach into its @children, so the column cannot do it for you (the wall ADR-0015 and ADR-0021 hit). ButtonJoin.first squares the bottom corners, last the top ones, middle all four, and none — the default — squares nothing. The plain ButtonGroup row stays unwelded.

A chunk of text in the cluster

ButtonGroupText is the piece of the cluster that is not a button — the https:// ahead of a host field, the page count between two steppers. It wears the buttons’ chrome so the cluster reads as one, and nothing else: no press, no focus, no tab stop. It is announced as text, because a node that says “button” offers an action that does not exist.

It takes the same join its neighbours do, derived the same way, so a chunk welds into a stack exactly as a button does.

A chunk stands a default-size button tall. Beside another ButtonSize, set height: on it at the call site — it is a plain Slint property, and a second size vocabulary here would be Button’s own cascade written twice.

API Reference

ButtonGroup publishes no properties, callbacks or functions of its own. What a call site can set on it is the Slint Rectangle it inherits.

ButtonGroupColumn

The stacked cluster, and the one that welds.

ButtonGroupColumn publishes no properties, callbacks or functions of its own. What a call site can set on it is the Slint Rectangle it inherits.

ButtonGroupText

The non-interactive chunk inside a cluster.

Properties

PropertyTypeDefaultDescription
textin stringno defaultText rendered inside the chunk.
joinin ButtonJoinButtonJoin.noneWhere this chunk sits in a welded group — the same knob its neighbours take, so a stack of them welds too.

Enums

EnumValues
ButtonJoinnone, first, middle, last

Accessibility

  • One node for the cluster. Both groups carry accessible-role: groupbox, so assistive technology announces what the buttons belong to before reading them. Slint 1.17 has no plain group role and groupbox is the nearest; GroupBox publishes the same role for a titled cluster.
  • The name is yours. The groups declare the role and no label, so a call site’s own accessible-label lands on that node. A group with no label is a container a screen reader announces without saying what it holds.
  • The buttons speak for themselves. Each keeps its own name, its own enabled state and its own tab stop — the cluster adds a node above them and takes nothing away. An icon-only button in a cluster still needs its accessible-label.
  • A chunk of text is text. ButtonGroupText announces accessible-role: text with its own content as the name, the way Kbd’s cap does. It takes no focus and answers no activation, so nothing in the cluster invites a press that does nothing.
  • join is paint. Squaring a corner changes no announcement: a welded button is announced exactly as a standalone one.