Skeleton

Пакет @cloud-ru/ds-skeleton предоставляет примитивы для индикации загрузки: блочный Skeleton, многострочный SkeletonText и контейнер-переключатель WithSkeleton, который сам выбирает, что показывать — скелетон или реальный контент.

Демо

Preview
Prop
Type
Value
borderRadius
text
data-test-id
text
height
text
loading
boolean
width
text
Code
<Skeleton loading width={240} height={24} borderRadius={4} />

Когда использовать

  • Когда данные подгружаются асинхронно и отображение контента задерживается более 200 мс.
  • Чтобы зарезервировать место под контент и избежать layout shift при появлении данных.
  • Для списков, карточек и текстовых блоков — как визуальная подсказка «идёт загрузка».

Когда не нужен скелетон: для мгновенных переходов (< 200 мс), для обычных спиннеров поверх модальных окон (используйте Loader), для пустых состояний (используйте EmptyState).

Секция описывает семантику и поведение скелетонов в макетах.

Анатомия

Variant

Типографическая роль строки для SkeletonText: display, headline, title, label, body — совпадают с осями Typography и задают высоту/межстрочник плейсхолдера.

Size

Размер текста: s, m, l — подбирается под размер реального контента, который заменяет скелетон.

Align

Выравнивание хвостовой (неполной) строки в SkeletonText: left — хвост слева, right — справа.

Установка

pnpm add @cloud-ru/ds-skeleton
import { Skeleton, SkeletonText, WithSkeleton } from '@cloud-ru/ds-skeleton'

Примеры использования

1. Блок фиксированного размера

1. Блок фиксированного размераПрямоугольник под аватарку/картинку
tsx
import { Skeleton } from '@cloud-ru/ds-skeleton';

export function Block() {
  return <Skeleton loading width={240} height={24} borderRadius={4} />;
}

2. Круглый блок

2. Круглый блокborderRadius=50% — под аватар
tsx
import { Skeleton } from '@cloud-ru/ds-skeleton';

export function Circle() {
  return <Skeleton loading width={48} height={48} borderRadius='50%' />;
}

3. Текстовые строки

3. Текстовые строкиlines контролирует количество строк; variant × size задают типографику
tsx
import { SkeletonText } from '@cloud-ru/ds-skeleton';

export function TextLines() {
  return <SkeletonText loading lines={3} variant='body' size='m' />;
}

4. Переключение loading → content

4. Переключение loading → contentWithSkeleton рендерит skeleton при loading=true, иначе — children
tsx
import { SkeletonText, WithSkeleton } from '@cloud-ru/ds-skeleton';

export function WithToggle() {
  const loading = true;
  return (
    <WithSkeleton loading={loading} skeleton={<SkeletonText loading lines={2} variant='body' size='m' />}>
      <p>Реальный контент после загрузки.</p>
    </WithSkeleton>
  );
}

Props

Skeleton

Types

PropsSkeletonProps
PropTypeDefaultRequiredDescription
borderRadiusBorderRadius<string | number>noРадиус скругления. Можно указать значение допустимое для CSSProperty.borderRadius (пример `'10px'`, `'50%'` и т.д)
childrenstring | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefinedno
classNamestringno
data-test-idstringno
heightHeight<string | number>noВысота блока. Можно указать значение допустимое для CSSProperty.height (пример `'60%'`, `'400px'` и т.д)
loadingbooleannoФлаг состояния загрузки. Если значение true, будет отрисован блок скелетона, если false - children.
widthWidth<string | number>noШирина блока. Можно указать значение допустимое для CSSProperty.width (пример `'60%'`, `'400px'` и т.д)

Types

SkeletonProps

SkeletonText

Types

PropsSkeletonTextProps
PropTypeDefaultRequiredDescription
align"left" | "right"leftnoВыравнивание: left, right
childrenstring | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefinedno
classNamestringno
data-test-idstringno
lineClassNamestringnoCSS-класс линии
linesnumber3noКоличество строк.
loadingbooleannoФлаг состояния загрузки. Если значение true, будет отрисован блок скелетона, если false - children.
rowClassNamestringnoCSS-класс строки
size"l" | "m" | "s"mnoМасштаб: s, m, l
variant"body" | "display" | "headline" | "label" | "title"bodynoРоль типографики (размер по anatomy)
widthWidth<string | number>noШирина блока. Можно указать значение допустимое для CSSProperty.width (пример `'60%'`, `'400px'` и т.д)

Unions

Types

SkeletonTextProps

Unions

WithSkeleton

Types

PropsWithSkeletonProps
PropTypeDefaultRequiredDescription
childrenstring | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefinedno
loadingbooleannoФлаг состояния загрузки. Если значение true, будет отрисован блок скелетона, если false - children.
skeletonReactNodeyesJSX скелетон

Types

WithSkeletonProps

Storybook

Figma