import { Renderable } from '../types/domain';
import { DOMContext } from '../dom/dom-context';
import { HeadlessPortal } from '../dom/headless-context';
import { Value } from '../std/value';
/**
 * Renders the given `renderable` with the provided `ctx` DOM context.
 *
 * @param renderable - The renderable node to be rendered.
 * @param ctx - The DOM context to be used for rendering.
 * @returns A function that can be called to clear the rendered node.
 * @public
 */
export declare const renderWithContext: (renderable: Renderable, ctx: DOMContext) => (removeTree?: boolean) => void;
/**
 * Options for rendering.
 * @public
 */
export type RenderOptions = {
    /**
     * The document to render to. It is inferred from the parent element if not provided.
     */
    doc?: Document;
    /**
     * Whether to clear the document before rendering. This is useful when the page has been pre-rendered on the server.
     */
    clear?: boolean;
    /**
     * Whether to dispose the renderable when the parent element is removed from the DOM.
     */
    disposeWithParent?: boolean;
};
/**
 * Renders a `Renderable` node into a specified parent element or selector.
 *
 * @param node - The `Renderable` node to render.
 * @param parent - The parent element or selector where the node should be rendered.
 * @param options - Optional rendering options.
 * @returns The result of rendering the `Renderable` node.
 * @throws Throws a `RenderingError` if the parent element cannot be found by the provided selector.
 * @public
 */
export declare const render: (node: Renderable, parent: Node | string, { doc, clear, disposeWithParent }?: RenderOptions) => () => void;
/**
 * Runs a renderable function in a headless environment.
 *
 * @param makeRenderable - A function that returns a Renderable to be rendered in the headless environment.
 * @param options - Optional configuration for the headless environment.
 * @param options.startUrl - The initial URL for the headless environment. Defaults to 'https://example.com'.
 * @param options.selector - The selector used to find the root element in the headless environment. Defaults to ':root'.
 * @returns An object containing the clear function, root element, and current URL Signal of the headless environment.
 * @public
 */
export declare const runHeadless: (makeRenderable: () => Renderable, { startUrl, selector, }?: {
    startUrl?: Value<string>;
    selector?: string;
}) => {
    clear: (removeTree?: boolean) => void;
    root: HeadlessPortal;
    currentURL: import('..').Prop<string>;
};
/**
 * Represents an error that occurs during rendering.
 * @public
 */
export declare class RenderingError extends Error {
    constructor(message: string);
}
/**
 * @internal
 */
export declare const _NODE_PLACEHOLDER_ATTR = "data-tts-node";
export declare const CLASS_PLACEHOLDER_ATTR = "data-tts-class";
/**
 * Represents an adapter for headless rendering environments.
 * This class provides methods to interact with elements in a headless context.
 *
 * This class is used to adapt the HeadlesContext to whatever you want to use to render your final HTML.
 * You can use libraries like cheerio to render your HTML.
 *
 * For cheerio an adapter could look like this:
 *
 * ```ts
 * const renderWithCheerio = (html: string, root: HeadlessPortal) => {
 *   const $ = cheerio.load(html)
 *
 *   // eslint-disable-next-line @typescript-eslint/no-explicit-any
 *   const adapter = new HeadlessAdapter<cheerio.Cheerio<any>>({
 *     // eslint-disable-next-line @typescript-eslint/no-explicit-any
 *     select: (selector: string): cheerio.Cheerio<any>[] => [$(selector)],
 *     getAttribute: (el, name: string) => el.attr(name) ?? null,
 *     setAttribute: (el, name: string, value: string | null) => {
 *       if (value === null) {
 *         el.removeAttr(name)
 *       } else {
 *         el.attr(name, value)
 *       }
 *     },
 *     getClass: el => el.attr('class') ?? '',
 *     setClass: (el, value: string | null) => {
 *       if (value === null) {
 *         el.removeAttr('class')
 *       } else {
 *         el.attr('class', value)
 *       }
 *     },
 *     getStyles: el => el.attr('style') ?? {},
 *     setStyles: (el, value: Record<string, string>) => {
 *       if (Object.keys(value).length === 0) {
 *         el.removeAttr('style')
 *       } else {
 *         el.css(value)
 *       }
 *     },
 *     appendHTML: (el, html) => el.append(html),
 *     getInnerHTML: el => el.html() ?? '',
 *     setInnerHTML: (el, html) => el.html(html),
 *     getInnerText: el => el.text() ?? '',
 *     setInnerText: (el, text) => el.text(text),
 *   })
 *
 *   adapter.setFromRoot(root, true)
 *
 *   return $.html()
 * }
 * ```
 *
 * This function will return the rendered HTML as a string.
 *
 * @typeParam EL - The type of elements in the headless environment.
 * @public
 */
