Merge pull request #7520 from element-hq/feature/bma/updateFonts

Update fonts on the headings
This commit is contained in:
Benoit Marty
2026-08-26 09:51:50 +02:00
committed by GitHub
77 changed files with 355 additions and 192 deletions
@@ -10,6 +10,7 @@ package io.element.android.libraries.designsystem.atomic.atoms
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import io.element.android.compound.theme.ElementTheme
@@ -20,11 +21,12 @@ fun RoomPreviewTitleAtom(
title: String,
modifier: Modifier = Modifier,
fontStyle: FontStyle? = null,
style: TextStyle = ElementTheme.typography.fontHeadingLgBold
) {
Text(
modifier = modifier,
text = title,
style = ElementTheme.typography.fontHeadingLgBold,
style = style,
textAlign = TextAlign.Center,
fontStyle = fontStyle,
color = ElementTheme.colors.textPrimary,
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.text
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Text
/**
* Render the title of a screen, but adapt the style if it does not fit on a single line,
* so that a wrapped title does not look oversized.
*
* @param title the title to render.
* @param style the style to use to render the [title].
* @param twoLinesStyle the style to use instead of [style] when the [title] does not fit on a single line with [style],
* so that a wrapped title does not look oversized.
* @param modifier the [Modifier] to apply to this layout.
*/
@Composable
fun AdaptativeTitle(
title: String,
style: TextStyle,
twoLinesStyle: TextStyle,
modifier: Modifier = Modifier,
) {
// If style and twoLinesStyle are the same, we don't need to measure the text.
if (style == twoLinesStyle) {
Text(
modifier = modifier.semantics {
heading()
},
style = style,
maxLines = 2,
text = title,
)
} else {
val textMeasurer = rememberTextMeasurer()
BoxWithConstraints(modifier = modifier) {
// Measure the title before rendering it, so that the style is picked in a single layout pass.
val fitsOnASingleLine = textMeasurer.measure(
text = title,
style = style,
constraints = constraints,
).lineCount == 1
Text(
modifier = Modifier.semantics {
heading()
},
style = if (fitsOnASingleLine) style else twoLinesStyle,
maxLines = 2,
text = title,
)
}
}
}
@PreviewsDayNight
@Composable
internal fun AdaptativeTitlePreview() = ElementPreview {
@Composable
fun AdaptativeTitleItem(
text: String,
content: @Composable () -> Unit,
) {
Column(
modifier = Modifier
.width(180.dp)
.background(ElementTheme.colors.bgSubtlePrimary),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
text = text,
style = ElementTheme.typography.fontBodyXsRegular,
color = ElementTheme.colors.textSecondary,
)
content()
}
}
Column(
modifier = Modifier.padding(4.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
// Fits on a single line: the large style is kept.
AdaptativeTitleItem("Adaptative, 1 line:") {
AdaptativeTitle(
title = "Chats",
style = ElementTheme.typography.fontHeadingLgBold,
twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
)
}
// Would be rendered on two lines with the large style: the smaller style is used instead.
AdaptativeTitleItem("Adaptative, 2 lines:") {
AdaptativeTitle(
title = "Tutte le conversazioni:",
style = ElementTheme.typography.fontHeadingLgBold,
twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
)
}
// Would be rendered on two lines with the large style: the smaller style is used instead
// and it's finally rendered on a single line with the smaller style.
AdaptativeTitleItem("Adaptative, but 1 line:") {
AdaptativeTitle(
title = "Tous les chats",
style = ElementTheme.typography.fontHeadingLgBold,
twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
)
}
// Short title, with small font, 1 line.
AdaptativeTitleItem("Always small, 1 line:") {
AdaptativeTitle(
title = "My space",
style = ElementTheme.typography.fontHeadingSmMedium,
twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
)
}
// Space name, which can still be rendered on two lines.
AdaptativeTitleItem("Always small, 2 lines:") {
AdaptativeTitle(
title = "A very long space name",
style = ElementTheme.typography.fontHeadingSmMedium,
twoLinesStyle = ElementTheme.typography.fontHeadingSmMedium,
)
}
}
}
@@ -46,7 +46,7 @@ fun SpaceHeaderRootView(
)
Text(
text = stringResource(CommonStrings.screen_space_list_title),
style = ElementTheme.typography.fontHeadingLgBold,
style = ElementTheme.typography.fontHeadingMdBold,
color = ElementTheme.colors.textPrimary,
textAlign = TextAlign.Center,
)
@@ -19,6 +19,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewAliasAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
@@ -68,11 +69,15 @@ fun SpaceHeaderView(
},
title = {
if (name != null) {
RoomPreviewTitleAtom(title = name)
RoomPreviewTitleAtom(
title = name,
style = ElementTheme.typography.fontHeadingMdBold,
)
} else {
RoomPreviewTitleAtom(
title = stringResource(id = CommonStrings.common_no_space_name),
fontStyle = FontStyle.Italic
fontStyle = FontStyle.Italic,
style = ElementTheme.typography.fontHeadingMdBold,
)
}
},