APP-2983: Fix RTL post alignment on native (#11600)

This commit is contained in:
Eric Bailey
2026-08-31 21:59:24 -05:00
committed by GitHub
parent 4881224d2f
commit 5be7d72011
7 changed files with 74 additions and 3 deletions
+7 -3
View File
@@ -2,6 +2,7 @@ import {useMemo} from 'react'
import {type StyleProp, type TextStyle} from 'react-native'
import {RichText as RichTextAPI} from '@bsky/sdk/richtext'
import {isRTLText} from '#/lib/strings/text-direction'
import {toShortUrl} from '#/lib/strings/url-helpers'
import {android, atoms as a, flatten, type TextStyleProp} from '#/alf'
import {isOnlyEmoji} from '#/alf/typography'
@@ -9,6 +10,7 @@ import {InlineLinkText, type LinkProps} from '#/components/Link'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {RichTextTag} from '#/components/RichTextTag'
import {Text, type TextProps} from '#/components/Typography'
import {IS_NATIVE} from '#/env'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
@@ -82,15 +84,17 @@ export function RichText({
}
}, [value])
const plainStyles = style
const {text, facets} = richText
const plainStyles: StyleProp<TextStyle> = [
style,
IS_NATIVE && isRTLText(text) ? {textAlign: 'right'} : null,
]
const suffixStyles =
suffix && suffixOffset
? android({paddingBottom: suffixOffset, marginBottom: -suffixOffset})
: null
const interactiveStyles = [plainStyles, interactiveStyle]
const {text, facets} = richText
if (!facets?.length) {
if (isOnlyEmoji(text)) {
const flattenedStyle = flatten(style)
+8
View File
@@ -1,2 +1,10 @@
// TS6.0 enables noUncheckedSideEffectImports
declare module '*.css'
declare module 'bidi-js' {
type Bidi = {
getBidiCharTypeName(character: string): string
}
export default function bidiFactory(): Bidi
}
@@ -0,0 +1,24 @@
import {describe, expect, it} from '@jest/globals'
import {isRTLText} from '../text-direction'
describe('isRTLText', () => {
it('recognizes right-to-left text', () => {
expect(isRTLText('עברית')).toBe(true)
expect(isRTLText('العربية')).toBe(true)
})
it('recognizes left-to-right text', () => {
expect(isRTLText('English')).toBe(false)
})
it('uses the first strong directional character', () => {
expect(isRTLText(' 123 🦋 עברית English')).toBe(true)
expect(isRTLText(' 123 🦋 English עברית')).toBe(false)
})
it('defaults to left-to-right when there are no strong characters', () => {
expect(isRTLText('123 🦋 ...')).toBe(false)
expect(isRTLText('')).toBe(false)
})
})
+17
View File
@@ -0,0 +1,17 @@
import bidiFactory from 'bidi-js'
const bidi = bidiFactory()
/**
* Checks the first strong directional character, matching HTML `dir="auto"`.
*/
export function isRTLText(text: string) {
for (const character of text) {
const type = bidi.getBidiCharTypeName(character)
if (type === 'R' || type === 'AL') return true
if (type === 'L') return false
}
return false
}
+7
View File
@@ -0,0 +1,7 @@
/**
* React Native Web sets `dir="auto"` on root Text elements, so the browser
* handles direction detection without JavaScript.
*/
export function isRTLText(_text: string) {
return false
}