Icon Swap
Animated icon transition component for toggling between two states.
A component for smoothly transitioning between two icons with scale and fade animations. Click the icons below to see the animation in action.
Interactive Demo
Theme Toggle
Audio Control
Usage
import { IconSwap, SunIcon, MoonIcon } from "@delphi/ui";
export function ThemeToggle() {
const [isDark, setIsDark] = useState(false);
return (
<button onClick={() => setIsDark(!isDark)}>
<IconSwap
icon={<MoonIcon className="size-5" />}
swappedIcon={<SunIcon className="size-5" />}
isSwapped={isDark}
className="size-5"
/>
</button>
);
}Audio Control Example
import { IconSwap, VolumeFullIcon, VolumeOffIcon } from "@delphi/ui";
export function AudioControl() {
const [isMuted, setIsMuted] = useState(false);
return (
<button onClick={() => setIsMuted(!isMuted)}>
<IconSwap
icon={<VolumeFullIcon className="size-5" />}
swappedIcon={<VolumeOffIcon className="size-5" />}
isSwapped={isMuted}
className="size-5"
duration={200}
/>
</button>
);
}API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | - | The first icon to display |
swappedIcon | ReactNode | - | The second icon to display |
isSwapped | boolean | - | Whether to show the swapped icon |
className | string | - | Container className (should include size) |
iconClassName | string | - | Additional className for icon wrappers |
duration | number | 300 | Transition duration in milliseconds |
easing | string | "ease-out" | Transition timing function |
Use for binary state toggles (play/pause, light/dark, mute/unmute)
Set explicit size on the className prop to contain the icons
Use similar-sized icons for smooth transitions
Keep transition duration short (150-300ms) for responsive feel
Use for more than two states — consider a different pattern
Use for icons that don't represent opposing states
Forget to set the container size — icons are absolutely positioned