Skip to main content

toggle

A two-state button that can be either on or off.

Philosophy

Toggles represent a stateful action - not navigation, not form submission, but "turn this on or off." The distinction from buttons matters: toggles carry aria-pressed state and communicate their current value visually. Built on @gentleduck/primitives/toggle for proper keyboard and accessibility behavior, styled with @gentleduck/variants to keep visual states clean and type-safe.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add toggle

npx @gentleduck/cli add toggle

Usage

import { Toggle } from '@/components/ui/toggle'
<Toggle>Toggle</Toggle>

Examples

Default

Outline

With Text

Small

Large

Disabled

RTL Support

Set the direction once with DirectionProvider (or <html dir="rtl">) and Toggle follows it. No dir prop needed.

Motion

Use MotionToggle for tap feedback and a staggered entrance animation powered by motion. Each child is wrapped in a scaleIn entrance (fade, scale, and blur) with a bouncy spring transition, staggered by 50ms per child, and the toggle scales to 0.97 on tap for a physical press feel.

API Reference

Toggle

PropTypeDefaultDescription
classNamestring-Additional CSS class names to apply
pressedboolean-The controlled pressed state of the toggle
defaultPressedbooleanfalseThe pressed state when initially rendered
onPressedChange(pressed: boolean) => void-Event handler called when the pressed state changes
variant'default' | 'outline''default'Visual style variant of the toggle
size'default' | 'sm' | 'lg''default'Size variant of the toggle
disabledbooleanfalseDisables the toggle if set to true
dir'ltr' | 'rtl'-Text direction. Resolved by primitives useDirection (dir prop -> DirectionProvider -> <html dir>).
childrenReact.ReactNode-Content rendered inside the toggle button
refReact.Ref<HTMLButtonElement>-Ref forwarded to the underlying button element

Data Attributes

AttributeValuesDescription
data-state"on" | "off"The pressed state of the toggle
data-disabledPresent when disabledWhether the toggle is disabled

MotionToggle

Adds whileTap press feedback (scale 0.97) and a staggered scaleIn entrance (fade, scale, and blur) on each child, delayed 50ms per index, with a springBouncy transition. Requires the motion package.

PropTypeDefaultDescription
...propsOmit<ToggleProps, 'onDrag' | 'onDragStart' | 'onDragEnd' | 'onAnimationStart'>-All props from Toggle except motion event handlers