Компоненты
Компоненты являются основными элементами настройки дизайн-системы. При совпадении типа компонента (внешнего вида) их можно переиспользовать на пользовательских сценариях (экранах). Например, кнопка с иконкой.
Позволяют быстро устанавливать и менять стиль оформления чата.
Пример настройки:
// Создание компонентов с кастомными цветами
let components = ChatComponents(colors: myColors, typography: myTypography)
// Переопределение параметров общих для SDK компонентов
components.navigationBarStyle.titleTextStyle.color = .white
components.searchBarStyle.cancelButtonStyle.tintColor = .white
// Создание темы из компонентов
let theme = ChatTheme(components: components)
или через конструктор build:
let components = ChatComponents.build { components in
components.searchBarStyle.cancelButtonStyle.tintColor = .black
components.loadingChatStyle.indicatorStyle.backgroundColor = .systemGray3
components.loadingChatStyle.indicatorStyle.cornerRadius = 20.0
components.audioPlayerStyle.playButtonStyle.image = ChatImage(system: "play.fill", tintColor: .red)
components.audioPlayerStyle.pauseButtonStyle.image = ChatImage(system: "pause.fill", tintColor: .green)
components.audioPlayerStyle.progressViewStyle.color = .black
components.audioPlayerStyle.progressViewStyle.backgroundColor = .yellow
}
Если нужно поменять стиль общего компонента только в одном месте, переопределите его в нужном пользовательском сценарии.
Параметры конструктора (все опциональные, имеют значения по умолчанию):
images:ChatImages— изображения, используемые в теме.colors:ChatColors— цветовая палитра.typography:ChatTypography— настройки шрифтов.
Стили компонентов чата
| Название | Описание |
|---|---|
navigationBarStyle | Стиль панели навигации (заголовок, кнопки назад/вперед, цвет фона и т.д.). |
searchBarStyle | Стиль панели поиска в панели навигации. |
loadingIndicatorStyle | Стиль индикатора загрузки (прогресс-бар, спиннер). Используется везде, где требуется отобразить процесс ожидания. |
loadingChatStyle | Стиль загрузки чата (экран при открытии чата). |
chatPlaceholderStyle | Стиль заглушки для пустого чата (например, когда нет сообщений). |
errorPlaceholderStyle | Стиль ошибки в чате (сетевая ошибка, сбой загрузки). Показывает информативное сообщение и действия (например, «Повторить»). |
inputTextStyle | Стиль текстового поля ввода сообщения. Настройка шрифта, цвета текста, placeholder'а, отступов и других параметров ввода. |
inputSearchTextStyle | Стиль текстового поля в панели поиска. |
audioPlayerStyle | Стиль аудиоплеера для воспроизведения голосовых сообщений. Включает внешний вид и поведение элементов управления. |
inputViewStyle | Стиль панели ввода сообщений (нижняя часть чата). Включает поле ввода, кнопки отправки и прикрепления. |
chatMenuStyle | Стиль меню выбора действий (добавление файла, фото, камера). |
photoPickerStyle — deprecated, используйте chatMenuStyle.
Примеры кастомизации типичных элементов
Поле ввода текста
components.inputTextStyle.apply { style in
style.cursorColor = UIColor(named: "BrandColor") ?? .systemBlue // курсор
style.textStyle.color = .label // цвет текста
style.backgroundColor = .systemBackground
}
Или только в экране чата (не затрагивая поиск):
let customInput = ChatInputTextStyle.build(with: components) { style in
style.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
}
theme.flows.chatFlow.inputViewStyle.inputTextStyle = customInput
Навигационная панель
components.navigationBarStyle.apply { style in
style.titleTextStyle.font = .systemFont(ofSize: 17, weight: .semibold)
style.titleTextStyle.color = .white
style.backgroundColor = UIColor(named: "BrandColor") ?? .systemBlue
}
Цвет пузырей сообщений
// Входящие (от оператора)
theme.flows.chatFlow.incomeMessages.bubbleTintColor = UIColor(named: "BubbleIncoming") ?? .systemGray5
// Исходящие (от клиента)
theme.flows.chatFlow.outcomeMessages.bubbleTintColor = UIColor(named: "BrandColor") ?? .systemBlue
// Цвет текста в пузырях
theme.flows.chatFlow.incomeMessages.textMessageStyle.textStyle.color = .label
theme.flows.chatFlow.outcomeMessages.textMessageStyle.textStyle.color = .white
Кнопка отправки
let customInput = ChatInputStyle.build(with: components) { style in
style.sendButtonStyle.image = ChatImage(system: "paperplane.fill", tintColor: .white)
style.sendButtonStyle.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
}
theme.flows.chatFlow.inputViewStyle = customInput
Панель поиска
components.searchBarStyle.apply { style in
style.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
style.cancelButtonStyle.tintColor = .white
}
Индикатор загрузки
components.loadingIndicatorStyle.apply { style in
style.indicatorColor = UIColor(named: "BrandColor") ?? .systemBlue
}
Экран загрузки чата
components.loadingChatStyle.apply { style in
style.indicatorStyle.backgroundColor = .systemGray6
style.indicatorStyle.cornerRadius = 16.0
}
Пустое состояние чата
// Текст при пустом чате
components.chatPlaceholderStyle.apply { style in
style.titleTextStyle.color = .secondaryLabel
style.titleTextStyle.font = .systemFont(ofSize: 15, weight: .regular)
}
// Заменить иллюстрацию (через токен изображений)
let images = ChatImages()
images.emptyChatPlaceholderImage = ChatImage(named: "EmptyChat", bundle: .main)
Ошибка загрузки
components.errorPlaceholderStyle.apply { style in
style.titleTextStyle.color = .label
style.repeatButtonStyle.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
}
// Заменить иллюстрацию ошибки (через токен)
images.errorPlaceholderImage = ChatImage(named: "ErrorIllustration", bundle: .main)
Аудиоплеер
components.audioPlayerStyle.apply { style in
style.playButtonStyle.image = ChatImage(system: "play.fill", tintColor: UIColor(named: "BrandColor") ?? .systemBlue)
style.pauseButtonStyle.image = ChatImage(system: "pause.fill", tintColor: UIColor(named: "BrandColor") ?? .systemBlue)
style.progressViewStyle.color = UIColor(named: "BrandColor") ?? .systemBlue
style.progressViewStyle.backgroundColor = .systemGray5
}
Поисковое поле ввода
components.inputSearchTextStyle.apply { style in
style.cursorColor = UIColor(named: "BrandColor") ?? .systemBlue
style.textStyle.color = .label
}
Соответствие Figma и SDK
На странице Components в Figma компоненты организованы в 8 секций. Ниже приведено соответствие между секциями Figma и стилями SDK:
Navigation (Figma)


