ToggleButtonGroup
A toggle button group is a set of ToggleButtons that share a selection: one alignment out of three, or any combination of bold, italic and underline. Where the buttons fire actions rather than holding a state, you want a ButtonGroup.
import { ToggleButton, ToggleButtonGroup, ToggleButtonGroupSeparator } from "ropav";Every button in the group needs an id, because that is the key the selection is carried in.
<ToggleButtonGroup aria-label="Text style" :default-selected-keys='["bold"]'>
<ToggleButton id="bold">Bold</ToggleButton>
<ToggleButton id="italic">
<ToggleButtonGroupSeparator />
Italic
</ToggleButton>
</ToggleButtonGroup>One or many
selection-mode is the whole difference between the two shapes this component takes. Left at single it behaves like a set of radio buttons drawn as a control; at multiple each button is independent and the group is a row of switches. disallow-empty-selection keeps at least one pressed, which is what you want where the group always describes some state — text is aligned somehow, even if the reader has not chosen.
toggle-button-group-selection.vue
<script setup lang="ts">
import { ToggleButton, ToggleButtonGroup, ToggleButtonGroupSeparator } from "ropav";
const alignments = [
{ id: "left", label: "Left" },
{ id: "center", label: "Centre" },
{ id: "right", label: "Right" },
] as const;
const styles = [
{ id: "bold", label: "Bold" },
{ id: "italic", label: "Italic" },
] as const;
</script>
<template>
<div class="stack">
<ToggleButtonGroup
aria-label="Alignment"
:default-selected-keys="['left']"
disallow-empty-selection
>
<template v-for="(item, index) in alignments" :key="item.id">
<ToggleButton :id="item.id">
<ToggleButtonGroupSeparator v-if="index > 0" />
{{ item.label }}
</ToggleButton>
</template>
</ToggleButtonGroup>
<ToggleButtonGroup aria-label="Text style" selection-mode="multiple">
<template v-for="(item, index) in styles" :key="item.id">
<ToggleButton :id="item.id">
<ToggleButtonGroupSeparator v-if="index > 0" />
{{ item.label }}
</ToggleButton>
</template>
</ToggleButtonGroup>
</div>
</template>
<style scoped>
.stack {
display: flex;
flex-direction: column;
gap: calc(var(--rp-spacing) * 6);
}
</style>v-model:selected-keys hands the selection to the caller; default-selected-keys just starts it somewhere. is-detached separates the buttons visually instead of joining them, for a group that should read as several controls that happen to agree.
Accessibility
- Each button keeps
aria-pressed, so a screen reader announces the state of the one it is on rather than the group's selection as a whole. - The group needs an
aria-label. "Text style" tells a reader what the pressed buttons are about; without it they hear three unrelated toggles. ToggleButtonGroupSeparatoris decorative andaria-hidden— it goes inside the button that follows it, the same as in a button group, so the rule travels with the button.- Single selection here is not a radio group. Where the choice is a form value with a name and a validation state, use a RadioGroup and let this component be the toolbar control it looks like.
API
ToggleButtonGroup
| Prop | Type | Default | Description |
|---|---|---|---|
defaultSelectedKeys | Iterable<ToggleGroupKey> | — | Selected keys in uncontrolled mode. |
disallowEmptySelection | boolean | — | Keeps at least one key selected, so the group can never be turned fully off. |
fullWidth | boolean | — | Stretches the group to the full width of its container. |
isDetached | boolean | false | Separates the buttons visually instead of joining them into one control. |
isDisabled | boolean | — | Disables every button in the group. |
orientation | "horizontal" | "vertical" | "horizontal" | Direction the buttons are laid out in. Falls back to the axis of an enclosing Toolbar. |
selectedKeys | Iterable<ToggleGroupKey> | — | Selected keys in controlled mode. |
selectionMode | "single" | "multiple" | "single" | Whether one or many buttons can be selected at a time. |
size | "xs" | "sm" | "md" | "lg" | — | Size for every button in the group. Each button can still set its own. |
Slots: default.
| Event | Payload |
|---|---|
selectionChange | Set<ToggleGroupKey> |
ToggleButtonGroupSeparator
ToggleButtonGroupSeparator takes nothing but class.