Building a Highlight Text Component in React

In modern web development, enhancing user experience by highlighting specific text within a larger body of content is a common requirement. Whether it’s for search results, annotations, or emphasizing key information, a Highlight Text component can be incredibly useful. In this article, we’ll walk through the process of building a simple yet effective Highlight Text component using React.

Here is the Example captured:

Highlight Text Component Example

Source Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* @author Edward <wang.huiyang@outlook.com>
* @created 2025-02-11
*/

import { Children } from "react"

interface Highlight {
value: string
style?: string
onPress?: (text: string) => void
}

interface HighlightTextProps {
highlights: Highlight[]
textStyle?: string
children: React.ReactNode
}

const splitText = ({
text,
highlights,
}: {
text: string
highlights: string[]
}): string[] => {
const highlightRegex: string[] = highlights.map(
(i) => `(${i.replace(/"/g, "").trim()})`
)

const finalRegex = new RegExp(highlightRegex.join("|"), "gm")

const parts =
text && highlightRegex.length > 0
? text.split(finalRegex).filter((i) => i !== undefined && i !== "")
: text
? [text]
: []

return parts
}

const HighlightText: React.FC<HighlightTextProps> = ({
children,
textStyle,
highlights,
}) => {
let text = ""
Children.map(children, (child) => {
if (typeof child === "string") {
text += child
}
})

const chunks = splitText({
text,
highlights: highlights.map((i) => i.value),
})

return (
<div className={textStyle}>
{chunks.map((chunk, index) => {
let keyword: JSX.Element | null = null
if (highlights) {
highlights.forEach((item) => {
const regexSource = highlights.map(
(i) => `(${i.value.replace(/"/g, "").trim()})`
)
const itemRegex = new RegExp(`^${regexSource.join("|")}$`, "gm")

if (itemRegex && itemRegex.test(chunk)) {
keyword = (
<span
key={index}
className={item.style}
onClick={() => item.onPress && item.onPress(chunk)}
>
{chunk}
</span>
)
}
})
}

if (keyword) {
return keyword
}

return <span key={index}>{chunk}</span>
})}
</div>
)
}

export default HighlightText

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<HighlightText
textStyle="u-font-14-colored mt-[12px] mx-[12px]"
highlights={[
{
value: state?.email,
style: "text-primary",
onPress: (text) => {
console.log(`Clicked: ${text}`)
},
},
]}
>
Enter the 6-digit verification code sent to {state?.email}. This code will
expire in 10 minutes.
</HighlightText>