sozsoft-platform/ui/src/components/shared/Highlighter.tsx

45 lines
1.4 KiB
TypeScript
Raw Normal View History

2026-08-16 15:30:07 +00:00
import { useMemo, Fragment } from 'react'
interface HighlighterProps {
/** Vurgulanacak kelimeler; boş/whitespace olanlar yok sayılır. */
searchWords: string[]
textToHighlight: string
highlightClassName?: string
}
const escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
/**
* react-highlight-words yerine kullanılan yerel bileşen.
* Kullanılan tek senaryo: arama kelimelerini büyük/küçük harf duyarsız
* eşleyip <mark> ile işaretlemek (paketteki `autoEscape` davranışı varsayılan).
*/
const Highlighter = ({ searchWords, textToHighlight, highlightClassName }: HighlighterProps) => {
const parts = useMemo(() => {
const words = searchWords.map((word) => word?.trim()).filter(Boolean)
if (words.length === 0 || !textToHighlight) return null
const pattern = new RegExp(`(${words.map(escapeRegExp).join('|')})`, 'gi')
return textToHighlight.split(pattern)
}, [searchWords, textToHighlight])
if (!parts) return <>{textToHighlight}</>
// split içindeki tek sayılı indeksler yakalanan gruplardır.
return (
<>
{parts.map((part, index) =>
index % 2 === 1 ? (
<mark key={index} className={highlightClassName}>
{part}
</mark>
) : (
<Fragment key={index}>{part}</Fragment>
),
)}
</>
)
}
export default Highlighter