All files / app/components Linkify.tsx

96.15% Statements 25/26
72.72% Branches 8/11
100% Functions 3/3
96.15% Lines 25/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 532x 2x   2x 612x 612x 612x 612x 612x 612x 612x 612x 612x               612x 612x   612x 622x 5x   617x   5x     5x 5x 5x                     612x     612x     2x  
import { Link as MuiLink } from "@material-ui/core";
import React from "react";
 
const urlRegex = () => {
  const protocol = `(?:https?://)?`;
  const auth = "(?:\\S+(?::\\S*)?@)?";
  const host = "(?:(?:[a-z0-9][-_]*)*[a-z0-9]+)";
  const domain = "(?:\\.(?:[a-z0-9]-*)*[a-z0-9]+)*";
  const tld = `(?:\\.)[a-z]{2,}`;
  const path = '(?:[/?#][^\\s\\u00a1-\\uffff"]*)?';
  const regex = `(?:${protocol}${auth}(?:${host}${domain}${tld})${path})`;
  const result = new RegExp(`(${regex})`, "ig");
  return result;
};
 
interface LinkifyProps {
  text: string;
}
 
function Linkify({ text }: LinkifyProps) {
  const nonCapturingRegex = urlRegex();
  const parts = text.split(nonCapturingRegex);
 
  const result = parts.map((part, i) => {
    if (!part || !part.match) {
      return null;
    }
    if (part.match(nonCapturingRegex)) {
      // Exclude email addresses
      Iif (part.includes("@") && !part.includes("/")) {
        return <React.Fragment key={i}>{part}</React.Fragment>;
      }
      const href = part.endsWith(".") ? part.slice(0, -1) : part;
      const protocolPrefix = part.match(/https?:?\/\//) ? "" : "//";
      return (
        <MuiLink
          key={i}
          target="_blank"
          rel="noreferrer"
          href={`${protocolPrefix}${href}`}
        >
          {part}
        </MuiLink>
      );
    }
    return <React.Fragment key={i}>{part}</React.Fragment>;
  });
 
  return <>{result}</>;
}
 
export default Linkify;