[Web] Fix clipped text when using numberOfLines={1} (#10105)

(cherry picked from commit 854ae60e7b)
This commit is contained in:
Samuel Newman
2026-03-23 09:17:49 -07:00
committed by Eric Bailey
parent cc4a436e45
commit a8b3bfe339
+33 -11
View File
@@ -1,7 +1,7 @@
import {UITextView} from 'react-native-uitextview' import {UITextView} from 'react-native-uitextview'
import {logger} from '#/logger' import {logger} from '#/logger'
import {atoms, useAlf, useTheme, web} from '#/alf' import {atoms as a, type TextStyleProp, useAlf, useTheme, web} from '#/alf'
import { import {
childHasEmoji, childHasEmoji,
normalizeTextStyles, normalizeTextStyles,
@@ -22,15 +22,24 @@ export function Text({
selectable, selectable,
title, title,
dataSet, dataSet,
numberOfLines,
...rest ...rest
}: TextProps) { }: TextProps) {
const {fonts, flags} = useAlf() const {fonts, flags} = useAlf()
const t = useTheme() const t = useTheme()
const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, style], { const s = normalizeTextStyles(
fontScale: fonts.scaleMultiplier, [
fontFamily: fonts.family, a.text_sm,
flags, t.atoms.text,
}) web(numberOfLines === 1 && numberOfLinesClippingFix),
style,
],
{
fontScale: fonts.scaleMultiplier,
fontFamily: fonts.family,
flags,
},
)
if (__DEV__) { if (__DEV__) {
if (!emoji && childHasEmoji(children)) { if (!emoji && childHasEmoji(children)) {
@@ -44,6 +53,7 @@ export function Text({
const shared = { const shared = {
uiTextView: true, uiTextView: true,
selectable, selectable,
numberOfLines,
style: s, style: s,
dataSet: Object.assign({tooltip: title}, dataSet || {}), dataSet: Object.assign({tooltip: title}, dataSet || {}),
...rest, ...rest,
@@ -82,10 +92,22 @@ export function P({style, ...rest}: TextProps) {
role: 'paragraph', role: 'paragraph',
}) || {} }) || {}
return ( return (
<Text <Text {...attr} {...rest} style={[a.text_md, a.leading_relaxed, style]} />
{...attr}
{...rest}
style={[atoms.text_md, atoms.leading_relaxed, style]}
/>
) )
} }
/**
* 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