Skip to content

Icon

A typed wrapper around Phosphor React Native. Size, color, and weight are all resolved from theme tokens — switching themes transforms every icon automatically without touching a single <Icon> component.

When to use: Any icon in the UI — navigation, action indicators, list row leading icons, status indicators.

When not to use: Don’t render Phosphor icon components directly — always use <Icon> so weight and color flow through the theme.

import { Icon } from '@/components';
import { House, Bell, Gear } from 'phosphor-react-native';
<Icon icon={House} size="md" color="primary" />
<Icon icon={Bell} size="lg" color="accent" />
<Icon icon={Gear} size="sm" color="muted" />
PropTypeDefaultDescription
iconPhosphorIconComponentPhosphor icon component (required)
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Icon pixel size from theme scale
color'primary' | 'secondary' | 'muted' | 'accent' | 'inverse' | 'onAccent' | 'success' | 'warning' | 'error''primary'Semantic color slot
weight'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone'theme.iconWeightOverrides the theme’s default icon weight
accessibilityLabelstringAnnounced by screen readers; omit for decorative icons
testIDstringFor testing
SizePixels
xs12
sm16
md20
lg24
xl32

The weight prop maps directly to Phosphor’s icon weight system. Each theme sets a default:

ThemeDefault iconWeightEffect
SlateregularClean, neutral strokes
ObsidianboldHeavier, more graphic icons
QuartzlightDelicate, airy icons

Leave weight unset to let the active theme control the personality. Override explicitly only for functional emphasis (e.g. weight="fill" for a selected state).

// Let the theme decide (recommended for most icons)
<Icon icon={House} size="md" color="primary" />
// Explicit override — always filled regardless of theme
<Icon icon={Star} size="md" color="accent" weight="fill" />

Decorative icons (no semantic meaning) should have no accessibilityLabel — they are hidden from screen readers automatically.

Meaningful icons (standalone, not next to a label) must have accessibilityLabel:

// ✓ Decorative — text label present
<View style={{ flexDirection: 'row', gap: 8 }}>
<Icon icon={Bell} size="md" color="primary" />
<Text>Notifications</Text>
</View>
// ✓ Meaningful — no adjacent label
<Icon icon={Bell} size="md" color="accent" accessibilityLabel="Notifications" />
  • IconButton — pressable icon with variants and sizes
  • Badge — often paired with Icon in notification indicators