forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import React from 'react'
2import {StyleSheet, type TextProps} from 'react-native'
3import {UITextView} from 'react-native-uitextview'
4
5import {lh, s} from '#/lib/styles'
6import {type TypographyVariant, useTheme} from '#/lib/ThemeContext'
7import {logger} from '#/logger'
8import {isIOS, isWeb} from '#/platform/detection'
9import {applyFonts, useAlf} from '#/alf'
10import {
11 childHasEmoji,
12 renderChildrenWithEmoji,
13 type StringChild,
14} from '#/alf/typography'
15
16export type CustomTextProps = Omit<TextProps, 'children'> & {
17 type?: TypographyVariant
18 lineHeight?: number
19 title?: string
20 dataSet?: Record<string, string | number>
21 selectable?: boolean
22} & (
23 | {
24 emoji: true
25 children: StringChild
26 }
27 | {
28 emoji?: false
29 children: TextProps['children']
30 }
31 )
32
33export {Text_DEPRECATED as Text}
34/**
35 * @deprecated use Text from `#/components/Typography.tsx` instead
36 */
37function Text_DEPRECATED({
38 type = 'md',
39 children,
40 emoji,
41 lineHeight,
42 style,
43 title,
44 dataSet,
45 selectable,
46 ...props
47}: React.PropsWithChildren<CustomTextProps>) {
48 const theme = useTheme()
49 const {fonts} = useAlf()
50
51 if (__DEV__) {
52 if (!emoji && childHasEmoji(children)) {
53 logger.warn(
54 `Text: emoji detected but emoji not enabled: "${children}"\n\nPlease add <Text emoji />'`,
55 )
56 }
57 }
58
59 const textProps = React.useMemo(() => {
60 const typography = theme.typography[type]
61 const lineHeightStyle = lineHeight ? lh(theme, type, lineHeight) : undefined
62
63 const flattened = StyleSheet.flatten([
64 s.black,
65 typography,
66 lineHeightStyle,
67 style,
68 ])
69
70 applyFonts(flattened, fonts.family)
71
72 // should always be defined on `typography`
73 // @ts-ignore
74 if (flattened.fontSize) {
75 // @ts-ignore
76 flattened.fontSize = Math.round(
77 // @ts-ignore
78 flattened.fontSize * fonts.scaleMultiplier,
79 )
80 }
81
82 return {
83 uiTextView: selectable && isIOS,
84 selectable,
85 style: flattened,
86 dataSet: isWeb
87 ? Object.assign({tooltip: title}, dataSet || {})
88 : undefined,
89 ...props,
90 }
91 }, [
92 dataSet,
93 fonts.family,
94 fonts.scaleMultiplier,
95 lineHeight,
96 props,
97 selectable,
98 style,
99 theme,
100 title,
101 type,
102 ])
103
104 return (
105 <UITextView {...textProps}>
106 {renderChildrenWithEmoji(children, textProps, emoji ?? false)}
107 </UITextView>
108 )
109}