GrAlert

  • ядро
  • Обратная связь
  • API · 10 props

Берут, когда сообщение относится к месту на странице.

import { GrAlert } from '@feugene/granularity/components/GrAlert'

Обзор

Когда брать

  • сообщение относится к месту на странице — предупреждение над формой, пояснение в разделе: оно живёт там же, где причина;
  • сообщение обязано остаться — тост уйдёт сам, а это читают столько, сколько нужно;
  • внутри есть действие — слот действий держит «Повторить», «Перейти к настройкам»;
  • сообщение появляется асинхронно — live объявляет его скринридеру, а не оставляет молча.

Когда взять другое

НужноБерите
Сообщение о результате действия, короткоеGrToaster
Ошибка ответа сервера со статусом и деталямиGrResponseErrorBanner
Ошибка одного поляGrFormField
На экране пусто, и надо объяснить почемуGrEmptyState
Требуется ответ пользователяGrConfirmDialog

Варианты все тона и виды — настоящим компонентом

Варианты · GrAlert
tone \ variantsoftoutline
primary
neutral
success
warning
danger
info
slate
azure

Матрица живая: наводите и нажимайте. Состояний наведения, фокуса и нажатия здесь нет — они за браузером, а не за пропом.

Playground контролы выводятся из API, а не пишутся руками

Сцена

Загружается…

0 изменено· состояние — в адресе

Примеры 6 у каждого — живое демо и его код

  • Предупреждение рядом с причиной

    Сообщение стоит в карточке оплаты, а не в углу экрана, и остаётся, пока с ним не разберутся, — в отличие от тоста. Заголовок — факт, текст — последствие, а слот #actions ставит выходы под текстом. «Напомнить через неделю» меняет предупреждение на заметку info той же формы.

    BillingBusiness plan · 18 seats
    Active
    Next invoice1 November · €522.00
    Payment methodVisa •••• 4242 · expires 10/26
  • Результат, который слышит диктор

    Одно сообщение, у которого меняются слова по итогу синхронизации: живой регион объявляет смену содержимого, а только что вставленный может пройти незамеченным. При live="auto" роль выбирает тон — warning и danger перебивают, success ждёт паузы. Запустите синхронизацию несколько раз: сервис отвечает по-разному.

    Fabrikam Books ConnectedInvoices and payments sync every hour.
    Last sync 2 hours ago
    214 invoices and 61 payments are in Fabrikam Books.
  • Тон, вес и значок, который называет предмет

    Тон и вариант — разные оси: инцидент — danger на тонированной подложке, плановые работы — outline и с ним не спорят. #icon меняет глиф на предмет — карту, ракету, часы. Сообщения, пришедшие вместе со страницей, — содержимое, а не события, поэтому у инцидента live="off".

    System statusUpdated 2 minutes ago
    Partial outage
    Card payments are delayed
    Charges go through, but receipts arrive up to 20 minutes late. We are working on it with the payment provider.
    Release 2026.10.6 is live
    Faster exports and the new invoice editor are on for every workspace.
    Maintenance on Saturday, 11 October
    02:00–03:00 UTC. Sign-in and the API stay up; exports pause for about ten minutes.
  • Два способа закрыть

    С v-model:visible крестик прячет сообщение, и больше никому знать не нужно. Только с @close это просьба: сообщение остаётся, решает экран — здесь он сначала спрашивает, потому что выключение сводок меняет пространство для всех.

    New: export to Excel
    Number formats and formulas survive the export. Find it under Reports → Export.
    AI summaries are on
    Every invoice and report opens with a three-line summary.

API порождается из пакета · разойтись не может

Props

