import { type ComponentPropsWithoutRef, type ComponentType, type FC, memo, useContext, } from "react"; import { PreContext, useIsMarkdownCodeBlock } from "./PreOverride"; import type { CodeComponent, CodeHeaderProps, PreComponent, SyntaxHighlighterProps, } from "./types"; import { DefaultCodeBlock } from "./CodeBlock"; import { useCallbackRef } from "@radix-ui/react-use-callback-ref"; import { withDefaultProps } from "./withDefaults"; import { DefaultCodeBlockContent } from "./defaultComponents"; import { memoCompareNodes } from "../memoization"; const CodeBlockOverride: FC = ({ node, components: { Pre, Code, SyntaxHighlighter: FallbackSyntaxHighlighter, CodeHeader: FallbackCodeHeader, }, componentsByLanguage = {}, children, ...codeProps }) => { const preProps = useContext(PreContext)!; const getPreProps = withDefaultProps(preProps); const WrappedPre: PreComponent = useCallbackRef((props) => (
  ));

  const getCodeProps = withDefaultProps(codeProps);
  const WrappedCode: CodeComponent = useCallbackRef((props) => (
    
  ));

  const language = /language-(\w+)/.exec(codeProps.className || "")?.[1] ?? "";

  // if the code content is not string (due to rehype plugins), return a default code block
  if (typeof children !== "string") {
    return (
      
    );
  }

  const SyntaxHighlighter: ComponentType =
    componentsByLanguage[language]?.SyntaxHighlighter ??
    FallbackSyntaxHighlighter;

  const CodeHeader: ComponentType =
    componentsByLanguage[language]?.CodeHeader ?? FallbackCodeHeader;

  return (
    
  );
};

export type CodeOverrideProps = ComponentPropsWithoutRef & {
  components: {
    Pre: PreComponent;
    Code: CodeComponent;
    CodeHeader: ComponentType;
    SyntaxHighlighter: ComponentType;
  };
  componentsByLanguage?:
    | Record<
        string,
        {
          CodeHeader?: ComponentType;
          SyntaxHighlighter?: ComponentType;
        }
      >
    | undefined;
};

const CodeOverrideImpl: FC = ({
  node,
  components,
  componentsByLanguage,
  ...props
}) => {
  const isCodeBlock = useIsMarkdownCodeBlock();
  if (!isCodeBlock) return ;
  return (
    
  );
};

export const CodeOverride = memo(CodeOverrideImpl, (prev, next) => {
  const isEqual =
    prev.components === next.components &&
    prev.componentsByLanguage === next.componentsByLanguage &&
    memoCompareNodes(prev, next);
  return isEqual;
});