Паттерны
Встроенная ссылка на источник
Когда использовать:
- Навигация естественно вписывается в предложение или справочный текст.
Заметки о композиции:
- Делайте текст ссылки описательным.
- Не прерывайте чтение расплывчатыми или слишком длинными фразами-ссылками.
Компромиссы:
- Хорошо подходит для документации и второстепенной навигации.
- Слабее подходит для основных действий.
import { Link, Text } from '@vega-ui/react';
export default function BasicUsage() {
return (
<Text size={3} style={{ width: '100%' }}>
Exports include every invoice from the selected period. Read how we calculate{' '}
<Link href='/docs/billing/taxes'>VAT for EU customers</Link>{' '}
before sharing the file with your accountant.
</Text>
);
}Самостоятельная второстепенная навигация
Когда использовать:
- Странице или панели нужна одна лёгкая второстепенная цель навигации.
Заметки о композиции:
- Делайте ссылку легко просматриваемой и ориентированной на место назначения.
- Добавляйте окружающий текст, когда контекст места назначения неочевиден.
Компромиссы:
- Небольшой визуальный вес.
- Её легче не заметить, чем кнопку.
import { Heading, Icon, Link } from '@vega-ui/react';
import { ArrowRightIcon } from '@vega-ui/icons';
import './examples.css';
const invoices = [
{ id: 'INV-2041', amount: '$1,240.00' },
{ id: 'INV-2040', amount: '$860.50' },
{ id: 'INV-2039', amount: '$2,115.00' },
];
export default function StandaloneNavigationLink() {
return (Ссылка в связке с роутером
Когда использовать:
- Приложение использует библиотеку маршрутизации, но хочет сохранить стилизацию ссылок VegaUI.
Заметки о композиции:
- Используйте
asChildс настоящим компонентом ссылки роутера. - Сохраняйте навигационную семантику у отрендеренного корня.
Компромиссы:
- Сохраняет единую стилизацию на разных слоях маршрутизации.
- Требует, чтобы дочерний компонент поддерживал ожидаемую семантику.
import { type AnchorHTMLAttributes, type MouseEvent, useState } from 'react';
import { Link } from '@vega-ui/react';
interface RouterLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
to: string
onNavigate(to: string): void
}
function RouterLink({ to, onNavigate, onClick, ...props }: RouterLinkProps) {
const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {
onClick?.(event);
event.preventDefault();Сравнение
Быстрое правило выбора
Используйте Link, когда основная задача — навигация.
Link и Button
Используйте Link, когда:
- взаимодействие ведёт на другую страницу, маршрут или раздел
Используйте Button, когда:
- взаимодействие выполняет действие или изменяет состояние
Главный компромисс: у ссылки семантика навигации, а у кнопки — семантика действия.
Link и Button asChild
Используйте Link, когда:
- достаточно оформления обычной текстовой ссылки
Используйте Button asChild, когда:
- навигация должна сохранять внешний вид кнопки
Главный компромисс: ссылка остаётся легче и текстовее, а кнопка-ссылка добавляет более выраженное оформление действия.
Link и Badge
Используйте Link, когда:
- текст должен куда-то вести
Используйте Badge, когда:
- интерфейсу нужны лишь компактные метаданные или метка статуса
Выбирайте этот компонент, когда
- Взаимодействие в первую очередь выполняет навигацию.
- Оформление текстовой ссылки подходит окружающему интерфейсу.
- Нужна встроенная или второстепенная навигация.
- интерфейс должен восприниматься как навигация, а не как команда
Не выбирайте этот компонент, когда
- Взаимодействие изменяет состояние.
- Видимая поверхность кнопки подходит лучше.
- Текст ссылки не описывает место назначения ясно.
Решение проблем
Ссылку, вероятно, стоит сделать кнопкой
Симптом
Взаимодействие выглядит нормально, но элемент выполняет действие, а не навигацию.
Вероятная причина
Link выбран для того, что изменяет состояние или отправляет данные.
Как проверить
- Спросите себя, что здесь главное: навигация или действие.
- Проверьте, меняет ли взаимодействие локальное или удалённое состояние.
Решение
- Используйте
Buttonдля действий. - Оставьте
Linkдля настоящей навигации.
Текст ссылки слишком расплывчатый
Симптом
По одному тексту пользователи не могут понять, куда ведёт ссылка.
Вероятная причина
Видимый текст общий, например «Нажмите здесь».
Как проверить
- Прочитайте текст ссылки без окружающих пояснений.
- Проверьте, понятно ли всё ещё место назначения.
Решение
- Перепишите текст ссылки так, чтобы он ясно описывал место назначения или результат.
Ссылка в связке с роутером теряет семантику
Симптом
Ссылка выглядит правильно, но отрендеренный дочерний элемент больше не ведёт себя как ссылка.
Вероятная причина
asChild использован с дочерним элементом, который не сохраняет семантику ссылки.
Как проверить
- Изучите отрендеренный корневой элемент.
- Проверьте, ведёт ли он себя по-прежнему как настоящая ссылка.
Решение
- Используйте компонент роутера, который сохраняет рендер и поведение ссылки.
- Оставьте рендер обычного якоря, когда полиморфизм не нужен.