GrProgressCircle
Берут, когда места по ширине нет.
Обзор
Когда брать
- места по ширине нет — плитка дашборда, ячейка, карточка показателя;
- значение важнее хода — число в центре читается как показатель, а не как ожидание;
- нужна шкала-«спидометр» —
shapeразрывает кольцо, когда так понятнее; - состояние нужно значком —
statusIconзаменяет число на успех или отказ по завершении.
Когда взять другое
| Нужно | Берите |
|---|---|
| Места по ширине хватает | GrProgressBar |
| Доля неизвестна, контент уже есть | GrLoading |
| Число без шкалы | GrStatistic |
| Доли нескольких частей целого | GrChartPie |
Варианты все тона и виды — настоящим компонентом
tone \ shape | circle | dashboard |
|---|---|---|
primary | ||
neutral | ||
success | ||
warning | ||
danger | ||
info | ||
slate | ||
azure |
Размеры
xssmmdlg
Playground контролы выводятся из API, а не пишутся руками
Загружается…
0 изменено· состояние — в адресе
<GrProgressCircle :value="72" showValue />Примеры 5 у каждого — живое демо и его код
Квоты там, где полосе нет места
Кольцо помещается в плитку рядом с подписью, а
show-valueставит долю внутрь — без числа кольцо читается украшением. Тон — вердикт: спокойный до 80 %, дальшеwarning, у потолкаdanger. Видимого заголовка у кольца нет, поэтому имя даётaria-label.Business planLimits reset in 12 days46%Storage23 of 50 GB85%Seats17 of 20 members98%API calls today98,120 of 100,000Отмена в центре, вердикт в конце
Слот по умолчанию владеет центром — здесь кнопка отмены, пока файл грузится. Она стоит рядом с ролью
progressbar, а не внутри неё, и для диктора остаётся кнопкой; слой центра указатель не ловит, кнопка включает его себе обратно. В концеstatus-iconпоказывает галочку, а наdanger— крест.Attachmentsscan-invoice-0418.pdf0.9 of 2.4 MB · 36%contract-northwind.pdf1.1 MB · uploadedreceipt-lunch.heicConnection lost at 52% — try againШкалы на карточке сервера
shape="dashboard"раскрывает кольцо снизу: шкала читается как измерение, а не как задача, идущая к концу.format-valueговорит в единицах читателя и становится заодноaria-valuetext; слот получает клампнутое значение и рисует две строки;thicknessутончает обводку.api-eu-2c6g.xlarge · Frankfurt · last 5 minutesHigh memoryCPU · 4 cores38%Memory · of 16 GB13.0 GBDisk · /var/lib128of 200 GBСначала неизвестно, потом известно
Пока экспорт считает счета, его объём неизвестен, и
indeterminateкрутит кольцо, не объявляя значения, — кольцо, замершее на нуле, читалось бы зависшей задачей. Потом доля заполняется, аstatus-iconпревращает сто процентов в галочку. В живой регион идёт только смена фазы, а не каждый процент.Export 214 invoicesSeptember 2026 · Excel with line items
API порождается из пакета · разойтись не может
Props
| Prop | Type | по умолчанию | Описание |
|---|---|---|---|
tone |
| undefined | Цветовая тональность дуги. |
size | "xs" | "sm" | "md" | "lg" | undefined | undefined | Диаметр кольца по шкале пакета. |
ariaLabel | string | undefined | undefined | Метка для скринридера (обязательна, если рядом нет видимого заголовка). |
value | number | undefined | 0 | Текущее значение `0..100`; выходящие за границы клампятся, `NaN` → `0`. |
shape | "circle" | "dashboard" | undefined | undefined | Замкнутое кольцо или дуга с вырезом снизу. |
indeterminate | boolean | undefined | false | Прогресс неизвестен: дуга бежит по кругу, значение наружу не объявляется. |
thickness | number | undefined | undefined | Толщина обводки в процентах диаметра. Не задана — по ступени `size`. |
showValue | boolean | undefined | false | Показать значение в центре кольца. Слот по умолчанию сильнее. |
formatValue | ((value: number) => string) | undefined | undefined | Свой формат значения. Управляет и подписью, и `aria-valuetext`. |
statusIcon | boolean | undefined | false | На завершении — галочка, при `tone="danger"` — крест вместо значения. |
trackless | boolean | undefined | undefined | Убрать дорожку: поверх картинки пустая часть кольца только шумит. |
Слоты
| Slot | Type | Описание |
|---|---|---|
default | { value: number; } | Содержимое центра вместо значения: иконка, две строки, кнопка отмены. |
Типы
Все экспортируемые типы подпути, по файлам, где они объявлены. Имена, дженерики и тела читаются из файлов деклараций пакета и разойтись не могут.
import type { GrProgressCircleProps, GrProgressCircleShape, GrArcGeometry } from '@feugene/granularity/components/GrProgressCircle'Файлdist/types/components/GrProgressCircle/GrProgressCircle.vue.d.ts
Пропы {@link GrProgressCircle}.
Круговой индикатор: определённый режим по value, неопределённый по
indeterminate, замкнутое кольцо или дуга-«дашборд».
interface GrProgressCircleProps {
/** Текущее значение `0..100`; выходящие за границы клампятся, `NaN` → `0`. */
value?: number;
/** Прогресс неизвестен: дуга бежит по кругу, значение наружу не объявляется. */
indeterminate?: boolean;
/** Замкнутое кольцо или дуга с вырезом снизу. */
shape?: GrProgressCircleShape;
/** Показать значение в центре кольца. Слот по умолчанию сильнее. */
showValue?: boolean;
/** Свой формат значения. Управляет и подписью, и `aria-valuetext`. */
formatValue?: (value: number) => string;Файлdist/types/components/GrProgressCircle/geometry.d.ts
type GrProgressCircleShape = typeof GR_PROGRESS_CIRCLE_SHAPES[number];interface GrArcGeometry {
/** Радиус с поправкой на толщину: обводка рисуется по обе стороны линии. */
radius: number;
circumference: number;
/** Длина дорожки — вся окружность либо её часть у «дашборда». */
arcLength: number;
/** `stroke-dasharray` дорожки. */
trackDashArray: string;
/** `stroke-dasharray` дуги значения. */
valueDashArray: string;
rotation: number;
}Файлdist/types/components/GrProgressCircle/grProgressCircleStyles.d.ts
type GrProgressCircleTone = GrTone;type GrProgressCircleSize = GrComponentSize;Файлdist/types/components/GrProgressCircle/config.d.ts
const grProgressCircleConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrProgressCircle">;Файлdist/types/components/GrProgressCircle/safelist.d.ts
const grProgressCircleSafelist: string[];Файлdist/types/components/GrProgressCircle/defaults.d.ts
Пропы GrProgressCircle, настраиваемые глобально через componentDefaults.
Только оформление: значение и режим принадлежат конкретному экземпляру.
interface GrProgressCircleConfigurableProps {
size: GrProgressCircleSize;
tone: GrProgressCircleTone;
shape: GrProgressCircleShape;
trackless: boolean;
}Файлdist/types/components/GrProgressCircle/index.d.ts
type GrProgressCircleInstance = ComponentExposed<typeof GrProgressCircleComponent>;Использование из прозы библиотеки
Центр лежит рядом с ролью, а не внутри неё
Разметка нарочно двухслойная: role="progressbar" несёт только SVG, а
содержимое центра — его сосед с абсолютным позиционированием.
Причина не косметическая. Роль-виджет объявляет своих потомков
презентационными, и кнопка «Отменить» внутри кольца — первый же сценарий
аплоада — оказалась бы nested-interactive: скринридер потерял бы и кнопку, и
индикатор. Слот центра обязан оставаться местом, куда можно положить что
угодно, включая интерактив.
Сам слой центра не ловит указатель (pointer-events: none) — иначе он накрыл
бы кольцо; интерактив внутри включает события себе обратно.
Значение, иконка, слот
Приоритет содержимого центра: слот → иконка итога → значение.
showValueпечатает проценты,formatValueзадаёт свой текст и заодноaria-valuetext;statusIconменяет число на галочку приvalue >= 100и на крест приtone="danger"— то есть только в терминальных состояниях;- слот по умолчанию получает уже клампнутое значение и перебивает оба варианта.
Пустой слот (например, кнопка под
v-if) центр не занимает — считается содержимое, а не факт передачи слота.
Значение в центре помещается начиная с sm; на xs его либо не показывают,
либо уменьшают кегль токеном --gr-progress-circle-value-size.
Формы
circle — замкнутое кольцо, отсчёт с двенадцати часов по часовой.
dashboard — три четверти окружности с вырезом строго снизу: под значением
освобождается место для подписи, а шкала читается как спидометр. Значение в
обеих формах означает одно и то же — доля пройденного, — меняется только длина
дорожки.
Тона общие с полосой
Дуга красится теми же переменными, что и GrProgressBar
(--gr-progress-bg, --gr-progress-success-bg и соседи): слой темизации у
прогресса один, и потребитель, перекрасивший его, ждёт, что круг и полоса
сойдутся. Каждая переменная берётся с фолбэком на роль темы — при гранулярном
импорте одного круга покомпонентная тема полосы не подключается, и без фолбэка
дуга осталась бы без цвета.
Своя у круга только геометрия: --gr-progress-circle-size,
--gr-progress-circle-track, --gr-progress-circle-cap,
--gr-progress-circle-value-size.
Неизвестный прогресс
indeterminate пускает дугу по кругу и не объявляет значения:
aria-valuenow не выставляется, подпись не печатается.
Под prefers-reduced-motion компонент показывает замкнутое нейтральное кольцо,
а не останавливает вращение. Остановленная четверть дуги читалась бы как
«прогресс 25 %» — тот же довод, по которому у GrProgressBar своя ветка
reduce, а не общий кламп анимаций.
Границы
bufferне переносится с полосы: слой «загружено с запасом» читается на шкале, которую видно слева направо целиком; на кольце две вложенные дуги выглядят одной толстой;- размер только по шкале пакета — пиксельный escape-hatch есть ровно у
GrAvatarиGrIcon; точечная подгонка идёт через--gr-progress-circle-size, а геометрия дуги считается в единицахviewBoxи от диаметра не зависит; - градиента по дуге нет — он требует
<linearGradient>со своимidв каждом экземпляре, то есть ещё одного источника расхождений гидрации; - сегментов и рисок нет — кольцо с делениями это индикатор шагов, а не прогресса.
Пропы этого примера