import { L as ListenerAbstract, a as SingleSubject } from './listener-CClDIhvK.js';
import { b as balBrowser } from './browser-B1u-Mq75.js';
import { b as waitAfterIdleCallback, i as isDescendant, o as addEventListener, p as removeEventListener } from './helpers-BNj87EbG.js';

class BalFocusListener extends ListenerAbstract {
    constructor() {
        super(...arguments);
        this.onFocusin = (ev) => {
            this.notify({ ev, isFocusIn: true, isFocusOut: false });
        };
        this.onFocusout = async (ev) => {
            await waitAfterIdleCallback();
            if (balBrowser.hasDocument && this.el) {
                const target = document.activeElement;
                if (target && !isDescendant(this.el, target)) {
                    this.notify({ ev, isFocusIn: false, isFocusOut: true });
                }
            }
        };
    }
    connect(el) {
        super.connect(el);
        if (this.el) {
            addEventListener(this.el, 'focusin', this.onFocusin);
            addEventListener(this.el, 'focusout', this.onFocusout);
        }
    }
    disconnect() {
        super.disconnect();
        if (this.el) {
            removeEventListener(this.el, 'focusin', this.onFocusin);
            removeEventListener(this.el, 'focusout', this.onFocusout);
        }
    }
}

class BalFocusSubject extends SingleSubject {
    constructor() {
        super((observer, data) => {
            if (data) {
                if (data.isFocusIn) {
                    if (observer.hasFocus === false) {
                        observer.focusInListener(data.ev);
                    }
                    observer.hasFocus = true;
                }
                if (data.isFocusOut) {
                    observer.focusOutListener(data.ev);
                    observer.hasFocus = false;
                }
            }
        });
        this.listener = new BalFocusListener();
    }
    attach(observer) {
        super.attach(observer);
        this.listener.connect(observer.el);
        this.listener.add(info => super.notify(info));
    }
    detach() {
        super.detach();
        this.listener.disconnect();
    }
}

function ListenToFocus() {
    return function (target, _propertyKey, _descriptor) {
        const { connectedCallback, disconnectedCallback } = target;
        target.connectedCallback = function () {
            if (!this._balFocusSubject) {
                this._balFocusSubject = new BalFocusSubject();
                this._balFocusSubject.attach(this);
            }
            return connectedCallback && connectedCallback.call(this);
        };
        target.disconnectedCallback = function () {
            if (this._balFocusSubject) {
                this._balFocusSubject.detach();
                this._balFocusSubject = undefined;
            }
            return disconnectedCallback && disconnectedCallback.call(this);
        };
    };
}

export { ListenToFocus as L };
