import * as React from "react";
import { PerseusI18nContext } from "./components/i18n-context";
import InteractionTracker from "./interaction-tracker";
import TranslationLinter from "./translation-linter";
import WidgetContainer from "./widget-container";
import type { DependenciesContext } from "./dependencies";
import type { PerseusStrings } from "./strings";
import type { APIOptions, APIOptionsWithDefaults, FilterCriterion, FindWidgetsFunction, FocusPath, Widget, WidgetProps } from "./types";
import type { HandleUserInputCallback, InitializeUserInputCallback } from "./user-input-manager";
import type { GetPromptJSONInterface, RendererPromptJSON } from "./widget-ai-utils/prompt-types";
import type { KeypadAPI } from "@khanacademy/math-input";
import type { PerseusRenderer, PerseusWidget, PerseusWidgetOptions, PerseusWidgetsMap, ShowSolutions, PerseusScore, UserInputMap } from "@khanacademy/perseus-core";
import type { LinterContextProps } from "@khanacademy/perseus-linter";
import "./styles/perseus-renderer.css";
type WidgetState = {
    isMobile?: boolean;
    inTable?: boolean;
    key?: number;
    paragraphIndex?: number;
    foundFullWidth?: boolean;
    baseElements?: any;
};
type Props = Partial<React.ContextType<typeof DependenciesContext>> & {
    content: PerseusRenderer["content"];
    widgets: PerseusRenderer["widgets"];
    images: PerseusRenderer["images"];
    apiOptions?: APIOptions;
    userInput?: UserInputMap;
    handleUserInput?: HandleUserInputCallback;
    initializeUserInput?: InitializeUserInputCallback;
    alwaysUpdate?: boolean;
    findExternalWidgets: FindWidgetsFunction;
    keypadElement?: KeypadAPI | null;
    onRender: (node?: any) => void;
    problemNum?: number;
    reviewMode?: boolean | null | undefined;
    highlightEmptyWidgets?: boolean;
    /**
     * If set to "all", all rationales or solutions will be shown. If set to
     * "selected", soltions will only be shown for selected choices. If set to
     * "none", solutions will not be shown-- equivalent to `undefined`.
     */
    showSolutions?: ShowSolutions;
    /**
     * If linterContext.highlightLint is true, then content will be passed to
     * the linter and any warnings will be highlighted in the rendered output.
     */
    linterContext: LinterContextProps;
    legacyPerseusLint?: ReadonlyArray<string>;
    /**
     *  Skip adding paragraph class
     */
    inline?: boolean;
    strings: PerseusStrings;
};
type State = {
    translationLintErrors: ReadonlyArray<string>;
    widgetInfo: Readonly<PerseusWidgetsMap>;
    jiptContent: any;
};
type DefaultProps = Required<Pick<Props, "alwaysUpdate" | "content" | "findExternalWidgets" | "images" | "linterContext" | "onRender" | "showSolutions" | "reviewMode" | "widgets">>;
/**
 * We want to be able to reset the question state when we go
 * from one question to another question. However it's kind of tricky:
 * 1. Content could be the same
 * 2. Problem number could be the same
 * 3. We don't want to reset when going from answerless to answerful data
 * So compare the prev props to the next props, but use
 * answerless for both for the comparison
 */
