;
if(Array.isArray(node))return Children.map(node,child=>linkifyMentions(child,agents,onMention));
if(isValidElement(node)){
if(typeof node.type!=="string")return node;
if(SKIP_TAGS.has(node.type))return node;
const kids=(node.props as {children?:ReactNode}).children;
if(kids==null)return node;
return cloneElement(node,undefined,linkifyMentions(kids,agents,onMention));
}
return node;
}
function mentionComponents(agents:MentionAgent[],onMention?:(id:string)=>void):Components {
const wrap=(tag:"p"|"li"|"td"|"th"|"h1"|"h2"|"h3"|"h4"|"h5"|"h6"|"blockquote")=>
function MentionTag({node:_node,children,...props}:{node?:unknown;children?:ReactNode}){
return createElement(tag,props,linkifyMentions(children,agents,onMention));
};
return {
...components,
p:wrap("p"),
li:wrap("li"),
td:wrap("td"),
th:wrap("th"),
h1:wrap("h1"),
h2:wrap("h2"),
h3:wrap("h3"),
h4:wrap("h4"),
h5:wrap("h5"),
h6:wrap("h6"),
blockquote:wrap("blockquote"),
};
}
export const ChatMarkdown = memo(function ChatMarkdown({
children,
agents=[],
onMention,
}:{
children:string;
agents?:MentionAgent[];
onMention?:(id:string)=>void;
}) {
const mdComponents=useMemo(
()=>agents.length?mentionComponents(agents,onMention):components,
[agents,onMention],
);
return (
sanitizeMarkdownUrl(url) ?? ""}
>
{children}
);
});