An ATproto social media client -- with an independent Appview.
at main 2.1 kB view raw
1import {UITextView} from 'react-native-uitextview' 2 3import {logger} from '#/logger' 4import {atoms, flatten, 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 ...rest 26}: TextProps) { 27 const {fonts, flags} = useAlf() 28 const t = useTheme() 29 const s = normalizeTextStyles([atoms.text_sm, t.atoms.text, flatten(style)], { 30 fontScale: fonts.scaleMultiplier, 31 fontFamily: fonts.family, 32 flags, 33 }) 34 35 if (__DEV__) { 36 if (!emoji && childHasEmoji(children)) { 37 logger.warn( 38 `Text: emoji detected but emoji not enabled: "${children}"\n\nPlease add <Text emoji />'`, 39 ) 40 } 41 } 42 43 const shared = { 44 uiTextView: true, 45 selectable, 46 style: s, 47 dataSet: Object.assign({tooltip: title}, dataSet || {}), 48 ...rest, 49 } 50 51 return ( 52 <UITextView {...shared}> 53 {renderChildrenWithEmoji(children, shared, emoji ?? false)} 54 </UITextView> 55 ) 56} 57 58function createHeadingElement({level}: {level: number}) { 59 return function HeadingElement({style, ...rest}: TextProps) { 60 const attr = 61 web({ 62 role: 'heading', 63 'aria-level': level, 64 }) || {} 65 return <Text {...attr} {...rest} style={style} /> 66 } 67} 68 69/* 70 * Use semantic components when it's beneficial to the user or to a web scraper 71 */ 72export const H1 = createHeadingElement({level: 1}) 73export const H2 = createHeadingElement({level: 2}) 74export const H3 = createHeadingElement({level: 3}) 75export const H4 = createHeadingElement({level: 4}) 76export const H5 = createHeadingElement({level: 5}) 77export const H6 = createHeadingElement({level: 6}) 78export function P({style, ...rest}: TextProps) { 79 const attr = 80 web({ 81 role: 'paragraph', 82 }) || {} 83 return ( 84 <Text 85 {...attr} 86 {...rest} 87 style={[atoms.text_md, atoms.leading_normal, flatten(style)]} 88 /> 89 ) 90}