export type DifferentQuestionPartialProps = Pick<Props, "content" | "widgets" | "problemNum">;
export declare function isDifferentQuestion(propsA: DifferentQuestionPartialProps, propsB: DifferentQuestionPartialProps): boolean;
declare class Renderer extends React.Component<Props, State> implements GetPromptJSONInterface {
    static contextType: React.Context<import("./components/i18n-context").I18nContextType>;
    context: React.ContextType<typeof PerseusI18nContext>;
    _currentFocus: FocusPath | null | undefined;
    _foundTextNodes: boolean;
    _interactionTrackers: {
        [id: string]: InteractionTracker<any>;
    };
    _isMounted: boolean;
    _isTwoColumn: boolean;
    _translationLinter: TranslationLinter;
    _widgetContainers: Map<string, WidgetContainer>;
    translationIndex: number;
    widgetIds: Array<string>;
    static defaultProps: DefaultProps;
    constructor(props: Props);
    componentDidMount(): void;
    UNSAFE_componentWillReceiveProps(nextProps: Props): void;
    shouldComponentUpdate(nextProps: Props, nextState: State): any | boolean;
    componentDidUpdate(prevProps: Props, prevState: State): void;
    componentWillUnmount(): void;
    getApiOptions: () => APIOptionsWithDefaults;
    _getInitialWidgetState: (props: Props) => {
        widgetInfo: State["widgetInfo"];
    };
    _getDefaultWidgetInfo: (widgetId: string) => any;
    _getWidgetInfo: (widgetId: string) => PerseusWidget;
    _isAnswerable(): boolean;
    renderWidget: (impliedType: string, id: string, state: WidgetState) => null | React.ReactNode;
    _getWidgetIndexById(id: string): number;
    getWidgetProps(widgetId: string): WidgetProps<any, any, PerseusWidgetOptions>;
    /**
     * Serializes the questions state so it can be recovered.
     *
     * If an instance of widgetProps is passed in, it generates the serialized
     * state from that instead of the current widget props.
     */
    /**
     * @deprecated - do not use in new code.
     */
    getSerializedState(): Record<string, any>;
    /**
     * Allows inter-widget communication.
     *
     * This function yields this Renderer's own internal widgets, and it's used
     * in two places.
     *
     * First, we expose our own internal widgets to each other by giving them
     * a `findWidgets` function that, in turn, calls this function.
     *
     * Second, we expose our own internal widgets to this Renderer's parent,
     * by allowing it to call this function directly. That way, it can hook us
     * up to other Renderers on the page, by writing a `findExternalWidgets`
     * prop that calls each other Renderer's `findInternalWidgets` function.
     *
     * Takes a `filterCriterion` on which widgets to return.
     * `filterCriterion` can be one of:
     *  * A string widget id
     *  * A string widget type
     *  * a function from (id, widgetInfo, widgetComponent) to true or false
     *
     * Returns an array of the matching widget components.
     *
     * If you need to do logic with more than the components, it is possible
     * to do such logic inside the filter, rather than on the result array.
     *
     * "Remember: abilities are not inherently good or evil, it's how you use
     * them." ~ Kyle Katarn
     * Please use this one with caution.
     */
    findInternalWidgets: (filterCriterion: FilterCriterion) => ReadonlyArray<Widget | null | undefined>;
    /**
     * Allows inter-widget communication.
     *
     * Includes both widgets internal to this Renderer, and external widgets
     * exposed by the `findExternalWidgets` prop.
     *
     * See `findInternalWidgets` for more information.
     */
    findWidgets: (filterCriterion: FilterCriterion) => any;
    getWidgetInstance: (id: string) => Widget | null | undefined;
    _onWidgetFocus: (id: string, focusPath?: ReadonlyArray<string>) => void;
    _onWidgetBlur: (id: string, blurPath: FocusPath) => void;
    getContent: (props: Props, state: State) => any;
    shouldRenderJiptPlaceholder: (props: Props, state: State) => boolean;
    replaceJiptContent: (content: string, paragraphIndex: number) => void;
    outputMarkdown: (ast: any, state: WidgetState) => React.ReactElement;
    outputNested: (ast: any, state: WidgetState) => React.ReactElement;
    outputNode: (node: any, nestedOutput: any, state: WidgetState) => any | null | React.ReactElement<React.ComponentProps<"div">> | React.ReactElement<React.ComponentProps<"span">> | React.ReactNode;
    handleRender: (prevProps: Props) => void;
    _setCurrentFocus: (path: FocusPath) => void;
    focus: () => boolean | null | undefined;
    getDOMNodeForPath: (path: FocusPath) => Element | Text | null | undefined;
    getInputPaths: () => ReadonlyArray<FocusPath>;
    focusPath: (path: FocusPath) => void;
    blurPath: (path: FocusPath) => void;
    blur: () => void;
    /**
     * Serializes widget state. Seems to be used only by editors though.
     *
     * @deprecated and likely a very broken API
     * [LEMS-3185] do not trust serializedState
     */
    serialize: () => Record<any, any>;
    /**
     * Returns an array of widget ids that are empty (meaning widgets where the
     * learner has not interacted with the widget yet or has not filled in all
     * fields).  For example, the `interactive-graph` widget is considered
     * empty if the graph is in the starting state.
     */
    emptyWidgets(): ReadonlyArray<string>;
    /**
     * Returns an object of the widget `.getUserInput()` results
     */
    getUserInputMap(): UserInputMap;
    /**
     * Returns an array of all widget IDs in the order they occur in
     * the content.
     */
    getWidgetIds: () => ReadonlyArray<string>;
    /**
     * Returns a JSON representation of the content and widgets
     * that can be passed to an LLM for prompt context.
     */
    getPromptJSON(): RendererPromptJSON;
    /**
     * Scores the content.
     *
     * @deprecated use scorePerseusItem
     */
    score(): PerseusScore;
    handletranslationLintErrors: (lintErrors: ReadonlyArray<string>) => void;
    render(): React.ReactNode;
}
export default Renderer;
