Индикатор загрузки асинхронных операций. Показывает, что система обрабатывает запрос и пользователь должен подождать. Три размера для разных контекстов встраивания.
Размеры
SM · MD · LG
SM
16px · 2px stroke
MD
24px · 2.5px stroke
LG
36px · 3px stroke
Токены размеров
Size · Stroke · Цвет
Свойство
SM
MD
LG
Диаметр
16px
24px
36px
Stroke
2px
2.5px
3px
Скорость
700ms linear infinite — единая для всех размеров
Track
var(--ds-stroke-low) — Static/Border/Neutral-Blue/Low (mirror-aware, все 4 темы)
Спиннер по умолчанию появляется через 800ms после монтирования — это CSS-анимация ds-spinner-appear.
Быстрые операции (<800ms) — спиннер не успевает появиться, нет мерцания
Длинные операции (>800ms) — получают видимый индикатор
Управлять через CSS-переменную: --ds-spinner-delay
Немедленный показ: style="--ds-spinner-delay:0ms"
Демо · delay=0ms
Мгновенный показ
Применяется в кнопках и inline-контекстах — пользователь уже инициировал действие и ожидает реакцию.
SM
MD
LG
В контексте кнопки
Loading state · SM spinner
data-loading="center" — иконки слева нет → спиннер заменяет лейбл (лейбл скрыт visibility, ширина кнопки держится)
data-loading="slot" — иконка слева ЕСТЬ → спиннер занимает её место, лейбл остаётся видимым
В loading-состоянии кнопка получает data-disabled и aria-busy="true". Spinner внутри кнопки помечен aria-hidden="true" (пропс decorative, Spinner.tsx:35) — родительская кнопка уже объявляет состояние через aria-busy, и второй голос для скринридера был бы дублем.
Тёмная тема
data-theme="dark"
SM
16px
MD
24px
LG
36px
В кнопке
Dark mode
Track — --ds-stroke-low (Static/Border/Neutral-Blue/Low), индикатор — --ds-neutral-fill (Static/Surface/Neutral-Blue/Accent). Оба mirror-aware: корректно инвертируются во всех 4 темах.
Правила использования
Поведение · Доступность
Применение
Когда использовать
Кнопка loading state — вместо иконки слева при отправке формы
Inline в карточке — загрузка данных внутри блока (SM или MD)
Полностраничная загрузка — LG в центре пустого экрана
Skeleton замена — когда структура контента неизвестна заранее
Ограничения
Чего избегать
Не используй вместо Progress Bar для длинных операций с известным прогрессом
Не показывай несколько спиннеров одновременно на одном экране
Не используй для determinate-прогресса — только для async без известного %
Не убирай без уведомления — показывай результат (success/error состояние)
Доступность
ARIA паттерн
Standalone: role="status" + aria-label="Загрузка"
В кнопке: aria-hidden="true", роль не задаётся (кнопка объявляет aria-busy="true")
Скрытый текст для screen readers: <span class="sr-only">Загрузка...</span>
Кнопка в loading state: обязательно disabled — предотвращает двойную отправку
Размер под контекст
Выбор размера
SM (16px) — кнопки SM/MD, inline-индикаторы, тесные UI