GrProgressBar

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

Берут, когда доля выполненного известна.

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

Обзор

Когда брать

  • доля выполненного известна — импорт, загрузка файла, шаг мастера: полоса отвечает «сколько осталось»;
  • конец неизвестен — indeterminate показывает, что процесс идёт, не обещая срока;
  • загружено больше, чем проиграно — buffer рисует второй слой: буферизация видео, предзагрузка;
  • значение надо показать словами — showValue с formatValue вместо отдельной подписи.

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

НужноБерите
Места по ширине нетGrProgressCircle
Доля неизвестна и контент уже естьGrLoading
Контента ещё нетGrSkeleton
Прогресс загрузки файловGrFileUpload
Показать долю от целого как данныеGrChartPie

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

tone

  • primary
  • neutral
  • success
  • warning
  • danger
  • info
  • slate
  • azure

Размеры

  • xs
  • sm
  • md
  • lg

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

Сцена

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

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

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

  • Ход в единицах читателя

    Импорт считает строки, и подпись тоже: format-value превращает долю в «1,140 of 3,000 rows» и отдаёт тот же текст в aria-valuetext. aria-label называет процесс — без него диктор произносит число без предмета. В конце тон становится вердиктом.

    Importing customerscustomers-2026-10.csv · matching by tax ID
    1,140 of 3,000 rows
  • Тон как вердикт

    Одна и та же полоса читается по-разному в зависимости от тона: primary — в графике, warning — под угрозой, danger — отстаём, success — готово, и бейдж рядом говорит то же. Значение показано у каждой полосы, поэтому подпись одной ширины и треки кончаются на одной линии.

    Q4 goals
    Move 40 customers to annual billingSales
    On track
    78%
    Cut invoice disputes below 2 %Finance
    At risk
    52%
    Ship the invoice editorProduct
    Done
    100%
    Answer support within 4 hoursSupport
    Off track
    31%
  • Итог и его части

    size задаёт вес: lg у итога, xs у частей под ним. Внутри карточки собственная рамка трека — вторая рамка, и borderless её убирает. В стопке полос значения уходят в свою колонку — подписи разной длины дали бы каждому треку свою ширину.

    StorageBusiness plan · deleted files are kept for 30 days
    38.2 of 50 GB
    Invoice PDFs
    21.4 GB
    Attachments
    11.2 GB
    Backups
    5.6 GB
  • Линия под шапкой, пока объём неизвестен

    Отчёт не знает, сколько продлится расчёт, и indeterminate ничего не обещает: полоса бежит, значение не объявляется. Тонкая линия xs без рамки лежит на краю шапки в гнезде, которое держит высоту и без неё, — отчёт не прыгает. При ограничении движения линия становится неподвижной нейтральной заливкой.

    Revenue by channelUpdated 10:42
    Web store€30,060.00
    Mobile app€17,320.00
    Resellers€7,210.00

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

Props

PropTypeпо умолчаниюОписание
tone
"primary" | "neutral" | "success" | "warning" | "danger" | ""primary" | "neutral" | "success" | "warning" | "danger" | "info" | "slate" | "azure" | undefined
"primary"Цветовая тональность заливки.
size"xs" | "sm" | "md" | "lg" | undefinedundefinedТолщина трека.
ariaLabelstring | undefinedundefinedМетка для скринридера (обязательна, если рядом нет видимого заголовка).
indeterminateboolean | undefinedfalseПрогресс неизвестен: полоса бежит, значение наружу не объявляется.
borderlessboolean | undefinedundefinedУбрать рамку трека: внутри карточки вторая рамка только шумит.
buffernumber | undefinedundefinedЗагружено с запасом: слой позади заливки, `0..100`. Не задан — слоя нет.
showValueboolean | undefinedfalseПоказать значение подписью справа от трека.
formatValue((value: number) => string) | undefinedundefinedСвой формат значения. Управляет и подписью, и `aria-valuetext`.
valueобязательныйnumber—Текущее значение `0..100`; выходящие за границы клампятся, нечисловое → `0`.

Типы

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

Импорт
import type { GrProgressBarProps, GrProgressBarConfigurableProps, GrProgressBarTone } from '@feugene/granularity/components/GrProgressBar'

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

GrProgressBarPropsinterface

Пропы {@link GrProgressBar}. Линейный индикатор прогресса: определённый режим по value и неопределённый по indeterminate, необязательный слой буфера и подпись значения.