PropTypeпо умолчаниюОписание
tone
"primary" | "neutral" | "success" | "warning" | "danger" | ""primary" | "neutral" | "success" | "warning" | "danger" | "info" | "slate" | "azure" | undefined
undefinedСмысл сообщения: цвет подложки и рамки, глиф иконки и — при `live="auto"` — роль для скринридера. `warning` и `danger` перебивают речь, остальные ждут паузы. По умолчанию `info`; глобально — `componentDefaults`.
variant"soft" | "outline" | undefinedundefinedВес: `soft` — тонированная подложка, `outline` — только рамка тона для спокойных пояснений рядом с другими сообщениями. По умолчанию `soft`.
titlestring | undefinedundefinedКороткий факт первой строкой: «Карта истекает через 12 дней». Подробности — в тексте под ним; без заголовка сообщение — одна строка текста.
closableboolean | undefinedundefinedКнопка закрытия. Сама она сообщение не прячет: эмитит `close` и `update:visible` — прятать ли, решает экран (см. `visible`).
liveGrAlertLive | undefinedundefinedКак сообщение объявляется скринридеру: `auto` — по тону, `assertive` — `role="alert"`, `polite` — `role="status"`, `off` — без роли, когда оно уже объявлено иначе. По умолчанию `auto`.
iconboolean | undefinedtrueПоказывать ли иконку тона. Своя иконка — слотом `#icon`; проп нужен для случая «иконка мешает»: узкая колонка, плотный список, сообщение в форме.
visiblev-modelboolean | undefinedtrueВидимость сообщения — **только контролируемая**: без пропа алерт виден всегда, и закрытие остаётся заботой потребителя (`@close`). С `v-model:visible` компонент прячет себя сам. Собственного состояния у пропа нет намеренно. Оно превратило бы кнопку закрытия в необратимое действие у всех, кто уже живёт на `@close` и, например, спрашивает по нему подтверждение.
backgroundColorstring | undefinedundefinedПодложка вместо тона — цвет бренда или партнёра. Раскладка, иконка и закрытие остаются прежними. Переменная `--gr-alert-bg` делает то же из CSS.
textColorstring | undefinedundefinedЦвет текста, заголовка и иконки вместо тона (`--gr-alert-*` в `tokens.md`).
borderColorstring | undefinedundefinedЦвет рамки вместо тона; у `outline` это главный цвет сообщения.

Слоты

SlotTypeОписание
defaultanyТекст сообщения.
iconanyИконка вместо глифа по тону. Декоративна: остаётся `aria-hidden`.
actionsanyДействия по сообщению: «Повторить», «Подробнее». Ложатся под текст.

События

EventСигнатураОписание
close(event: "close"): void—
update:visible(event: "update:visible", value: boolean): void—

Типы

Все экспортируемые типы подпути, по файлам, где они объявлены. Имена, дженерики и тела читаются из файлов деклараций пакета и разойтись не могут.

Импорт
import type { GrAlertTone, GrAlertLive, GrAlertProps } from '@feugene/granularity/components/GrAlert'

Файлdist/types/components/GrAlert/config.d.ts

grAlertConfigconst
const grAlertConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrAlert">;

Файлdist/types/components/GrAlert/GrAlert.vue.d.ts

GrAlertTonetype
type GrAlertTone = GrTone;
GrAlertLivetype

Режим объявления сообщения скринридеру. auto — по тону: warning/danger перебивают речь (role="alert"), остальные ждут паузы (role="status").

type GrAlertLive = 'auto' | 'assertive' | 'polite' | 'off';
GrAlertPropsinterface
interface GrAlertProps {
    /**
     * Смысл сообщения: цвет подложки и рамки, глиф иконки и — при `live="auto"` —
     * роль для скринридера. `warning` и `danger` перебивают речь, остальные ждут
     * паузы. По умолчанию `info`; глобально — `componentDefaults`.
     */
    tone?: GrAlertTone;
    /**
     * Вес: `soft` — тонированная подложка, `outline` — только рамка тона для
     * спокойных пояснений рядом с другими сообщениями. По умолчанию `soft`.
     */
    variant?: GrAlertVariant;
    /**
     * Короткий факт первой строкой: «Карта истекает через 12 дней». Подробности —
     * в тексте под ним; без заголовка сообщение — одна строка текста.
     */
    title?: string;
    /**
     * Кнопка закрытия. Сама она сообщение не прячет: эмитит `close` и
     * `update:visible` — прятать ли, решает экран (см. `visible`).
     */
    closable?: boolean;
    /**
     * Как сообщение объявляется скринридеру: `auto` — по тону, `assertive` —
     * `role="alert"`, `polite` — `role="status"`, `off` — без роли, когда оно уже
     * объявлено иначе. По умолчанию `auto`.
     */
    live?: GrAlertLive;
    /**
     * Показывать ли иконку тона. Своя иконка — слотом `#icon`; проп нужен для
     * случая «иконка мешает»: узкая колонка, плотный список, сообщение в форме.
     */
    icon?: boolean;
    /**
     * Видимость сообщения — **только контролируемая**: без пропа алерт виден
     * всегда, и закрытие остаётся заботой потребителя (`@close`). С
     * `v-model:visible` компонент прячет себя сам.
     *
     * Собственного состояния у пропа нет намеренно. Оно превратило бы кнопку
     * закрытия в необратимое действие у всех, кто уже живёт на `@close` и,
     * например, спрашивает по нему подтверждение.
     */
    visible?: boolean;
    /**
     * Подложка вместо тона — цвет бренда или партнёра. Раскладка, иконка и
     * закрытие остаются прежними. Переменная `--gr-alert-bg` делает то же из CSS.
     */
    backgroundColor?: string;
    /** Цвет текста, заголовка и иконки вместо тона (`--gr-alert-*` в `tokens.md`). */
    textColor?: string;
    /** Цвет рамки вместо тона; у `outline` это главный цвет сообщения. */
    borderColor?: string;
}
GrAlertEmitsinterface
interface GrAlertEmits {
    /** Нажата кнопка закрытия. Эмитится всегда, с `v-model:visible` и без него. */
    (e: 'close'): void;
    /** Пользователь закрыл сообщение (`v-model:visible`). */
    (e: 'update:visible', value: boolean): void;
}

