Vize

Button Group

Accessible, unstyled adjacent action group with optional toolbar roving focus.

Package @vizejs/ui/button-group
Maturity stable
Own the source vize lib pull button-group
Requires context
Aliases button group, button bar, action group, toolbar
Covers WAI-ARIA Toolbar, React Aria Toolbar, shadcn/ui Button

Usage

import { ButtonGroup, ButtonGroupItem } from "@vizejs/ui/button-group";

Or copy the source into your project with vize lib pull button-group (see Source Distribution).

API

ButtonGroup

Source: src/families/actions/button-group/button-group.vue

Props

Prop Type Default Description
as PrimitiveAs "div" Native element, custom element, or component to render.
role ButtonGroupRole "group" Accessible grouping semantics for adjacent actions.
disabled boolean false Disable every item and remove the group from roving focus.
orientation ButtonGroupOrientation "horizontal" Directional layout hint used by toolbar arrow-key roving focus.
loop boolean true Whether arrow-key navigation wraps at the first and last enabled item.
rovingFocus boolean undefined Whether items participate in a single-tabstop roving focus model. Defaults to true for role="toolbar" and false for plain groups.
ariaLabel string undefined Accessible name when no visible label or aria-labelledby supplies one.
ariaLabelledby string undefined Space-separated ids that label the group.
ariaDescribedby string undefined Space-separated ids that describe the group.

Events

Event Payload Description
press [value: string, nativeEvent: MouseEvent] Fired after an enabled item is activated by pointer or keyboard.

Slots

Slot Slot props Description
default ButtonGroupSlotState Compound ButtonGroup items. Receives grouping, availability, and navigation state.

Exposed

Member Type Description
disabled boolean Whether the group suppresses every item activation.
orientation ButtonGroupOrientation Directional layout hint used by toolbar arrow-key roving focus.
role ButtonGroupRole Accessible grouping role rendered by the root.
rovingFocus boolean Whether items participate in a single-tabstop roving focus model.
state ButtonGroupState Stable state token for styling and tests.
activeValue string | null Currently active item value, or null before an item is focusable.
element PrimitiveElement | null Rendered root element or component instance.
focus (options?: FocusOptions) => void Move focus to the active or first enabled item.
focusValue (value: string, options?: FocusOptions) => boolean Move focus to an enabled item by value and report whether it was found.

ButtonGroupItem

Source: src/families/actions/button-group/button-group-item.vue

Props

Prop Type Default Description
as PrimitiveAs "button" Native element, custom element, or component to render.
native boolean auto Whether the rendered target already implements native button semantics.
type "button" | "reset" | "submit" "button" Native button submission behavior.
value (required) string required Stable item value emitted by item and group press events.
disabled boolean false Disable this item while preserving the rest of the group.
ariaLabel string undefined Accessible name when no visible label or aria-labelledby supplies one.
ariaLabelledby string undefined Space-separated ids that label this item.
ariaDescribedby string undefined Space-separated ids that describe this item.

Events

Event Payload Description
press [value: string, nativeEvent: MouseEvent] Fired after user activation reaches this enabled item.

Slots

Slot Slot props Description
default ButtonGroupItemSlotState Renders item contents with current availability and navigation state.

Exposed

Member Type Description
value string Item value used by the group navigation and press contract.
disabled boolean Whether this item or its group suppresses activation.
orientation ButtonGroupOrientation Directional layout hint inherited from the group.
state ButtonGroupItemState Stable state token for styling and tests.
element PrimitiveElement | null Rendered item element or component instance.
focus (options?: FocusOptions) => void Move focus to the rendered item.

Behavior

ID Component Scenario Behavior Assertion
B1 button-group.vue grouped actions renders an accessible group with item data, part, and disabled hooks renders grouped button semantics without adding visual CSS
B2 button-group.vue toolbar navigation role="toolbar" opts into one-tabstop roving focus by default toolbar roving focus follows orientation and skips disabled
B3 button-group.vue group navigation override plain groups may opt into roving focus while preserving their ARIA role plain groups can opt into roving focus without toolbar role
B4 button-group-item.vue activation enabled items emit item and group press events in dispatch order pointer and keyboard activation emit value-carrying events
B5 button-group-item.vue disabled disabled groups and items suppress activation and leave tab order safely disabled groups and items suppress activation
B6 button-group-item.vue custom element semantics non-native items receive role="button" and synthesize keyboard clicks custom items expose button semantics and keyboard activation
B7 both public instance root and items expose focus methods and immutable state snapshots exposes focus, focusValue, activeValue, and item state
B8 button-group-item.vue duplicate value mount and reactive value changes reject duplicate item values rejects duplicate item values...
B9 button-group-item.vue provider boundary items fail loudly when rendered outside a matching group provider items require a matching group provider

Contract

ButtonGroup is a headless compound primitive for adjacent actions such as button bars, editor toolbars, card action rows, and destructive-confirmation clusters. It owns no selection model and emits no visual CSS. Consumers style through data-vize-ui, data-state, data-disabled, data-orientation, data-role, and part attributes.

role="group" preserves the native tab order by default. role="toolbar" defaults to a single tab stop with arrow-key movement because that is the WAI-ARIA toolbar expectation. Consumers may explicitly set rovingFocus on either role.

Items require a unique string value so item-level and group-level press events, activeValue, roving tabindex, and focusValue() stay stable across polymorphic rendering, slot changes, and DOM reordering. Duplicate values throw VIZE_UI_BUTTON_GROUP_VALUE_DUPLICATE during registration or reactive value changes before more than one item can own the active tab stop.