Перейти к содержимому

alert —— Предупреждение

Alert — это «приколоченная к странице подсказка»: причина неудачного сохранения, истекающая срок действия учётной записи, текущий режим «только чтение». Его отличие от message — постоянство: message исчезает через несколько секунд, а alert остается на месте, пользователь может прочитать его когда угодно. core/alert предельно тонок, суть — отображение семантики на роли live region.

  • Реализация <LhAlert> на каждой платформе: сводка ошибок формы, объявление на уровне страницы, постоянно висящая подсказка о результате операции, разъяснительное пояснение.
  • Сценарии, где содержимое должно быть прочитано пользователем по своей инициативе и не исчезает со временем.
  • Не следует использовать: мгновенная обратная связь по операции (используйте message, автоисчезновение сдержаннее); системные асинхронные уведомления (используйте notification, крепится к углу и не занимает место в потоке документа); операции, требующие подтверждения пользователем (используйте popconfirm / dialog).
import {
getAlertClassNames,
getAlertRole,
getAlertIconName,
} from '@lh-ui/share/core/alert'
import type { LhAlertType, LhAlertState, LhAlertRole } from '@lh-ui/share/core/alert'

Двухролевое отображение: warning / danger → role="alert" (немедленно прерывает чтение), info / success → role="status" (мягкое чтение в очереди). У этого разделения есть основание: APG (ARIA Authoring Practices) прямо указывает, что alert применяется для «важного и чувствительного ко времени» контента. Ошибку, которую пользователь увидит на 5 секунд позже, он может уже успеть повторить, а успешная подсказка ничем не грозит.

Четыре булевых состояния — независимые классы: closable / showIcon / plain / withTitle получают каждый свой модификатор — потому что они влияют на раскладку (под иконку нужно оставить место, под заголовок — увеличить вертикальные отступы, под кнопку закрытия — место справа), а не просто меняют цвет. Разделение на независимые классы позволяет SCSS писать раскладку под комбинации.

plain — плоский режим: убирает фон и рамку, оставляя только цвет иконки и текста — для сценариев «не хочется слишком выпячивать, но нужно постоянное присутствие» (например, серая полоса пояснения вверху страницы). Его отличие от режима по умолчанию — визуальный вес, а не семантика.

Отображение иконок потребляет существующий набор: success → check (не success — в наборе иконок нет иконки success, успех выражается галочкой), danger → error. Это отдельный слой отображения «семантика → конкретная иконка», UI-слою не нужно знать, что именно есть в наборе иконок.

Функция Сигнатура Возврат Назначение
getAlertClassNames (state: LhAlertState) => string[] классы тип + 4 булева состояния
getAlertRole (type: LhAlertType) => LhAlertRole ‘alert’ | ‘status’ роль live region
getAlertIconName (type: LhAlertType) => string имя иконки четыре семантических иконки
export type LhAlertType = 'info' | 'success' | 'warning' | 'danger'
export type LhAlertRole = 'alert' | 'status'
export interface LhAlertState {
type: LhAlertType
closable: boolean // показывать кнопку закрытия
showIcon: boolean // показывать семантическую иконку
plain: boolean // плоский режим (без фона и рамки)
withTitle: boolean // есть заголовок (двухчастные заголовок + описание)
}
getAlertRole('info') // 'status'
getAlertRole('success') // 'status'
getAlertRole('warning') // 'alert'
getAlertRole('danger') // 'alert'
  • role вешается на корневой элемент alert: <div class="lh-alert lh-alert--danger" role="alert">. alert, существующий при загрузке страницы, будет прочитан немедленно; динамически вставленному alert для надёжности добавляют aria-live (часть скринридеров непоследовательно реагирует на динамически вставленный role=alert).
  • Иконка с aria-hidden: семантика уже передана текстом, повторное чтение «предупреждение» — это шум. Иконка раскрывается только если несёт информацию, которой нет в тексте.
  • Доступность кнопки закрытия: aria-label="Закрыть", после нажатия alert удаляется из DOM — само удаление не требует дополнительного уведомления (прямой результат действия пользователя).
  • Иерархия заголовка и описания: при наличии заголовка он размечается как <div class="lh-alert__title" role="heading"> (или просто <h4>), описание идёт отдельным абзацем. Скринридер обрабатывает поток документа как есть.
  • Не используйте alert для ошибок валидации формы: ошибки полей должны быть рядом с полем (aria-describedby + aria-invalid в form), а alert — для сводной подсказки по всей форме.
