highlight.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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. function 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.substring(0, idx)}
  32. <span className={className}>
  33. {children.substring(idx, idx + highlightText.length)}
  34. </span>
  35. {children.substring(idx + highlightText.length)}
  36. </Fragment>
  37. );
  38. }
  39. const Highlight = styled(HighlightComponent)`
  40. font-weight: normal;
  41. background-color: ${p => p.theme.yellow200};
  42. color: ${p => p.theme.textColor};
  43. `;
  44. export default Highlight;
  45. export {HighlightComponent};