import { TypedEventTarget } from "@hydroperx/event";
import Draggable from "@hydroperx/draggable";
import { EMObserver } from "./utils/EMObserver";
import { TileSizeMap, TileSize } from "./enum/TileSize";
import { State } from "./State";
import { Layout, LayoutGroup, LayoutTile } from "./Layout";
declare const Tiles_base: TypedEventTarget<TilesEventMap>;
/**
 * Tiles layout.
 */
export declare class Tiles extends Tiles_base {
    /**
     * Attribute name used for identifying a tile's ID.
     */
    static readonly ATTR_ID = "data-id";
    /**
     * Attribute name used for indicating a tile's size.
     */
    static readonly ATTR_SIZE = "data-size";
    /**
     * Attribute name used for indicating that a tile is actively in drag.
     */
    static readonly ATTR_DRAGGING = "data-dragging";
    /**
     * Attribute name used for indicating that a tile is checked.
     */
    static readonly ATTR_CHECKED = "data-checked";
    /** @hidden */
    _state: State;
    /** @hidden */
    _container: HTMLElement;
    /** @hidden */
    _dir: "horizontal" | "vertical";
    /** @hidden */
    _class_names: {
        group: string;
        groupLabel: string;
        groupLabelText: string;
        groupTiles: string;
        tile: string;
        tileContent: string;
    };
    /** @hidden */
    _small_size: number;
    /** @hidden */
    _tile_gap: number;
    /** @hidden */
    _group_gap: number;
    /** @hidden */
    _group_width: number;
    /** @hidden */
    _inline_groups: number;
    /** @hidden */
    _height: number;
    /** @hidden */
    _label_height: number;
    /** @hidden */
    _rearrange_timeout: number;
    /** @hidden */
    _state_update_timeout: number;
    /** @hidden */
    _drag_enabled: boolean;
    /** @hidden */
    _selection_enabled: boolean;
    /** @hidden */
    _em_observer: EMObserver;
    /** @hidden */
    _em: number;
    /** @hidden */
    _layout: Layout;
    /** @hidden */
    _buttons: Map<string, HTMLButtonElement>;
    /** @hidden */
    _group_draggables: Map<HTMLDivElement, Draggable>;
    /** @hidden */
    _tile_draggables: Map<HTMLButtonElement, Draggable>;
    /** @hidden */
    _tile_drag_end_handlers: WeakMap<HTMLButtonElement, (element: Element, x: number, y: number, event: Event) => void>;
    /** @hidden */
    _resize_observer: ResizeObserver | null;
    /** @hidden */
    _tile_removal_work: undefined | ((button: HTMLButtonElement) => Promise<void>);
    /** @hidden */
    _group_removal_work: undefined | ((div: HTMLDivElement) => Promise<void>);
    /**
     * Tile sizes in the cascading `em` unit.
     * @hidden
     */
    _tile_em: TileSizeMap;
    constructor(params: {
        /**
         * Container.
         */
        element: Element;
        /**
         * The direction of the tile container.
         */
        direction: "horizontal" | "vertical";
        /**
         * Customisable class names.
         */
        classNames: {
            /**
             * Class name used for identifying groups.
             */
            group: string;
            /**
             * Class name used for identifying group labels.
             */
            groupLabel: string;
            /**
             * Class name used for identifying group label texts.
             */
            groupLabelText: string;
            /**
             * Class name used for identifying the group tiles container.
             */
            groupTiles: string;
            /**
             * Class name used for identifying tiles.
             */
            tile: string;
            /**
             * Class name used for identifying tile contents.
             */
            tileContent: string;
        };
        /**
         * Whether drag-n-drop is enabled.
         * @default true
         */
        dragEnabled?: boolean;
        /**
         * Whether tile selection is enabled.
         * @default true
         */
        selectionEnabled?: boolean;
        /**
         * The size of small tiles, in cascading `em` units.
         */
        smallSize: number;
        /**
         * Gap between tiles, in cascading `em` units.
         */
        tileGap: number;
        /**
         * Gap between groups, in cascading `em` units.
         */
        groupGap: number;
        /**
         * Group width in small tiles, effective only
         * in vertical containers (must be >= 4).
         * @default 6
         */
        groupWidth?: number;
        /**
         * Number of inline groups, effective only
         * in vertical containers (must be >= 1).
         * @default 1
         */
        inlineGroups?: number;
        /**
         * Height in small tiles, effective only
         * in horizontal containers (must be >= 4).
         * @default 6
         */
        height?: number;
        /**
         * Group label height in the cascading `em` unit.
         */
        labelHeight: number;
        /**
         * Work to do before removing a group from the DOM.
         * This is typically used for tweening the group view.
         */
        groupRemovalWork?: (div: HTMLDivElement) => Promise<void>;
        /**
         * Work to do before removing a tile from the DOM.
         * This is typically used for tweening the tile view.
         */
        tileRemovalWork?: (button: HTMLButtonElement) => Promise<void>;
    });
    /**
     * The overall tiles state.
     */
    get state(): State;
    /**
     * Clears everything.
     */
    clear(): void;
    /**
     * Destroys the `Tiles` instance, disposing
     * of any observers and removing the container from the DOM.
     */
    destroy(removeFromDOM?: boolean): void;
    /**
     * Adds a group to the end and returns its `div` element.
     * @throws If group ID is duplicate.
     */
    addGroup(params: AddGroupParams): void;
    /**
     * Removes a group.
     * @throws If the group does not exist.
     */
    removeGroup(id: string): void;
    /**
     * Attempts to add a tile.
     *
     * If both `x` and `y` are null, this method always succeeds,
     * adding the tile to the best position available.
     *
     * @throws If tile ID is duplicate.
     * @throws If group is specified and does not exist.
     * @throws If either of `x` and `y` are `null`, but not both.
     * @returns `true` if successfully added tile; `false` otherwise.
     * It can fail depending on the `x` and `y` parameters.
     */
    addTile(params: AddTileParams): boolean;
    /**
     * Removes a tile.
     * @throws If the tile does not exist.
     */
    removeTile(id: string): void;
    /**
     * Renames a group.
     */
    renameGroup(id: string, label: string): void;
    /**
     * Attempts to resize a tile.
     */
    resizeTile(id: string, size: TileSize): boolean;
    /**
     * Attempts to move a tile.
     * @param x X coordinate in small tiles unit (1x1).
     * @param y Y coordinate in small tiles unit (1x1).
     */
    moveTile(id: string, x: number, y: number): boolean;
    /**
     * Returns which tiles are checked.
     */
    checkedTiles(): string[];
    /**
     * Returns whether a tile is checked or not.
     */
    getChecked(tile: string): boolean;
    /**
     * Sets whether a tile is checked or not.
     */
    setChecked(tile: string, value: boolean): void;
    /**
     * Toggles whether a tile is checked or not.
     */
    toggleChecked(tile: string): void;
    /**
     * Shorthand to `addEventListener()`.
     */
    on<K extends keyof TilesEventMap>(type: K, listenerFn: (event: TilesEventMap[K]) => void, options?: AddEventListenerOptions): void;
    on(type: string, listenerFn: (event: Event) => void, options?: AddEventListenerOptions): void;
    /**
     * Shorthand to `removeEventListener()`.
     */
    off<K extends keyof TilesEventMap>(type: K, listenerFn: (event: TilesEventMap[K]) => void, options?: EventListenerOptions): void;
    off(type: string, listenerFn: (event: Event) => void, options?: EventListenerOptions): void;
    /**
     * Returns the number of inline groups available for
     * the given width (either in `px` or `em`).
     * *Applies to vertical layouts only.*
     *
     * @throws If not in a vertical layout.
     */
    inlineGroupsAvailable(width: string): number;
    /**
     * Indicates the number of inline groups in a vertical layout.
     *
     * @throws If not in a vertical layout.
     */
    get inlineGroups(): number;
    set inlineGroups(val: number);
    /**
     * Rearranges the layout.
     *
     * This call may be necessary if the container is scaled to zero, usable
     * after the scale is greater than zero.
     */
    rearrange(): void;
    /**
     * Rearranges the layout when the minimum scale to make it work
     * is reached.
     *
     * This call may be necessary if the container is initially scaled to zero.
     */
    rearrangeOverMinimumScale(): AbortController;
    /** @hidden */
    _keep_groups_contiguous(): void;
    /** @hidden */
    _deferred_rearrange(): void;
    /** @hidden */
    _deferred_state_update_signal(): void;
    /** @hidden */
    _state_update_signal(): void;
}
/**
 * Tiles event map.
 */
