this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 117 lines 3.2 kB view raw
1import {UITextView} from 'react-native-uitextview' 2 3import {logger} from '#/logger' 4import {atoms as a, type TextStyleProp, useAlf, useTheme, web} from '#/alf' 5import { 6 childHasEmoji, 7 normalizeTextStyles, 8 renderChildrenWithEmoji, 9 type TextProps, 10} from '#/alf/typography' 11 12export type {TextProps} 13export {Text as Span} from 'react-native' 14 15/** 16 * Our main text component. Use this most of the time. 17 */ 18export function Text({ 19 children, 20 emoji, 21 style, 22 selectable, 23 title, 24 dataSet, 25 numberOfLines, 26 ...rest 27}: TextProps) { 28 const {fonts, flags} = useAlf() 29 const t = useTheme() 30 const s = normalizeTextStyles( 31 [ 32 a.text_sm, 33 t.atoms.text, 34 web(numberOfLines === 1 && numberOfLinesClippingFix), 35 style, 36 ], 37 { 38 fontScale: fonts.scaleMultiplier, 39 fontFamily: fonts.family, 40 flags, 41 }, 42 ) 43 44 if (__DEV__) { 45 if (!emoji && childHasEmoji(children)) { 46 logger.warn( 47 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-base-to-string 48 `Text: emoji detected but emoji not enabled: "${children}"\n\nPlease add <Text emoji />'`, 49 ) 50 } 51 } 52 53 const shared = { 54 uiTextView: true, 55 selectable, 56 numberOfLines, 57 style: s, 58 dataSet: Object.assign({tooltip: title}, dataSet || {}), 59 ...rest, 60 } 61 62 return ( 63 <UITextView {...shared}> 64 {renderChildrenWithEmoji(children, shared, emoji ?? false)} 65 </UITextView> 66 ) 67} 68 69function createHeadingElement({level}: {level: number}) { 70 return function HeadingElement({style, ...rest}: TextProps) { 71 const attr = 72 web({ 73 role: 'heading', 74 'aria-level': level, 75 }) || {} 76 return <Text {...attr} {...rest} style={style} /> 77 } 78} 79 80/* 81 * Use semantic components when it's beneficial to the user or to a web scraper 82 */ 83export const H1 = createHeadingElement({level: 1}) 84export const H2 = createHeadingElement({level: 2}) 85export const H3 = createHeadingElement({level: 3}) 86export const H4 = createHeadingElement({level: 4}) 87export const H5 = createHeadingElement({level: 5}) 88export const H6 = createHeadingElement({level: 6}) 89export function P({style, ...rest}: TextProps) { 90 const attr = 91 web({ 92 role: 'paragraph', 93 }) || {} 94 return ( 95 <Text {...attr} {...rest} style={[a.text_md, a.leading_relaxed, style]} /> 96 ) 97} 98 99/** 100 * HACKFIX: React Native Web applies `overflow: hidden` to 101 * text when using the `numberOfLines` prop, which causes it to clip 102 * ascenders/descenders. It only needs to be doing this for the X axis, 103 * so override the style with `overflowX: 'hidden'`. 104 * Note this only works for `numberOfLines={1}` -sfn 105 * 106 * @see https://github.com/necolas/react-native-web/pull/2836 107 */ 108const numberOfLinesClippingFix = { 109 overflowY: 'visible', 110 overflowX: 'clip', 111 // mimic browser default behavior of `min-width: 0` on `overflow: hidden` 112 // elements to allow text to shrink smaller than its intrinsic width when 113 // necessary 114 minWidth: 0, 115 // this is neater and supports vertical writing modes, but it's only baseline newly available 116 // overflowInline: 'clip', 117} satisfies React.CSSProperties as TextStyleProp