The Icon component provides a consistent way to display SVG icons with support for sizing, colors, and responsive properties.
Basic Usage
import { Icon } from 'reshaped';
import IconHome from './icons/Home';
function App() {
return <Icon svg={IconHome} />;
}
Sizes
Control icon size using various methods:
import { Icon } from 'reshaped';
import IconStar from './icons/Star';
// Base unit multiplier
<Icon svg={IconStar} size={4} />
<Icon svg={IconStar} size={6} />
<Icon svg={IconStar} size={8} />
// CSS values
<Icon svg={IconStar} size="16px" />
<Icon svg={IconStar} size="1.5rem" />
<Icon svg={IconStar} size="1em" />
Default size is 1em, which inherits the parent font size.
Responsive Sizes
Size can be responsive across breakpoints:
<Icon
svg={IconStar}
size={{ s: 4, m: 5, l: 6 }}
/>
Colors
Apply semantic colors to icons:
import { Icon } from 'reshaped';
import IconCheck from './icons/Check';
<Icon svg={IconCheck} color="neutral" />
<Icon svg={IconCheck} color="neutral-faded" />
<Icon svg={IconCheck} color="primary" />
<Icon svg={IconCheck} color="positive" />
<Icon svg={IconCheck} color="warning" />
<Icon svg={IconCheck} color="critical" />
<Icon svg={IconCheck} color="disabled" />
Auto Width
Use the icon’s natural width instead of a square bounding box:
<Icon svg={IconLogo} autoWidth size={6} />
With Text
Icons automatically match text size when used inline:
import { Icon, Text, View } from 'reshaped';
import IconStar from './icons/Star';
<View direction="row" gap={1} align="center">
<Icon svg={IconStar} />
<Text variant="body-2">Favorite</Text>
</View>
<Text variant="featured-3">
<View direction="row" gap={2} align="center">
<Icon svg={IconStar} />
Large heading with icon
</View>
</Text>
Complete Examples
Icon Button
import { Icon, Button } from 'reshaped';
import IconTrash from './icons/Trash';
<Button
variant="ghost"
icon={<Icon svg={IconTrash} />}
attributes={{ 'aria-label': 'Delete' }}
/>
Icon with Badge
import { Icon, Badge, View } from 'reshaped';
import IconBell from './icons/Bell';
function NotificationIcon({ count }) {
return (
<View attributes={{ style: { position: 'relative', display: 'inline-flex' } }}>
<Icon svg={IconBell} size={6} />
{count > 0 && (
<Badge
size="small"
color="critical"
rounded
attributes={{
style: {
position: 'absolute',
top: -4,
right: -4,
}
}}
>
{count}
</Badge>
)}
</View>
);
}
Icon List
import { Icon, Text, View } from 'reshaped';
import IconCheck from './icons/Check';
function FeatureList({ features }) {
return (
<View gap={3}>
{features.map((feature, index) => (
<View key={index} direction="row" gap={2} align="start">
<Icon svg={IconCheck} size={5} color="positive" />
<Text variant="body-2">{feature}</Text>
</View>
))}
</View>
);
}
Status Icons
import { Icon, Text, View } from 'reshaped';
import IconCheck from './icons/Check';
import IconClock from './icons/Clock';
import IconX from './icons/X';
function StatusIndicator({ status, message }) {
const statusConfig = {
success: { icon: IconCheck, color: 'positive' },
pending: { icon: IconClock, color: 'warning' },
error: { icon: IconX, color: 'critical' },
};
const config = statusConfig[status];
return (
<View direction="row" gap={2} align="center">
<Icon svg={config.icon} size={5} color={config.color} />
<Text variant="body-3" color={config.color}>
{message}
</Text>
</View>
);
}
Icon Grid
import { Icon, Card, View, Text } from 'reshaped';
import IconHome from './icons/Home';
import IconUser from './icons/User';
import IconSettings from './icons/Settings';
import IconMail from './icons/Mail';
function IconGrid() {
const items = [
{ icon: IconHome, label: 'Home', color: 'primary' },
{ icon: IconUser, label: 'Profile', color: 'positive' },
{ icon: IconSettings, label: 'Settings', color: 'warning' },
{ icon: IconMail, label: 'Messages', color: 'critical' },
];
return (
<View direction="row" gap={4}>
{items.map((item, index) => (
<Card
key={index}
padding={4}
onClick={() => console.log(item.label)}
>
<View gap={2} align="center">
<Icon svg={item.icon} size={8} color={item.color} />
<Text variant="caption-1">{item.label}</Text>
</View>
</Card>
))}
</View>
);
}
Loading Spinner Icon
import { Icon } from 'reshaped';
import IconLoader from './icons/Loader';
<Icon
svg={IconLoader}
size={6}
color="primary"
attributes={{
style: {
animation: 'spin 1s linear infinite',
}
}}
/>
Icon in Table
import {
Table,
TableHead,
TableBody,
TableRow,
TableHeading,
TableCell,
Icon,
Text,
View
} from 'reshaped';
import IconCheck from './icons/Check';
import IconX from './icons/X';
function FeatureTable({ features }) {
return (
<Table border>
<TableHead>
<TableRow>
<TableHeading>Feature</TableHeading>
<TableHeading align="center">Available</TableHeading>
</TableRow>
</TableHead>
<TableBody>
{features.map(feature => (
<TableRow key={feature.id}>
<TableCell>{feature.name}</TableCell>
<TableCell align="center">
<Icon
svg={feature.available ? IconCheck : IconX}
size={5}
color={feature.available ? 'positive' : 'critical'}
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}
Accessibility
The Icon component automatically sets aria-hidden="true" since icons are typically decorative. For icons that convey meaning, ensure the parent element has appropriate accessibility attributes:
// Good: Button with aria-label
<Button
icon={<Icon svg={IconTrash} />}
attributes={{ 'aria-label': 'Delete item' }}
/>
// Good: Icon with visible text
<View direction="row" gap={1} align="center">
<Icon svg={IconInfo} />
<Text>Information</Text>
</View>
Props
svg
React.ComponentType | React.ReactElement | null
required
Icon SVG component or element to render.
size
number | string | responsive
default:"1em"
Icon size. Can be a number (base unit multiplier), string (CSS value like ‘1em’, ‘16px’), or responsive.
color
string
default:"undefined"
Icon color based on color tokens.Options: neutral, neutral-faded, positive, critical, warning, primary, disabled
Use the width of the SVG asset instead of providing a square bounding box.
className
string
default:"undefined"
Additional classname for the root element.
attributes
object
default:"undefined"
Additional attributes for the root element.