Last active
September 10, 2020 08:00
-
-
Save JLarky/f885f68f71b48f317b0eb381f2140d59 to your computer and use it in GitHub Desktop.
Example of automatically detecting links (http and email) in text and turning it into react components. Note I think linkifyjs detects less accurately than linkify-it and react-linkify is slightly over engineered and looked stale at the moment.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import LinkifyIt from 'linkify-it'; | |
import tlds from 'tlds'; | |
import React from 'react'; | |
const linkify = new LinkifyIt(); | |
linkify.tlds(tlds); | |
// based on https://github.com/tasti/react-linkify/blob/d0afedd671fd59b1d73ce5bdbadf90268824edb7/src/components/Linkify.jsx | |
export function parseString( | |
string: string, | |
componentDecorator: (match: LinkifyIt.Match, i: number) => React.ReactNode | |
): React.ReactNode { | |
if (string === '') { | |
return string; | |
} | |
const matches = linkify.match(string); | |
if (!matches) { | |
return string; | |
} | |
const elements: React.ReactNode[] = []; | |
let lastIndex = 0; | |
matches.forEach((match, i) => { | |
// Push preceding text if there is any | |
if (match.index > lastIndex) { | |
elements.push(string.substring(lastIndex, match.index)); | |
} | |
elements.push(componentDecorator(match, i)); | |
lastIndex = match.lastIndex; | |
}); | |
// Push remaining text if there is any | |
if (string.length > lastIndex) { | |
elements.push(string.substring(lastIndex)); | |
} | |
return elements.length === 1 ? elements[0] : elements; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Match } from 'linkify-it'; | |
import React from 'react'; | |
import { parseString } from '../vendor/linkify/linkify'; | |
const decorateComponent = (match: Match, i: number) => ( | |
<a | |
key={i} | |
href={match.url} | |
target="_blank" | |
rel="noopener noreferrer" | |
className="font-bold hover:underline" | |
title={match.raw} | |
> | |
{match.text} | |
</a> | |
); | |
export const LinkifyIt: React.FC<{ text: string }> = ({ text }) => { | |
return <>{parseString(text, decorateComponent)}</>; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment