import * as react_jsx_runtime from 'react/jsx-runtime';
import * as react from 'react';
import { JSX, ComponentType } from 'react';
import { MermaidConfig } from 'mermaid';
import { RemendOptions } from 'remend';
import { BundledLanguage, BundledTheme } from 'shiki';
export { BundledLanguage, BundledTheme } from 'shiki';
import { Pluggable, PluggableList } from 'unified';
import { Element, Parents } from 'hast';
import { Options as Options$1 } from 'remark-rehype';

interface AnimatePlugin {
    name: "animate";
    rehypePlugin: Pluggable;
    type: "animate";
}
interface AnimateOptions {
    animation?: "fadeIn" | "blurIn" | "slideUp" | (string & {});
    duration?: number;
    easing?: string;
    sep?: "word" | "char";
}
declare function createAnimatePlugin(options?: AnimateOptions): AnimatePlugin;

interface ExtraProps {
    node?: Element | undefined;
}
type AllowElement = (element: Readonly<Element>, index: number, parent: Readonly<Parents> | undefined) => boolean | null | undefined;
type UrlTransform = (url: string, key: string, node: Readonly<Element>) => string | null | undefined;
type Components = {
    [Key in keyof JSX.IntrinsicElements]?: ComponentType<JSX.IntrinsicElements[Key] & ExtraProps> | keyof JSX.IntrinsicElements;
} & {
    [key: string]: ComponentType<Record<string, unknown> & ExtraProps> | keyof JSX.IntrinsicElements | undefined;
};
interface Options {
    allowElement?: AllowElement;
    allowedElements?: readonly string[];
    children?: string;
    components?: Components;
    disallowedElements?: readonly string[];
    rehypePlugins?: PluggableList;
    remarkPlugins?: PluggableList;
    remarkRehypeOptions?: Readonly<Options$1>;
    skipHtml?: boolean;
    unwrapDisallowed?: boolean;
    urlTransform?: UrlTransform;
}
declare const defaultUrlTransform: UrlTransform;

/**
 * A single token in a highlighted line
 */
interface HighlightToken {
    bgColor?: string;
    color?: string;
    content: string;
    htmlAttrs?: Record<string, string>;
    htmlStyle?: Record<string, string>;
    offset?: number;
}
/**
 * Result from code highlighting (compatible with shiki's TokensResult)
 */
interface HighlightResult {
    bg?: string;
    fg?: string;
    rootStyle?: string | false;
    tokens: HighlightToken[][];
}
/**
 * Options for highlighting code
 */
interface HighlightOptions {
    code: string;
    language: BundledLanguage;
    themes: [string, string];
}
/**
 * Plugin for code syntax highlighting (Shiki)
 */
interface CodeHighlighterPlugin {
    /**
     * Get list of supported languages
     */
    getSupportedLanguages: () => BundledLanguage[];
    /**
     * Get the configured themes
     */
    getThemes: () => [BundledTheme, BundledTheme];
    /**
     * Highlight code and return tokens
     * Returns null if highlighting not ready yet (async loading)
     * Use callback for async result
     */
    highlight: (options: HighlightOptions, callback?: (result: HighlightResult) => void) => HighlightResult | null;
    name: "shiki";
    /**
     * Check if language is supported
     */
    supportsLanguage: (language: BundledLanguage) => boolean;
    type: "code-highlighter";
}
/**
 * Mermaid instance interface
 */
interface MermaidInstance {
    initialize: (config: MermaidConfig) => void;
    render: (id: string, source: string) => Promise<{
        svg: string;
    }>;
}
/**
 * Plugin for diagram rendering (Mermaid)
 */
interface DiagramPlugin {
    /**
     * Get the mermaid instance (initialized with optional config)
     */
    getMermaid: (config?: MermaidConfig) => MermaidInstance;
    /**
     * Language identifier for code blocks
     */
    language: string;
    name: "mermaid";
    type: "diagram";
}
/**
 * Plugin for math rendering (KaTeX)
 */
interface MathPlugin {
    /**
     * Get CSS styles for math rendering (injected into head)
     */
    getStyles?: () => string;
    name: "katex";
    /**
     * Get rehype plugin for rendering math
     */
    rehypePlugin: Pluggable;
    /**
     * Get remark plugin for parsing math syntax
     */
    remarkPlugin: Pluggable;
    type: "math";
}
/**
 * Plugin for CJK text handling
 */
interface CjkPlugin {
    name: "cjk";
    /**
     * @deprecated Use remarkPluginsBefore and remarkPluginsAfter instead
     * All remark plugins (for backwards compatibility)
     */
    remarkPlugins: Pluggable[];
    /**
     * Remark plugins that must run AFTER remarkGfm
     * (e.g., autolink boundary splitting, strikethrough enhancements)
     */
    remarkPluginsAfter: Pluggable[];
    /**
     * Remark plugins that must run BEFORE remarkGfm
     * (e.g., remark-cjk-friendly which modifies emphasis handling)
     */
    remarkPluginsBefore: Pluggable[];
    type: "cjk";
}
/**
 * Plugin configuration passed to Streamdown
 */
interface PluginConfig {
    cjk?: CjkPlugin;
    code?: CodeHighlighterPlugin;
    math?: MathPlugin;
    mermaid?: DiagramPlugin;
}

/**
 * Hook to check if the current block has an incomplete (unclosed) code fence.
 *
 * Returns `true` when the code fence in this block is still being streamed.
 * Useful for deferring expensive renders (syntax highlighting, Mermaid diagrams)
 * until the code block is complete.
 */
declare const useIsCodeFenceIncomplete: () => boolean;

declare const parseMarkdownIntoBlocks: (markdown: string) => string[];

/**
 * Normalizes indentation in HTML blocks to prevent Markdown parsers from
 * treating indented HTML tags as code blocks (4+ spaces = code in Markdown).
 *
 * Useful when rendering AI-generated HTML content with nested tags that
 * are indented for readability.
 *
 * @param content - The raw HTML/Markdown string to normalize
 * @returns The normalized string with reduced indentation before HTML tags
 */
declare const normalizeHtmlIndentation: (content: string) => string;
type ControlsConfig = boolean | {
    table?: boolean;
    code?: boolean;
    mermaid?: boolean | {
        download?: boolean;
        copy?: boolean;
        fullscreen?: boolean;
        panZoom?: boolean;
    };
};
interface LinkSafetyModalProps {
    isOpen: boolean;
    onClose: () => void;
    onConfirm: () => void;
    url: string;
}
interface LinkSafetyConfig {
    enabled: boolean;
    onLinkCheck?: (url: string) => Promise<boolean> | boolean;
    renderModal?: (props: LinkSafetyModalProps) => React.ReactNode;
}
interface MermaidErrorComponentProps {
    chart: string;
    error: string;
    retry: () => void;
}
interface MermaidOptions {
    config?: MermaidConfig;
    errorComponent?: React.ComponentType<MermaidErrorComponentProps>;
}
type AllowedTags = Record<string, string[]>;
type StreamdownProps = Options & {
    mode?: "static" | "streaming";
    BlockComponent?: React.ComponentType<BlockProps>;
    parseMarkdownIntoBlocksFn?: (markdown: string) => string[];
    parseIncompleteMarkdown?: boolean;
    /** Normalize HTML block indentation to prevent 4+ spaces being treated as code blocks. @default false */
    normalizeHtmlIndentation?: boolean;
    className?: string;
    shikiTheme?: [BundledTheme, BundledTheme];
    mermaid?: MermaidOptions;
    controls?: ControlsConfig;
    isAnimating?: boolean;
    animated?: boolean | AnimateOptions;
    caret?: keyof typeof carets;
    plugins?: PluginConfig;
    remend?: RemendOptions;
    linkSafety?: LinkSafetyConfig;
    /** Custom tags to allow through sanitization with their permitted attributes */
    allowedTags?: AllowedTags;
};
declare const defaultRehypePlugins: Record<string, Pluggable>;
declare const defaultRemarkPlugins: Record<string, Pluggable>;
declare const carets: {
    block: string;
    circle: string;
};
interface StreamdownContextType {
    controls: ControlsConfig;
    isAnimating: boolean;
    linkSafety?: LinkSafetyConfig;
    mermaid?: MermaidOptions;
    mode: "static" | "streaming";
    shikiTheme: [BundledTheme, BundledTheme];
}
declare const StreamdownContext: react.Context<StreamdownContextType>;
type BlockProps = Options & {
    content: string;
    shouldParseIncompleteMarkdown: boolean;
    shouldNormalizeHtmlIndentation: boolean;
    index: number;
    /** Whether this block is incomplete (still being streamed) */
    isIncomplete: boolean;
};
declare const Block: react.MemoExoticComponent<({ content, shouldParseIncompleteMarkdown: _, shouldNormalizeHtmlIndentation, index: __, isIncomplete, ...props }: BlockProps) => react_jsx_runtime.JSX.Element>;
declare const Streamdown: react.MemoExoticComponent<({ children, mode, parseIncompleteMarkdown: shouldParseIncompleteMarkdown, normalizeHtmlIndentation: shouldNormalizeHtmlIndentation, components, rehypePlugins, remarkPlugins, className, shikiTheme, mermaid, controls, isAnimating, animated, BlockComponent, parseMarkdownIntoBlocksFn, caret, plugins, remend: remendOptions, linkSafety, allowedTags, ...props }: StreamdownProps) => react_jsx_runtime.JSX.Element>;

export { type AllowElement, type AllowedTags, type AnimateOptions, Block, type BlockProps, type CjkPlugin, type CodeHighlighterPlugin, type Components, type ControlsConfig, type DiagramPlugin, type ExtraProps, type HighlightOptions, type LinkSafetyConfig, type LinkSafetyModalProps, type MathPlugin, type MermaidErrorComponentProps, type MermaidOptions, type PluginConfig, Streamdown, StreamdownContext, type StreamdownContextType, type StreamdownProps, type UrlTransform, createAnimatePlugin, defaultRehypePlugins, defaultRemarkPlugins, defaultUrlTransform, normalizeHtmlIndentation, parseMarkdownIntoBlocks, useIsCodeFenceIncomplete };
