Глоссарий
Определения ключевых терминов дизайн-системы.
Основные понятия
Токен (Token)
Атомарное значение дизайн-системы — цвет, шрифт или иконка. Задаётся один раз и используется во всём SDK как значение по умолчанию.
Классы-токены: ChatColors, ChatTypography, ChatImages
// Токен цвета
let colors = ChatColors()
colors.link = .systemBlue // применяется везде, где используется "link"
Компонент (Component)
Готовый виджет SDK с настраиваемым внешним видом: кнопка, поле ввода, навигационная панель и т.д. Компоненты используют токены как значения по умолчанию, но допускают точечные переопределения.
Класс-контейнер: ChatComponents
let components = ChatComponents()
// Переопределяем конкретную кнопку — не затрагивая цвета глобально
components.navigationBarStyle.titleTextStyle.color = .white
Сценарий / Flow
Набор стилей, привязанный к конкретному экрану SDK. Позволяет переопределить любой компонент только на одном экране, не затрагивая остальные.
Классы: ChatFlow (экран чата), SearchFlow (экран поиска)
// Изменяем цвет кнопки только в экране поиска
theme.flows.searchFlow.navigationBarStyle.titleTextStyle.color = .black
// В экране чата цвет остаётся прежним
Тема (ChatTheme)
Контейнер верхнего уровня, объединяющий токены, компоненты и сценарии. Передаётся в SDK для применения.
let theme = ChatTheme(colors: colors, typography: typography)
chatCenterSDK.theme = theme
chatCenterSDK.darkTheme = darkTheme // отдельная тема для тёмного режима
Стиль (Style)
Объект, задающий внешний вид конкретного элемента UI. Например, NavigationBarStyle, ChatInputStyle, TextChatMessageStyle. Большинство стилей лениво инициализируются из ChatComponents.
Полный список: Стили.
ChatImage
Унифицированная обёртка над UIImage. Поддерживает SF Symbols, кастомные изображения из бандла и готовые UIImage.
ChatImage(system: "paperplane.fill", tintColor: .white) // SF Symbol
ChatImage(named: "icon_send", bundle: .main) // из бандла
ChatImage(image: myUIImage) // готовый UIImage
Appearance (Внешний вид)
Режим отображения системного UI: .light (светлая) или .dark (тёмная). Определяется через UITraitCollection.userInterfaceStyle.
SDK реагирует на смену Appearance через darkTheme:
chatCenterSDK.theme— используется в.lightchatCenterSDK.darkTheme— используется в.dark(если задан)
// Проверка текущего режима:
if traitCollection.userInterfaceStyle == .dark {
// тёмный режим
}
Dynamic Color
UIColor, автоматически меняющийся в зависимости от Appearance. Создаётся через closure-конструктор UIColor(dynamicProvider:):
let adaptive = UIColor { trait in
trait.userInterfaceStyle == .dark ? .white : .black
}
colors.main = adaptive
Когда использовать: если хотите задать один объект ChatColors, который работает и в светлой, и в тёмной теме — вместо создания двух ChatColors.
Fallback
Запасное значение на случай если основное возвращает nil. В Swift используется оператор ??:
// UIFont(name:size:) вернёт nil если шрифт не найден
typography.message = UIFont(name: "Roboto-Regular", size: 14) ?? .systemFont(ofSize: 14)
// UIColor(named:) вернёт nil если ассет не найден
colors.main = UIColor(named: "BrandBlue") ?? .systemBlue
Без fallback приложение получит nil вместо шрифта/цвета, что приведёт к сбросу на системные значения или крашу.
PostScript Name
Точное внутреннее имя шрифта, используемое системой iOS. Отличается от имени файла или отображаемого названия:
| Значение | |
|---|---|
| Файл | Roboto-Regular.ttf |
| Семейство | Roboto |
| PostScript Name | Roboto-Regular ← используется в UIFont(name:size:) |
Для получения списка всех PostScript-имён:
for family in UIFont.familyNames.sorted() {
for name in UIFont.fontNames(forFamilyName: family) {
print(name)
}
}
Иерархия дизайн-системы
ChatTheme
├── ChatColors ← токены цветов
├── ChatTypography ← токены шрифтов
├── ChatImages ← токены изображений/иконок
├── ChatComponents ← компоненты (используют токены)
│ ├── navigationBarStyle: NavigationBarStyle
│ ├── inputViewStyle: ChatInputStyle
│ ├── audioPlayerStyle: AudioPlayerStyle
│ └── ... (10+ компонентов)
└── ChatFlows
├── ChatFlow ← стили экрана чата (переопределяют компоненты)
└── SearchFlow ← стили экрана поиска (переопределяют компоненты)
Приоритет переопределения (от низшего к высшему):
Токен → Компонент → Flow
Если одно свойство задано и в токене, и в компоненте, и во flow — используется значение из flow.
Таблица соответствий
| Задача | Что изменить | Уровень |
|---|---|---|
| Цвет везде в SDK | ChatColors | Токен |
| Шрифт везде в SDK | ChatTypography | Токен |
| Иконка везде в SDK | ChatImages | Токен |
| Кнопка/панель везде | ChatComponents.*Style | Компонент |
| Элемент только в чате | theme.flows.chatFlow.* | Flow |
| Элемент только в поиске | theme.flows.searchFlow.* | Flow |
Часто путают
ChatMessageStyle vs ChatMessagesStyles
ChatMessageStyle(без s на конце) — базовый стиль одного сообщения: время, статус, отступы, иконки ошибок.ChatMessagesStyles(с s) — контейнер для всех типов сообщений (textMessageStyle,imageMessageStyle, и т.д.), плюс аватар, пузырь и маска.
chatFlow.outcomeMessages vs chatFlow.incomeMessages
outcomeMessages— исходящие сообщения (от пользователя/клиента).incomeMessages— входящие сообщения (от оператора/агента).
typography.title vs navigationBarStyle.titleTextStyle
typography.title— глобальный токен шрифта, используется как значение по умолчанию.navigationBarStyle.titleTextStyle— конкретное свойство навигационной панели. Если задать его явно, оно переопределяет токенtypography.titleтолько для навигации.
Когда выбирать: Токен, Компонент или Flow
Простое правило
| Задача | Уровень |
|---|---|
| Должно применяться везде в SDK | Токен |
| Конкретный виджет на всех экранах | Компонент |
| Изменить только один экран | Flow |
Конкретный пример: цвет заголовка навигационной панели
// Вариант 1 — Токен (влияет на весь SDK, если компонент не переопределён явно)
let typography = ChatTypography()
typography.title = .systemFont(ofSize: 18, weight: .bold)
// ← navigationBarStyle возьмёт этот шрифт по умолчанию, пока titleTextStyle не задан
// Вариант 2 — Компонент (переопределяет токен, влияет на ВСЕ экраны)
let components = ChatComponents()
components.navigationBarStyle.titleTextStyle.font = .systemFont(ofSize: 18, weight: .bold)
components.navigationBarStyle.titleTextStyle.color = .white
// ← явное переопределение: typography.title больше не влияет на NavBar
// Вариант 3 — Flow (только экран поиска, chatFlow не затронут)
theme.flows.searchFlow.navigationBarStyle.titleTextStyle.color = .black
// ← chatFlow.navigationBarStyle остаётся прежним
Приоритет при конфликте: Flow > Компонент > Токен
Если одно свойство задано на нескольких уровнях — побеждает Flow.