CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-aria--button

React hooks for implementing accessible button components with comprehensive keyboard, mouse, and touch interaction handling.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

toggle-button-groups.mddocs/

Toggle Button Groups

Manages collections of toggle buttons with proper ARIA semantics, supporting both single and multiple selection modes. The group hooks provide container management and individual item behavior for toggle button collections.

Capabilities

useToggleButtonGroup Hook

Creates container behavior for toggle button groups with proper ARIA semantics.

/**
 * Provides container behavior for toggle button groups with proper ARIA semantics
 * and keyboard navigation support.
 */
function useToggleButtonGroup(
  props: AriaToggleButtonGroupProps,
  state: ToggleGroupState,
  ref: RefObject<HTMLElement | null>
): ToggleButtonGroupAria;

useToggleButtonGroupItem Hook

Creates behavior for individual items within a toggle button group.

/**
 * Provides the behavior and accessibility implementation for a toggle button component
 * within a toggle button group. Handles selection state coordination with the group.
 */
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'button'>, state: ToggleGroupState, ref: RefObject<HTMLButtonElement | null>): ToggleButtonAria<ButtonHTMLAttributes<HTMLButtonElement>>;
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'a'>, state: ToggleGroupState, ref: RefObject<HTMLAnchorElement | null>): ToggleButtonAria<AnchorHTMLAttributes<HTMLAnchorElement>>;
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'div'>, state: ToggleGroupState, ref: RefObject<HTMLDivElement | null>): ToggleButtonAria<HTMLAttributes<HTMLDivElement>>;
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'input'>, state: ToggleGroupState, ref: RefObject<HTMLInputElement | null>): ToggleButtonAria<InputHTMLAttributes<HTMLInputElement>>;
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'span'>, state: ToggleGroupState, ref: RefObject<HTMLSpanElement | null>): ToggleButtonAria<HTMLAttributes<HTMLSpanElement>>;
function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<ElementType>, state: ToggleGroupState, ref: RefObject<Element | null>): ToggleButtonAria<DOMAttributes>;

Usage Examples:

import { useToggleButtonGroup, useToggleButtonGroupItem } from "@react-aria/button";
import { useToggleGroupState } from "@react-stately/toggle";
import { useRef } from "react";

// Basic toggle button group
function ToggleButtonGroup(props) {
  let groupRef = useRef<HTMLDivElement | null>(null);
  let state = useToggleGroupState(props);
  let { groupProps } = useToggleButtonGroup(props, state, groupRef);

  return (
    <div {...groupProps} ref={groupRef}>
      {props.children}
    </div>
  );
}

// Toggle button group item
function ToggleButtonGroupItem(props) {
  let ref = useRef<HTMLButtonElement | null>(null);
  let { buttonProps, isPressed, isSelected, isDisabled } = useToggleButtonGroupItem(
    props, 
    props.state, 
    ref
  );

  return (
    <button
      {...buttonProps}
      style={{
        background: isPressed
          ? (isSelected ? 'darkblue' : 'gray')
          : (isSelected ? 'blue' : 'lightgray'),
        color: isSelected ? 'white' : 'black',
        border: '1px solid #ccc',
        padding: '8px 12px'
      }}
      ref={ref}>
      {props.children}
    </button>
  );
}

// Complete toggle button group example
function TextAlignmentGroup() {
  let groupRef = useRef<HTMLDivElement | null>(null);
  let state = useToggleGroupState({
    selectedKeys: ['center'],
    selectionMode: 'single',
    onChange: (selectedKeys) => {
      console.log('Selected alignment:', [...selectedKeys]);
    }
  });
  let { groupProps } = useToggleButtonGroup({
    'aria-label': 'Text alignment',
    orientation: 'horizontal'
  }, state, groupRef);

  return (
    <div {...groupProps} ref={groupRef} style={{ display: 'flex', gap: 2 }}>
      <ToggleButtonGroupItem id="left" state={state}>
        Left
      </ToggleButtonGroupItem>
      <ToggleButtonGroupItem id="center" state={state}>
        Center
      </ToggleButtonGroupItem>
      <ToggleButtonGroupItem id="right" state={state}>
        Right
      </ToggleButtonGroupItem>
    </div>
  );
}

// Multiple selection group
function FeatureToggles() {
  let groupRef = useRef<HTMLDivElement | null>(null);
  let state = useToggleGroupState({
    selectedKeys: ['bold'],
    selectionMode: 'multiple',
    onChange: (selectedKeys) => {
      console.log('Active features:', [...selectedKeys]);
    }
  });
  let { groupProps } = useToggleButtonGroup({
    'aria-label': 'Text formatting options'
  }, state, groupRef);

  return (
    <div {...groupProps} ref={groupRef} style={{ display: 'flex', gap: 4 }}>
      <ToggleButtonGroupItem id="bold" state={state}>
        <strong>B</strong>
      </ToggleButtonGroupItem>
      <ToggleButtonGroupItem id="italic" state={state}>
        <em>I</em>
      </ToggleButtonGroupItem>
      <ToggleButtonGroupItem id="underline" state={state}>
        <u>U</u>
      </ToggleButtonGroupItem>
    </div>
  );
}

Toggle Button Group Props Interface

Configuration options for toggle button groups.

interface AriaToggleButtonGroupProps extends ToggleGroupProps, AriaLabelingProps {
  /**
   * The orientation of the toggle button group.
   * @default 'horizontal'
   */
  orientation?: Orientation;
  /** Whether the toggle button group is disabled. */
  isDisabled?: boolean;
}

