import { Primitive, Prop } from '@tempots/core';
import { ProviderMark, Clear, Providers } from '../types/domain';
import { BrowserContext } from './browser-context';
import { DOMContext, HandlerOptions } from './dom-context';
/**
 * Attribute name for hydration IDs.
 * Used to match server-rendered elements with client-side renderables during hydration.
 * @public
 */
export declare const HYDRATION_ID_ATTR = "data-tempo-id";
/**
 * Options for streaming HTML output.
 * @public
 */
export interface StreamOptions {
    /**
     * Whether to generate placeholder attributes for hydration.
     */
    generatePlaceholders?: boolean;
}
declare abstract class HeadlessBase {
    readonly parent: HeadlessBase | undefined;
    readonly id: string;
    private readonly properties;
    readonly children: HeadlessNode[];
    constructor(parent: HeadlessBase | undefined);
    isElement(): this is HeadlessBase;
    isText(): this is HeadlessText;
    getText(): string;
    removeChild(child: HeadlessNode): void;
    remove(): void;
    abstract isPortal(): this is HeadlessPortal;
    /**
     * Generates HTML output as an async stream of string chunks.
     * This allows for progressive rendering and better memory efficiency
     * for large DOM trees.
     *
     * @param options - Options for streaming output.
     * @yields String chunks of HTML content.
     */
    abstract toHTMLStream(options?: StreamOptions): AsyncGenerator<string>;
    getPortals(): HeadlessPortal[];
    elements(): HeadlessBase[];
    abstract toHTML(): string;
    hasInnerHTML(): boolean;
    getInnerHTML(): string;
    getInnerText(): string;
    hasInnerText(): boolean;
    hasChildren(): boolean;
    hasClasses(): boolean;
    hasStyles(): boolean;
    hasAttributes(): boolean;
    hasHandlers(): boolean;
    hasRenderableProperties(): boolean;
    getById(id: string): HeadlessBase | undefined;
    trigger<E>(event: string, detail: E): void;
    click(): void;
    on<E>(event: string, listener: (event: E, ctx: HeadlessContext) => void, ctx: HeadlessContext, options?: HandlerOptions): Clear;
    addClasses(tokens: string[]): void;
    removeClasses(tokens: string[]): void;
    getClasses(): string[];
    getAttributes(): [string, unknown][];
    getVisibleAttributes(): (["class", string[]] | ["style", string | Record<string, string>] | [string, string])[];
    setStyle(name: string, value: string): void;
    getStyle(name: string): string;
    getStyles(): Record<string, string>;
    makeAccessors(name: string): {
        get(): unknown;
        set(value: unknown): void;
    };
}
export declare class HeadlessElement extends HeadlessBase {
    readonly tagName: string;
    readonly namespace: string | undefined;
    constructor(tagName: string, namespace: string | undefined, parent: HeadlessBase | undefined);
    isPortal(): this is HeadlessPortal;
    /**
     * Builds the attributes string for this element.
     * Returns an object containing the attributes string and any innerHTML value.
     */
    private buildAttributesString;
    toHTML(generatePlaceholders?: boolean): string;
    /**
     * Generates HTML output as an async stream of string chunks.
     * Yields the opening tag, then each child's content, then the closing tag.
     *
     * @param options - Options for streaming output.
     * @yields String chunks of HTML content.
     */
    toHTMLStream(options?: StreamOptions): AsyncGenerator<string>;
}
export declare class HeadlessPortal extends HeadlessBase {
    readonly selector: string | HTMLElement;
    constructor(selector: string | HTMLElement, parent: HeadlessBase | undefined);
    isPortal(): this is HeadlessPortal;
    toHTML(): string;
    /**
     * Portals don't render inline - they render at their target selector.
     * This method yields nothing for the inline position.
     */
    toHTMLStream(options?: StreamOptions): AsyncGenerator<string>;
    contentToHTML(generatePlaceholders?: boolean): string;
    /**
     * Streams the portal's content HTML.
     * Unlike toHTMLStream, this yields the actual content for rendering at the target location.
     *
     * @param options - Options for streaming output.
     * @yields String chunks of the portal's content.
     */
    contentToHTMLStream(options?: StreamOptions): AsyncGenerator<string>;
}
export declare class HeadlessText {
    text: string;
    readonly id: string;
    constructor(text: string);
    isElement(): this is HeadlessElement;
    isText(): this is HeadlessText;
    getText(): string;
    toHTML(): string;
    /**
     * Streams the text content as a single chunk.
     *
     * @param options - Options (unused for text nodes, kept for API consistency).
     * @yields The text content.
     */
    toHTMLStream(options?: StreamOptions): AsyncGenerator<string>;
}
export type HeadlessNode = HeadlessElement | HeadlessPortal | HeadlessText;
export interface HeadlessContainer {
    currentURL: Prop<string>;
}
export declare class HeadlessContext implements DOMContext {
    readonly element: HeadlessBase;
    readonly reference: HeadlessNode | undefined;
    readonly container: HeadlessContainer;
    readonly providers: Providers;
    constructor(element: HeadlessBase, reference: HeadlessNode | undefined, container: HeadlessContainer, providers: Providers);
    appendOrInsert(element: HeadlessNode): void;
    makeChildElement(tagName: string, namespace: string | undefined): DOMContext;
    makeChildText(text: Primitive): DOMContext;
    setText(text: Primitive): void;
    getText(): string;
    makeRef(): DOMContext;
    makeMarker(): DOMContext;
    makePortal(selector: string | HTMLElement): DOMContext;
    /**
     * Sets a provider for the given provider mark.
     *
     * @param mark - The provider mark to set the provider for.
     * @param value - The provider to set for the given mark.
     * @returns A new `DOMContext` instance with the specified provider.
     */
    setProvider<T>(mark: ProviderMark<T>, value: T, onUse: undefined | (() => void)): DOMContext;
    getProvider<T>(mark: ProviderMark<T>): {
        value: T;
        onUse: (() => void) | undefined;
    };
    tryGetProvider<T>(mark: ProviderMark<T>): {
        value: T;
        onUse: (() => void) | undefined;
    } | undefined;
    clear(removeTree: boolean): void;
    on<E>(event: string, listener: (event: E, ctx: HeadlessContext) => void): Clear;
    addClasses(tokens: string[]): void;
    removeClasses(tokens: string[]): void;
    getClasses(): string[];
    isBrowserDOM(): this is BrowserContext;
    isBrowser(): this is BrowserContext;
    isHeadlessDOM(): this is HeadlessContext;
    isHeadless(): this is HeadlessContext;
    setStyle(name: string, value: string): void;
    getStyle(name: string): string;
    makeAccessors(name: string): {
        get(): unknown;
        set(value: unknown): void;
    };
    moveRangeBefore(startRef: DOMContext, endRef: DOMContext, targetRef: DOMContext): void;
    removeRange(startRef: DOMContext, endRef: DOMContext): void;
    removeAllBefore(ref: DOMContext): void;
    detach(): void;
    reattach(): void;
}
export {};
