Дизайн-токены
Дизайн-токены — атомарные переменные, которые хранят значения UI-параметров: цвета, типографику, отступы, радиусы, тени. Токены живут отдельно от компонентов и применяются везде, где нужна визуальная консистентность.
Преимущества:
- Консистентность — единый источник значений для всей команды
- Темизация — простая смена тем через изменение токенов
- Платформенная независимость — токены для web, iOS, Android
- Ребрендинг — изменения без массовой миграции кода
Структура токенов
Токены орг анизованы в три уровня иерархии:
1. Core tokens (базовые)
"Базовые" значения: палитра, базовые размеры, исходные числовые значения.
// tokens/base.json
{
"color": {
"base": {
"neutral": {
"900": { "value": "#1b1b1b" },
"50": { "value": "#f5f5f5" }
},
"blue": {
"500": { "value": "#3b82f6" }
}
}
},
"space": {
"base": {
"4": { "value": "16px" },
"6": { "value": "24px" }
}
}
}
2. Semantic tokens (семантические)
Значения с бизнес-смыслом, которые ссылаются на core токены.
// tokens/semantic.json
{
"color": {
"text": {
"primary": { "value": "{color.base.neutral.900}" },
"inverse": { "value": "{color.base.neutral.50}" }
},
"bg": {
"surface": { "value": "{color.base.neutral.50}" },
"brand": { "value": "{color.base.blue.500}" }
}
},
"space": {
"m": { "value": "{space.base.4}" },
"l": { "value": "{space.base.6}" }
}
}
3. Component tokens (компонентные)
Локальные токены для специфичных компонентов. Используются только когда компонент требует уникальные значения, не покрытые семантическими токенами.
// tokens/components.json
{
"button": {
"primary": {
"bg": { "value": "{color.bg.brand}" },
"text": { "value": "{color.text.inverse}" }
}
}
}
MUST
-
Все UI-значения берутся из токенов:
- Цвета, типографика, отступы, размеры, радиусы, тени
-
UI-код использует только семантические или компонентные токены:
- Core токены используются только внутри слоя токенов
- Запрещено использовать core токены напрямую в UI-коде
-
Новые компоненты не добавляют захардкоженных значений:
- ❌ Запрещено:
color: '#1b1b1b',padding: 16px - ✅ Правильно:
color: var(--color-text-primary),padding: var(--space-m)
- ❌ Запрещено:
-
Имена токенов отражают смысл использования, а не конкретное значение:
- ✅ Правильно:
color.text.primary,color.bg.surface,space.m - ❌ Неправильно:
color.blue.500,space.cardPadding,color.darkGray
- ✅ Правильно:
-
Иерархия должна быть предсказуемой и единообразной:
color.text.primary
color.text.secondary
color.bg.surface
color.bg.brand
space.s
space.m
space.l
radius.s
radius.m
shadow.level.1
shadow.level.2
SHOULD
-
Семантика важнее конкретного значения:
color.text.primaryвместоcolor.neutral.900space.mвместоspace.16px
-
Компонентные токены создавать только для уникальных компонентов:
- Не создавать компонентные токены для каждого компонента без необходимости
- Использовать семантические токены везде, где возможно
FORBIDDEN
- Использовать core токены напрямую в UI:
/* ❌ Неправильно */
.title {
color: var(--color-base-neutral-900);
}
/* ✅ Правильно */
.title {
color: var(--color-text-primary);
}
- Создавать токены "на один экран" или с привязкой к контексту:
/* ❌ Неправильно */
{
"space": {
"promoCardSpecial": { "value": "18px" },
"landingHeroPadding": { "value": "32px" }
}
}
/* ✅ Правильно */
{
"space": {
"l": { "value": "18px" },
"xl": { "value": "32px" }
}
}
- Смешивать захардкоженные значения с токенами:
/* ❌ Неправильно — часть значений из токенов, часть захардкожена */
.card {
color: var(--color-text-primary);
background: #ffffff; /* захардкожено */
padding: var(--space-m);
border-radius: 8px; /* захардкожено */
}
Темизация и ребрендинг
MUST
Переключение темы меняет семантические токены, а не UI-код:
/* ✅ Правильно */
:root {
--color-text-primary: #1b1b1b;
--color-bg-surface: #ffffff;
}
[data-theme='dark'] {
--color-text-primary: #f5f5f5;
--color-bg-surface: #121212;
}
.card {
color: var(--color-text-primary);
background: var(--color-bg-surface);
}
Поставка токенов
MUST
-
Токены хранятся отдельно от продуктового кода:
- Отдельный репозиторий или workspace-пакет
- Независимая версионность
-
Продукты получают токены как артефакты сборки:
- CSS variables для web
- TypeScript/JavaScript для типизации
- JSON для других платформ (iOS, Android)
SHOULD
-
Использовать генераторы токенов:
- Style Dictionary
- Figma Tokens plugin
- Tokens Studio
-
Версионировать токены:
- Semantic versioning (semver)
- Changelog для изменений
- Миграционные гайды при breaking changes
Примеры использования
✅ Правильно
/* CSS */
.card {
background: var(--color-bg-surface);
color: var(--color-text-primary);
padding: var(--space-m);
border-radius: var(--radius-m);
box-shadow: var(--shadow-level-1);
}
/* Tailwind CSS */
<div className="text-text-primary bg-bg-surface p-m rounded-m shadow-1">
Контент карточки
</div>
/* MUI System */
<Box
sx={{
color: 'text.primary',
bgcolor: 'bg.surface',
p: 'm',
borderRadius: 'm',
boxShadow: 1,
}}
>
Контент карточки
</Box>
❌ Неправильно
/* ❌ Захардкоженные значения */
.card {
background: #fff;
color: #1b1b1b;
padding: 16px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* ❌ Захардкоженные значения в Tailwind */
<div className="text-[#1b1b1b] bg-white p-4 rounded-xl">
Контент карточки
</div>
/* ❌ Использование core токенов напрямую */
<Box
sx={{
color: 'base.neutral.900',
bgcolor: 'base.neutral.50',
}}
>
Контент карточки
</Box>