@varialkit/icons
v0.1.2
Published
Scalable icon primitives for Solara docs and component packages.
Readme
Icons Package
Scalable icon primitives for Solara docs and component packages.
Exports
Icon: runtime SVG renderer with accessibility defaultsicons/iconNames: typed icon ID listiconMetadata: rich metadata used by docs/search UIiconCatalog: metadata list optimized for grid renderinganimations.css: predefined keyframes for icon presets
Example
import { Icon } from "@solara/icons";
export function Example() {
return <Icon name="search" aria-label="Search" size={24} />;
}Package Goals
This package is designed to scale from a handful of icons to thousands while keeping:
- icon definition ownership localized per icon file
- rendering and animation behavior centralized in one runtime component
- docs website consumption package-backed (no deep imports into package internals)
- local sync workflow fast and predictable in
apps/website
Source Of Truth And File Layout
Current architecture is source-driven and generated-in-place (no external build script yet).
packages/icons/
├── src/
│ ├── components/
│ │ └── Icon.tsx # Runtime renderer and behavior logic
│ ├── generated/
│ │ ├── types.ts # Shared icon types/contracts
│ │ └── icons/
│ │ ├── <icon-id>.ts # One icon definition per file
│ │ └── index.ts # Central registry + derived maps
│ ├── styles/
│ │ └── animations.css # Keyframes used by presets
│ └── index.tsx # Public package API
└── README.mdWhere Logic Lives
src/generated/icons/<icon-id>.ts- owns one icon's SVG path markup (
svg) - owns metadata (
name,description,keywords,sizes, optionalanimation) - owns optional icon-specific motion rules (
motion) for path-level behavior
- owns one icon's SVG path markup (
src/generated/icons/index.ts- imports all icon definition modules
- builds
iconDefinitions,iconData, andiconMetadataregistries
src/components/Icon.tsx- runtime rendering (
<svg dangerouslySetInnerHTML />) - accessibility behavior (
aria-hiddendefaults,role="img"when labeled) - size/variant/stroke width handling
- animation behavior resolution (global preset or icon path-level motion)
- runtime rendering (
src/index.tsx- stable public exports for package consumers (
Icon, catalog, names, metadata)
- stable public exports for package consumers (
Data Model
The core contract is SolaraIconDefinition in src/generated/types.ts.
id: icon identifier (SolaraIconName)svg: inner SVG markup (paths/groups/etc; no wrapping<svg>)metadata: documentation and discovery datadefaults(optional): icon rendering defaults such asstrokeWidthmotion(optional): per-path animation rules with trigger and timing controls
Important: path-level motion depends on data-part attributes in the icon's svg markup.
If a motion.paths[].part value is missing in SVG markup, that path rule cannot apply.
Icon Component API
Icon accepts all standard SVGAttributes<SVGSVGElement> except name, plus:
name: SolaraIconName(required)size?: SolaraIconSize | number | stringundefineddefaults to1emnumberconverts to pixel string (for example24->"24px")
strokeWidth?: number- applied on the root
<svg> - falls back to icon-level default when available
- applied on the root
variant?: "default" | "primary" | "secondary" | "accent" | "error" | "warning"- mapped to theme token color variables
animated?: boolean- enables metadata/motion-based animation behavior
animation?: "spin-clockwise" | "pulse" | "bounce"- explicit override preset for root-level animation
Animation Behavior Rules
Animation resolution order:
- Explicit
animationprop (root-level preset override) - Icon
motionrules (path-level behavior viadata-part) - Icon metadata animation (
metadata.animation) whenanimated=true - No animation
Trigger behavior:
motion.trigger = "hover": path rules apply only when the icon is hoveredmotion.trigger = "manual": path rules apply wheneveranimated=true
Accessibility Defaults
- Without a label:
aria-hidden="true"focusable="false"
- With
aria-labeloraria-labelledby:role="img"- icon is treated as semantic content
Use labels for meaningful icons in content; keep unlabeled icons decorative.
How To Add A New Icon
Additions should be atomic and centered around one icon definition file.
- Pick an ID in kebab-case (example:
arrow-circle-left). - Create
src/generated/icons/arrow-circle-left.ts. - Export a
SolaraIconDefinitionobject with:idsvgpath markup (usecurrentColor; adddata-partmarkers if motion is needed)metadatawithname,description,keywords,sizes, optionalanimation- optional
defaultsand optionalmotion
- Register the icon in
src/generated/icons/index.ts:- import the new module
- add it to
iconDefinitionList
- Verify package consumers:
iconNames/icons/iconCataloginclude the new icon automatically
- Validate with typecheck:
pnpm --filter @solara/website typecheck
Minimal icon module template:
import type { SolaraIconDefinition } from "../types";
export const myIcon: SolaraIconDefinition = {
id: "my-icon",
svg: '<path data-part="main" d="..." stroke="currentColor" vector-effect="non-scaling-stroke" />',
metadata: {
name: "My Icon",
description: "One-line purpose.",
keywords: ["my", "icon"],
sizes: [16, 20, 24, 32]
}
};Pipeline To Website
Current flow from icon file to docs explorer:
- Icon definition is added under
packages/icons/src/generated/icons/* - Registry in
src/generated/icons/index.tsderives package maps - Public API in
src/index.tsxexportsiconCatalog,Icon, and names - Website route
apps/website/app/(main)/icons/page.tsximportsiconCatalogfrom@solara/icons - Client grid
apps/website/app/components/IconGrid.tsxrenders searchable/filterable previews using packageIcon
Because website imports use @solara/icons, this stays aligned with local sync mode and package contracts.
Local Dev And Real-Time Updates
For near-instant package edits in the website:
- run
pnpm dev:local(orpnpm dev:local:icons) - edit files under
packages/icons/src/... - refresh/check
/iconsfor updated data and preview behavior
If updates do not appear, verify the mode badge shows Local Sync and that imports stay package-based.
Notes For Large Icon Sets
- Keep each icon in its own file to reduce merge conflicts and keep ownership clear.
- Maintain
iconDefinitionListordering intentionally (for deterministic docs ordering). - Keep metadata quality high (
keywordsanddescription) since docs search depends on it. - Prefer path-level motion for icon-specific behavior and reserve root-level presets for broad overrides.