| Компонент Figma | Варианты | Стиль SDK |
|---|---|---|
| Top Navigation | iOS/Android × Light/Dark | navigationBarStyle (NavigationBarStyle) |
| Bottom Input | Empty, Filled, Voice Record, Voice Recorded, Search Navigation | inputViewStyle (ChatInputStyle) |
| Cite Bottom | Message / Photo / Docs × Light/Dark | ChatInputQuoteStyle (в chatFlow) |
| Scroll Button | Light / Dark | ScrollToMessageButtonStyle |
| Badge | Single / Numerous × Light/Dark | Визуальный стиль бейджа не настраивается публично в SDK; количество непрочитанных доступно через getUnreadMessagesCount и делегат |
Status (Figma)

| Компонент Figma | Варианты | Стиль SDK |
|---|---|---|
| Message status | Прочитано, Доставлено, Доставляется, Ошибка, Отредактировано (Client/Agent, с подложкой/без) | ChatMessageStyle: readStatusImage, deliveredStatusImage, pendingStatusImage, editedStatusImage, errorStatusColor |
Button (Figma)

| Тип кнопки (Figma) | Состояния | Стиль SDK |
|---|---|---|
| Bot | Normal, Active, Pressed, Disable, Loading, Error | QuickReplyStyle |
| Text | Normal, Active, Pressed, Disable, Loading, Error | TextButtonStyle |
| Icon | Normal, Active, Pressed, Disable, Loading, Error | IconButtonStyle |
| Image | Normal, Active, Pressed, Disable, Loading, Error | ButtonStyle |
| Selection | Normal, Pressed, Disable | QuickReplyStyle |
Bubbles (Figma)

