Icon Swap Toggle React component
A toggle button that swaps between two icons with a rotate, 3D flip, pop or slide: ready-made pairs for play/pause, mute, like, save, show/hide, menu/close, light/dark and copy/copied, or any two icons of your own.
When to use the Icon Swap Toggle component
Use Icon Swap Toggle for two-state controls that live as a single icon: play / pause, mute, like, bookmark, show password, menu / close, theme. The swap animation makes the state change obvious without any text.
Always set labels for custom pairs so screen reader users hear what the button will do.
Installation
Add the Icon Swap Toggle component to your project with the shadcn CLI. It lands in components/icon-swap-toggle.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add https://reactframe.com/r/icon-swap-toggle.jsonOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<IconSwapToggle /> accepts 12 props, all optional.
| Prop | Type | Default |
|---|---|---|
| preset | "play" | "sound" | "heart" | "bookmark" | "eye" | "menu" | "theme" | "copy" | "play" |
| iconOff Your own pair; overrides the preset. | React.ReactNode | — |
| iconOn | React.ReactNode | — |
| effect | "rotate" | "flip" | "scale" | "slide" | "rotate" |
| on | boolean | — |
| defaultOn | boolean | false |
| onChange | (on: boolean) => void | — |
| labels Accessible names for each state, e.g. ["Play", "Pause"]. | [string, string] | — |
| variant | "ghost" | "outline" | "solid" | "outline" |
| size | number | 44 |
| theme | "dark" | "light" | "dark" |
| className | string | — |
- preset"play" | "sound" | "heart" | "bookmark" | "eye" | "menu" | "theme" | "copy"Default: "play"
- iconOff
Your own pair; overrides the preset.
React.ReactNode - iconOnReact.ReactNode
- effect"rotate" | "flip" | "scale" | "slide"Default: "rotate"
- onboolean
- defaultOnbooleanDefault: false
- onChange(on: boolean) => void
- labels
Accessible names for each state, e.g. ["Play", "Pause"].
[string, string] - variant"ghost" | "outline" | "solid"Default: "outline"
- sizenumberDefault: 44
- theme"dark" | "light"Default: "dark"
- classNamestring
FAQ
- Which effect should I use?
- Rotate for symbolic swaps (play/pause, menu/close), pop for likes and saves, flip for view switches, slide for media controls. They all respect reduced motion.
- Is it accessible?
- It's a real button with aria-pressed and a label that changes with the state (Play / Pause, Mute / Unmute...).
- Can I control it from outside?
- Yes. Pass on and onChange to keep it in sync with your player, form or store.