Паттерны
Иконка внутри элемента управления
Когда использовать:
- кнопке или триггеру нужен один декоративный глиф
Заметки о композиции:
- согласуйте размер иконки с плотностью элемента управления
- позвольте
currentColorнаследоваться от родительского элемента
Компромиссы:
- единообразно и компактно
- декоративными глифами легко злоупотребить
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'>
ExportИконка в строке статуса
Когда использовать:
- тексту нужен небольшой символ рядом
Заметки о композиции:
- иконка должна оставаться второстепенной по отношению к тексту
- не полагайтесь на иконку как на единственный сигнал статуса
Компромиссы:
- быстрый визуальный просмотр
- для ясности всё равно нужен текст
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>Обёртка для собственного SVG
Когда использовать:
- собственный или сторонний SVG должен следовать тому же контракту размеров VegaUI
Заметки о композиции:
- дочерний SVG должен быть совместим с пробрасываемыми SVG-пропсами
- явные размеры используйте, только когда токенов недостаточно
Компромиссы:
- единообразная интеграция иконок
- легче получить расхождения, если каждой иконке задавать размер явно
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>
);
}
Сравнение
Быстрое правило выбора
Используйте Icon, чтобы рендерить SVG с размерами и цветом по правилам VegaUI. Используйте текст или подписи, когда смысл должен быть явным, а не чисто визуальным.
Icon или «голый» SVG
- Используйте
Iconдля единообразных размеров и наследования цвета. - «Голый» SVG используйте, только если намеренно хотите обойти общий контракт иконок.
Icon или Avatar
- Используйте
Iconдля символической графики. - Используйте
Avatarдля идентификации людей или сущностей.
Выбирайте этот компонент, когда
- нужен один масштабируемый SVG-глиф
- размер должен следовать токенам иконок VegaUI
Не выбирайте этот компонент, когда
- интерфейсу нужен полноценный самостоятельный статус с подписью
- содержимое на самом деле не является SVG-иконкой
Решение проблем
Иконка игнорирует проп size
Симптом
Изменение size не влияет на размеры отрендеренной иконки.
Вероятная причина
Уже заданы явные пропсы width или height.
Как проверить
- изучите отрендеренные пропсы
- проверьте, присутствуют ли
widthилиheight
Исправление
Уберите явные размеры, если хотите, чтобы применялся размер из токена.
Иконка невидима или неправильного цвета
Симптом
Иконка рендерится, но её цвет неожиданный.
Вероятная причина
Иконка использует currentColor, поэтому её цвет определяет окружающий текст или элемент управления.
Как проверить
- изучите вычисленное значение
colorв родительском контексте
Исправление
Задайте нужный цвет текста у родителя или передайте явный проп color.
Самостоятельная иконка не объявляется
Симптом
Визуально иконка несёт смысл, но вспомогательные технологии её не объявляют.
Вероятная причина
Icon по умолчанию ставит aria-hidden='true'.
Как проверить
- изучите атрибуты отрендеренного элемента
Исправление
Передайте смысл через соседний текст или подписанный родительский элемент управления, а не полагайтесь только на иконку.