43 lines
1.0 KiB
TypeScript
43 lines
1.0 KiB
TypeScript
import { Fragment, type ReactNode } from "react";
|
|
|
|
const URL_REGEX = /(https?:\/\/[^\s<>"]+[^\s<>".,;:!?)\]}'])/gi;
|
|
|
|
export function autolink(text: string): ReactNode[] {
|
|
if (!text) return [];
|
|
const parts: ReactNode[] = [];
|
|
let lastIndex = 0;
|
|
let match: RegExpExecArray | null;
|
|
URL_REGEX.lastIndex = 0;
|
|
|
|
while ((match = URL_REGEX.exec(text)) !== null) {
|
|
if (match.index > lastIndex) {
|
|
parts.push(
|
|
<Fragment key={`t-${lastIndex}`}>
|
|
{text.slice(lastIndex, match.index)}
|
|
</Fragment>,
|
|
);
|
|
}
|
|
const url = match[0];
|
|
parts.push(
|
|
<a
|
|
key={`a-${match.index}`}
|
|
href={url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-ark-gold underline underline-offset-2 break-all hover:text-ark-gold2"
|
|
>
|
|
{url}
|
|
</a>,
|
|
);
|
|
lastIndex = match.index + url.length;
|
|
}
|
|
|
|
if (lastIndex < text.length) {
|
|
parts.push(
|
|
<Fragment key={`t-${lastIndex}`}>{text.slice(lastIndex)}</Fragment>,
|
|
);
|
|
}
|
|
|
|
return parts;
|
|
}
|