SVG Icon Pattern
Instructions
When creating or updating icons in the lib/ui/icons directory, follow these standards to ensure consistency and flexibility.
1. Icon Component Definition
Export a named component that receives SvgProps from @lib/ui/props. Spread these props onto the svg element.
tsx1// ✅ Good: SvgProps pattern 2import { SvgProps } from '@lib/ui/props' 3 4export const MyIcon = (props: SvgProps) => ( 5 <svg 6 xmlns="http://www.w3.org/2000/svg" 7 width="1em" 8 height="1em" 9 viewBox="0 0 24 24" 10 fill="currentColor" 11 {...props} 12 > 13 <path d="..." /> 14 </svg> 15) 16 17// ❌ Bad: IconWrapper inside icon definition 18export const MyIcon = (props: any) => ( 19 <IconWrapper {...props}> 20 <svg>...</svg> 21 </IconWrapper> 22)
2. Sizing and Dimensions
- Calculate dimensions based on the
viewBoxattribute. - The largest dimension (width or height) should always be
1em. - The smaller dimension should be calculated proportionally:
(smaller / larger)em. - Neither width nor height should exceed
1em.
tsx1// Example for non-square icon (viewBox="0 0 22 20") 2// height = 20/22 = 0.909 3<svg width="1em" height="0.909em" viewBox="0 0 22 20" ...>
3. Styling and Colors
- Use
fill="currentColor"orstroke="currentColor"to allow the icon to inherit colors from its parent. - For multi-colored icons, use specific colors only where necessary.
4. Usage and Sizing
Size icons at the usage site using the fontSize property within the style prop. This leverages the 1em base size defined in the icon component.
tsx1// ✅ Good: Direct sizing via style 2<MyIcon style={{ fontSize: 24 }} /> 3 4// ❌ Bad: Using size prop (requires IconWrapper) 5<MyIcon size={24} />
Anti-Patterns to Avoid
- DO NOT wrap icons with
IconWrapperinside the icon component file. - DO NOT use hardcoded pixel values for
widthandheightin thesvgelement. - DO NOT use
IconWrapperat the usage site if simplefontSizestyling is sufficient.