import React, { useCallback, useMemo } from 'react'
import { Link } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import PropTypes from 'prop-types'
const useStyles = makeStyles(
(theme) => ({
link: {
textDecoration: 'none',
color: theme.palette.primary.main,
},
}),
{ name: 'RaLink' },
)
const Linkify = ({ text, ...rest }) => {
const classes = useStyles()
const linkify = useCallback((text) => {
const urlRegex =
/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/gi
return [...text.matchAll(urlRegex)]
}, [])
const parse = useCallback(() => {
const matches = linkify(text)
if (matches.length === 0) return text
const elements = []
let lastIndex = 0
matches.forEach((match, index) => {
// Push text located before matched string
if (match.index > lastIndex) {
elements.push(text.substring(lastIndex, match.index))
}
const href = match[0]
// Push Link component
elements.push(
{href}
,
)
lastIndex = match.index + href.length
})
// Push remaining text
if (text.length > lastIndex) {
elements.push(
,
)
}
return elements.length === 1 ? elements[0] : elements
}, [linkify, text, rest, classes.link])
const parsedText = useMemo(() => parse(), [parse])
return <>{parsedText}>
}
Linkify.propTypes = {
text: PropTypes.string,
}
export default React.memo(Linkify)