Icons
The examples that import shape-aware-morph use the npm package. It is in progress. See Install.
Lucide
The script tag build has the 1,858 Lucide icons built in. Use any Lucide name.
<morph-icon name="camera" size="48"></morph-icon>
With the npm package, registerLucide() registers all the Lucide icons. It loads them on demand. To ship fewer icons, import the ones you use. Each icon family is its own module with one named export per icon (camelCase). A bundler drops the icons you do not import.
<script type="module">
import { defineMorphIcon, registerIcons } from 'shape-aware-morph';
import { mic, micOff } from 'shape-aware-morph/lucide';
registerIcons({ mic, 'mic-off': micOff });
defineMorphIcon();
const icon = document.createElement('morph-icon');
icon.setAttribute('name', 'mic');
document.body.append(icon);
setTimeout(() => icon.setAttribute('name', 'mic-off'), 500);
</script>
The default export of shape-aware-morph/lucide is the whole map keyed by the original names (import all from 'shape-aware-morph/lucide').
Names that start with a digit, or that are reserved words, get a leading underscore in the export (for example _24Hours).
The 12 sets
All 12 sets are separate modules. The icon names inside <morph-icon> are <family>:<name>, for example tabler-outline:bell. Lucide names have no prefix.
| Import path | Style | License |
|---|---|---|
shape-aware-morph/lucide | stroke | Lucide (ISC) |
shape-aware-morph/tabler-outline | stroke | Tabler (MIT) |
shape-aware-morph/tabler-filled | fill | Tabler (MIT) |
shape-aware-morph/hugeicons | stroke | Hugeicons (MIT) |
shape-aware-morph/phosphor-thin-s | stroke | Phosphor (MIT) |
shape-aware-morph/phosphor-light-s | stroke | Phosphor (MIT) |
shape-aware-morph/phosphor-regular-s | stroke | Phosphor (MIT) |
shape-aware-morph/phosphor-bold-s | stroke | Phosphor (MIT) |
shape-aware-morph/phosphor-fill | fill | Phosphor (MIT) |
shape-aware-morph/phosphor-duotone-s | stroke | Phosphor (MIT) |
shape-aware-morph/remix-line-s | stroke | Remix (Remix Icon License 1.0) |
shape-aware-morph/remix-fill | fill | Remix (Remix Icon License 1.0) |
registerFamilyIcons
The sets other than Lucide use registerFamilyIcons(family, icons). Pass the family id and a map of the icons you import. The names become <family>:<name>.
<script type="module">
import { defineMorphIcon, registerFamilyIcons } from 'shape-aware-morph';
import { bell, bellOff } from 'shape-aware-morph/tabler-outline';
registerFamilyIcons('tabler-outline', { bell, 'bell-off': bellOff });
defineMorphIcon();
const icon = document.createElement('morph-icon');
icon.setAttribute('name', 'tabler-outline:bell');
document.body.append(icon);
setTimeout(() => icon.setAttribute('name', 'tabler-outline:bell-off'), 500);
</script>
The default export of a family module is the full family spec. You can pass it to registerFamilyFile. An unknown family id throws an error that lists the known ids.
Your own icons
registerSVGs reads plain SVG markup. It supports path, line, polyline, polygon, circle, ellipse, and rect. It scales the viewBox to the 24 grid. It returns the list of registered names.
import { registerLucide, registerSVGs, planMorph } from 'shape-aware-morph';
await registerLucide();
const names = registerSVGs({
'my-spark': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6.1L12 16.6 6.6 19.6l1.2-6.1L3.3 9.3l6.1-.7z"/></svg>',
}, { kind: 'stroke' });
console.log(names); // ['my-spark']
const plan = planMorph('my-spark', 'heart'); // the name works like any icon name
console.log(plan.frame(0.5).length > 0); // true
// <morph-icon name="my-spark">
kind: 'stroke'(default): outline icons with stroke width 2. Names stay as you give them.kind: 'fill': solid icons. Names becomesvg:<name>. Usefamily: 'mine'to choose the prefix.- A
viewBoxwith a non-zero origin is not supported. Groups, transforms, and styles are ignored. - Solid shapes (
circle,ellipse,rect,polygon) become paths, so they morph like path icons. - An invalid path, a
kindother than'stroke'or'fill', or a non-object argument throws an error.
Your own icons then morph with every other icon.
<script type="module">
import { defineMorphIcon, registerLucide, registerSVGs } from 'shape-aware-morph';
await registerLucide();
registerSVGs({
'my-spark': '<svg viewBox="0 0 24 24"><path d="M12 3l2.6 5.6 6.1.7-4.5 4.2 1.2 6.1L12 16.6 6.6 19.6l1.2-6.1L3.3 9.3l6.1-.7z"/></svg>',
});
defineMorphIcon();
const icon = document.createElement('morph-icon');
icon.setAttribute('name', 'my-spark');
document.body.append(icon);
setTimeout(() => icon.setAttribute('name', 'heart'), 500);
</script>
For a lower-level path, registerIcons(map) takes icon nodes in the Lucide format. See JavaScript.