"use client"; import "@assistant-ui/react-markdown/styles/dot.css"; import "react-shiki/css"; import { StreamdownTextPrimitive, useIsStreamdownCodeBlock, type StreamdownTextComponents, type SyntaxHighlighterProps, } from "@assistant-ui/react-streamdown"; import { type CodeHeaderProps } from "@assistant-ui/react-markdown"; import { OpenInSyntaxHighlighter } from "@/components/xulux/chat/OpenInCard"; import { XuluxAskQuestion } from "@/components/xulux/chat/XuluxAskQuestion"; import { type ComponentPropsWithoutRef, type CSSProperties, type FC, memo, } from "react"; import { CheckIcon, CopyIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import ShikiHighlighter from "react-shiki"; import Link from "next/link"; import { useCopyToClipboard } from "@assistant-ui/ui/hooks/use-copy-to-clipboard"; const XuluxMarkdownTextImpl = () => { return ( null, }, "ask-question": { SyntaxHighlighter: XuluxAskQuestion, CodeHeader: () => null, }, text: { SyntaxHighlighter: PlainTextSyntaxHighlighter, }, }} /> ); }; export const XuluxMarkdownText = memo(XuluxMarkdownTextImpl); const CodeHeader: FC = ({ language, code }) => { const { isCopied, copyToClipboard } = useCopyToClipboard(); const onCopy = () => { if (!code || isCopied) return; copyToClipboard(code); }; return (
{language}
); }; const SyntaxHighlighter: FC = ({ code, language }) => { return ( {code.trim()} ); }; const PlainTextSyntaxHighlighter: FC = ({ code }) => { return (
      {code.trim()}
    
); }; const markdownComponents = { SyntaxHighlighter: SyntaxHighlighter, h1: ({ className, ...props }: ComponentPropsWithoutRef<"h1">) => (

), h2: ({ className, ...props }: ComponentPropsWithoutRef<"h2">) => (

), h3: ({ className, ...props }: ComponentPropsWithoutRef<"h3">) => (

), h4: ({ className, ...props }: ComponentPropsWithoutRef<"h4">) => (

), h5: ({ className, ...props }: ComponentPropsWithoutRef<"h5">) => (

), h6: ({ className, ...props }: ComponentPropsWithoutRef<"h6">) => (
), p: ({ className, ...props }: ComponentPropsWithoutRef<"p">) => (

), a: ({ className, href, children, title, target, rel, }: ComponentPropsWithoutRef<"a">) => { const linkClass = cn( "text-primary hover:text-primary/80 underline underline-offset-2", className, ); if (href?.startsWith("/")) { return ( {children} ); } return ( {children} ); }, blockquote: ({ className, ...props }: ComponentPropsWithoutRef<"blockquote">) => (

), ul: ({ className, ...props }: ComponentPropsWithoutRef<"ul">) => (
    li]:mt-1", className, )} {...props} /> ), ol: ({ className, ...props }: ComponentPropsWithoutRef<"ol">) => (
      li]:mt-1", className, )} {...props} /> ), li: ({ className, ...props }: ComponentPropsWithoutRef<"li">) => (
    1. ), hr: ({ className, ...props }: ComponentPropsWithoutRef<"hr">) => (
      ), table: ({ className, ...props }: ComponentPropsWithoutRef<"table">) => (
      ), th: ({ className, ...props }: ComponentPropsWithoutRef<"th">) => ( , pre: ({ className, ...props }: ComponentPropsWithoutRef<"pre">) => (
        ),
        code: function Code({
          className,
          ...props
        }: ComponentPropsWithoutRef<"code">) {
          const isCodeBlock = useIsStreamdownCodeBlock();
          return (
            
          );
        },
        CodeHeader,
      };
      
      ), td: ({ className, ...props }: ComponentPropsWithoutRef<"td">) => ( ), tr: (props: ComponentPropsWithoutRef<"tr">) =>