import { PopupOpenCases, PopupCloseCases } from "./popupElement.types";
import { AttributeMap } from "../baseElement";
import WUPPopupArrowElement from "./popupArrowElement";
import PopupListener from "./popupListener";
import WUPBaseModal from "../baseModal";
declare const tagName = "wup-popup";
declare global {
    interface HTMLElementTagNameMap {
        [tagName]: WUPPopupElement;
    }
}
declare module "react" {
    namespace JSX {
        interface IntrinsicElements {
            /**  Popup element
             *  @see {@link WUPPopupElement} */
            [tagName]: WUP.Base.ReactHTML<WUPPopupElement> & WUP.BaseModal.JSXProps & WUP.Popup.Attributes;
        }
    }
}
declare module "preact/jsx-runtime" {
    namespace JSX {
        interface HTMLAttributes<RefType> {
        }
        interface IntrinsicElements {
            /**  Popup element
             *  @see {@link WUPPopupElement} */
            [tagName]: HTMLAttributes<WUPPopupElement> & WUP.Modal.JSXProps;
        }
    }
}
/** Popup element
 * @see demo {@link https://yegorich555.github.io/web-ui-pack/popup}
 * @example
 * JS/TS
 * ```js
 * WUPPopupElement.$defaults.arrowEnable = true;
 *
 * const el = document.createElement('wup-popup');
 * el.$options.openCase = PopupOpenCases.onClick | PopupOpenCases.onFocus;
 * el.$options.target = document.querySelector('button');
 * // if placement impossible according to rules rest of possible rules will be applied
 * el.$options.placement = [
 *  WUPPopupElement.$placements.$top.$middle,
 *  WUPPopupElement.$placements.$bottom.$middle,
 *  WUPPopupElement.$placements.$bottom.$middle.$adjust, // adjust means 'ignore align to fit layout`
 *  WUPPopupElement.$placements.$bottom.$middle.$adjust.$resizeHeight, // resize means 'allow to resize to fit layout'
 * ];
 * document.body.append(el);
 * // or
 * const btn = document.querySelector('button');
 * // this is the most recommended way because $attach appends popup only by onShow and removes byHide
 * const detach = WUPPopupElement.$attach(
                    { target: btn, text: "Some text content here", openCase: PopupOpenCases.onFocus | PopupOpenCases.onClick },
                    (popup) => { popup.className = "popup-class-here"; }
                  )'
 *```
 * HTML
 * ```html
 * <button id="btn1">Target</button>
 * <!-- You can skip pointing attribute 'target' if popup appended after target -->
 * <wup-popup w-target="#btn1" w-placement="top-start">Some content here</wup-popup>
 * ```
 * @tutorial Troubleshooting:
 * * You can set minWidth, minHeight to prevent squeezing of popup or don't use rule '.$adjust'
 * * Don't override styles: display, transform (possible to override only for animation)
 * * Don't use inline styles: maxWidth, maxHeight, minWidth, minHeight
 * * If target removed (when popup $isOpened) and appended again you need to update $options.target (because $options.target cleared)
 * * Popup has overflow 'auto'; If you change to 'visible' it will apply maxWidth/maxHeight to first children (because popup must be restricted by maxSize to avoid layout issues)
 * * During the closing attr 'hide' is appended only if css-animation-duration is detected
 * * Popup can't be more than 100vw & 100vh (impossible to disable the rule)
 * * known issue: popup can be positioned wrong if parent has transfrom style: https://stackoverflow.com/revisions/15256339/2 this is css-core issue. To fix: place popup outside such parent or remove transform style on parent */
