Aquarium add-icon
Add a new mParticle SVG icon to the Aquarium library. Handles SVG optimization, registration, type updates, and exports. Use when adding a new icon from an SVG file. Triggers on add icon, new icon, add svg, mp icon, mparticle icon.
git clone https://github.com/mParticle/aquarium
T=$(mktemp -d) && git clone --depth=1 https://github.com/mParticle/aquarium "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/add-icon" ~/.claude/skills/mparticle-aquarium-add-icon && rm -rf "$T"
.claude/skills/add-icon/skill.mdAdd mParticle Icon
You are an icon integration specialist for the Aquarium component library. You take an SVG file and a name, then register it across all required files so it's available as
<Icon name="iconName" />.
When to Use
- "Add this SVG as an icon"
- "Add a new mParticle icon"
- "Register this icon as mpSomething"
Not for: Rokt/Untitled UI icons from
@untitledui/icons — see .cursor/rules/add-untitled-ui-icon.mdc for those.
Required Inputs
- SVG source — a file path or inline SVG content
- Icon name — camelCase name for the icon (e.g.,
,mpGroup
)dataFlow
If the user doesn't provide a name, infer one from the SVG filename or ask.
The Process
Step 1: Prepare the SVG
- Read the source SVG
- Optimize with svgo:
npx svgo <input> -o <output> --pretty - Post-optimization fixes:
- Replace
orfill="black"
on the rootfill="none"
with<svg>
(enables theming)fill="currentColor" - Remove explicit
andwidth
attributes — keep onlyheightviewBox - Ensure the
attribute is presentxmlns
- Replace
- Save to
src/assets/svg/mp_<category>_lt_<kebab-name>.svg
Category conventions:
| Category | Prefix | Use for |
|---|---|---|
| Action | | Interactive actions (edit, delete, play, filter) |
| Product module | | Product areas (analytics, identity, catalog) |
| Informational | | Status, context, metadata (group, user, help) |
| Data type | | Data types (string, number, boolean, array) |
If unsure, default to
info.
Step 2: Import and export in src/components/icons/index.ts
src/components/icons/index.tsAdd the import (alphabetically among mParticle imports):
import MyNewIcon from 'src/assets/svg/mp_info_lt_my-new.svg?react'
Add to the export block (alphabetically):
export { // ...existing exports... MyNewIcon, // ... }
Step 3: Register in src/constants/Icons.ts
src/constants/Icons.tsAdd the import from
src/components/icons:
import { // ...existing imports... MyNewIcon, } from 'src/components/icons'
Add the icon entry (alphabetically by key):
myNew: { light: MyNewIcon, default: 'light', },
Step 4: Add to src/types/icons.ts
src/types/icons.tsAdd the name to the
IconNames union (alphabetically):
export type IconNames = // ... 'myNew' // ...
Step 5: Verify
npm run build npx tsc --noEmit
Both must pass before committing.
Naming Conventions
- SVG filename:
(e.g.,mp_<category>_lt_<kebab-case-name>.svg
)mp_info_lt_mp-group.svg - Import variable: PascalCase ending in
(e.g.,Icon
)MpGroupIcon - Icon name key: camelCase matching the user's requested name (e.g.,
)mpGroup - IconNames type: same camelCase string (e.g.,
)'mpGroup'
Duo-tone Variants
If the user provides both light and duo-tone SVGs:
- Name the duo-tone file
mp_<category>_dt_<kebab-name>.svg - Import as
MyNewIconDt - Register both variants:
myNew: { light: MyNewIcon, 'duo-tone': MyNewIconDt, default: 'light', },
Constraints
- DO run svgo to optimize every SVG before committing
- DO use
on the rootfill="currentColor"
element<svg> - DO remove explicit
/width
— only keepheightviewBox - DO verify build and tsc pass after registration
- DO NOT add to docs manually — the
story auto-discovers icons from theIconTable
mapIcons - DO NOT add mParticle SVG icons to
Rokt exports sectionsrc/components/index.ts - DO NOT forget any of the 4 registration files
Reference Files
- SVG assets:
src/assets/svg/ - Icon imports/exports:
src/components/icons/index.ts - Icon map:
src/constants/Icons.ts - Icon types:
src/types/icons.ts - Icon component:
src/components/general/Icon/Icon.tsx - Rokt icons guide:
.cursor/rules/add-untitled-ui-icon.mdc