export declare class HeadlessAdapter<EL> {
    /**
     * Selects elements from the headless environment.
     * @param selector - The selector to select elements from. The supported selectors are CSS selectors whose complexity depends on the adapter implementation.
     * @returns An array of elements.
     */
    readonly select: (selector: string) => EL[];
    /**
     * Gets the value of an attribute from an element.
     * @param el - The element to get the attribute from.
     * @param attr - The attribute to get the value from.
     * @returns The value of the attribute or null if the attribute is not set.
     */
    readonly getAttribute: (el: EL, attr: string) => string | null;
    /**
     * Sets the value of an attribute on an element.
     * @param el - The element to set the attribute on.
     * @param attr - The attribute to set the value of.
     * @param value - The value to set the attribute to.
     */
    readonly setAttribute: (el: EL, attr: string, value: string | null) => void;
    /**
     * Gets the class of an element.
     * @param el - The element to get the class from.
     * @returns The class of the element or an empty string if the class is not set.
     */
    readonly getClass: (el: EL) => string | null;
    /**
     * Sets the class of an element.
     * @param el - The element to set the class on.
     * @param cls - The class to set.
     */
    readonly setClass: (el: EL, cls: string | null) => void;
    /**
     * Gets the styles of an element.
     * @param el - The element to get the styles from.
     * @returns The styles of the element.
     */
    readonly getStyles: (el: EL) => Record<string, string>;
    /**
     * Sets the styles of an element.
     * @param el - The element to set the styles on.
     */
    readonly setStyles: (el: EL, styles: Record<string, string>) => void;
    /**
     * Appends HTML to an element.
     * @param el - The element to append the HTML to.
     * @param html - The HTML to append.
     */
    readonly appendHTML: (el: EL, html: string) => void;
    /**
     * Gets the inner HTML of an element.
     * @param el - The element to get the inner HTML from.
     * @returns The inner HTML of the element or an empty string if the inner HTML is not set.
     */
    readonly getInnerHTML: (el: EL) => string | null;
    /**
     * Sets the inner HTML of an element.
     * @param el - The element to set the inner HTML on.
     * @param html - The inner HTML to set.
     */
    readonly setInnerHTML: (el: EL, html: string) => void;
    /**
     * Gets the inner text of an element.
     * @param el - The element to get the inner text from.
     * @returns The inner text of the element or an empty string if the inner text is not set.
     */
    readonly getInnerText: (el: EL) => string | null;
    /**
     * Sets the inner text of an element.
     * @param el - The element to set the inner text on.
     * @param text - The inner text to set.
     */
    readonly setInnerText: (el: EL, text: string) => void;
    constructor({ select, getAttribute, setAttribute, getClass, setClass, getStyles, setStyles, appendHTML, getInnerHTML, setInnerHTML, getInnerText, setInnerText, }: {
        select: (selector: string) => EL[];
        getAttribute: (el: EL, attr: string) => string | null;
        setAttribute: (el: EL, attr: string, value: string | null) => void;
        getClass: (el: EL) => string | null;
        setClass: (el: EL, cls: string | null) => void;
        getStyles: (el: EL) => Record<string, string>;
        setStyles: (el: EL, styles: Record<string, string>) => void;
        appendHTML: (el: EL, html: string) => void;
        getInnerHTML: (el: EL) => string | null;
        setInnerHTML: (el: EL, html: string) => void;
        getInnerText: (el: EL) => string | null;
        setInnerText: (el: EL, text: string) => void;
    });
    /**
     * Sets the content of the root element from a HeadlessPortal. Generally this will be the same instance that is
     * returned by `runHeadless`.
     *
     * @param root - The HeadlessPortal containing the content to set.
     * @param setPlaceholders - Whether to set placeholders for the content. This allows you to restore the original content
     * when you render on the server and then hydrate on the client.
     */
    readonly setFromRoot: (root: HeadlessPortal, setPlaceholders: boolean) => void;
}
/**
 * Restores all placeholders in the DOM. This function is useful when the HTML is rendered on the server and then
 * hydrated on the client. It restores the original content that was replaced with placeholders during the initial
 * render. When you render on the server side, make sure to call `HeadlessAdapter.setFromRoot` with the result of
 * `runHeadless` and the second parameter `setPlaceholders` to `true`.
 * @public
 */
export declare const restoreTempoPlaceholders: () => void;
