Button group
Joins buttons into one segmented control: merged borders, rounded corners at the ends only. The row is one object, so it is the group that decides how it is drawn, from whether the buttons are joined at all down to the variant, the tone, the size and the density every button inside picks up.
Usage
Examples
Variants and tones
variant and tone are named once on the group. The variant wins over whatever a button inside was given; the tone is only a fallback.
One segment, another tone
A segment keeps its own tone against the group, which is how a neutral row holds a single destructive action.
Orientation
vertical stacks the segments in a column instead of a row, the joining following the axis.
Detached
detached leaves the buttons apart, each keeping its own corners and borders, while the group still hands its appearance props down.
Seamless
seamless removes the lines drawn at each joint, leaving a single frame with its outer edges intact.
Elevated
elevated gives the shadow to the row rather than to each segment. Detached, each button casts its own again.
Sizes
size sets the height of every segment: 24, 32, 40, 48 or 56 pixels. It wins over whatever a button inside was given.
Compact
compact takes 4px off the height of every segment.
Full width
fullWidth stretches the row across its parent and gives every segment an equal share of that width.
With icons
Segments carry iconStart and iconEnd the way any button does. A VIconButton is a segment too, and still needs its label.
Link
A segment given an href renders an <a>. A disabled link has its address dropped, which leaves it neither focusable nor followable.
States
disabled on the group adds up with each button's own: a segment cannot opt back in once the row is off. loading stays the button's own.
API
Props
| Prop | Type | Default |
|---|---|---|
orientation | ButtonGroupOrientation'horizontal' | 'vertical' | 'horizontal' |
The direction the buttons are joined in: a row by default, or a column under vertical. | ||
detached | boolean | false |
| Leaves the buttons as separate ones, with a gap between them and each keeping its own corners, instead of joining them into a segmented control. Everything the group hands down still travels, and an elevated row then lets each button cast its own shadow. | ||
seamless | boolean | false |
Takes the lines out from between the joined buttons: no seam is drawn, and the borders on both sides of every shared edge are cleared, so the row reads as one frame rather than as segments. The outer edges stay. It has no effect under detached, where there is no shared edge to take a line off. | ||
fullWidth | boolean | false |
Stretches the row across the whole inline size of its parent, every segment taking an equal share of that width whatever its label measures. A segment never shrinks below its own label, so a row of labels too long for the parent overflows rather than being crushed. Under vertical it is the width alone, a column already stretching every segment across it. | ||
variant | ButtonVariant'solid' | 'outline' | 'ghost' | 'soft' | none |
How much visual weight every segment carries, on VButton's own values: solid, outline, ghost or soft. It wins over the variant a button inside was given, a segment of another silhouette no longer reading as part of the row. Left out, each button keeps its own. | ||
tone | ButtonTone'accent' | 'neutral' | 'danger' | none |
The colour the segments take, among accent, neutral and danger. This one is a fallback rather than an order: a button that names a tone of its own keeps it, which is what lets a single destructive action stand out in the row. | ||
size | ButtonSize'xs' | 'sm' | 'md' | 'lg' | 'xl' | none |
The height of the segments, from the size scale shared by every control: xs, sm, md, lg or xl. It wins over the size a button inside was given. Left out, each button keeps its own. | ||
compact | boolean | none |
| Takes 4px off the height of every segment. It wins over the value a button inside was given. Left out, each button keeps its own. | ||
elevated | boolean | none |
| Raises the row off the page with the shadow scale, on the terms of VButton's own prop. The shadow is the row's and not each segment's, which is what keeps the joints clear: three overlapping shadows would draw a dark band down each of them. It wins over the value a button inside was given. Left out, each button keeps its own. | ||
disabled | boolean | none |
| Makes every segment unusable. This one adds up rather than overruling: a button that disables itself stays disabled in a row that says nothing, and a segment cannot opt back in once the row is switched off. | ||
label | string | none |
What screen readers announce for the row, which is a role="group": "Text formatting", "View". A group with no name is announced as a bare group. A consumer aria-label or aria-labelledby wins over it. | ||
Slots
| Slot | Type |
|---|---|
default | {} |
| The VButtons and VIconButtons to join together. | |