import { getAlertClassNames, getAlertRole, getAlertIconName } from '@lh-ui/share/core/alert'
getAlertClassNames({ type: 'warning', closable: true, showIcon: true, plain: false, withTitle: false })
// ['lh-alert', 'lh-alert--warning', 'lh-alert--closable', 'lh-alert--show-icon']
getAlertRole('danger') // 'alert'
getAlertIconName('success') // 'check'
<!-- Vue3: базовое использование -->
<template>
<LhAlert type="warning" :closable="true" show-icon title="Внимание">
Идёт окно технического обслуживания, часть функций может быть недоступна.
</LhAlert>
</template>
<!-- Сводка ошибок формы: рендерится только при непустом failedRules -->
<template>
<LhAlert
v-if="failedRules.length"
type="danger"
show-icon
:closable="false"
title="В форме есть N полей, требующих исправления"
>
<ul>
<li v-for="rule in failedRules" :key="rule.field">{{ rule.message }}</li>
</ul>
</LhAlert>
</template>
// React: управляемое отображение (visible state + кнопка закрытия onClick ставит false);
// содержимое alert лучше оставить в DOM ради SEO и обратной совместимости — переключаем через CSS display, а не размонтированием
// uniapp: <view> + семантическая иконка через <image> или шрифтовой значок; closable в минипрограмме — catchtap
Класс Семантика
.lh-alert корневой контейнер
.lh-alert--{info|success|warning|danger} семантический тип (фон + рамка + цвет иконки)
.lh-alert--closable есть кнопка закрытия (место справа)
.lh-alert--show-icon есть иконка (место слева)
.lh-alert--plain плоский режим (прозрачный фон, без рамки)
.lh-alert--with-title двухчастный (увеличенные вертикальные отступы)
.lh-alert__icon / __title / __content / __close иконка / заголовок / описание / кнопка закрытия

Семантические цвета: --lh-info-color / --lh-success-color / --lh-warning-color / --lh-danger-color; светлый фон получается смешиванием семантического цвета с низкой прозрачностью (отдельный набор для светлой и тёмной темы); скругление --lh-border-radius-base.

  • alert — часть потока документа: он занимает место в раскладке и сдвигает содержимое. Постоянно висящий вверху страницы alert сдвигает весь контент — фиксия положения (position: sticky) остаётся на усмотрение UI-слоя, core этим не занимается.
  • Прерывистость role="alert" — палка о двух концах: несколько одновременно висящих danger alert будут прерывать чтение друг за другом, это очень плохой опыт. В сценарии сводки ошибок лучше показывать один alert со списком всех проблем, а не заводить отдельный alert на каждую ошибку.
  • Динамически вставленный alert: role=alert предполагает, что элемент уже находится в DOM в момент чтения; вставленный через JS следует дублировать aria-live="assertive" (alert) или "polite" (status). Это задача UI-слоя.
  • closable и персистентность состояния: alert, закрытый пользователем, воскреснет после перезагрузки страницы. Если нужно «больше не показывать после закрытия» (например, объявление прочитано), бизнес-слой обязан сохранить флаг в localStorage.
  • Семантика plain-режима не меняется: плоский режим меняет только визуал, а role и цвет иконки, определяемые type, остаются — не нужно ради «неприметности» понижать danger до info, это семантическое понижение.
  • Внутри alert не размещаем интерактивные кнопки: если нужны «повторить» или «подробнее», кнопка в __content вполне допустима (role alert не запрещает взаимодействия), но не имитируйте диалоговое окно через alert.
@lh-ui/share/core/alert → getAlertRole( )
返回值
(填好参数后点运行)

Copyright © 2024-2026 FengMo WenXue