Файлdist/types/components/GrAlert/defaults.d.ts

GrAlertConfigurablePropsinterface

Пропы GrAlert, настраиваемые глобально через <GrConfigProvider :component-defaults="{ GrAlert: { … } }">. live выбивается из правила «только оформление» (ср. GrButton/defaults.ts) намеренно: режим объявления скринридеру — решение уровня приложения, а не отдельного сообщения. Продукт, у которого алерты не должны перебивать речь, иначе обязан ставить live="polite" на каждый.

interface GrAlertConfigurableProps {
    tone: GrTone;
    variant: GrAlertVariant;
    closable: boolean;
    live: GrAlertLive;
}

Файлdist/types/components/GrAlert/grAlertStyles.d.ts

GrAlertVarianttype
type GrAlertVariant = typeof GR_ALERT_VARIANTS[number];

Использование из прозы библиотеки

Тон и вариант — разные оси

tone отвечает за цвет и смысл (info, success, warning, danger, slate, azure), variant — за вес: soft (тонированная подложка) или outline (только рамка). Любая комбинация осмысленна.

Цвета выражены токенами --gr-* целиком, поэтому сообщение одинаково корректно в светлой и тёмной теме. Точечная подгонка — пропы backgroundColor, textColor, borderColor либо переменные --gr-alert-* (см. tokens.md).

Как сообщение объявляется скринридеру

Ключевая роль здесь у live, и по умолчанию она выведена из тона:

liveЧто получает элементКогда
auto (по умолчанию)alert для warning/danger, status для остальныхобычный случай
assertiverole="alert" — перебивает чтениесообщение требует немедленной реакции
politerole="status" — дождётся паузысообщение можно дочитать позже
offроли нет вовсесообщение уже объявлено другим способом

Смысл дефолта: role="alert" прерывает речь, и вешать его на каждое информационное сообщение значит превращать спокойную подсказку в тревогу.

Режим настраивается глобально — приложению, которому алерты не должны перебивать речь, не нужно ставить проп на каждый:

vue
<GrConfigProvider :component-defaults="{ GrAlert: { live: 'polite' } }">

Через componentDefaults задаются также tone, variant и closable.

Иконка

По умолчанию глиф выбирается по тону. Слот #icon подменяет его, проп :icon="false" убирает:

vue
<GrAlert tone="success">
  <template #icon>
    <IconRocket />
  </template>
  Deploy finished.
</GrAlert>

<GrAlert tone="slate" :icon="false">
  Draft saved automatically.
</GrAlert>

Иконка декоративна в обоих случаях — она остаётся aria-hidden, потому что смысл несёт текст, а не картинка. Сообщение без иконки читается спокойнее и уместно там, где алертов много: плотная форма, список настроек.

Действия

Кнопки «Повторить», «Подробнее» кладутся в слот #actions, а не в текст: они получают своё место под сообщением и не разрывают фразу.

vue
<GrAlert tone="danger" title="Export failed" closable>
  The report service returned 502.

  <template #actions>
    <GrButton size="sm" tone="danger" @click="retry">Retry</GrButton>
    <GrButton size="sm" variant="outline" tone="danger">Open logs</GrButton>
  </template>
</GrAlert>
Закрытие: close против v-model:visible

closable добавляет кнопку. Дальше — выбор потребителя:

vue
<!-- сообщение остаётся, пока экран не решит иначе -->
<GrAlert closable @close="askConfirmation" />

<!-- сообщение прячет себя само -->
<GrAlert v-model:visible="shown" closable />

Собственного состояния у visible нет намеренно: без пропа алерт не исчезает по клику, а только сообщает о намерении событием close. Иначе кнопка закрытия стала бы необратимым действием у всех, кто по close спрашивает подтверждение или пишет отметку на сервер. close эмитится в обоих режимах.

Смежное
  • theming.md — роли цвета и суффиксы.
  • tokens.md — переменные --gr-alert-*.