Flex

Контейнер для flex-раскладки. Управляет направлением, выравниванием, переносом и отступами между детьми через пропсы — без ручных display: flex и gap в разметке потребителя.

Демо

Preview
123
Prop
Type
Value
align
flex-start | center | flex-end | baseline | stretch
data-test-id
text
direction
row | row-reverse | column | column-reverse
gap
025m | 050m | 1m | 2m | 3m | 4m | 5m | 6m | 7m | 8m | 9m | 10m
justify
flex-start | center | flex-end | space-between | space-around | space-evenly
wrap
nowrap | wrap | wrap-reverse
Code
<Flex direction="row" justify="space-between" align="center" gap="2m" wrap="nowrap" />

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

  • Нужно расположить несколько элементов в ряд или столбец с предсказуемым отступом между ними.
  • Требуется выравнивание группы по главной (justify) или поперечной (align) оси.
  • Элементы должны переноситься на новую строку при нехватке места (wrap).

Когда не нужен:

  • Двумерная сетка с явными строками и колонками:
    • используйте CSS Grid.
  • Единичный элемент без соседей — обёртка-flex ничего не даёт.

Do / Don’t

  • ✅ Задавайте отступы через gap (токен модульной шкалы) — единый ритм с дизайн-системой.
  • ❌ Не вставляйте distance-обёртки или margin между детьми вручную.
  • ✅ Для произвольной ширины/высоты используйте width / height (число, keyword ElementSize или CSS-строка).
  • ❌ Не оборачивайте Flex в дополнительный div со своим display: flex ради выравнивания.
  • ✅ Берите Flex для одномерной раскладки (ряд или столбец).
  • ❌ Не стройте на Flex двумерные сетки — это задача CSS Grid.
  • ✅ Полиморфизм через as (as='nav', as='ul') — семантический тег без потери раскладки.
  • ❌ Не дублируйте Flex ради смены тега — передайте as.

Анатомия

Direction (default row)

Направление главной оси (проп direction). Тип — Extract валидных значений flex-direction:

  • row / row-reverse — строка (и в обратном порядке).
  • column / column-reverse — столбец (и в обратном порядке).

Justify

Выравнивание по главной оси (justify-content). Тип — Extract из CSSProperties['justifyContent']:

  • flex-start / center / flex-end — к началу / центру / концу.
  • space-between / space-around / space-evenly / stretch — распределение свободного пространства.

Align

Выравнивание по поперечной оси (align-items). Тип — Extract из CSSProperties['alignItems']:

  • flex-start / center / flex-end — к началу / центру / концу.
  • self-start / self-end — по краю с учётом align-self.
  • baseline — по базовой линии текста.
  • stretch — растянуть детей по поперечной оси.

Align content

Выравнивание строк многострочного flex (align-content, проп alignContent, работает при wrap). Тип — Extract из CSSProperties['alignContent']: flex-start / center / flex-end / space-between / space-around / space-evenly / stretch / baseline.

Wrap (default nowrap)

Перенос детей (flex-wrap). Принимает boolean (truewrap) либо явное значение:

  • nowrap — без переноса.
  • wrap — перенос на новую строку.
  • wrap-reverse — перенос в обратном порядке.

Gap (default нет)

Отступ между детьми. Пропсы gap (CSS gap), columnGap (column-gap) и rowGap (row-gap) принимают только токен модульной шкалы (m = модуль 8px, привязан к dimension-токенам DS). Произвольные числа/строки не поддерживаются.

Модульная шкала:

  • 025m — 2px
  • 050m — 4px
  • 1m — 8px
  • 2m — 16px
  • 3m — 24px
  • 4m — 32px
  • 5m — 40px
  • 6m — 48px
  • 7m — 56px
  • 8m — 64px
  • 9m — 72px
  • 10m — 80px

Токены резолвятся через data-* + SCSS в CSS-переменные --sn-primitive-dimension-* (тема, override через CSS), без инлайн-стилей.

Overflow

Поведение переполнения по осям (overflow / overflowX / overflowY). Тип — Extract из CSSProperties['overflow']:

  • visible — контент выходит за границы (по умолчанию).
  • hidden / clip — обрезается.
  • scroll — всегда со скроллом.
  • auto — скролл при переполнении.

Size (width / height / flex)

width, height и flex используют один тип Size:

  • keyword ElementSizemax-content / min-content / fit-content / auto / inherit / initial / unset. Резолвится через data-* + SCSS.
  • число — интерпретируется как px для width/height (width={200}), как flex-grow для flex (flex={1}). Инлайн-стилем.
  • CSS-строку — '50%', '12rem', для flex — shorthand '1 1 auto'. Инлайн-стилем.

fullWidth — shorthand для width: 100%.

Установка

pnpm add @cloud-ru/ds-uikit-product-flex
import { Flex } from '@cloud-ru/ds-uikit-product-flex'
import '@cloud-ru/ds-uikit-product-flex/style.css'

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

Тулбар

ТулбарГлавная и вторичные действия по краям, выравнивание по центру.
tsx
import { Button } from '@cloud-ru/ds-button';
import { Flex } from '@cloud-ru/ds-uikit-product-flex';

