Illustrations
illustration-icons/ stores illustration SVG assets that should not enter the generic icon or business icon systems.
Illustrations are usually larger, more detailed, and keep fixed colors. They are intended for empty states, onboarding, result pages, error pages, and other page-level visual communication. They do not follow the generic 24x24 linear icon rules, and they do not use the business icon outlined, filled, or multicolor cleanup rules.
When to use it
Use illustration-icons/ when an SVG:
- is a page-level illustration rather than a small control icon
- needs to keep fixed colors, gradients, opacity, or complex layers
- only needs width and height customization
- does not fit
icons/orbusiness-icons/
If the artwork should be reused as a 24px UI icon, put it in icons/ or business-icons/ instead.
Directory
illustration-icons/<category>/<illustration-name>.svg
illustration-icons/<category>/<illustration-name>.json
illustration-icons/index.json
illustration-icons/metadata/index.json
docs/public/metadata/illustration-icons.jsonIllustrations need same-name per-SVG metadata JSON for search, AI illustration selection, and docs. The root illustration-icons/index.json is generated; illustration-icons/metadata/index.json is the latest repository metadata snapshot used directly by the Figma plugin, GitHub checks, and skills lookup. During docs builds, that source snapshot is copied to docs/public/metadata/illustration-icons.json as the deployed URL fallback.
File names must be lowercase kebab-case and directly determine package export names:
illustration-icons/other/empty-page.svg -> EmptyPageCleanup And Validation
Illustrations do not run color conversion or size cleanup. Fixed colors, gradients, width, height, and viewBox values are preserved from the source SVG whenever possible.
Baseline validation checks:
- paths must use
illustration-icons/<category>/<illustration-name>.svg; useotherwhen the category is unclear - same-name metadata must exist at
illustration-icons/<category>/<illustration-name>.json - file names must be lowercase kebab-case
- the root element must be
<svg> <script>and<foreignObject>are not allowed- event attributes such as
onclickare not allowed javascript:URLs are not allowed- root
illustration-icons/index.jsonmust matchnode ./scripts/writeIllustrationIndex.mts illustration-icons/metadata/index.jsonmust matchnode ./scripts/writeAssetMetadata.mts;docs/public/metadatais copied during docs builds
Run locally:
node ./scripts/writeIllustrationIndex.mts
node ./scripts/writeAssetMetadata.mts
node ./scripts/checkIllustrationSvgSource.mtsFigma plugin submission
When “Illustrations” is selected in the Figma plugin, the plugin will:
- submit files to
illustration-icons/<category>/*.svg - submit matching
illustration-icons/<category>/*.json - skip color conversion
- skip size cleanup
- skip
icons/*.jsongeneration, but create illustration same-name metadata JSON - use a single illustration category; choose
otherwhen the category is unclear - only block SVGs that fail the illustration SVG baseline safety checks
After the plugin opens a PR, GitHub workflows handle illustrations like generic icons and business icons:
fix-icon-sourcerefreshes and formatsillustration-icons/index.json, same-name metadata JSON, and repository snapshots;docs/public/metadatais copied during docs builds- PR lint runs
pnpm lint:svg:illustration - same-repository Figma illustration PRs can enter the auto-merge flow
- after merging to
main, a Figma PR that includesillustration-icons/<category>/*.svgtriggers the icon release flow and publishes a new npm version
When “Generic icons” is selected, the plugin keeps using the existing icons/*.svg + icons/*.json flow. When “Business icons” is selected, it keeps using the business-icons/<color-mode>/*.svg flow.
Usage
Illustrations are generated into illustration subpath entries in the existing packages instead of being mixed into the generic default entries.
React package
pnpm add @ycloud-web/icons-reactimport { EmptyPage } from '@ycloud-web/icons-react/illustration';
export function EmptyState() {
return (
<EmptyPage
width="100%"
height="auto"
alt="No data"
/>
);
}Illustration components default to width="100%" and height="auto". They do not support color, because illustrations keep fixed source colors.
Other framework packages use the same illustration subpath pattern:
import { EmptyPage } from '@ycloud-web/icons-preact/illustration';
import { EmptyPage } from '@ycloud-web/icons-vue/illustration';
import { EmptyPage } from '@ycloud-web/icons-solid/illustration';
import { EmptyPage } from '@ycloud-web/icons-svelte/illustration';
import { EmptyPage } from '@ycloud-web/icons-astro/illustration';
import { EmptyPage } from '@ycloud-web/icons-react-native/illustration';The Angular package exports illustration definitions that can be rendered as inline SVG or serialized by your application:
import { getIllustration } from '@ycloud-web/icons-angular/illustration';
const emptyPage = getIllustration('empty-page');Static package
Install this package when you need the raw SVG file URL:
pnpm add @ycloud-web/icons-staticimport emptyPageUrl from '@ycloud-web/icons-static/illustration-icons/other/empty-page.svg';Data package
Install this package when you need structured SVG definitions or data URIs:
pnpm add @ycloud-web/icons-dataimport { getIllustration, illustrations } from '@ycloud-web/icons-data/illustration';
const emptyPage = getIllustration('empty-page');
const sameIllustration = illustrations['empty-page'];