Files
jiang13-bbs/frontend/components/AutolinkText.tsx

63 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import type { ReactNode } from "react";
import { usePostLinkNewTab } from "@/components/PostLinkProvider";
import { linkifyParts } from "@/lib/linkify";
function AutolinkAnchor({
href,
children,
openInNewTab,
}: {
href: string;
children: ReactNode;
openInNewTab: boolean;
}) {
return (
<a
href={href}
className="j13-autolink break-all"
style={{ color: "var(--accent)", textDecoration: "underline" }}
{...(openInNewTab ? { target: "_blank", rel: "noopener noreferrer" } : {})}
onClick={(e) => e.stopPropagation()}
onContextMenu={(e) => e.stopPropagation()}
>
{children}
</a>
);
}
/**
* 纯文本自动识别 URL。
* forceNewTab:聊天等场景始终新开;否则读 PostLinkProvider(post_link_new_tab)。
*/
export default function AutolinkText({
text,
renderText,
forceNewTab = false,
}: {
text: string;
renderText?: (segment: string) => ReactNode;
forceNewTab?: boolean;
}) {
const settingNewTab = usePostLinkNewTab();
const openInNewTab = forceNewTab || settingNewTab;
const parts = linkifyParts(text);
return (
<>
{parts.map((p, i) => {
const key = `l-${i}`;
if (p.type === "url") {
return (
<AutolinkAnchor key={key} href={p.href} openInNewTab={openInNewTab}>
{p.value}
</AutolinkAnchor>
);
}
if (renderText) return <span key={key}>{renderText(p.value)}</span>;
return <span key={key}>{p.value}</span>;
})}
</>
);
}