export function Toolbar() {
  return (
    <Flex justify='space-between' align='center' gap='2m' fullWidth>
      <Button label='Назад' view='outline' appearance='neutral' />
      <Flex gap='1m'>
        <Button label='Отмена' view='outline' appearance='neutral' />
        <Button label='Сохранить' />
      </Flex>
    </Flex>
  );
}

Вертикальный стек

Вертикальный стекdirection='column' + gap для колонки одинаковой ширины.
tsx
import { Button } from '@cloud-ru/ds-button';
import { Flex } from '@cloud-ru/ds-uikit-product-flex';

export function Stack() {
  return (
    <Flex direction='column' gap='1m' width={220}>
      <Button label='Первый' fullWidth />
      <Button label='Второй' fullWidth view='outline' appearance='neutral' />
      <Button label='Третий' fullWidth view='outline' appearance='neutral' />
    </Flex>
  );
}

Перенос

Переносwrap + gap в узком контейнере фиксированной ширины.
ReactTypeScriptSCSSViteStorybookPlaywright
tsx
import { Flex } from '@cloud-ru/ds-uikit-product-flex';

const items = ['React', 'TypeScript', 'SCSS', 'Vite', 'Storybook', 'Playwright'];

const chipStyle = {
  display: 'inline-flex',
  alignItems: 'center',
  padding: '4px 12px',
  borderRadius: 16,
  background: 'var(--sn-theme-color-neutral-background1Level)',
  boxShadow: 'inset 0 0 0 1px var(--sn-theme-color-available-borderColor)',
} as const;

export function WrapTags() {
  return (
    <Flex wrap gap='1m' width={240}>
      {items.map(item => (
        <span key={item} style={chipStyle}>
          {item}
        </span>
      ))}
    </Flex>
  );
}

Props

Types

PropsFlexProps
PropTypeDefaultRequiredDescription
align"baseline" | "center" | "flex-end" | "flex-start" | "self-end" | "self-start" | "stretch"noВыравнивание по поперечной оси (`align-items`).
alignContent"baseline" | "center" | "flex-end" | "flex-start" | "space-around" | "space-between" | "space-evenly" | "stretch"noВыравнивание строк многострочного flex (`align-content`, работает при `wrap`).
asElementTypenoЭлемент или компонент для рендера. По умолчанию `div`.
childrenReactNodenoСодержимое контейнера.
classNamestringnoДополнительный класс.
columnGap"025m" | "050m" | "10m" | "1m" | "2m" | "3m" | "4m" | "5m" | "6m" | "7m" | "8m" | "9m"noОтступ между колонками (CSS `column-gap`). Только токен модульной шкалы (см. `gap`).
data-test-idstringnoСтабильный идентификатор для e2e/tests.
direction"column" | "column-reverse" | "row" | "row-reverse"noНаправление главной оси (`flex-direction`). По умолчанию `row`.
flexSizenoЗначение CSS-свойства `flex`. Keyword (`ElementSize` — `auto` / `max-content` / … → через `data-*`), число (`flex-grow`) или shorthand-строка (`'1 1 auto'`).
fullWidthbooleanfalsenoРастянуть контейнер на всю ширину родителя (`width: 100%`).
gap"025m" | "050m" | "10m" | "1m" | "2m" | "3m" | "4m" | "5m" | "6m" | "7m" | "8m" | "9m"noОтступ между детьми (CSS `gap`). Только токен модульной шкалы (привязан к dimension-токенам DS). <pre> 025m - 2px 050m - 4px 1m - 8px 2m - 16px 3m - 24px 4m - 32px 5m - 40px 6m - 48px 7m - 56px 8m - 64px 9m - 72px 10m - 80px </pre>
heightSizenoВысота контейнера. Keyword (`ElementSize`), число (px) или CSS-строка (`'50%'`).
innerRefanynoRef на реальный DOM-элемент/инстанс, который рендерится через `as`.
justify"center" | "flex-end" | "flex-start" | "space-around" | "space-between" | "space-evenly" | "stretch"noВыравнивание по главной оси (`justify-content`).
overflow"auto" | "clip" | "hidden" | "scroll" | "visible"noПереполнение по обеим осям (`overflow`).
overflowX"auto" | "clip" | "hidden" | "scroll" | "visible"noПереполнение по горизонтали (`overflow-x`).
overflowY"auto" | "clip" | "hidden" | "scroll" | "visible"noПереполнение по вертикали (`overflow-y`).
rowGap"025m" | "050m" | "10m" | "1m" | "2m" | "3m" | "4m" | "5m" | "6m" | "7m" | "8m" | "9m"noОтступ между строками (CSS `row-gap`). Только токен модульной шкалы (см. `gap`).
styleCSSPropertiesnoИнлайн-стили, домешиваются последними и перекрывают `width`/`height`/`flex`.
widthSizenoШирина контейнера. Keyword (`ElementSize`), число (px) или CSS-строка (`'50%'`).
wrapboolean | WrapnoПеренос детей (`flex-wrap`). `true` → `wrap`, `false` → `nowrap`, либо явное значение `nowrap` | `wrap` | `wrap-reverse`.

Unions

Types

FlexProps

Unions

Storybook