highlight.tsx 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. type HighlightProps = {
  4. /**
  5. * The original text
  6. */
  7. children: string;
  8. /**
  9. * The text to highlight
  10. */
  11. text: string;
  12. /**
  13. * Should highlighting be disabled?
  14. */
  15. disabled?: boolean;
  16. };
  17. type Props = Omit<React.HTMLAttributes<HTMLDivElement>, keyof HighlightProps> &
  18. HighlightProps;
  19. const HighlightComponent = ({className, children, disabled, text}: Props) => {
  20. // There are instances when children is not string in breadcrumbs but not caught by TS
  21. if (!text || disabled || typeof children !== 'string') {
  22. return <Fragment>{children}</Fragment>;
  23. }
  24. const highlightText = text.toLowerCase();
  25. const idx = children.toLowerCase().indexOf(highlightText);
  26. if (idx === -1) {
  27. return <Fragment>{children}</Fragment>;
  28. }
  29. return (
  30. <Fragment>
  31. {children.substr(0, idx)}
  32. <span className={className}>{children.substr(idx, highlightText.length)}</span>
  33. {children.substr(idx + highlightText.length)}
  34. </Fragment>
  35. );
  36. };
  37. const Highlight = styled(HighlightComponent)`
  38. font-weight: normal;
  39. background-color: ${p => p.theme.yellow200};
  40. color: ${p => p.theme.textColor};
  41. `;
  42. export default Highlight;
  43. export {HighlightComponent};