const { useState } = React,
{ render } = ReactDOM,
rootNode = document.getElementById('root')
const srcText = `Amazon and Facebook are encouraging their employees in Seattle to stay home after workers for each company tested positive for the novel coronavirus.
Amazon (AMZN) revealed earlier this week that one of its Seattle-based employees has been diagnosed with the virus. On Wednesday, Facebook said a contractor who works at one of its offices in Seattle had tested positive.`
const sampleKeywords = [
{word: 'Amazon', tag: 'ORG'},
{word: 'Facebook', tag: 'ORG'},
{word: 'Seattle', tag: 'GEO'},
{word: 'earlier this week', tag: 'TIME'},
{word: 'on Wednesday', tag: 'TIME'}
]
const TaggedText = ({text, keywords}) => {
const rawKeywords = keywords.map(({word}) => word),
markedText = text.replace(new RegExp(rawKeywords.join('|'), 'gi'), w => `|${w}|`),
textBlocks = markedText.split('|').filter(textBlock => textBlock.length != 0)
return (
<span style={{lineHeight:'160%'}}>
{
textBlocks.map((textBlock,key) => {
const tag = (keywords.find(({word}) => word.toLowerCase() == textBlock.toLowerCase()) || {tag: null}).tag
return <span {...{key,...(tag && {tag})}}>{textBlock}{tag && <span className="tagLabel">{tag}</span>}</span>
})
}
</span>
)
}
render(<TaggedText text={srcText} keywords={sampleKeywords} />, rootNode)
span.tagLabel {
background: #fff;
border-radius: 3px;
font-size: 10px;
font-weight: bold;
margin-left: 10px;
color: grey;
}
span[tag="ORG"] {
background: #bf405c;
padding: 2px 10px;
border-radius: 5px;
color: #fff;
white-space: nowrap;
}
span[tag="GEO"] {
background: #3a8a2e;
padding: 2px 10px;
border-radius: 5px;
color: #fff;
white-space: nowrap;
}
span[tag="TIME"] {
background: #822e8a;
padding: 2px 10px;
border-radius: 5px;
color: #fff;
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>