Toggle

Pressed-state toggle built on Radix with ripple feedback, icon motion, and both text and icon-only control patterns.

Live Playground

Use the bookmark example to inspect the pressed-state motion, outline surface, and the filled icon change on activation.

Toggle the bookmark to inspect the pressed-state motion, ripple burst, and the filled icon treatment on the active state.

Install And Iterate

Install the component directly into your codebase, then branch into v0 if you want to iterate on variations.

Install

npx shadcn@latest add @iconiq/toggle

Build with v0

Send the registry bundle into v0 when you want to explore new colorways, copy, or layout directions quickly.

Notes

  • Use controlled pressed state when the surrounding interface needs to react immediately to the toggle value.
  • Outline works well for utility toggles like save, bookmark, or watch actions.

Usage

Start with a single controlled utility toggle like the snippet below, then expand into additional variants and sizes as needed.

"use client"; import { Bookmark } from "lucide-react";import { useState } from "react";import { Toggle } from "@/components/ui/toggle"; export function BookmarkToggle() {  const [bookmarked, setBookmarked] = useState(false);   return (    <Toggle      aria-label="Toggle bookmark"      className="gap-2 rounded-lg px-4 shadow-sm"      onPressedChange={setBookmarked}      pressed={bookmarked}      variant="outline"    >      <Bookmark        className="size-5"        fill={bookmarked ? "currentColor" : "none"}      />      Bookmark    </Toggle>  );}

API Details

Each item below covers the documented props and the behavior that matters during implementation.

Toggle

8 props

Single pressed-state toggle built on Radix Toggle, with Motion-driven button, icon, and ripple feedback layered over shadcn-style size and variant classes.
childrenReactNode
Required
Visible button content rendered inside the animated inner span. This can be plain text, icons, or both.
variant"default" | "outline"
Defaultdefault
Visual treatment from the internal CVA config. Outline adds the input border and shadow-sm treatment.
size"default" | "sm" | "lg"
Defaultdefault
Height and horizontal padding preset applied through the shared toggleVariants helper.
pressedboolean
Controlled pressed state from Radix Toggle.Root. Use this when the parent should own the on/off state.
defaultPressedboolean
Initial pressed state for uncontrolled usage.
onPressedChange(pressed: boolean) => void
Called after the component kicks off its local motion sequence, with the next pressed value from Radix.
disabledboolean
Disables the toggle and prevents the hover, tap, and pressed-state interaction flow.
classNamestring
Merged onto the rendered motion button for local spacing or surface overrides.

Notes

Additional Radix toggle button props such as aria-label, name, value, and type are forwarded through the underlying Toggle.Root surface.
The component renders Radix Root with asChild internally, then supplies its own motion.button as the child node.