diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index 17ab93272c..a33eaf1536 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -1,7 +1,7 @@ import {UITextView} from 'react-native-uitextview' import {logger} from '#/logger' -import {atoms, useAlf, useTheme, web} from '#/alf' +import {atoms as a, type TextStyleProp, useAlf, useTheme, web} from '#/alf' import { childHasEmoji, normalizeTextStyles, @@ -22,15 +22,24 @@ export function Text({ selectable, title, dataSet, + numberOfLines, ...rest }: TextProps) { const {fonts, flags} = useAlf() const t = useTheme() - const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, style], { - fontScale: fonts.scaleMultiplier, - fontFamily: fonts.family, - flags, - }) + const s = normalizeTextStyles( + [ + a.text_sm, + t.atoms.text, + web(numberOfLines === 1 && numberOfLinesClippingFix), + style, + ], + { + fontScale: fonts.scaleMultiplier, + fontFamily: fonts.family, + flags, + }, + ) if (__DEV__) { if (!emoji && childHasEmoji(children)) { @@ -44,6 +53,7 @@ export function Text({ const shared = { uiTextView: true, selectable, + numberOfLines, style: s, dataSet: Object.assign({tooltip: title}, dataSet || {}), ...rest, @@ -82,10 +92,22 @@ export function P({style, ...rest}: TextProps) { role: 'paragraph', }) || {} return ( - + ) } + +/** + * HACKFIX: React Native Web applies `overflow: hidden` to + * text when using the `numberOfLines` prop, which causes it to clip + * ascenders/descenders. It only needs to be doing this for the X axis, + * so override the style with `overflowX: 'hidden'`. + * Note this only works for `numberOfLines={1}` -sfn + * + * @see https://github.com/necolas/react-native-web/pull/2836 + */ +const numberOfLinesClippingFix = { + overflowY: 'visible', + overflowX: 'clip', + // this is neater and supports vertical writing modes, but it's only baseline newly available + // overflowInline: 'clip', +} satisfies React.CSSProperties as TextStyleProp