Patterns
Inline Control Icon
When to use:
- a button or trigger needs one decorative glyph
Composition notes:
- keep icon size aligned with the control density
- let
currentColorinherit from the parent control
Trade-offs:
- consistent and compact
- easy to overuse decorative glyphs
import { Button, Icon } from '@vega-ui/react';
import { ChevronDownIcon, DownloadIcon, PlusIcon } from '@vega-ui/icons';
export default function IconInsideAButton() {
return (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-4)' }}>
<Button type='button'>
<Icon size='sm'><PlusIcon /></Icon>
Add member
</Button>
<Button type='button' variant='secondary' appearance='ghost'>
ExportStatus Row Icon
When to use:
- text needs a small adjacent symbol
Composition notes:
- keep the icon secondary to the text
- do not rely on the icon as the only status signal
Trade-offs:
- fast visual scanning
- still needs text for clarity
import { Icon, Text } from '@vega-ui/react';
import { CircleCheckIcon, ShieldIcon, TriangleAlertIcon } from '@vega-ui/icons';
export default function InfoRow() {
return (
<ul style={{ display: 'flex', flexDirection: 'column', gap: 'var(--spacing-4)', margin: 0, padding: 0, listStyle: 'none', width: '100%' }}>
<li style={{ display: 'flex', alignItems: 'flex-start', gap: 'var(--spacing-4)' }}>
<Icon size='sm' style={{ flexShrink: 0, marginBlockStart: 'var(--spacing-3)', color: 'var(--color-green-accent-500)' }}><CircleCheckIcon /></Icon>
<Text size={3}>SSO is enabled for this workspace</Text>
</li>
<li style={{ display: 'flex', alignItems: 'flex-start', gap: 'var(--spacing-4)' }}>
<Icon size='sm' style={{ flexShrink: 0, marginBlockStart: 'var(--spacing-3)', color: 'var(--color-primary-500)' }}><ShieldIcon /></Icon>Custom SVG Wrapper
When to use:
- a custom or third-party SVG should use the same VegaUI sizing contract
Composition notes:
- keep the child SVG compatible with forwarded SVG props
- use explicit dimensions only when token sizing is not enough
Trade-offs:
- consistent icon integration
- easier to produce drift if every icon is explicitly sized
import type { SVGProps } from 'react';
import { Icon } from '@vega-ui/react';
function OrbitMark(props: SVGProps<SVGSVGElement>) {
return (
<svg viewBox='0 0 24 24' fill='none' strokeWidth={2} strokeLinecap='round' {...props}>
<circle cx='12' cy='12' r='3' />
<ellipse cx='12' cy='12' rx='10' ry='4.5' transform='rotate(-30 12 12)' />
</svg>
);
}
Comparison
Quick Decision Rule
Use Icon to render SVGs with VegaUI sizing and color behavior. Use text or labels when the meaning should be explicit rather than purely visual.
Icon vs raw SVG
- Use
Iconfor consistent sizing and color inheritance. - Use raw SVG only when you intentionally want to bypass the shared icon contract.
Icon vs Avatar
- Use
Iconfor symbolic graphics. - Use
Avatarfor people or entity identity.
Choose This Component When
- you need one scalable SVG glyph
- sizing should follow VegaUI icon tokens
Do Not Choose This Component When
- the UI needs a full labeled status on its own
- the content is not really an SVG icon
Troubleshooting
The Icon Ignores The size Prop
Symptom
Changing size does not affect the rendered icon dimensions.
Likely Cause
Explicit width or height props are already set.
How To Verify
- inspect the rendered props
- check whether
widthorheightis present
Fix
Remove explicit dimensions if you want token sizing to apply.
The Icon Is Invisible Or Wrongly Colored
Symptom
The icon renders but its color is unexpected.
Likely Cause
The icon uses currentColor, so the surrounding text or control color is driving it.
How To Verify
- inspect the computed
colorof the parent context
Fix
Set the desired text color on the parent or pass an explicit color prop.
A Standalone Icon Is Not Announced
Symptom
The icon has meaning visually, but assistive technology does not announce it.
Likely Cause
Icon defaults to aria-hidden='true'.
How To Verify
- inspect the rendered element attributes
Fix
Provide meaning through adjacent text or a labeled parent control rather than relying on the raw icon alone.