CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-radix-ui--react-toggle

A two-state button component with full accessibility support and keyboard navigation

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

index.mddocs/

Radix UI React Toggle

Radix UI React Toggle is a fully accessible two-state button component that can be pressed/unpressed. Built on Radix UI's primitive foundation, it provides comprehensive accessibility features, keyboard navigation, and flexible state management patterns for React applications.

Package Information

  • Package Name: @radix-ui/react-toggle
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @radix-ui/react-toggle
  • Peer Dependencies: React 16.8+ (npm install react@^16.8.0)

Core Imports

import { Toggle, Root } from "@radix-ui/react-toggle";
import type { ToggleProps } from "@radix-ui/react-toggle";

For CommonJS:

const { Toggle, Root } = require("@radix-ui/react-toggle");

Basic Usage

import { Toggle } from "@radix-ui/react-toggle";

// Uncontrolled toggle with default state
function BasicToggle() {
  return (
    <Toggle defaultPressed={false} onPressedChange={(pressed) => console.log(pressed)}>
      Toggle Me
    </Toggle>
  );
}

// Controlled toggle
function ControlledToggle() {
  const [isPressed, setIsPressed] = useState(false);
  
  return (
    <Toggle pressed={isPressed} onPressedChange={setIsPressed}>
      {isPressed ? "On" : "Off"}
    </Toggle>
  );
}

Architecture

The Toggle component provides a clean, accessible interface for two-state interactions:

  • HTML Button Foundation: Built on semantic button elements for maximum compatibility
  • State Management: Supports both controlled and uncontrolled component patterns
  • Event Handling: Proper event composition and disabled state management
  • Accessibility: Automatic ARIA attributes and semantic data attributes
  • Composition: Supports asChild prop for flexible element composition

Capabilities

Toggle Component

The main toggle component that renders as a button with press/unpress functionality.

/**
 * Toggle component - A two-state button that can be pressed/unpressed
 */
const Toggle: React.ForwardRefExoticComponent<
  ToggleProps & React.RefAttributes<HTMLButtonElement>
>;

/**
 * Root component - Alias for Toggle following Radix UI naming conventions
 */
const Root: React.ForwardRefExoticComponent<
  ToggleProps & React.RefAttributes<HTMLButtonElement>
>;

Usage Examples:

// Basic uncontrolled usage
<Toggle defaultPressed onPressedChange={(pressed) => console.log(pressed)}>
  Like
</Toggle>

// Controlled usage
<Toggle pressed={isPressed} onPressedChange={setIsPressed}>
  {isPressed ? "Liked" : "Like"}
</Toggle>

// With custom styling via data attributes
<Toggle 
  className="toggle-button"
  data-testid="like-button"
>
  <HeartIcon />
</Toggle>

// Using asChild for custom element
<Toggle asChild>
  <button className="custom-toggle-button">
    Custom Toggle
  </button>
</Toggle>

// Using Root alias
<Toggle.Root pressed={isPressed}>
  Toggle Content
</Toggle.Root>

Toggle Props Interface

Complete props interface extending standard HTML button attributes.

interface ToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  /**
   * The controlled state of the toggle
   */
  pressed?: boolean;
  
  /**
   * The state of the toggle when initially rendered
   * Use when you do not need to control the state
   * @defaultValue false
   */
  defaultPressed?: boolean;
  
  /**
   * Callback that fires when the state of the toggle changes
   */
  onPressedChange?: (pressed: boolean) => void;
  
  /**
   * When true, merges props into the child element instead of rendering a button
   * Enables the slot pattern for custom element composition
   */
  asChild?: boolean;
  
  /**
   * All standard HTML button attributes are supported:
   * - Event handlers: onClick, onMouseDown, onMouseUp, onDoubleClick, etc.
   * - Form attributes: type, disabled, form, name, value, etc.
   * - Accessibility: aria-*, role, tabIndex, etc.
   * - Styling: className, style, data-*, etc.
   * - Standard attributes: id, title, lang, dir, etc.
   */
}

State Management Patterns

Controlled Pattern

When you need to manage the toggle state externally:

function ControlledExample() {
  const [isPressed, setIsPressed] = useState(false);
  
  // External state updates
  useEffect(() => {
    if (someCondition) {
      setIsPressed(true);
    }
  }, [someCondition]);
  
  return (
    <Toggle 
      pressed={isPressed} 
      onPressedChange={setIsPressed}
    >
      {isPressed ? "Active" : "Inactive"}
    </Toggle>
  );
}

Uncontrolled Pattern

When the toggle manages its own state internally:

function UncontrolledExample() {
  return (
    <Toggle 
      defaultPressed={false}
      onPressedChange={(pressed) => {
        // React to state changes without controlling the state
        console.log("Toggle is now:", pressed ? "pressed" : "unpressed");
      }}
    >
      Toggle Me
    </Toggle>
  );
}

Accessibility Features

The Toggle component provides comprehensive accessibility features:

ARIA Attributes (Automatic)

// When pressed=false or unpressed
<button aria-pressed="false" data-state="off">...</button>

// When pressed=true or pressed  
<button aria-pressed="true" data-state="on">...</button>

// When disabled
<button disabled data-disabled="">...</button>

Keyboard Navigation

  • Space Key: Toggles the pressed state
  • Enter Key: Toggles the pressed state (standard button behavior)
  • Tab Navigation: Follows standard focus order
  • Focus Management: Proper focus handling when disabled

Screen Reader Support

  • Announces current state via aria-pressed attribute
  • Compatible with all major screen readers
  • Proper role semantics as a toggle button

Data Attributes for Styling

The component automatically applies data attributes for CSS styling:

/* Target different states */
.toggle-button[data-state="on"] {
  background-color: blue;
  color: white;
}

.toggle-button[data-state="off"] {
  background-color: gray;
  color: black;
}

.toggle-button[data-disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

Advanced Usage

Custom Element Composition (asChild)

Use the asChild prop to merge toggle functionality into custom elements:

function CustomToggle() {
  return (
    <Toggle asChild pressed={isPressed} onPressedChange={setIsPressed}>
      <div className="custom-toggle-div" role="button" tabIndex={0}>
        <Icon name={isPressed ? "heart-filled" : "heart-outline"} />
        <span>{isPressed ? "Liked" : "Like"}</span>
      </div>
    </Toggle>
  );
}

Event Handler Composition

Toggle properly composes event handlers when extending functionality:

function EnhancedToggle() {
  const handleClick = (event) => {
    console.log("Custom click handler");
    // Toggle's internal handler will still run unless preventDefault() is called
  };
  
  return (
    <Toggle 
      onClick={handleClick}
      onPressedChange={(pressed) => console.log("State changed:", pressed)}
    >
      Enhanced Toggle
    </Toggle>
  );
}

Form Integration

Toggle works seamlessly with forms:

function FormToggle() {
  return (
    <form>
      <Toggle 
        name="notifications"
        value="enabled"
        defaultPressed
        onPressedChange={(pressed) => {
          // Update form state or trigger validation
        }}
      >
        Enable Notifications
      </Toggle>
    </form>
  );
}

Types

/**
 * Complete props interface for Toggle component
 */
interface ToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  pressed?: boolean;
  defaultPressed?: boolean;
  onPressedChange?: (pressed: boolean) => void;
  asChild?: boolean;
}

Install with Tessl CLI

npx tessl i tessl/npm-radix-ui--react-toggle

docs

index.md

tile.json