import React, { JSX } from 'react'; import { findAll } from 'highlight-words-core'; import styled from 'styled-components'; export const HighlightContext = React.createContext([]); export type CatalogHighlightProps = React.PropsWithChildren; export function CatalogHighlight(props: CatalogHighlightProps): JSX.Element | null { const { children } = props; const searchWords = React.useContext(HighlightContext); if (!searchWords.length) { return children ? <>{children} : null; } function highlight(str: string, childIdx: number = 0) { const chunks = findAll({ searchWords, textToHighlight: str, }); return ( {chunks.map((chunk, idx) => { const { end, highlight, start } = chunk; const text = str.substr(start, end - start); if (highlight) { return {text}; } else { return text; } })} ); } if (typeof children === 'string') { return highlight(children); } else if (Array.isArray(children)) { return ( <> {children.map((child, idx) => typeof children === 'string' ? highlight(child, idx) : child || null, )} ); } else { return <>{children}; } } const HighlightedText = styled.span` background-color: var(--catalog-highlight-bg-color); color: var(--catalog-highlight-text-color); `;