KQ-579 · MORPH/ICON
Morph Icon
Icons that become each other rather than swapping. Five built-in pairs — play/pause, menu/close, plus/cross, heart, sun/moon — are each drawn twice with matching commands and point counts, so motion interpolates the d attribute directly and every corner travels to its counterpart on snap, one crisp overshoot arriving at the shape it means. The control is a real toggle button: aria-pressed carries the state, the accessible name swaps with it, and Enter and Space work because nothing was reinvented.
Waylight deck controls
Both shapes in a pair carry the same commands and the same point count, so one walks into the other instead of blinking.
Pressed 1 of 5 — Saved
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/morph-icon
Props
- pair
- "play-pause" | "menu-close" | "plus-cross" | "heart" | "sun-moon"
- default —
- Which morph. Each pair ships both shapes with the same commands and point count.
- pressed / defaultPressed
- boolean
- default false
- Controlled or initial state; aria-pressed tracks it either way.
- onPressedChange
- (pressed: boolean) => void
- default —
- Fires on toggle, after the internal state has moved.
- labels
- [string, string]
- default —
- Accessible names for the two states; each pair carries a sensible default.
- size
- number
- default 24
- Icon size in pixels. The button pads around it, so the hit target grows with it.
| Prop | Type | Default | Description |
|---|---|---|---|
| pair | "play-pause" | "menu-close" | "plus-cross" | "heart" | "sun-moon" | — | Which morph. Each pair ships both shapes with the same commands and point count. |
| pressed / defaultPressed | boolean | false | Controlled or initial state; aria-pressed tracks it either way. |
| onPressedChange | (pressed: boolean) => void | — | Fires on toggle, after the internal state has moved. |
| labels | [string, string] | — | Accessible names for the two states; each pair carries a sensible default. |
| size | number | 24 | Icon size in pixels. The button pads around it, so the hit target grows with it. |