GrLoading
Берут, когда контент уже есть и обновляется.
Обзор
Когда брать
- контент уже есть и обновляется — таблица перезапрашивается, форма отправляется: старое видно, но недоступно;
- ожидание короткое —
delayне показывает спиннер вовсе, если ответ пришёл быстро; - блокировать надо весь экран —
fullscreenна время операции, которую нельзя прерывать; - оверлей нужен императивно — директива
v-loadingвместо компонента в разметке.
Когда взять другое
| Нужно | Берите |
|---|---|
| Контента ещё нет вовсе | GrSkeleton |
| Известна доля выполненного | GrProgressBar / GrProgressCircle |
| Ожидание внутри кнопки | GrButton с loading |
| Загрузка файла | GrFileUpload |
Playground контролы выводятся из API, а не пишутся руками
Этот компонент живёт поверх экрана, а не внутри холста: его открывает экран, а конструктору открывать его неоткуда. Примеры ниже показывают его в работе.
0 изменено· состояние — в адресе
<GrLoading>Текст</GrLoading>Примеры 3 у каждого — живое демо и его код
Таблица, пересчитанная на месте
Слой ложится на ближайшего позиционированного предка, поэтому
relativeна блоке решает, докуда он дотянется: таблица ждёт, переключатель периода — нет, а старые цифры видны под подложкой.delayне даёт быстрому ответу — неделя приходит за 120 мс — мигнуть спиннером.Revenue by lineSubscriptions€76,900+6%Add-ons€9,450+3%Services€14,200+11%Карточка, заблокированная на время сохранения
v-loadingнакрывает карточку, на которой стоит, и блокирует её:aria-busyна карточке иinertна детях, чтобы Tab не уходил в поля, которых не видно. Опции — объектом: текст, задержка, — а фокус возвращается на место, когда слой закрывается.Payout accountWhere card payments are paid out every Monday. 13 / 18Переключение пространства
Переключение перезагружает всё, что держит приложение, поэтому ждёт весь экран: его накрывает
fullscreen. Слот по умолчанию заменяет спиннер тем, чего ждут, — каким пространство открывается.Workspaces
API порождается из пакета · разойтись не может
Props
| Prop | Type | по умолчанию | Описание |
|---|---|---|---|
text | string | undefined | undefined | Подпись под спиннером. Пустая строка убирает её совсем. По умолчанию — из локали. |
zIndexVar | string | undefined | undefined | Имя CSS-переменной слоя — escape-hatch мимо `--gr-z-loading`. |
spinner | Component | undefined | undefined | Свой компонент спиннера вместо иконки по умолчанию. |
spinnerClass | string | undefined | undefined | Дополнительные классы обёртки спиннера. |
spinnerSize | number | "xs" | "sm" | "md" | "lg" | undefined | 28 | Размер спиннера: шкала пакета либо произвольный в пикселях. |
spinnerTone | GrIconTone | undefined | "neutral" | Тон спиннера из палитры. |
animated | boolean | undefined | true | Вращение спиннера. По умолчанию включено. |
background | string | undefined | undefined | Свой `background-color`. Задан — дефолтный скрим `--gr-overlay-bg` снимается. |
fullscreen | boolean | undefined | false | Накрыть весь экран (`position: fixed`) вместо ближайшего позиционированного предка. |
delay | number | undefined | 0 | Задержка показа в миллисекундах: короткая загрузка не мигает оверлеем. |
customClass | string | undefined | undefined | Дополнительные классы корня оверлея. |
Слоты
| Slot | Type | Описание |
|---|---|---|
default | any | Содержимое панели целиком вместо спиннера с подписью. |
События
| Event | Сигнатура | Описание |
|---|---|---|
show | (event: "show"): void | — |
Типы
Все экспортируемые типы подпути, по файлам, где они объявлены. Имена, дженерики и тела читаются из файлов деклараций пакета и разойтись не могут.
import type { GrLoadingProps, GrLoadingEmits } from '@feugene/granularity/components/GrLoading'Файлdist/types/components/GrLoading/config.d.ts
const grLoadingConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrLoading">;Файлdist/types/components/GrLoading/safelist.d.ts
const grLoadingSafelist: string[];Файлdist/types/components/GrLoading/GrLoading.vue.d.ts
Пропы {@link GrLoading}.
Оверлей загрузки: спиннер с подписью поверх соседнего контента. fullscreen
накрывает весь экран, иначе оверлей ложится на ближайшего позиционированного
предка.
interface GrLoadingProps {
/** Подпись под спиннером. Пустая строка убирает её совсем. По умолчанию — из локали. */
text?: string;
/** Свой компонент спиннера вместо иконки по умолчанию. */
spinner?: Component;
/** Дополнительные классы обёртки спиннера. */
spinnerClass?: string;
/** Размер спиннера: шкала пакета либо произвольный в пикселях. */
spinnerSize?: GrIconSize | number;
/** Тон спиннера из палитры. */
spinnerTone?: GrIconTone;
/** Вращение спиннера. По умолчанию включено. */
animated?: boolean;
/** Свой `background-color`. Задан — дефолтный скрим `--gr-overlay-bg` снимается. */
background?: string;
/** Накрыть весь экран (`position: fixed`) вместо ближайшего позиционированного предка. */
fullscreen?: boolean;
/** Имя CSS-переменной слоя — escape-hatch мимо `--gr-z-loading`. */
zIndexVar?: string;
/** Задержка показа в миллисекундах: короткая загрузка не мигает оверлеем. */
delay?: number;
/** Дополнительные классы корня оверлея. */
customClass?: string;
}interface GrLoadingEmits {
/**
* Оверлей появился на экране — сразу или по истечении `delay`. По этому
* событию директива блокирует контент под оверлеем: до показа блокировать
* нечего, иначе быстрый запрос молча «замораживал» бы форму.
*/
(e: 'show'): void;
}Использование из прозы библиотеки
Два режима
По умолчанию оверлей ложится на ближайшего позиционированного предка — это
загрузка куска страницы. fullscreen накрывает весь экран: это загрузка уровня
приложения.
Директива режим выбирает сама: target = document.body → fullscreen, иначе
инлайновый. Контейнеру со position: static она временно ставит relative, а
контейнеру со скруглением — overflow: hidden, чтобы размытая подложка не
вылезала за скруглённую форму.
Задержка
delay (мс) откладывает показ. Запрос, ответивший быстрее задержки, не
показывает оверлей вовсе — мигание раздражает сильнее, чем отсутствие
индикации.
<GrLoading v-if="pending" :delay="200" />Отсчёт начинается с монтирования, то есть с момента старта загрузки. Пока он идёт, контент не блокируется: иначе быстрый запрос молча замораживал бы форму.
Доступность
Оверлей — role="status" с aria-live="polite": подпись читается диктором в
момент появления, не перебивая пользователя.
Визуального перекрытия недостаточно: без блокировки таб уходит в форму, которую
уже не видно, а диктор читает её как обычную. Директива поэтому в момент показа
объявляет контейнер aria-busy="true", а его остальным детям ставит inert —
поддерево целиком выпадает из таб-порядка, из событий указателя и из дерева
доступности. При закрытии inert снимается только с того, что поставила она
сама, и фокус возвращается туда, где был, если пользователь не увёл его сам.
Декларативный <GrLoading> соседями не распоряжается — он их не знает.
Нужна блокировка на этом же контейнере — берите директиву.
Фокус-ловушки внутри оверлея нет намеренно: ловить в нём нечего, а inert
соседей закрывает задачу целиком.
Слой
Полноэкранный режим сидит на токене --gr-z-loading (1150) — выше модалок,
потому что блокирует приложение целиком, и ниже тостов, чтобы не прятать
уведомление о фоновой ошибке. Инлайновый режим к шкале отношения не имеет:
z-10 — порядок внутри своего контейнера.
zIndexVar подменяет переменную слоя своей — escape-hatch того же вида, что у
useFloating. Сырого числа компонент не принимает: см. docs/z-index.md.
Скрим
Затемнение под панелью — роль темы --gr-overlay-bg, та же, что у GrModal и
GrDrawer: оверлей загрузки обязан выглядеть как остальные модальные слои и
менять плотность вместе с темой.
Проп background задаёт свой background-color и отменяет скрим целиком —
нужен, когда оверлей ложится на уже затемнённую поверхность.
Спиннер и содержимое
spinnerSize и spinnerTone идут через GrIcon — шкала иконок и токены
текста, а не пиксели в разметке. spinner подменяет саму иконку, animated
выключает вращение.
Слот заменяет содержимое панели целиком — прогресс с процентами, кнопку отмены долгой операции:
<GrLoading>
<GrProgressBar :value="percent" class="w-48" />
<GrButton size="xs" variant="outline" @click="abort">Отменить</GrButton>
</GrLoading>Подпись по умолчанию берётся из локали (gr.loading.defaultText); text
задаёт свою, пустая строка убирает совсем.
Директива
const controller = createLoading({ target: '#report', text: 'Считаем отчёт', delay: 200 })
controller.setText('Почти готово')
controller.close()v-loading принимает либо булево, либо объект опций (те же, что у компонента,
плюс target и fullscreen). Смена target или режима пересоздаёт оверлей,
всё остальное обновляется на месте.
Пропы этого примера