import { FElement } from "./renderer";
export declare type RawValue = number | string | boolean;
export declare type MaybeProperty<T> = T | Compilable<T>;
export declare type MapToMaybeProperties<T> = {
    [K in keyof T]: MaybeProperty<T[K]>;
};
export declare function embed<Val extends Compilable<any> | any>(val: Val): any;
export declare class EventBinder {
    protected _handle?: ((...args: any[]) => void) | undefined;
    protected _handler?: string | undefined;
    protected _prior_clause?: EventBinder | undefined;
    protected _when?: string;
    protected _thens: string[];
    protected _preventer?: string;
    protected _prevent?: (...args: any[]) => boolean;
    protected _stopper?: string;
    protected _stop?: (...args: any[]) => boolean;
    constructor(_handle?: ((...args: any[]) => void) | undefined, _handler?: string | undefined, _prior_clause?: EventBinder | undefined);
    compile_inner(): string;
    compile(): (event: Event, elem: FElement) => unknown;
    /** Trigger the handler with the given properties when this event fires. */
    static handle<U extends any[]>(handler: (...args: U) => unknown, ...args: MapToMaybeProperties<U>): EventBinder;
    /** Add another non-exclusive handling clause. Useful in conjunction with `when()`. */
    or<U extends any[]>(handler: (...args: U) => unknown, ...args: MapToMaybeProperties<U>): EventBinder;
    /** Add a condition which must be true for the handler to fire. */
    when(prop: Compilable<boolean> | boolean): this;
    /** Add a side effect to be triggered after the handler fires. */
    then(effect: Compilable<any>): this;
    /** Always stop propagation on this event. */
    stop(): this;
    /** Always prevent default on this event. */
    prevent(): this;
    /** Stop propagation on this event if the predicate returns true. */
    stop_if<U extends RawValue[]>(predicate: (...args: U) => boolean, ...args: MapToMaybeProperties<U>): this;
    /** Prevent default on this event if the predicate returns true. */
    prevent_if<U extends RawValue[]>(predicate: (...args: U) => boolean, ...args: MapToMaybeProperties<U>): this;
}
export declare abstract class Compilable<Returns = any> {
    returns: Returns;
    abstract compile(): string;
    equals<Rhs extends Compilable<any> | any>(rhs: Rhs): Compilable.Infix<this, Rhs>;
    is_not<Rhs extends Compilable<any> | any>(rhs: Rhs): Compilable.Infix<this, Rhs>;
    dot<Prop extends Returns extends {} ? keyof Returns : never>(property: Prop): Compilable.Dot<Returns, Prop>;
    and(rhs: Compilable<any>): Compilable.Infix<this, Compilable<any>>;
    or(rhs: Compilable<any>): Compilable.Infix<this, Compilable<any>>;
    to_string(): Compilable.Computed<string>;
    to_number(): Compilable.Computed<number>;
}
export declare namespace Compilable {
    class Snippet<Returns = any> extends Compilable<Returns> {
        code: string;
        constructor(code: string);
        compile(): string;
    }
    class Computed<Returns = any> extends Compilable<Returns> {
        template: string;
        terms: any[];
        constructor(template: string, ...terms: any[]);
        compile(): string;
    }
    class Infix<Lhs extends Compilable<any> | any, Rhs extends Compilable<any> | any> extends Compilable<boolean> {
        op: string;
        lhs: Lhs;
        rhs: Rhs;
        constructor(op: string, lhs: Lhs, rhs: Rhs);
        compile(): string;
    }
    class Dot<Returns extends {}, Prop extends keyof Returns> extends Compilable<Returns extends null ? null : Returns extends undefined ? undefined : Returns[Prop]> {
        parent: Compilable<Returns>;
        property: Prop;
        constructor(parent: Compilable<Returns>, property: Prop);
        compile(): string;
    }
    class Property<Obj extends {}, Prop extends keyof Obj> extends Compilable<Obj[Prop]> {
        prefix: string;
        property: Prop;
        static create<Obj extends {}, Prop extends keyof Obj = keyof Obj>(prefix: string, property: Prop): Property<Obj, Prop>;
        static create_event<Obj extends {}, Prop extends keyof Obj>(eventCtor: new (...args: any[]) => Obj, property: Prop): Property<Obj, Prop>;
        constructor(prefix: string, property: Prop);
        compile(): string;
    }
    class CategoryProperty<Obj extends {}, Prop extends keyof Obj> extends Compilable<Obj[Prop]> {
        prefix: string;
        property: Prop;
        categories: {
            [name: string]: Obj[Prop];
        };
        static create<Obj extends {}, Prop extends keyof Obj, Categories extends {
            [name: string]: Obj[Prop];
        }>(prefix: string, property: Prop, categories: Categories): CategoryProperty<Obj, Prop> & { [K in keyof Categories]: Compilable<boolean>; };
        static create_event<Obj extends {}, Prop extends keyof Obj, Categories extends {
            [name: string]: Obj[Prop];
        }>(obj: new (...args: any[]) => Obj, property: Prop, categories: Categories): CategoryProperty<Obj, Prop> & { [K in keyof Categories]: Compilable<boolean>; };
        constructor(prefix: string, property: Prop, categories: {
            [name: string]: Obj[Prop];
        });
        compile(): string;
    }
}
/** Trigger the handler with the given properties when this event fires. */
export declare let handle: typeof EventBinder.handle;
/** Helper objects for retrieving event and element properties in catalyst helpers. */
interface Target {
    value: string;
    textContent: string;
    selectedOptions: HTMLOptionElement[];
}
export declare const get: {
    elem: (prop: string) => Compilable.Property<any, string | number | symbol>;
    target: {
        value: Compilable.Property<Target, "value">;
        content: Compilable.Property<Target, "textContent">;
        selected: Compilable.Computed<string[]>;
        bounds: Compilable.Computed<ClientRect>;
    };
    node: Compilable.Computed<HTMLElement>;
    event: Compilable.Computed<Event>;
    mouse: {
        button: Compilable.CategoryProperty<MouseEvent, "button"> & {
            left: Compilable<boolean>;
            middle: Compilable<boolean>;
            right: Compilable<boolean>;
        };
        x: Compilable.Property<MouseEvent, "clientX">;
        y: Compilable.Property<MouseEvent, "clientY">;
        wheel: {
            delta_mode: Compilable.Property<WheelEvent, "deltaMode">;
            delta_x: Compilable.Property<WheelEvent, "deltaX">;
            delta_y: Compilable.Property<WheelEvent, "deltaY">;
            delta_z: Compilable.Property<WheelEvent, "deltaZ">;
        };
    };
    keyboard: {
        key: Compilable.Property<KeyboardEvent, "key">;
        mod: (mod: string) => Compilable.Computed<boolean>;
    };
    do: {
        target: {
            clear: Compilable.Snippet<any>;
            style: (property: MaybeProperty<string>, value: any) => Compilable.Snippet<any>;
        };
    };
};
/** Registry for compiled event handlers (automatically maintained when compiled). */
export declare let handlers: {
    [id: string]: ReturnType<EventBinder["compile"]>;
};
export {};
