-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
151 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,77 @@ | ||
import compile from './compile'; | ||
|
||
test('empty content should works', () => { | ||
expect(compile('', 'party')).toMatchObject([]); | ||
expect(compile('', ['party'])).toMatchObject([]); | ||
}); | ||
|
||
test('empty keywords should works', () => { | ||
const content = 'Welcome everyone to my party'; | ||
expect(compile(content, '')).toMatchObject([content]); | ||
expect(compile(content, [''])).toMatchObject([content]); | ||
expect(compile(content, [])).toMatchObject([content]); | ||
}); | ||
|
||
test('empty content and empty keywords should works', () => { | ||
expect(compile('', '')).toMatchObject([]); | ||
expect(compile('', [''])).toMatchObject([]); | ||
expect(compile('', [])).toMatchObject([]); | ||
}); | ||
|
||
test('no matched word should works', () => { | ||
const content = 'Welcome everyone to come and join my birthday party.'; | ||
expect(compile(content, 'tom')).toMatchObject([ | ||
{ | ||
text: content, | ||
matched: false, | ||
}, | ||
]); | ||
expect(compile(content, 'tom')).toMatchObject([content]); | ||
}); | ||
|
||
test('a single matched word should works', () => { | ||
const content = 'Welcome everyone to come and join my birthday party.'; | ||
expect(compile(content, 'party')).toMatchObject([ | ||
{ | ||
text: 'Welcome everyone to come and join my birthday ', | ||
matched: false, | ||
}, | ||
{ | ||
text: 'party', | ||
matched: true, | ||
}, | ||
{ | ||
text: '.', | ||
matched: false, | ||
}, | ||
'Welcome everyone to come and join my birthday ', | ||
{ text: 'party', matched: true }, | ||
'.', | ||
]); | ||
}); | ||
|
||
test(`multiple matched words should works`, () => { | ||
const content = | ||
'hi, party time. Welcome everyone to come and join my birthday party.'; | ||
expect(compile(content, 'party')).toMatchObject([ | ||
{ | ||
text: 'hi, ', | ||
matched: false, | ||
}, | ||
{ | ||
text: 'party', | ||
matched: true, | ||
}, | ||
{ | ||
text: ' time. Welcome everyone to come and join my birthday ', | ||
matched: false, | ||
}, | ||
{ | ||
text: 'party', | ||
matched: true, | ||
}, | ||
{ | ||
text: '.', | ||
matched: false, | ||
}, | ||
'hi, ', | ||
{ text: 'party', matched: true }, | ||
' time. Welcome everyone to come and join my birthday ', | ||
{ text: 'party', matched: true }, | ||
'.', | ||
]); | ||
}); | ||
|
||
test('matched word at begin should works', () => { | ||
const content = 'party.Welcome everyone.'; | ||
expect(compile(content, 'party')).toMatchObject([ | ||
{ | ||
text: 'party', | ||
matched: true, | ||
}, | ||
{ | ||
text: '.Welcome everyone.', | ||
matched: false, | ||
}, | ||
{ text: 'party', matched: true }, | ||
'.Welcome everyone.', | ||
]); | ||
}); | ||
|
||
test('matched word at end should works', () => { | ||
const content = 'Welcome everyone to my party'; | ||
expect(compile(content, 'party')).toMatchObject([ | ||
{ | ||
text: 'Welcome everyone to my ', | ||
matched: false, | ||
}, | ||
{ | ||
text: 'party', | ||
matched: true, | ||
}, | ||
'Welcome everyone to my ', | ||
{ text: 'party', matched: true }, | ||
]); | ||
}); | ||
|
||
test('empty content should works', () => { | ||
expect(compile('', 'party')).toMatchObject([]); | ||
}); | ||
|
||
test('empty keywords should works', () => { | ||
test('multiple keywords as props should works', () => { | ||
const content = 'Welcome everyone to my party'; | ||
expect(compile(content, '')).toMatchObject([ | ||
{ | ||
text: content, | ||
matched: false, | ||
}, | ||
|
||
expect(compile(content, ['party', 'to'])).toMatchObject([ | ||
'Welcome everyone ', | ||
{ text: 'to', matched: true }, | ||
' my ', | ||
{ text: 'party', matched: true }, | ||
]); | ||
}); | ||
|
||
test('empty content and empty keywords should works', () => { | ||
expect(compile('', '')).toMatchObject([]); | ||
expect(compile(content, ['party', 'other'])).toMatchObject([ | ||
'Welcome everyone to my ', | ||
{ text: 'party', matched: true }, | ||
]); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,37 @@ | ||
import { CSSProperties, FC, Fragment, useMemo } from 'react'; | ||
import { FC, Fragment, ReactNode, useCallback, useMemo } from 'react'; | ||
import compile from './compile'; | ||
|
||
const defaultStyle = { | ||
color: '#00BC70', | ||
}; | ||
|
||
type KeywordsHighlightProps = { | ||
keywords: string; | ||
style?: CSSProperties; | ||
type HighlightWordsProps = { | ||
words: string; | ||
children: string; | ||
render?: (keyword: string) => ReactNode; | ||
}; | ||
|
||
const KeywordsHighlight: FC<KeywordsHighlightProps> = ({ | ||
keywords, | ||
style = defaultStyle, | ||
const HighlightWords: FC<HighlightWordsProps> = ({ | ||
words, | ||
children, | ||
render, | ||
}) => { | ||
const nodes = useMemo(() => { | ||
return compile(children, keywords); | ||
}, [children, keywords]); | ||
const nodes = useMemo(() => compile(children, words), [children, words]); | ||
|
||
const realRender = useCallback( | ||
(word: string) => { | ||
return render ? render(word) : <mark>{word}</mark>; | ||
}, | ||
[render], | ||
); | ||
|
||
return ( | ||
<Fragment> | ||
{nodes.map((node, idx) => { | ||
return ( | ||
<Fragment key={idx}> | ||
{node.matched ? <span style={style}>{node.text}</span> : node.text} | ||
{typeof node === 'string' ? node : realRender(node.text)} | ||
</Fragment> | ||
); | ||
})} | ||
</Fragment> | ||
); | ||
}; | ||
|
||
export default KeywordsHighlight; | ||
export default HighlightWords; |