11import React from "react"
2+ import { StyleProp , TextStyle } from "react-native"
23
34import { makeStyles , Text } from "@rn-vui/themed"
45
6+ type TagHandler = {
7+ style ?: StyleProp < TextStyle >
8+ onPress ?: ( ) => void
9+ }
10+
511type RichTextProps = {
612 text : string
7- bold : string
13+ tags ?: Record < string , TagHandler >
14+ style ?: StyleProp < TextStyle >
815}
916
10- export const RichText : React . FC < RichTextProps > = ( { text, bold } ) => {
17+ const SPLIT_PATTERN = / ( < \w + > .* ?< \/ \w + > ) / g
18+ const TAG_PATTERN = / ^ < ( \w + ) > ( .* ) < \/ \1> $ /
19+
20+ export const RichText : React . FC < RichTextProps > = ( { text, tags, style } ) => {
1121 const styles = useStyles ( )
1222
13- if ( ! text . includes ( bold ) ) {
14- return < Text style = { styles . body } > { text } </ Text >
23+ const allTags : Record < string , TagHandler > = {
24+ bold : { style : styles . bold } ,
25+ link : { style : styles . link } ,
26+ ...tags ,
1527 }
1628
17- const [ before , after ] = text . split ( bold )
29+ const parts = text . split ( SPLIT_PATTERN ) . map ( ( part , i ) => {
30+ const match = part . match ( TAG_PATTERN )
31+ if ( ! match ) return part
1832
19- return (
20- < Text style = { styles . body } >
21- { before }
22- < Text style = { styles . bold } > { bold } </ Text >
23- { after }
24- </ Text >
25- )
33+ const [ , tag , inner ] = match
34+ const handler = allTags [ tag ]
35+ return (
36+ < Text key = { i } style = { handler ?. style } onPress = { handler ?. onPress } >
37+ { inner }
38+ </ Text >
39+ )
40+ } )
41+
42+ return < Text style = { [ styles . body , style ] } > { parts } </ Text >
2643}
2744
2845const useStyles = makeStyles ( ( { colors } ) => ( {
@@ -35,4 +52,8 @@ const useStyles = makeStyles(({ colors }) => ({
3552 fontWeight : "700" ,
3653 color : colors . black ,
3754 } ,
55+ link : {
56+ textDecorationLine : "underline" ,
57+ color : colors . black ,
58+ } ,
3859} ) )
0 commit comments