# Icon System OpenChamber uses an SVG sprite-based icon system for performance. All icons are rendered via a single hidden SVG sprite injected into the DOM, referenced by ``. ## Usage ```tsx import { Icon } from "@/components/icon/Icon"; ``` ## Icon Names Icons use kebab-case names based on Remixicon. To find an icon name: 1. Start from the Remixicon component name: `RiArrowDownSLine` 2. Remove `Ri` prefix → `ArrowDownSLine` 3. Convert to kebab-case → `arrow-down-s` Common suffixes: - `Line` / `Fill` are dropped from the sprite name - Numbers are preserved: `RiChat4Line` → `chat-4` ## Adding a New Icon 1. Import and use it in your code: `` 2. Run `bun run icons:sprite` to regenerate the sprite with the new icon 3. The script scans `packages/ui/src` for all `RiX` usages and extracts SVG paths If the icon doesn't exist in the sprite, the script will warn you. ## Sizing The `Icon` component does not have a `size` prop. Use Tailwind classes instead: ```tsx {/* 16px */} {/* 20px */} {/* 24px */} ``` ## Type Safety ```tsx import type { IconName } from "@/components/icon/icons"; const icon: IconName = "arrow-down-s"; // type-checked ``` ## Architecture - `sprite.ts` — Auto-generated SVG path data (run `bun run generate-icon-sprite` to regenerate) - `Icon.tsx` — The `` component, injects sprite on first mount - `icons.ts` — TypeScript type `IconName` The sprite is injected as a hidden `` element containing `` elements. Each `` renders ``. ## Migration from @remixicon/react Old: ```tsx import { RiArrowDownSLine } from "@remixicon/react"; ``` New: ```tsx import { Icon } from "@/components/icon/Icon"; ``` If an icon is used as a component reference (not JSX): ```tsx // Old: const icon = RiStackLine; return ; // New: const icon: IconName = "stack"; return ; ```