Components / Actions
IconMorph
Icons that morph between states: menu to close, play to pause, copy to check, and more.
Install
npx shadcn@latest add https://irisui.dev/r/icon-morph.jsonimport { IconMorph } from "@/components/iris/icon-morph/icon-morph";Preview
IconMorph
Stroke icons that morph between two states — menu to close, play to pause, plus to check, copy to check, sun to moon, chevron turn, bell muted to on, heart to liked.
When to use
- Inside toggle buttons where the icon itself should show the new state: nav menu, media play, add-to-list, copy, theme, expand/collapse, notifications, like.
- When you want state changes to read as one continuous shape change rather than an icon swap.
- The icons carry no label: always put them inside a
button(orButton) with an accessible name. For a full copy control with feedback text, useCopyButton; for a light/dark control, useThemeSwitch.
Usage
import { IconMorph } from "@/components/iris/icon-morph/icon-morph";
<button type="button" aria-label={open ? "Close menu" : "Open menu"} aria-expanded={open} onClick={() => setOpen(!open)}>
<MenuIcon state={open} size={20} />
</button>
<IconMorph name="heart" state={liked} />
<ChevronIcon state={expanded} pointing="right" turn={90} size={16} />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
name |
"menu" | "play" | "plus" | "copy" | "theme" | "chevron" | "bell" | "heart" |
— | Which icon (required on IconMorph only). Each also has a named export: MenuIcon, PlayPauseIcon, PlusCheckIcon, CopyCheckIcon, SunMoonIcon, ChevronIcon, BellIcon, HeartIcon. |
state |
boolean |
false |
The second state: close, pause, check, check, moon, turned, notifications on, liked. |
size |
number |
24 |
Rendered size in px. |
strokeWidth |
number |
1.75 |
Stroke width in the 24-unit grid. |
turn |
number |
180 |
ChevronIcon only: degrees turned when state is true. |
pointing |
"down" | "right" |
"down" |
ChevronIcon only: rest direction. |
...props |
SVGProps<SVGSVGElement> |
— | Other SVG attributes (className, style). |
Notes
- The SVG is
aria-hidden; convey state on the button (aria-pressed,aria-expanded, or a changingaria-label). - Strokes use
currentColor, so the icon follows the button's text colour (play and pause are filled withcurrentColor); the liked heart fills whenstateis true and takes--icon-morph-like(default--red). - Morphs ride spring tokens; reduced motion switches states instantly.