GrLoading

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

Берут, когда контент уже есть и обновляется.

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

Обзор

Когда брать

  • контент уже есть и обновляется — таблица перезапрашивается, форма отправляется: старое видно, но недоступно;
  • ожидание короткое — delay не показывает спиннер вовсе, если ответ пришёл быстро;
  • блокировать надо весь экран — fullscreen на время операции, которую нельзя прерывать;
  • оверлей нужен императивно — директива v-loading вместо компонента в разметке.

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

НужноБерите
Контента ещё нет вовсеGrSkeleton
Известна доля выполненногоGrProgressBar / GrProgressCircle
Ожидание внутри кнопкиGrButton с loading
Загрузка файлаGrFileUpload

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

Сцена

Этот компонент живёт поверх экрана, а не внутри холста: его открывает экран, а конструктору открывать его неоткуда. Примеры ниже показывают его в работе.

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

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

  • Таблица, пересчитанная на месте

    Слой ложится на ближайшего позиционированного предка, поэтому relative на блоке решает, докуда он дотянется: таблица ждёт, переключатель периода — нет, а старые цифры видны под подложкой. delay не даёт быстрому ответу — неделя приходит за 120 мс — мигнуть спиннером.

    Revenue by line
    Subscriptions€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

PropTypeпо умолчаниюОписание
textstring | undefinedundefinedПодпись под спиннером. Пустая строка убирает её совсем. По умолчанию — из локали.
zIndexVarstring | undefinedundefinedИмя CSS-переменной слоя — escape-hatch мимо `--gr-z-loading`.
spinnerComponent | undefinedundefinedСвой компонент спиннера вместо иконки по умолчанию.
spinnerClassstring | undefinedundefinedДополнительные классы обёртки спиннера.
spinnerSizenumber | "xs" | "sm" | "md" | "lg" | undefined28Размер спиннера: шкала пакета либо произвольный в пикселях.
spinnerToneGrIconTone | undefined"neutral"Тон спиннера из палитры.
animatedboolean | undefinedtrueВращение спиннера. По умолчанию включено.
backgroundstring | undefinedundefinedСвой `background-color`. Задан — дефолтный скрим `--gr-overlay-bg` снимается.
fullscreenboolean | undefinedfalseНакрыть весь экран (`position: fixed`) вместо ближайшего позиционированного предка.
delaynumber | undefined0Задержка показа в миллисекундах: короткая загрузка не мигает оверлеем.
customClassstring | undefinedundefinedДополнительные классы корня оверлея.

Слоты

SlotTypeОписание
defaultanyСодержимое панели целиком вместо спиннера с подписью.

События

EventСигнатураОписание
show(event: "show"): void—

Типы

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

Импорт
import type { GrLoadingProps, GrLoadingEmits } from '@feugene/granularity/components/GrLoading'

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

grLoadingConfigconst
const grLoadingConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrLoading">;

Файлdist/types/components/GrLoading/safelist.d.ts

grLoadingSafelistconst
const grLoadingSafelist: string[];

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

GrLoadingPropsinterface

Пропы {@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;
}
GrLoadingEmitsinterface
interface GrLoadingEmits {
    /**
     * Оверлей появился на экране — сразу или по истечении `delay`. По этому
     * событию директива блокирует контент под оверлеем: до показа блокировать
     * нечего, иначе быстрый запрос молча «замораживал» бы форму.
     */
    (e: 'show'): void;
}

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

Два режима

По умолчанию оверлей ложится на ближайшего позиционированного предка — это загрузка куска страницы. fullscreen накрывает весь экран: это загрузка уровня приложения.

Директива режим выбирает сама: target = document.body → fullscreen, иначе инлайновый. Контейнеру со position: static она временно ставит relative, а контейнеру со скруглением — overflow: hidden, чтобы размытая подложка не вылезала за скруглённую форму.

Задержка

delay (мс) откладывает показ. Запрос, ответивший быстрее задержки, не показывает оверлей вовсе — мигание раздражает сильнее, чем отсутствие индикации.

vue
<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 выключает вращение.

Слот заменяет содержимое панели целиком — прогресс с процентами, кнопку отмены долгой операции:

vue
<GrLoading>
  <GrProgressBar :value="percent" class="w-48" />
  <GrButton size="xs" variant="outline" @click="abort">Отменить</GrButton>
</GrLoading>

Подпись по умолчанию берётся из локали (gr.loading.defaultText); text задаёт свою, пустая строка убирает совсем.

Директива
ts
const controller = createLoading({ target: '#report', text: 'Считаем отчёт', delay: 200 })
controller.setText('Почти готово')
controller.close()

v-loading принимает либо булево, либо объект опций (те же, что у компонента, плюс target и fullscreen). Смена target или режима пересоздаёт оверлей, всё остальное обновляется на месте.