Icon System Architecture
This document details the technical architecture of Hibiscus's centralized icon system, which replaced inline SVG icons with a unified "griddy icons" approach.
System Overview
The icon system provides a centralized, type-safe way to manage and use icons throughout the Hibiscus application. It replaces inline SVG definitions with a unified icon handler that ensures consistency, maintainability, and performance.
Architecture Components
1. Icon Definition Structure
Icons are defined in a centralized structure with type safety:
// Icon definitions with categorization
interface IconDefinitions {
// File operations
file: string
folder: string
openFile: string
// UI controls
close: string
expand: string
collapse: string
// Navigation
back: string
forward: string
up: string
down: string
// Application specific
hibiscus: string
knowledge: string
graph: string
}
2. Icon Handler Component
The Icon component provides a unified interface for rendering icons:
interface IconProps {
name: keyof IconDefinitions
size?: number | string
className?: string
onClick?: () => void
}
export function Icon({ name, size = 16, className, onClick }: IconProps) {
const iconPath = icons[name]
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
className={className}
onClick={onClick}
>
<path d={iconPath} fill="currentColor" />
</svg>
)
}
3. SVG Path Optimization
All SVG icons are optimized for:
- Minimal Path Data: Simplified path commands for smaller bundle size
- Consistent ViewBox: Standard 24x24 viewBox for uniform scaling
- Fill-CurrentColor: Icons inherit text color for theme integration
- No Stroke Data: Simplified rendering with fill-only paths
Implementation Details
Icon Library Structure
The icon system is organized into logical categories:
File System Icons
file- Generic file iconfolder- Folder/directory iconfolderOpen- Open folder statefileText- Text file iconfileCode- Code file icon
Navigation Icons
arrowLeft- Left navigationarrowRight- Right navigationarrowUp- Up navigationarrowDown- Down navigationchevronLeft- Collapsed statechevronRight- Expanded state
Action Icons
close- Close/dismiss actionadd- Add/create actionremove- Remove/delete actionedit- Edit/modify actionsave- Save action
Application Icons
hibiscus- Application logo/icongraph- Knowledge graph iconsearch- Search functionalitysettings- Settings/configuration
Theme Integration
Icons seamlessly integrate with the theme system:
.icon {
color: var(--text);
transition: color 0.2s ease;
}
.icon:hover {
color: var(--accent);
}
.icon.active {
color: var(--accent-secondary);
}
Performance Optimizations
Bundle Size Reduction
- Deduplication: Eliminated duplicate inline SVG definitions
- Path Compression: Optimized SVG path data
- Tree Shaking: Unused icons are eliminated during build
Runtime Performance
- No DOM Parsing: Icons rendered as SVG elements directly
- CSS Inheritance: Icons inherit text color properties
- Minimal Re-renders: Icon components are pure functions
Migration from Inline SVGs
Before (Inline SVGs)
// Old approach with inline SVGs
function FileIcon() {
return (
<svg width="16" height="16" viewBox="0 0 24 24">
<path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2Z" />
</svg>
)
}
After (Griddy Icons)
// New approach with centralized icons
function FileIcon() {
return <Icon name="file" size={16} />
}
Benefits of Migration
- Maintainability: Single source of truth for icon definitions
- Consistency: All icons use the same rendering approach
- Performance: Reduced bundle size and better runtime performance
- Developer Experience: Type-safe icon usage with IntelliSense support
- Theme Integration: Automatic theme color inheritance
Component Integration
Updated Components
All UI components were updated to use the new icon system:
Tree View Component
// Before
<TreeNode>
<svg>...</svg> {/* inline */}
<span>{name}</span>
</TreeNode>
// After
<TreeNode>
<Icon name={isFolder ? 'folder' : 'file'} />
<span>{name}</span>
</TreeNode>
Tab Bar Component
// Before
<Tab>
<svg>...</svg> {/* inline close icon */}
<span>{title}</span>
</Tab>
// After
<Tab>
<Icon name="close" onClick={onClose} />
<span>{title}</span>
</Tab>
Search Panel Component
// Before
<SearchResult>
<svg>...</svg> {/* inline search icon */}
<span>{result}</span>
</SearchResult>
// After
<SearchResult>
<Icon name="search" />
<span>{result}</span>
</SearchResult>
Icon Usage Guidelines
When to Use Icons
- Navigation: Use arrow icons for directional navigation
- Actions: Use action icons for user interactions
- States: Use icons to represent component states
- Hierarchy: Use folder/file icons for tree structures
Icon Sizing
Standard icon sizes for different contexts:
- Header/Title Bar: 16px
- Button Icons: 14px
- Tree View: 16px
- Tab Bar: 12px
- Status Bar: 12px
- Small Controls: 10px
Color Usage
Icons inherit text color by default but can be customized:
/* Default behavior */
.icon {
color: var(--text);
}
/* Hover state */
.icon:hover {
color: var(--accent);
}
/* Active state */
.icon.active {
color: var(--accent-secondary);
}
/* Disabled state */
.icon.disabled {
color: var(--text-muted);
}
Adding New Icons
1. Define Icon Path
Add the SVG path to the icon definitions:
// icons.ts
export const icons = {
// existing icons...
newIcon: "M12,2L14.09,8.26L21,9.27L16.5,13.14L17.82,20L12,16.77L6.18,20L7.5,13.14L3,9.27L9.91,8.26L12,2Z"
}
2. Update Type Definitions
Add the new icon to the type definitions:
3. Use in Components
Use the new icon throughout the application:
Future Enhancements
Planned Improvements
- Icon Sprites: Consider SVG sprite optimization for very large icon sets
- Dynamic Loading: Lazy load icon definitions for reduced initial bundle
- Icon Animation: Add support for animated icons
- Custom Icons: Allow user-defined icon extensions
- Icon Themes: Support for different icon styles (outlined, filled, etc.)
Extensibility
The icon system is designed to be extensible:
- Plugin Architecture: Easy to add new icon packs
- Theme Variants: Support for different icon styles per theme
- Custom Definitions: Allow runtime icon definition additions
- Icon Packs: Support for loading external icon libraries
Testing Considerations
Unit Tests
- Icon Rendering: Verify icons render correctly with different props
- Theme Integration: Test icon color changes with theme switches
- Size Variations: Ensure icons scale properly at different sizes
- Accessibility: Verify icons have proper ARIA labels when needed
Visual Regression Tests
- Icon Consistency: Ensure icons maintain appearance across updates
- Theme Testing: Verify icon appearance in all theme variants
- Browser Compatibility: Test rendering across different browsers
- Performance: Monitor icon rendering performance
This icon system provides a robust, maintainable foundation for visual elements throughout Hibiscus, ensuring consistency and performance while enabling future extensibility.