| Компонент Figma | Варианты | Стиль SDK |
|---|---|---|
| Message Base (Agent) | Normal, MultiContent, Deleted, Typing, Search agent, Snooze, Error | ChatMessagesStyles в chatFlow.incomeMessages / chatFlow.systemMessages |
| Message Base (Client) | Normal, MultiContent, Error | ChatMessagesStyles в chatFlow.outcomeMessages |
Анатомия баббла в Figma: Avatar → Tail → Content (текст/медиа) → Status. Настраивается через:
showAvatar— отображение аватараmessageBubbleEndMargin— отступ баббла от края экранаcontainerLeftOffset/containerRightOffset— отступы контейнера
Figma-состояния → SDK-свойства
| Figma состояние | Описание | Свойство SDK |
|---|---|---|
| Normal | Обычное сообщение | textMessageStyle, imageMessageStyle, bubbleTintColor |
| MultiContent | Текст + медиа в одном пузыре | Определяется типом контента автоматически |
| Typing | Индикатор «печатает» | chatFlow.systemMessages (системное сообщение) |
| Snooze | Оператор временно недоступен | ScheduleChatMessageStyle |
| Search agent | Результат поиска с выделением | SearchChatMessageStyle (в searchFlow) |
| Error | Ошибка отправки | ChatMessageStyle.errorStatusColor, errorTextStyle, errorInfoButton |
| Deleted | Удалённое сообщение | Не настраивается публично |
Input Field (Figma)
| Компонент Figma | Варианты | Стиль SDK |
|---|---|---|
| Input field | Пустое, частично заполненное, полностью заполненное | inputTextStyle (ChatInputTextStyle) |
OS UI (Figma)
| Компонент Figma | Описание | Стиль SDK |
|---|---|---|
| iOS Select File | Системный выбор файла | chatMenuStyle (ChatMenuStyle) |
| Gallery | Галерея фотографий | chatMenuStyle |
| Select Image | Выбор изображения | chatMenuStyle |
Content (Figma)
| Компонент Figma | Описание | Стиль SDK |
|---|---|---|
| Content | Типы контента в сообщениях: текст, картинка, файл, аудио, опрос, цитата, OG-превью и др. | TextChatMessageStyle, ImageChatMessageStyle, FileChatMessageStyle, AudioChatMessageStyle, SurveyChatMessageStyle, QuoteStyle, OpenGraphViewStyle |
Illustration (Figma)
| Компонент Figma | Варианты | Стиль SDK |
|---|---|---|
| Illustration | Приветствие, Поиск, Ошибка и др. | emptyChatPlaceholderImage, errorPlaceholderImage, searchNotFoundPlaceholderImage (в ChatImages) |
Меню вложений (chatMenuStyle)
chatMenuStyle управляет внешним видом меню выбора файлов, фотографий и камеры — всплывающего листа, который появляется при нажатии на кнопку прикрепления.
Доступные свойства
| Свойство | Тип | Описание | Значение по умолчанию |
|---|---|---|---|
backgroundColor | UIColor | Фон листа меню | colors.background |
tintColor | UIColor | Цвет иконок и кнопок | .clear (системный) |
titleTextStyle | ChatTextStyle | Стиль текста кнопок меню | body шрифт, colors.link цвет |
cornerRadius | CGFloat | Скругление углов листа | 0.0 |
maximumImagesCount | UInt8 | Максимальное количество изображений для выбора | 10 |
Пример настройки
// Глобально через ChatComponents (применяется ко всем экранам)
components.chatMenuStyle.apply { style in
style.backgroundColor = UIColor(named: "BackgroundPrimary") ?? .white
style.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
}
Или через build для точечного создания нового экземпляра:
let menuStyle = ChatMenuStyle.build(with: components) { style in
style.backgroundColor = .white
style.tintColor = .systemBlue
style.maximumImagesCount = 5 // ограничить выбор до 5 изображений
}
components.chatMenuStyle = menuStyle
Только для экрана чата
Если нужно изменить стиль меню только в чате (не затрагивая другие экраны):
// Доступ через chatFlow (свойство называется addFileMenuStyle)
theme.flows.chatFlow.addFileMenuStyle.apply { style in
style.backgroundColor = UIColor(named: "BackgroundPrimary") ?? .white
style.tintColor = UIColor(named: "BrandColor") ?? .systemBlue
}
chatFlow.addFileMenuStyle и components.chatMenuStyle — это один объект по умолчанию. Чтобы изменить меню только в chatFlow без глобального эффекта, создайте новый экземпляр через build и присвойте его напрямую: theme.flows.chatFlow.addFileMenuStyle = myMenuStyle.