interface ToggleGroupProps {
  /** The currently selected keys in the collection (controlled). */
  selectedKeys?: 'all' | Iterable<Key>;
  /** The initial selected keys in the collection (uncontrolled). */
  defaultSelectedKeys?: 'all' | Iterable<Key>;
  /** Handler that is called when the selection changes. */
  onChange?: (keys: Selection) => void;
  /** The type of selection that is allowed in the collection. */
  selectionMode?: SelectionMode;
  /** Whether the collection allows empty selection. */
  disallowEmptySelection?: boolean;
}

type SelectionMode = 'none' | 'single' | 'multiple';
type Selection = 'all' | Set<Key>;
type Orientation = 'horizontal' | 'vertical';

Toggle Button Group Return Interface

Return value from the useToggleButtonGroup hook.

interface ToggleButtonGroupAria {
  /**
   * Props for the toggle button group container.
   */
  groupProps: DOMAttributes;
}

Toggle Button Group Item Props Interface

Configuration options for individual toggle button group items.

interface AriaToggleButtonGroupItemOptions<E extends ElementType> extends Omit<AriaToggleButtonGroupItemProps<E>, 'children'> {
  /** An identifier for the item in the selectedKeys of a ToggleButtonGroup. */
  id: Key;
  /** The HTML element or React element used to render the button. @default 'button' */
  elementType?: E | JSXElementConstructor<any>;
  /** Whether the button is disabled. */
  isDisabled?: boolean;
  /** Handler that is called when the press is released over the target. */
  onPress?: (e: PressEvent) => void;
  /** Handler that is called when a press interaction starts. */
  onPressStart?: (e: PressEvent) => void;
  /** Handler that is called when a press interaction ends. */
  onPressEnd?: (e: PressEvent) => void;
  /** Handler that is called when the press state changes. */
  onPressChange?: (isPressed: boolean) => void;
  /** Handler that is called when a press is released over the target. */
  onPressUp?: (e: PressEvent) => void;
  /** Whether to prevent focus from moving to the button when pressing it. */
  preventFocusOnPress?: boolean;
}

Toggle Group State Interface

State management interface for toggle button groups (from @react-stately/toggle).

interface ToggleGroupState {
  /** The keys for the currently selected items. */
  selectedKeys: Set<Key>;
  /** Whether the collection allows empty selection. */
  disallowEmptySelection: boolean;
  /** The selection mode for the collection. */
  selectionMode: SelectionMode;
  /** Whether the collection is disabled. */
  isDisabled: boolean;
  /** Sets the selected keys. */
  setSelected(key: Key, selected: boolean): void;
  /** Toggles the selection state of an item. */
  toggleKey(key: Key): void;
  /** Replaces the selection with only the given key. */
  selectKey(key: Key): void;
  /** Selects all items in the collection. */
  selectAll(): void;
  /** Clears the selection. */
  clearSelection(): void;
}

State Management

Toggle button groups require state management via the useToggleGroupState hook from @react-stately/toggle:

import { useToggleGroupState } from "@react-stately/toggle";

// Single selection mode (radio group behavior)
let state = useToggleGroupState({
  selectionMode: 'single',
  selectedKeys: ['option1'],
  onChange: (keys) => console.log('Selected:', [...keys])
});

// Multiple selection mode (checkbox group behavior)  
let state = useToggleGroupState({
  selectionMode: 'multiple',
  selectedKeys: ['option1', 'option3'],
  onChange: (keys) => console.log('Selected:', [...keys])
});

// No selection allowed
let state = useToggleGroupState({
  selectionMode: 'none'
});

Selection Modes

Single Selection Mode

  • Behaves like a radio group
  • Only one item can be selected at a time
  • Selecting a new item deselects the previous one
  • ARIA role="radiogroup" on container
  • ARIA role="radio" on items
  • Uses aria-checked instead of aria-pressed

Multiple Selection Mode

  • Behaves like a checkbox group
  • Multiple items can be selected simultaneously
  • Items can be toggled independently
  • ARIA role="toolbar" on container
  • ARIA role="button" on items
  • Uses aria-pressed for selection state

No Selection Mode

  • Items cannot be selected
  • Used for command buttons that trigger actions
  • ARIA role="toolbar" on container
  • No selection state management

Accessibility Features

  • ARIA Roles: Automatic role assignment based on selection mode
  • Keyboard Navigation: Arrow key navigation between items
  • Selection States: Proper ARIA attributes for selection
  • Screen Reader Support: Clear group and item identification
  • Focus Management: Roving tabindex for keyboard navigation
  • Disabled States: Group and item level disabled support

Orientation Support

Groups support both horizontal and vertical orientations:

  • Horizontal: Left/Right arrow key navigation
  • Vertical: Up/Down arrow key navigation
  • Automatic ARIA: Proper aria-orientation attribute

Integration with Toolbar

useToggleButtonGroup internally uses useToolbar from @react-aria/toolbar for:

  • Keyboard navigation
  • Focus management
  • ARIA toolbar semantics
  • Orientation handling

Item Coordination

Group items automatically coordinate with the group state:

  • Selection Sync: Item selection reflects group state
  • State Updates: Item interactions update group state
  • Disabled Inheritance: Items inherit group disabled state
  • Focus Management: Shared focus management across items

Install with Tessl CLI

npx tessl i tessl/npm-react-aria--button

docs

core-button.md

index.md

toggle-button-groups.md

toggle-button.md

tile.json