Baseline Text

Author: Tad Fisher

Wrapper for the Text element to add additional padding after the last baseline such that the height of the last line of text matches the style's lineHeight

/**
 * Wrapper for the [Text] element which adds additional padding after the last baseline
 * such that the height of the last line of text matches the style's
 * [lineHeight][TextStyle.lineHeight].
 */
@Composable
fun BaselineText(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    inlineContent: Map<String, InlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
) = BaselineText(
    AnnotatedString(text),
    modifier,
    color,
    fontSize,
    fontStyle,
    fontWeight,
    fontFamily,
    letterSpacing,
    textDecoration,
    textAlign,
    lineHeight,
    overflow,
    softWrap,
    maxLines,
    inlineContent,
    onTextLayout,
    style
)

/**
 * Wrapper for the [Text] element which adds additional padding after the last baseline
 * such that the height of the last line of text matches the style's
 * [lineHeight][TextStyle.lineHeight].
 */
@Composable
fun BaselineText(
    text: AnnotatedString,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    inlineContent: Map<String, InlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = {},
    style: TextStyle = LocalTextStyle.current
) {
    val resolvedLineHeight = lineHeight.takeOrElse { style.lineHeight }
    val resolvedFontSize = fontSize.takeOrElse { style.fontSize }
    val paddedModifier = if (resolvedLineHeight.isSpecified && resolvedFontSize.isSpecified) {
        with(LocalDensity.current) {
            val lineHeightDp = resolvedLineHeight.toDp()
            val fontSizeDp = resolvedFontSize.toDp()
            Modifier.paddingFromBaseline(
                top = fontSizeDp,
                bottom = lineHeightDp - fontSizeDp
            )
        }
    } else {
        Modifier
    }
    Text(
        text,
        modifier = modifier.then(paddedModifier),
        color,
        fontSize,
        fontStyle,
        fontWeight,
        fontFamily,
        letterSpacing,
        textDecoration,
        textAlign,
        lineHeight,
        overflow,
        softWrap,
        maxLines,
        inlineContent,
        onTextLayout,
        style
    )
}

Have a project you'd like to submit? Fill this form, will ya!

If you like this snippet, you might also like:

Maker OS is an all-in-one productivity system for developers

I built Maker OS to track, manage & organize my life. Now you can do it too!