export default class WUPPopupElement<TOptions extends WUP.Popup.Options = WUP.Popup.Options, Events extends WUP.Popup.EventMap = WUP.Popup.EventMap> extends WUPBaseModal<TOptions, Events> {
    #private;
    /** Returns this.constructor // watch-fix: https://github.com/Microsoft/TypeScript/issues/3841#issuecomment-337560146 */
    static get observedOptions(): Array<keyof WUP.Popup.Options>;
    static get observedAttributes(): Array<string>;
    static get mappedAttributes(): Record<string, AttributeMap>;
    static $placements: {
        $top: WUP.Popup.Place.EdgeFunc;
        $bottom: WUP.Popup.Place.EdgeFunc;
        $left: WUP.Popup.Place.EdgeFunc;
        $right: WUP.Popup.Place.EdgeFunc;
    };
    /** Returns placement */
    static $placementAttrs: (attr: WUP.Popup.Attributes["w-placement"]) => Array<WUP.Popup.Place.PlaceFunc> | undefined;
    static get $styleRoot(): string;
    static get $style(): string;
    /** Default options. Change it to configure default behavior */
    static $defaults: WUP.Popup.Options;
    static cloneDefaults<T extends Record<string, any>>(): T;
    /** Listen for target according to openCase and create/remove popup when it's required (by open/close).
     *  This helps to avoid tons of hidden popups on HTML;
     *  Firing detach doesn't required if target removed by target.remove() or target.parent.removeChild(target);
     *  If target is removed via changing innerHTML you should fire detach() to avoid memoryLeak
     *  @returns detach-function (hide,remove popup and remove eventListeners)
     *  @example
     *  const detach = WUPPopupElement.$attach(
     *     {
     *       target: document.querySelector("button") as HTMLElement,
     *       text: "Some text here",
     *       openCase: PopupOpenCases.onClick,
     *     },
     *     // (el) => el.class = "popup-attached"
     *   );
     * @tutorial Troubleshooting:
     * * $attach doesn't work with openCase.always it doesn't make sense
     * * every new attach on the same target > re-init previous (1 attach per target is possible)
     * * Firing detach() doesn't required if target removed by `target.remove()` or `target.parent.removeChild(target)`;
     * * If popup is hidden and target is removed via `target.parent.innerHTML="another content"` you should fire detach() to avoid memoryLeak
     */
    static $attach<T extends WUPPopupElement>(options: WUP.Popup.AttachOptions, 
    /** Fires when popup is added to document */
    callback?: (el: T) => void): () => void;
    /** Returns arrowElement if $options.arrowEnable=true and after popup $isOpened */
    $refArrow?: WUPPopupArrowElement;
    /** Force to update position. Call this if related styles are changed & need to re-calc position */
    $refresh(): void;
    protected gotReady(): void;
    protected gotRender(): void;
    _refListener?: PopupListener;
    /** Called after gotReady() and $open() (to re-init according to options) */
    protected init(): void;
    protected gotChanges(propsChanged: Array<string> | null): void;
    /** Defines target on show; @returns Element | Error */
    defineTarget(): HTMLElement | SVGElement;
    protected setMaxHeight(px: number | null): void;
    protected setMaxWidth(px: number | null): void;
    /** Collect/calc all required values into #state (when menu shows) */
    protected buildState(): void;
    /** Required to stop previous animations/timeouts (for case when option animation is changed) */
    _stopAnimation?: () => void;
    protected goAnimate(animTime: number, isHide: boolean): Promise<boolean>;
    goOpen(openCase: PopupOpenCases, ev: MouseEvent | FocusEvent | null): Promise<boolean>;
    gotOpen(openCase: PopupOpenCases, ev: MouseEvent | FocusEvent | null): void;
    goClose(closeCase: PopupCloseCases, ev: MouseEvent | FocusEvent | KeyboardEvent | null): Promise<boolean>;
    /** Hide popup. @closeCase as reason of hide(). Calling 2nd time at once will stop previous hide-animation */
    gotClose(closeCase: PopupCloseCases, ev: MouseEvent | FocusEvent | KeyboardEvent | null, immediately?: boolean): void;
    /** Returns `target.getBoundingClientRect()` Use function to change placement logic based on target-rect
     * @WARN it's called with screen-frequency (per frame) */
    getTargetRect(target: Element): DOMRect;
    /** Update position of popup. Call this method in cases when you changed options */
    protected updatePosition(): DOMRect | undefined;
    protected resetState(): void;
    protected gotRemoved(): void;
    /** Call when need to re-init */
    protected disposeListener(): void;
    protected dispose(): void;
}
export {};
