import { RemoteEvent } from './RemoteEvent.ts';
import type { RemoteElementAttributeDefinition, RemoteElementEventListenerDefinition, RemoteElementEventListenersDefinition, RemoteElementPropertiesDefinition, RemoteElementPropertyDefinition, RemoteElementPropertyTypeOrBuiltIn, RemoteElementSlotsDefinition, RemoteElementSlotDefinition } from './types.ts';
/**
 * A class that represents a remote custom element, which can have properties,
 * attributes, event listeners, methods, and slots that are synchronized with
 * a host environment.
 */
export type RemoteElementConstructor<Properties extends Record<string, any> = {}, Methods extends Record<string, (...args: any[]) => any> = {}, Slots extends Record<string, any> = {}, EventListeners extends Record<string, any> = {}> = {
    new (): RemoteElement<Properties, Methods, Slots, EventListeners> & Properties & Methods;
    /**
     * The slots that can be populated on this remote element.
     */
    readonly remoteSlots?: RemoteElementSlotsDefinition<Slots> | readonly (keyof Slots)[];
    /**
     * The resolved slot definitions for this remote element.
     */
    readonly remoteSlotDefinitions: Map<string, RemoteElementSlotDefinition>;
    /**
     * The properties that can be synchronized between this remote element and
     * its host representation.
     */
    readonly remoteProperties?: RemoteElementPropertiesDefinition<Properties> | readonly (keyof Properties)[];
    /**
     * The resolved property definitions for this remote element.
     */
    readonly remotePropertyDefinitions: Map<string, RemoteElementPropertyNormalizedDefinition>;
    /**
     * Creates a new definition for a property that will be synchronized between
     * this remote element and its host representation.
     */
    createProperty<Value = unknown>(name: string, definition?: RemoteElementPropertyDefinition<Value>): void;
    /**
     * The attributes that can be synchronized between this remote element and
     * its host representation.
     */
    readonly remoteAttributes?: readonly string[];
    /**
     * The resolved attribute definitions for this remote element.
     */
    readonly remoteAttributeDefinitions: Map<string, RemoteElementAttributeDefinition>;
    /**
     * The event listeners that can be synchronized between this remote element
     * and its host representation.
     */
    readonly remoteEvents?: RemoteElementEventListenersDefinition<EventListeners> | readonly (keyof EventListeners)[];
    /**
     * The resolved event listener definitions for this remote element.
     */
    readonly remoteEventDefinitions: Map<string, RemoteElementEventListenerDefinition>;
    /**
     * The methods on the corresponding host element that you can call from the remote
     * environment.
     */
    readonly remoteMethods?: Methods | readonly (keyof Methods)[];
};
/**
 * Returns the properties type from a remote element constructor.
 */
export type RemotePropertiesFromElementConstructor<T> = T extends {
    new (): RemoteElement<infer Properties, any, any, any>;
} ? Properties : never;
/**
 * Returns the methods type from a remote element constructor.
 */
export type RemoteMethodsFromElementConstructor<T> = T extends {
    new (): RemoteElement<any, infer Methods, any, any>;
} ? Methods : never;
/**
 * Returns the slots type from a remote element constructor.
 */
export type RemoteSlotsFromElementConstructor<T> = T extends {
    new (): RemoteElement<any, any, infer Slots, any>;
} ? Slots : never;
/**
 * Returns the event listeners type from a remote element constructor.
 */
export type RemoteEventListenersFromElementConstructor<T> = T extends {
    new (): RemoteElement<any, any, any, infer EventListeners>;
} ? EventListeners : never;
/**
 * Options that can be passed when creating a new remote element class with
 * `createRemoteElement()`.
 */
