Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
1import {UITextView} from 'react-native-uitextview'
2
3import {logger} from '#/logger'
4import {atoms, 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, 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 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-base-to-string
39 `Text: emoji detected but emoji not enabled: "${children}"\n\nPlease add <Text emoji />'`,
40 )
41 }
42 }
43
44 const shared = {
45 uiTextView: true,
46 selectable,
47 style: s,
48 dataSet: Object.assign({tooltip: title}, dataSet || {}),
49 ...rest,
50 }
51
52 return (
53 <UITextView {...shared}>
54 {renderChildrenWithEmoji(children, shared, emoji ?? false)}
55 </UITextView>
56 )
57}
58
59function createHeadingElement({level}: {level: number}) {
60 return function HeadingElement({style, ...rest}: TextProps) {
61 const attr =
62 web({
63 role: 'heading',
64 'aria-level': level,
65 }) || {}
66 return <Text {...attr} {...rest} style={style} />
67 }
68}
69
70/*
71 * Use semantic components when it's beneficial to the user or to a web scraper
72 */
73export const H1 = createHeadingElement({level: 1})
74export const H2 = createHeadingElement({level: 2})
75export const H3 = createHeadingElement({level: 3})
76export const H4 = createHeadingElement({level: 4})
77export const H5 = createHeadingElement({level: 5})
78export const H6 = createHeadingElement({level: 6})
79export function P({style, ...rest}: TextProps) {
80 const attr =
81 web({
82 role: 'paragraph',
83 }) || {}
84 return (
85 <Text
86 {...attr}
87 {...rest}
88 style={[atoms.text_md, atoms.leading_relaxed, style]}
89 />
90 )
91}