For anyone having the same problem:
Following is a function that will set highlight format on any matching node with the words array that you have. call this inside a useEffect hook. you can provide the words as array of strings. you can change the style for highlighted text with your CSS outside of the javascript.
const highlightWords = () => {
editor.update(() => {
const root = $getRoot()
const textNodes: TextNode[] = []
// Traverse all nodes to find text nodes
root.getChildren().forEach((node) => {
if ($isTextNode(node)) {
textNodes.push(node)
} else if ($isElementNode(node)) {
node.getChildren().forEach((child) => {
if ($isTextNode(child)) {
textNodes.push(child)
}
})
}
})
// Process each text node
textNodes.forEach((textNode) => {
let text = textNode.getTextContent()
let newNodes: TextNode[] = []
let lastIndex = 0
words.forEach((word) => {
const regex = new RegExp(`\\b${word}\\b`, 'gi')
let match
while ((match = regex.exec(text)) !== null) {
const start = match.index
const end = start + word.length
// Add text before the match
if (start > lastIndex) {
newNodes.push($createTextNode(text.slice(lastIndex, start)))
}
// Add highlighted text
const highlightedNode = $createTextNode(text.slice(start, end))
highlightedNode.setFormat('highlight')
newNodes.push(highlightedNode)
lastIndex = end
}
})
// Add remaining text
if (lastIndex < text.length) {
newNodes.push($createTextNode(text.slice(lastIndex)))
}
// Replace the original node with new nodes
if (newNodes.length > 0) {
textNode.replace(newNodes[0])
for (let i = 1; i < newNodes.length; i++) {
newNodes[i - 1].insertAfter(newNodes[i])
}
}
})
})
}
What is does is that checks for all matching nodes and goes inside a loop one by one of the nodes and checks the text of the node with the word you are looking for.