Typography
ChatTypography controls two SDK typography layers:
- Font sizes — 6 semantic tokens (
big,medium,mediumUpper,regular,small,error). These areChatTypography(...)constructor parameters, each is aChatFontStyleinstance. - Custom fonts — 20 TTF substitution points (
*FontPath: String?). These arevarproperties in the class body; set them after creating the object (viaapply { ... }or direct assignment), not through the constructor. Paths are relative toapp/src/main/assets/.
The tables below list all SDK-configurable fonts and sizes. If you find a field in the SDK code that is not in these lists, it is not part of the public API and cannot be changed.
Font sizes
| Field | Type | Default size | Description |
|---|---|---|---|
big | ChatFontStyle | 20 sp (R.dimen.ecc_text_big) | Large font (titles, accents) |
mediumUpper | ChatFontStyle | 18 sp (R.dimen.ecc_text_medium_upper) | Slightly larger than medium |
medium | ChatFontStyle | 16 sp (R.dimen.ecc_text_medium) | Medium font |
regular | ChatFontStyle | 14 sp (R.dimen.ecc_text_regular) | Main SDK font (message text) |
small | ChatFontStyle | 12 sp (R.dimen.ecc_text_small) | Small font (timestamps, captions) |
error | ChatFontStyle | 11 sp (R.dimen.ecc_error_text_size) | Font for error messages |
ChatFontStyle stores the size as a dimen resource reference in sp units (which preserves accessibility scaling at the system level) — changes to the system font scale automatically scale all 6 semantic tokens.
Custom fonts — 20 substitution points
All fields are String? with a default of null (system font is used). The value is a path relative to app/src/main/assets/, for example "fonts/Roboto-Regular.ttf".
| Field | Description |
|---|---|
defaultFontRegularPath | Default font (Regular) |
defaultFontBoldPath | Default bold font |
defaultFontLightPath | Default thin font |
toolbarTitleFontPath | Toolbar title |
toolbarSubtitleFontPath | Toolbar subtitle |
placeholderTitleFontPath | Welcome screen title |
placeholderSubtitleFontPath | Welcome screen subtitle |
quoteHeaderFontPath | Quote header |
quoteAuthorFontPath | Quote author |
quoteMessageFontPath | Quoted message text |
quoteTimeFontPath | Quote timestamp |
inputQuotedMessageFontPath | Quoted message in the input field |
bubbleMessageFontPath | Chat message text |
bubbleTimeFontPath | Chat timestamp |
messageHeaderFontPath | Date/time headers between messages |
typingFontPath | Typing indicator |
scheduleAlertFontPath | Schedule notice |
systemMessageFontPath | System messages |
emptyMediaAndFilesHeaderFontPath | Empty "Media and files" list header |
emptyMediaAndFilesDescriptionFontPath | Empty "Media and files" list description |
Basic setup
val typography = ChatTypography().apply {
// Global defaults — fill all other fields if they are null
defaultFontRegularPath = "fonts/MyFont-Regular.ttf"
defaultFontBoldPath = "fonts/MyFont-Bold.ttf"
defaultFontLightPath = "fonts/MyFont-Light.ttf"
// Per-element overrides
toolbarTitleFontPath = "fonts/MyFont-Medium.ttf"
bubbleMessageFontPath = "fonts/MyFont-Regular.ttf"
}
val theme = ChatTheme(
applicationContext,
typography = typography
)
First set defaultFontRegularPath / defaultFontBoldPath / defaultFontLightPath — this covers 95% of the surface. Then add *FontPath only for elements that need a different font.
The SDK caches Typeface through an internal TypefaceCache. If the file at the given path is missing from assets/, the SDK silently falls back to the system font — no exception. Check the list of files in app/src/main/assets/fonts/ before release.
Full brand kit
Overriding both fonts and sizes. Semantic tokens are set via the constructor; *FontPath fields — via apply { ... }.
fontSize type is strictly @DimenResR.dimen.brand_text_* and R.color.brand_* below are placeholders. Declare them in your app's app/src/main/res/values/dimens.xml (or the corresponding colors.xml) before the build, otherwise you'll get an Unresolved reference.
ChatFontStyle.fontSize: Int? is declared without the @DimenRes annotation, but in most SDK pipelines the value is processed via Resources.getDimension(...) (see TextViewFabric, InputViewFabric). Pass only an R.dimen.* identifier. A literal in sp (fontSize = 22) will lead either to Resources$NotFoundException or to an incorrect size (for example, in spannable text where the value is applied as a raw pixel size).
val brandTypography = ChatTypography(
big = ChatFontStyle(fontSize = R.dimen.brand_text_big), // e.g., 22 sp
regular = ChatFontStyle(fontSize = R.dimen.brand_text_regular), // e.g., 15 sp
small = ChatFontStyle(fontSize = R.dimen.brand_text_small) // e.g., 13 sp
).apply {
defaultFontRegularPath = "fonts/Brand-Regular.ttf"
defaultFontBoldPath = "fonts/Brand-Bold.ttf"
defaultFontLightPath = "fonts/Brand-Light.ttf"
toolbarTitleFontPath = "fonts/Brand-Medium.ttf"
}
val theme = ChatTheme(
applicationContext,
colors = brandColors,
images = brandImages,
typography = brandTypography
)
A detailed scenario of building light and dark themes is in Themes.
Related sections
- Design system: overview — how
ChatTheme,ChatColors,ChatImages,ChatTypographyare organized. - Screen components — where the listed fonts appear on screen.
- Colors —
ChatColorstable. - Images —
ChatImagesfields. - Themes — how
ChatTypographyis integrated intoChatTheme. - Flows — screen-specific customization.
- Accessibility — sp units and Dynamic Type.
- Known limitations — parameters with server-side priority.