remold/ui

Icon

An icon that reshapes into the next one. Pass any icon component, from Lucide, Heroicons or your own SVGs.

Installation

npm install @remold-ui/react

Using plain JavaScript? Install @remold-ui/dom instead. It brings @remold-ui/core with it.

Usage

Pass the icon you'd normally render, as a component or an element:

import { Remold } from "@remold-ui/react";
import { HugeiconsIcon } from "@hugeicons/react";
import { Cancel01Icon, Menu01Icon } from "@hugeicons/core-free-icons";

<Remold.Icon
  icon={<HugeiconsIcon icon={open ? Cancel01Icon : Menu01Icon} />}
  className="size-5"
/>

It works with any icon set, or your own SVG components and inline <svg>. Remold reads the icon's shapes (paths, circles, ellipses, rectangles, lines, polylines and polygons) into one path, and takes its viewBox, fill and stroke from the icon. Props you set yourself, such as strokeWidth, win. When the next icon has more strokes or fewer, spare strokes grow out of a neighbour or merge into one.

On the server, and on the first paint in the browser, the icon is rendered exactly as it is. Remold takes over before the first frame is drawn, so there's no flash.

Path data

If your icons are SVG path data rather than components, pass path instead. Several strokes go in one path:

<Remold.Icon
  path={open ? "M6 6l12 12M18 6 6 18" : "M4 7h16M4 12h16M4 17h16"}
  fill="none"
  stroke="currentColor"
  strokeWidth={2}
/>

Without React you drive the morph yourself: createMorph pairs the two paths and a spring value moves between them. Paths from iconToPath (above) morph the same way, using their d.

Limits

  • An icon whose SVG uses transform can't be read as one path. It's shown as it is, without morphing, and a warning names the element to flatten.
  • One look per icon: if an icon's shapes are painted differently from each other (a filled dot inside an outline icon), they all take the icon's own look while it morphs.

Examples

A single toggle

API reference

Prop

Type

Data attributes

AttributeMeaning
data-rm-animatingPresent while the icon is morphing.

On this page