Паттерны
Компактное действие на панели инструментов
Когда использовать:
- Плотным панелям инструментов или заголовкам нужны компактные действия.
Заметки по композиции:
- Делайте подписи явными через
aria-label. - Оставляйте вариант только с иконкой для привычных действий.
Компромиссы:
- Экономит место.
- Менее явно, чем текстовые кнопки.
import { Icon, IconButton, Text } from '@vega-ui/react';
import { EllipsisIcon, PencilIcon, Share2Icon } from '@vega-ui/icons';
import { useState } from 'react';
export default function BasicUsage() {
const [lastAction, setLastAction] = useState('');
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--spacing-2)', width: '100%' }}>
<header style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-2)' }}>
<Text size={4} fontWeight={600} style={{ flex: 1, minWidth: 0 }}>Brand guidelines</Text>
<IconButton type='button' size='sm' variant='secondary' appearance='transparent' aria-label='Rename document' onClick={() => setLastAction('Rename')}>Встроенное действие сброса
Когда использовать:
- Небольшой локальный контрол очищает или удаляет соседнее состояние.
Заметки по композиции:
- Размещайте кнопку рядом с тем, на что она влияет.
- Держите действие узконаправленным.
Компромиссы:
- Очень компактно.
- Легко злоупотребить в формах без достаточного контекста.
import type { CSSProperties } from 'react';
import { Icon, IconButton, Label, TextField, TextFieldInput } from '@vega-ui/react';
import { SearchIcon, XIcon } from '@vega-ui/icons';
import { FormEvent, useRef, useState } from 'react';
export default function InlineClearAction() {
const input = useRef<HTMLInputElement>(null);
const [query, setQuery] = useState('quarterly report');
const [submitted, setSubmitted] = useState('');
const clear = () => {
setQuery('');Навигационная поверхность с иконкой
Когда использовать:
- Навигации нужен вид иконки-кнопки с сохранением семантики ссылки.
Заметки по композиции:
- Используйте
asChildс настоящей ссылкой. - Цель перехода должна быть очевидна из окружающего контекста и доступной подписи.
Компромиссы:
- Сильная визуальная согласованность.
- Легко использовать неправильно для неоднозначной навигации.
import { Icon, IconButton } from '@vega-ui/react';
import { BookOpenIcon, LifeBuoyIcon, RssIcon } from '@vega-ui/icons';
const links = [
{ href: '/docs', label: 'Documentation', icon: <BookOpenIcon /> },
{ href: '/support', label: 'Help center', icon: <LifeBuoyIcon /> },
{ href: '/blog/rss.xml', label: 'Blog RSS feed', icon: <RssIcon /> },
];
export default function NavigationalIconSurface() {
return (
<nav aria-label='Resources'>Сравнение
Быстрое правило выбора
Используйте IconButton, когда действие компактное, распространённое и узнаваемое без видимого текста.
IconButton или Button
Используйте IconButton, когда:
- места мало
- действие распространённое и узнаваемое
Используйте Button, когда:
- видимый текст делает действие понятнее
Главный компромисс: иконка-кнопка плотнее, а обычная кнопка понятнее.
IconButton или Link
Используйте IconButton, когда:
- взаимодействие — это действие
Используйте Link, когда:
- взаимодействие в первую очередь ведёт на другую страницу
Главный компромисс: у иконки-кнопки семантика действия, а у ссылки — семантика навигации.
IconButton или ButtonBase
Используйте IconButton, когда:
- продукту явно нужен контракт размеров и раскладки иконки-кнопки
Используйте ButtonBase, когда:
- строится низкоуровневая собственная поверхность действия с иконкой
Выбирайте этот компонент, когда
- Действие строится вокруг иконки и хорошо понятно.
- Места мало.
- Интерфейсу всё равно нужна поверхность действия, похожая на кнопку.
- действие должно оставаться компактным, не превращаясь в общий низкоуровневый примитив
Не выбирайте этот компонент, когда
- Смысл действия неясен без видимого текста.
- Взаимодействие в первую очередь ведёт на другую страницу.
- Обычная кнопка сделала бы действие понятнее.
Решение проблем
Смысл действия неясен
Симптом
Пользователи видят иконку, но не понимают, что делает действие.
Вероятная причина
IconButton использован для действия, которому нужен видимый текст или более сильный контекст.
Как проверить
- Скройте окружающий контекст и проверьте, остаётся ли действие очевидным.
- Проверьте, имеет ли та же иконка устойчивый смысл в других местах продукта.
Решение
- Перейдите на
Button, если видимый текст делает действие понятнее. - Оставляйте вариант только с иконкой для привычных действий.
Нет доступного имени
Симптом
Кнопка визуально работает, но у неё нет понятной доступной подписи.
Вероятная причина
Не задан aria-label или другой поддерживаемый способ подписи.
Как проверить
- Изучите отрендеренную разметку.
- Проверьте инструментами доступности или выводом скринридера.
Решение
- Задайте явную доступную подпись.
Полиморфный IconButton ведёт себя странно
Симптом
Внешний вид иконки-кнопки рендерится, но дочерний элемент не поддерживает нужную семантику или пропсы.
Вероятная причина
asChild использован с несовместимым дочерним элементом.
Как проверить
- Изучите отрендеренный дочерний элемент.
- Проверьте, соответствует ли он нужной семантике действия или навигации.
Решение
- Используйте дочерний элемент, который поддерживает нужное поведение.
- Оставляйте рендер по умолчанию, когда полиморфизм не нужен.