export interface RemoteElementCreatorOptions<Properties extends Record<string, any> = {}, Methods extends Record<string, any> = {}, Slots extends Record<string, any> = {}, EventListeners extends Record<string, any> = {}> {
    /**
     * The slots that can be populated on this remote element.
     */
    slots?: RemoteElementConstructor<Properties, Methods, Slots, EventListeners>['remoteSlots'];
    /**
     * The properties that can be synchronized between this remote element and
     * its host representation.
     */
    properties?: RemoteElementConstructor<Properties, Methods, Slots, EventListeners>['remoteProperties'];
    /**
     * The attributes that can be synchronized between this remote element and
     * its host representation.
     */
    attributes?: RemoteElementConstructor<Properties, Methods, Slots, EventListeners>['remoteAttributes'];
    /**
     * The event listeners that can be synchronized between this remote element
     * and its host representation.
     */
    events?: RemoteElementConstructor<Properties, Methods, Slots, EventListeners>['remoteEvents'];
    /**
     * The methods on the corresponding host element that you can call from the remote
     * environment.
     */
    methods?: RemoteElementConstructor<Properties, Methods, Slots, EventListeners>['remoteMethods'];
}
export declare function createRemoteElement<Properties extends Record<string, any> = {}, Methods extends Record<string, any> = {}, Slots extends Record<string, any> = {}, EventListeners extends Record<string, any> = {}>({ slots, properties, attributes, events, methods, }?: NoInfer<RemoteElementCreatorOptions<Properties, Methods, Slots, EventListeners>>): RemoteElementConstructor<Properties, Methods, Slots, EventListeners>;
/**
 * A base class for creating “remote” HTML elements, which have properties, attributes,
 * event listeners, slots, and methods that can be synchronized between a host and
 * remote environment. When subclassing `RemoteElement`, you can define how different fields
 * in the class will be synchronized by defining the `remoteProperties`, `remoteAttributes`,
 * `remoteEvents`, and/or `remoteMethods` static properties.
 *
 * @example
 * ```ts
 * class CustomButton extends RemoteElement {
 *   static remoteAttributes = ['disabled', 'primary'];
 *   static remoteEvents = ['click'];
 *
 *   focus() {
 *     console.log('Calling focus in the remote environment...');
 *     return this.callRemoteMethod('focus');
 *   }
 * }
 * ```
 */
export declare abstract class RemoteElement<Properties extends Record<string, any> = {}, Methods extends Record<string, (...args: any[]) => any> = {}, Slots extends Record<string, any> = {}, EventListeners extends Record<string, any> = {}> extends HTMLElement {
    static readonly slottable = true;
    static readonly remoteSlots?: any;
    static readonly remoteProperties?: any;
    static readonly remoteAttributes?: any;
    static readonly remoteEvents?: any;
    static readonly remoteMethods?: any;
    static get observedAttributes(): string[];
    /**
     * The resolved property definitions for this remote element.
     */
    static get remotePropertyDefinitions(): Map<string, RemoteElementPropertyNormalizedDefinition>;
    /**
     * The resolved attribute definitions for this remote element.
     */
    static get remoteAttributeDefinitions(): Map<string, RemoteElementAttributeDefinition>;
    /**
     * The resolved event listener definitions for this remote element.
     */
    static get remoteEventDefinitions(): Map<string, RemoteElementEventListenerDefinition>;
    /**
     * The resolved slot definitions for this remote element.
     */
    static get remoteSlotDefinitions(): Map<string, RemoteElementSlotDefinition>;
    protected static __finalized: boolean;
    private static readonly __observedAttributes;
    private static readonly __attributeToPropertyMap;
    private static readonly __eventToPropertyMap;
    private static readonly __remotePropertyDefinitions;
    private static readonly __remoteAttributeDefinitions;
    private static readonly __remoteEventDefinitions;
    private static readonly __remoteSlotDefinitions;
    /**
     * Creates a new definition for a property that will be synchronized between
     * this remote element and its host representation.
     */
    static createProperty<Value = unknown>(name: string, definition?: RemoteElementPropertyDefinition<Value>): void;
    /**
     * Consumes all the static members defined on the class and converts them
     * into the internal representation used to handle properties, attributes,
     * and event listeners.
     */
    protected static finalize(): typeof this;
    /** @internal */
    __slots?: Slots;
    /** @internal */
    __properties?: Properties;
    /** @internal */
    __methods?: Methods;
    /** @internal */
    __eventListeners?: EventListeners;
    constructor();
    attributeChangedCallback(attribute: string, _oldValue: any, newValue: any): void;
    connectedCallback(): void;
    disconnectedCallback(): void;
    addEventListener(type: string, listener: ((event: RemoteEvent) => void) | {
        handleEvent: (event: RemoteEvent) => void;
    } | null, options?: boolean | AddEventListenerOptions): void;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
    /**
     * Updates a single remote property on an element node. If the element is
     * connected to a remote root, this function will also make a `mutate()` call
     * to communicate the change to the host.
     */
    updateRemoteProperty(name: string, value?: unknown): void;
    /**
     * Updates a single remote attribute on an element node. If the element is
     * connected to a remote root, this function will also make a `mutate()` call
     * to communicate the change to the host.
     */
    updateRemoteAttribute(name: string, value?: string): void;
    /**
     * Performs a method through `RemoteConnection.call()`, using the remote ID and
     * connection for the provided node.
     */
    callRemoteMethod(method: string, ...args: any[]): unknown;
}
interface RemoteElementPropertyNormalizedDefinition<Value = unknown> {
    name: string;
    type: RemoteElementPropertyTypeOrBuiltIn<Value>;
    alias?: string[];
    event?: string;
    attribute?: string;
    default?: Value;
}
export {};
//# sourceMappingURL=RemoteElement.d.ts.map