import { type ComponentType, type FunctionComponent, type JSX } from "react";
import type { Elements } from "../../util/element.js";
import type { ChildProps } from "../util/props.js";
/**
 * Dispatch table from a `JSX.IntrinsicElements` key to a renderer component.
 * - Each entry is optional — unmapped elements fall through and render as themselves (e.g. an unmapped `<tree-foo>` appears as a raw `<tree-foo>` HTML element).
 * - Per-entry component receives `JSX.IntrinsicElements[K] & E` — the declared props for that element type, plus any extra props `E` the mapper is configured to thread through.
 */
export type Mapping<E = unknown> = {
    [K in keyof JSX.IntrinsicElements]?: ComponentType<JSX.IntrinsicElements[K] & E>;
};
/** Props for the `Mapping` component returned by `createMapper()`. */
export interface MappingProps<E = unknown> extends ChildProps {
    /** Mapping entries that extend or override the inherited mapping inside this subtree. */
    readonly mapping: Mapping<E>;
}
/**
 * Props for the `Mapper` component returned by `createMapper()`.
 * - `children` holds the pre-walked elements to dispatch.
 * - All other props are spread onto every mapped child as additional props (`E`).
 */
export type MapperProps<E = unknown> = E & {
    readonly children?: Elements;
};
/**
 * Create a `[Mapping, Mapper]` pair of components backed by their own private React context.
 *
 * - `Mapping` extends or overrides the mapping inside a subtree (useful for swapping in custom renderers for specific element types).
 * - `Mapper` accepts a pre-walked iterable of elements as `children` and dispatches each to the registered component for its `type`. Any other props passed to `Mapper` are spread onto every dispatched child.
 *
 * Each call creates its own context — independent mappers don't interfere with each other.
 *
 * @typeParam E The shape of any extra props the mapper threads through to every dispatched child. Defaults to `unknown` (no extras).
 *
 * @example
 * // No extras:
 * const [TreeCardMapping, TreeCardMapper] = createMapper({
 *   "tree-directory": DirectoryCard,
 *   "tree-file": FileCard,
 * });
 * <TreeCardMapper>{walkElements(children)}</TreeCardMapper>
 *
 * @example
 * // With extras (`path` threaded into every dispatched child):
 * const [TreeMenuMapping, TreeMenuMapper] = createMapper<{ path?: AbsolutePath }>({
 *   "tree-directory": TreeMenuItem,
 *   "tree-file": TreeMenuItem,
 * });
 * <TreeMenuMapper path="/foo">{queryElements(children, query)}</TreeMenuMapper>
 */
export declare function createMapper<E = unknown>(defaults?: Mapping<E>): [Mapping: FunctionComponent<MappingProps<E>>, Mapper: FunctionComponent<MapperProps<E>>];
