mcpField
M
morphing-icons

morphing-icons

github.com/raphaelsalajaDesign & UI46367 installsUpdated today
Repository

About morphing-icons

morphing-icons is a skill for building or reviewing icons that transition by moving a fixed set of three SVG lines. It defines shared geometry, motion, reduced-motion behavior, and accessibility checks for icon components.

Key features

  1. 01Model each icon as three SVG lines
  2. 02Use a shared 14-by-14 viewBox
  3. 03Define grouped rotation variants
  4. 04Specify morph easing and duration
  5. 05Check reduced-motion and accessibility attributes

Use cases

  1. 01Build icons that morph between states
  2. 02Review SVG icon interpolation components
  3. 03Audit grouped arrow rotation behavior

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/raphaelsalaja/skills --skill morphing-icons

After installing, type/morphing-iconsin Claude Code to confirm it loaded.

Bundled filesagents/openai.yaml

Details

From the project README

Morphing icons

This skill builds or reviews icons that morph by moving the same three SVG lines. Any icon can become any other because the line count never changes.

Every check is a pair. The broken line sits beside the line that replaces it.

Exactly three lines is required. A 14 viewBox is the published coordinate system, with center 7. A two-line check that omits the third line is a finding. Press and hover timing for buttons around the icon belongs to timing-functions. The line morph itself uses the transition in this skill.

When to use

Use this when asked to create morphing icons, to animate between two icons, or to review an icon component that interpolates SVG lines. Do not use it for a crossfade between two <svg> trees.

1. Lock the model

Each line is { x1, y1, x2, y2, opacity? }. Each icon is { lines, rotation?, group? } and lines is a tuple of three. The collapsed line is zero length at the center, with opacity: 0.

const CENTER = 7;
const collapsed = { x1: CENTER, y1: CENTER, x2: CENTER, y2: CENTER, opacity: 0 };

2. Draw within the constraint

Every icon has three lines. Unused lines are collapsed, never null and never omitted. Those are morphing-three-lines and morphing-use-collapsed. Every icon uses the same viewBox. The published size is 14 by 14. That is morphing-consistent-viewbox.

A check keeps the third line collapsed. A menu uses three real strokes. A "more" icon uses three zero-length dots. Rotational variants, such as four arrows, share one line list, one group and a rotation of 0, 90, 180 or -90. Different point lists for arrow-down and arrow-right fail morphing-group-variants.

3. Move them

The stroke interpolation uses ease: [0.19, 1, 0.22, 1] and duration: 0.4. That duration is for the morph, not for press or hover. Rotation inside a group uses a spring via useSpring. Crossing groups calls rotation.jump, not an animated set. Those are morphing-spring-rotation and morphing-jump-non-grouped.

When useReducedMotion() is true, the transition duration is 0. That is morphing-reduced-motion. Lines set strokeLinecap="round". That is morphing-strokelinecap-round. The svg sets aria-hidden="true" when it is decorative. That is morphing-aria-hidden.

4. Report or build, then stop

If the user asked for a review, write findings and the summary. If they asked for an icon, build it in the project's component and do not add a second icon system beside an existing one.

The pair

Every check is a pair. The broken line sits beside the line that replaces it.

RuleBrokenReplacement
morphing-three-linesA check icon with two line objectsA third line set to collapsed
morphing-use-collapsednull in the lines tupleThe collapsed constant
morphing-consistent-viewboxOne icon in a 14 box and another in a 28 boxVIEWBOX_SIZE = 14 for every icon
morphing-group-variantsarrow-down drawn with its own pointsThe same arrowLines, group: "arrow", rotation: 90
morphing-spring-rotationtransition={{ duration: 0.3 }} on grouped rotationuseSpring for that rotation
morphing-jump-non-groupedrotation.set when the groups differrotation.jump
morphing-reduced-motionA morph with no reduced-motion branchduration: 0 when reduced motion is on
morphing-strokelinecap-roundstrokeLinecap="butt"strokeLinecap="round"
morphing-aria-hidden<svg width={size} height={size}>aria-hidden="true"

Reporting

Severity. HIGH is a line count other than three, or rotational variants that do not share a group and a line list. MEDIUM is a missing reduced-motion branch, or rotation that animates across groups. LOW is a butt cap or a missing aria-hidden on a decorative icon.

Verification. Read the declared values in the files in scope. A browser is optional. Mark any check you could not run as Not verified.

Format. One finding per root cause:

file:line - [rule-id] what is wrong

Then a summary:

RuleCountSeverity

Block when any HIGH remains. Approve otherwise, and leave lesser rows in the table. Never Approve a file you did not read. With nothing to report, say "No actionable findings" and list what was not verified.

Comments

Markdown supported