interface GrProgressBarProps {
    /** Текущее значение `0..100`; выходящие за границы клампятся, нечисловое → `0`. */
    value: number;
    /** Загружено с запасом: слой позади заливки, `0..100`. Не задан — слоя нет. */
    buffer?: number;
    /** Прогресс неизвестен: полоса бежит, значение наружу не объявляется. */
    indeterminate?: boolean;
    /** Показать значение подписью справа от трека. */
    showValue?: boolean;
    /** Свой формат значения. Управляет и подписью, и `aria-valuetext`. */
    formatValue?: (value: number) => string;

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

grProgressBarConfigconst
const grProgressBarConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrProgressBar">;

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

grProgressBarSafelistconst
const grProgressBarSafelist: string[];

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

GrProgressBarConfigurablePropsinterface

Пропы GrProgressBar, настраиваемые глобально через componentDefaults.

interface GrProgressBarConfigurableProps {
    size: GrComponentSize;
    borderless: boolean;
}

Файлdist/types/components/GrProgressBar/grStyle.d.ts

GrProgressBarTonetype
type GrProgressBarTone = GrTone;
GrProgressBarSizetype
type GrProgressBarSize = GrComponentSize;

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

Когда прогресс неизвестен
vue
<GrProgressBar :value="percent" :indeterminate="!sizeKnown" aria-label="Импорт" />

indeterminate побеждает value: полоса бежит, aria-valuenow и aria-valuetext не выставляются вовсе — по спецификации это и есть признак неопределённости, отдельного aria-busy не нужно. Подпись значения в этом режиме не рендерится: показывать нечего.

Это самый частый сценарий прогресса — запрос ушёл, а размер ответа сервер не сообщил. GrFileUpload включает режим сам, когда у XHR нет lengthComputable.

Под prefers-reduced-motion: reduce полоса не замирает, а становится нейтральной заливкой на всю ширину (--gr-progress-indeterminate-bg). Замерший кадр бегущей полосы лёг бы у левого края и читался как «прогресс 40%», то есть врал бы о состоянии; заливка на всю ширину говорит «работа идёт, значение неизвестно» и не притворяется ни нулём, ни завершением. Период пробега — --gr-progress-indeterminate-duration. Общий контракт движения — motion.md.

Подпись значения
vue
<GrProgressBar :value="percent" show-value aria-label="Загрузка" />

<GrProgressBar :value="percent" :format-value="v => `${gb(v)} из 32 ГБ`" show-value />

showValue печатает целые проценты справа от трека. Подпись фиксированной ширины и с табличными цифрами: переход 9% → 10% не должен дёргать трек.

formatValue управляет и подписью, и aria-valuetext — «184 из 512 МБ» вместо голого «36». Без своего формата aria-valuetext не выставляется: «36» при aria-valuemax="100" диктор уже читает как проценты, дублировать это текстом незачем. Формат работает и без showValue — тогда он остаётся только для скринридера.

Буфер
vue
<GrProgressBar :value="played" :buffer="buffered" aria-label="Воспроизведение" />

Второй слой позади заливки: воспроизведено против загруженного в буфер, залито против подтверждённого сервером. Клампится по тем же правилам, что value (0..100, NaN → 0), и не обязан быть больше значения — слой просто окажется короче заливки.

Буфер не наследует tone и красится одним --gr-progress-buffer-bg: -light-роли есть не у всех восьми тонов, а нейтральный слой между треком и заливкой читается у любого из них.

Значение вне диапазона

value и buffer клампятся в 0..100, любое нечисловое значение превращается в 0. Полоса, которой отдали -5 или 140, не ломает раскладку и не отдаёт наружу невалидный aria-valuenow — это осознанная граница, а не побочный эффект.

Сюда же попадает не доехавший обязательный value: полоса рисуется пустой, aria-valuenow="0", а в dev-режиме компонент печатает предупреждение. Молчать здесь нельзя — aria-valuenow="NaN" диктор читает, и это нарушение axe.

Оформление

size — xs…lg, читается из GrConfigProvider; для линейной полосы это толщина трека и кегль подписи, ширину задаёт контейнер. Тон заливки — tone из палитры пакета.

borderless снимает рамку трека и тоже читается из GrConfigProvider. Рамка нужна на голом фоне, где трек --gr-muted почти не отличается от страницы; внутри карточки она становится второй рамкой рядом с её собственной.

Точечная кастомизация — переменные --gr-progress-bg (и по одной на каждый тон), --gr-progress-buffer-bg, --gr-progress-indeterminate-bg, --gr-progress-indeterminate-duration. Полный список — tokens.md.

Доступное имя

role="progressbar" стоит на треке, ariaLabel — единственный способ дать полосе имя: соседний заголовок именем не считается. Внутри GrFileUpload метку подставляет сам загрузчик.