Skip to content
Lenso UI

ToggleButton

An interactive toggle control for on/off or selected/unselected states

Usage

import { ToggleButton } from '@lenso/ui';
"use client";
import { Heart } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";
export function Basic() {  return (    <ToggleButton>      <ToggleButton.Icon>        <Heart />      </ToggleButton.Icon>      Like    </ToggleButton>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Examples

Variants

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Heart } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./source.stylex";export function Variants() {  return (    <div {...stylex.props(styles.row)}>      <ToggleButton>        <ToggleButton.Icon>          <Heart />        </ToggleButton.Icon>        Default      </ToggleButton>      <ToggleButton variant="ghost">        <ToggleButton.Icon>          <Heart />        </ToggleButton.Icon>        Ghost      </ToggleButton>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Icon Only

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Bookmark, Heart } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./source.stylex";export function IconOnly() {  return (    <div {...stylex.props(styles.row)}>      <ToggleButton isIconOnly aria-label="Like">        <ToggleButton.Icon>          <Heart />        </ToggleButton.Icon>      </ToggleButton>      <ToggleButton isIconOnly aria-label="Bookmark" variant="ghost">        <ToggleButton.Icon>          <Bookmark />        </ToggleButton.Icon>      </ToggleButton>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Sizes

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Heart } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./source.stylex";export function Sizes() {  return (    <div {...stylex.props(styles.column)}>      <div {...stylex.props(styles.row)}>        {(["sm", "md", "lg"] as const).map((size, index) => (          <ToggleButton key={size} size={size}>            <ToggleButton.Icon>              <Heart />            </ToggleButton.Icon>            {["Small", "Medium", "Large"][index]}          </ToggleButton>        ))}      </div>      <div {...stylex.props(styles.row)}>        {(["sm", "md", "lg"] as const).map((size) => (          <ToggleButton key={size} isIconOnly aria-label="Like" size={size}>            <ToggleButton.Icon>              <Heart />            </ToggleButton.Icon>          </ToggleButton>        ))}      </div>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Disabled

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Heart, HeartFill } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./source.stylex";export function Disabled() {  return (    <div {...stylex.props(styles.row)}>      <ToggleButton disabled>        <ToggleButton.Icon>          <Heart />        </ToggleButton.Icon>        Like      </ToggleButton>      <ToggleButton defaultPressed disabled>        <ToggleButton.Icon>          <HeartFill />        </ToggleButton.Icon>        Like      </ToggleButton>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Controlled

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Heart, HeartFill } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import { useState } from "react";import * as stylex from "@stylexjs/stylex";import { styles } from "./source.stylex";export function Controlled() {  const [selected, setSelected] = useState(false);  return (    <div {...stylex.props(styles.controlled)}>      <ToggleButton pressed={selected} onPressedChange={setSelected}>        <ToggleButton.Icon>{selected ? <HeartFill /> : <Heart />}</ToggleButton.Icon>        {selected ? "Liked" : "Like"}      </ToggleButton>      <p {...stylex.props(styles.muted)}>        Status:{" "}        <span {...stylex.props(styles.medium)}>{selected ? "Selected" : "Not selected"}</span>      </p>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Customization

Tailwind CSS

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { Heart } from "@gravity-ui/icons";import { ToggleButton } from "@lenso/ui";import { styles } from "./source.stylex";export function CustomStyles() {  return (    <ToggleButton xstyle={styles.custom}>      <ToggleButton.Icon xstyle={styles.icon}>        <Heart />      </ToggleButton.Icon>      Save article    </ToggleButton>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Global CSS

To customize the ToggleButton component classes, you can use the @layer components directive. Learn more.

@layer components {  .toggle-button {    @apply bg-purple-500 text-white;  }
  .toggle-button--icon-only {    @apply rounded-lg;  }}

Styling Reference

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The ToggleButton component uses these CSS classes (View source styles):

Base & Size Classes [!toc]

  • .toggle-button - Base toggle button styles
  • .toggle-button--sm - Small size variant
  • .toggle-button--md - Medium size variant (default)
  • .toggle-button--lg - Large size variant

Variant Classes [!toc]

  • .toggle-button--default - Default variant with filled background
  • .toggle-button--ghost - Ghost variant with transparent background

Modifier Classes [!toc]

  • .toggle-button--icon-only - Icon-only toggle button
  • .toggle-button--icon-only.toggle-button--sm - Small icon-only
  • .toggle-button--icon-only.toggle-button--lg - Large icon-only

Interactive States

The toggle button supports both CSS pseudo-classes and data attributes for flexibility:

  • Selected: [data-selected="true"] (accent background and foreground)
  • Hover: :hover or [data-hovered="true"]
  • Active/Pressed: :active or [data-pressed="true"] (includes scale transform)
  • Focus: :focus-visible or [data-focus-visible="true"] (shows focus ring)
  • Disabled: :disabled or [aria-disabled="true"] (reduced opacity, no pointer events)

API Reference

ToggleButton

Inherits from React Aria ToggleButton.

PropTypeDefaultDescription
variant'default' | 'ghost''default'Visual style variant
size'sm' | 'md' | 'lg''md'Size of the toggle button
isIconOnlybooleanfalseWhether the button contains only an icon
isSelectedboolean-Controlled selected state
defaultSelectedbooleanfalseDefault selected state (uncontrolled)
isDisabledbooleanfalseWhether the toggle button is disabled
onChange(isSelected: boolean) => void-Handler called when selection changes
onPress(e: PressEvent) => void-Handler called when the button is pressed
childrenReact.ReactNode | (values: ToggleButtonRenderProps) => React.ReactNode-Button content or render prop

Render Props

When using the render prop pattern, these values are provided:

PropTypeDescription
isSelectedbooleanWhether the button is currently selected
isPressedbooleanWhether the button is currently pressed
isHoveredbooleanWhether the button is hovered
isFocusedbooleanWhether the button is focused
isFocusVisiblebooleanWhether the button should show focus indicator
isDisabledbooleanWhether the button is disabled