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 {applyFonts, useAlf} from '#/alf'
9import {
10 childHasEmoji,
11 renderChildrenWithEmoji,
12 type StringChild,
13} from '#/alf/typography'
14import {IS_IOS, IS_WEB} from '#/env'
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 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-base-to-string
55 `Text: emoji detected but emoji not enabled: "${children}"\n\nPlease add <Text emoji />'`,
56 )
57 }
58 }
59
60 const textProps = React.useMemo(() => {
61 const typography = theme.typography[type]
62 const lineHeightStyle = lineHeight ? lh(theme, type, lineHeight) : undefined
63
64 const flattened = StyleSheet.flatten([
65 s.black,
66 typography,
67 lineHeightStyle,
68 style,
69 ])
70
71 applyFonts(flattened, fonts.family)
72
73 // should always be defined on `typography`
74 // @ts-ignore
75 if (flattened.fontSize) {
76 // @ts-ignore
77 flattened.fontSize = Math.round(
78 // @ts-ignore
79 flattened.fontSize * fonts.scaleMultiplier,
80 )
81 }
82
83 return {
84 uiTextView: selectable && IS_IOS,
85 selectable,
86 style: flattened,
87 dataSet: IS_WEB
88 ? Object.assign({tooltip: title}, dataSet || {})
89 : undefined,
90 ...props,
91 }
92 }, [
93 dataSet,
94 fonts.family,
95 fonts.scaleMultiplier,
96 lineHeight,
97 props,
98 selectable,
99 style,
100 theme,
101 title,
102 type,
103 ])
104
105 return (
106 <UITextView {...textProps}>
107 {renderChildrenWithEmoji(children, textProps, emoji ?? false)}
108 </UITextView>
109 )
110}