export type TilesEventMap = {
    addedgroup: CustomEvent<{
        group: LayoutGroup;
        div: HTMLDivElement;
        labelDiv: HTMLDivElement;
        tilesDiv: HTMLDivElement;
    }>;
    addedtile: CustomEvent<{
        tile: LayoutTile;
        button: HTMLButtonElement;
        contentDiv: HTMLDivElement;
    }>;
    stateupdate: CustomEvent<State>;
    dragstart: CustomEvent<{
        tile: HTMLButtonElement;
    }>;
    drag: CustomEvent<{
        tile: HTMLButtonElement;
    }>;
    dragend: CustomEvent<{
        tile: HTMLButtonElement;
    }>;
    groupdragstart: CustomEvent<{
        group: HTMLDivElement;
    }>;
    groupdrag: CustomEvent<{
        group: HTMLDivElement;
    }>;
    groupdragend: CustomEvent<{
        group: HTMLDivElement;
    }>;
    selectionchange: CustomEvent<{
        tiles: string[];
    }>;
    click: CustomEvent<{
        tile: string;
    }>;
};
/**
 * Parameters for adding a group.
 */
export type AddGroupParams = {
    /**
     * Unique group ID.
     */
    id: string;
    /**
     * Initial label to display for the group.
     * @default ""
     */
    label?: string;
};
/**
 * Parameters for adding a tile.
 */
export type AddTileParams = {
    /**
     * Tile ID.
     */
    id: string;
    /**
     * Group to attach tile to. If unspecified,
     * tile is attached to either the last group (if unlabeled)
     * or a new last anonymous group.
     */
    group?: string;
    /**
     * Horizontal position in small tiles.
     */
    x?: number;
    /**
     * Vertical position in small tiles.
     */
    y?: number;
    /**
     * Tile size.
     * @default medium
     */
    size?: TileSize;
};
export {};
