Icon System Documentation - Sasha Studio
Overview
Sasha Studio uses Phosphor Icons (@phosphor-icons/react) as its primary icon library. We chose Phosphor for its:
- Modern, friendly aesthetic - Softer, more rounded design compared to geometric alternatives
- Consistency - Uniform stroke width and visual weight across all icons
- Flexibility - Multiple weights (thin, light, regular, bold, fill, duotone)
- Large icon set - Over 7,000+ icons covering all UI needs
- React-first - Built specifically for React with proper TypeScript support
Architecture
Icon Mapping Layer
We use a centralized icon mapping layer (src/components/icons/index.jsx) that:
- Provides a single source of truth for all icons
- Maps icon names to maintain backwards compatibility
- Allows easy switching between icon libraries
- Centralizes icon configuration and defaults
Benefits of This Approach
- Easy migration - Changed from Lucide React without updating component code
- Consistency - All icons share default props and behavior
- Maintainability - Single file to update when adding/changing icons
- Flexibility - Can mix icon libraries during transition periods
Usage Guidelines
Standard Icon Sizes
| Size Class |
Pixels |
Use Case |
w-3 h-3 |
12px |
Small indicators, badges |
w-3.5 h-3.5 |
14px |
Sidebar items, small buttons |
w-4 h-4 |
16px |
Default size, buttons, inputs |
w-5 h-5 |
20px |
Larger buttons, headers |
w-6 h-6 |
24px |
Feature icons, empty states |
w-8 h-8 |
32px |
Large feature displays |
Icon Weights
- regular (default) - Standard UI elements
- bold - Emphasis, selected states
- light - Subtle, secondary elements
- fill - Active/selected states
- duotone - Special emphasis (use sparingly)
Color Usage
- Inherit from text - Default approach using
currentColor
- Explicit colors - Use Tailwind classes like
text-primary, text-muted-foreground
- Interactive states - Use hover/active color transitions
Implementation Examples
Basic Usage
import { MessageSquare, Settings, Folder } from '../components/icons';
// Simple icon
<MessageSquare className="w-4 h-4" />
// With color
<Settings className="w-4 h-4 text-primary" />
// With hover effect
<Folder className="w-4 h-4 hover:text-primary transition-colors" />
Advanced Usage
// Custom weight
<MessageSquare className="w-4 h-4" weight="bold" />
// Mirrored for RTL
<ChevronRight className="w-4 h-4" mirrored />
// With aria-label for accessibility
<button aria-label="Settings">
<Settings className="w-4 h-4" />
</button>
Complete Icon Reference
Chat & Communication
| Icon Name |
Component |
Usage |
| MessageSquare |
Chat |
Conversations, chat bubbles |
| ChatCircle |
ChatCircle |
Alternative chat icon |
Navigation & UI
| Icon Name |
Component |
Usage |
| ChevronDown |
CaretDown |
Dropdowns, accordions |
| ChevronRight |
CaretRight |
Navigation, expandable items |
| Plus |
Plus |
Add, create new |
| X |
X |
Close, dismiss |
| Search |
MagnifyingGlass |
Search inputs |
File & Folder
| Icon Name |
Component |
Usage |
| Folder |
Folder |
Closed folders |
| FolderOpen |
FolderOpen |
Open folders |
| FolderPlus |
FolderPlus |
Create folder |
| File |
File |
Generic files |
| FileText |
FileText |
Documents |
| FileCode |
FileCode |
Code files |
Actions
| Icon Name |
Component |
Usage |
| Edit3/Edit2 |
PencilSimple |
Edit actions |
| Trash2 |
Trash |
Delete actions |
| Save |
FloppyDisk |
Save actions |
| Download |
Download |
Download files |
| Upload |
Upload |
Upload files |
| RefreshCw |
ArrowsClockwise |
Refresh, sync |
| Settings |
Gear |
Settings, preferences |
Status & Information
| Icon Name |
Component |
Usage |
| Check |
Check |
Success, complete |
| AlertTriangle |
Warning |
Warnings, alerts |
| Info |
Info |
Information |
| Clock |
Clock |
Time, duration |
| History |
ClockCounterClockwise |
History, logs |
Theme & View
| Icon Name |
Component |
Usage |
| Moon |
Moon |
Dark mode |
| Sun |
Sun |
Light mode |
| Eye |
Eye |
Show, preview |
| EyeOff |
EyeSlash |
Hide |
| Maximize2 |
ArrowsOutSimple |
Fullscreen |
| Minimize2 |
ArrowsInSimple |
Exit fullscreen |
Development
| Icon Name |
Component |
Usage |
| Terminal |
Terminal |
Command line |
| GitBranch |
GitBranch |
Git branches |
| GitCommit |
GitCommit |
Commits |
| Server |
Server |
Backend, servers |
| Globe |
Globe |
Web, public |
| Shield |
Shield |
Security |
| Zap |
Lightning |
Performance, quick |
Media & Misc
| Icon Name |
Component |
Usage |
| Mic |
Microphone |
Voice input |
| MicOff |
MicrophoneSlash |
Mute |
| Sparkles |
Sparkle |
AI, magic, special |
| Star |
Star |
Favorites, ratings |
| Brain |
Brain |
AI, intelligence |
| Loader2 |
SpinnerGap |
Loading states |
Adding New Icons
Process
- Find the icon in Phosphor Icons
- Import it in
src/components/icons/index.jsx:import { NewIconName } from '@phosphor-icons/react';
- Export it with appropriate naming:
export { NewIconName as DesiredName };
- Use it in your components:
import { DesiredName } from '../components/icons';
Naming Conventions
- Use PascalCase for icon names
- Be descriptive but concise
- Maintain consistency with existing names
- Consider backwards compatibility
Accessibility
Best Practices
- Decorative icons - Use
aria-hidden="true" for purely decorative icons
- Interactive icons - Always include
aria-label on icon-only buttons
- Icon with text - Icon enhances text, no additional aria needed
- Status icons - Include screen reader text for important status indicators
Examples
// Icon-only button
<button aria-label="Open settings">
<Settings className="w-4 h-4" aria-hidden="true" />
</button>
// Icon with text
<button>
<Plus className="w-4 h-4" aria-hidden="true" />
<span>Add Item</span>
</button>
// Status indicator
<div>
<Check className="w-4 h-4 text-green-500" aria-hidden="true" />
<span className="sr-only">Completed</span>
</div>
Performance Considerations
Bundle Size
- Phosphor uses tree-shaking - only imported icons are bundled
- Current usage: ~50 icons β 15-20KB gzipped
- Each icon is typically 300-400 bytes
Optimization Tips
- Import only needed icons (automatic with our mapping layer)
- Use consistent icon sizes to optimize CSS
- Lazy load icon-heavy components when possible
- Consider using SVG sprites for very large icon sets
Migration from Lucide React
We migrated from Lucide React to Phosphor Icons for a friendlier, more modern aesthetic. The migration was seamless thanks to our icon mapping layer:
- No component changes required - Mapping layer handles name differences
- Backwards compatible - Old icon names still work
- Gradual migration possible - Can run both libraries simultaneously
- Easy rollback - Single file change to revert if needed
Key Differences
- Visual style - Phosphor is rounder, softer
- Weight options - Phosphor offers more weight variants
- Icon names - Some naming differences handled by mapping
- API - Similar props, minor differences in customization
Troubleshooting
Common Issues
Icons not displaying
- Check import path is correct (
'../components/icons')
- Ensure icon name is exported from mapping file
- Verify className includes size classes
Wrong icon size
- Use Tailwind width/height classes (
w-4 h-4)
- Don't use size prop with className
- Check parent container constraints
Icon color issues
- Default is
currentColor (inherits text color)
- Use
text-* classes for specific colors
- Check dark mode color classes
Build errors
- Ensure icons/index.jsx has .jsx extension
- Check all imports reference correct path
- Verify @phosphor-icons/react is installed
Last Updated: 2025-08-07
Icon Library: @phosphor-icons/react v2.1.10