var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try {
            step(generator.next(value));
        }
        catch (e) {
            reject(e);
        } }
        function rejected(value) { try {
            step(generator["throw"](value));
        }
        catch (e) {
            reject(e);
        } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { Host, h } from "@stencil/core";
export class CpslPopover {
    constructor() {
        this.startedInside = false;
        this.startedWhenMounted = false;
        this.configureTriggerInteraction = () => {
            const { trigger, triggerAction, destroyTriggerInteraction } = this;
            if (destroyTriggerInteraction) {
                destroyTriggerInteraction();
            }
            if (trigger === undefined) {
                return;
            }
            this.triggerEl = document.getElementById(trigger);
            if (!this.triggerEl) {
                console.error(`A trigger element with the ID "${trigger}" was not found in the DOM.`, this.el);
                return;
            }
            let triggerCallbacks = [];
            /**
             * Based upon the kind of trigger interaction
             * the user wants, we setup the correct event
             * listeners.
             */
            switch (triggerAction) {
                case 'hover':
                    triggerCallbacks = [
                        {
                            eventName: 'mouseenter',
                            callback: () => __awaiter(this, void 0, void 0, function* () {
                                this.present();
                            }),
                        },
                        {
                            eventName: 'mouseleave',
                            callback: () => {
                                if (!this.containerEl.matches(':hover')) {
                                    this.close();
                                }
                                else {
                                    this.containerEl.addEventListener('mouseleave', () => {
                                        this.close();
                                    });
                                }
                            },
                        },
                        {
                            eventName: 'click',
                            callback: (ev) => ev.stopPropagation(),
                        },
                    ];
                    break;
                case 'click':
                default:
                    triggerCallbacks = [
                        {
                            eventName: 'click',
                            callback: (e) => {
                                var _a;
                                const targetId = (_a = e.target.id) !== null && _a !== void 0 ? _a : '';
                                if (targetId === 'ignore-click') {
                                    return;
                                }
                                if (!this.open) {
                                    this.present();
                                }
                            },
                        },
                    ];
                    break;
            }
            triggerCallbacks.forEach(({ eventName, callback }) => this.triggerEl.addEventListener(eventName, callback));
            this.destroyTriggerInteraction = () => {
                triggerCallbacks.forEach(({ eventName, callback }) => this.triggerEl.removeEventListener(eventName, callback));
            };
        };
        this.setPosition = () => {
            var _a;
            const anchorEl = (_a = this.anchorEl) !== null && _a !== void 0 ? _a : this.triggerEl;
            if (anchorEl && typeof window !== 'undefined') {
                const windowWidth = window.innerWidth;
                const windowHeight = window.innerHeight;
                const elWidth = this.el.clientWidth;
                const elHeight = this.el.clientHeight;
                const { top, left, height, width } = anchorEl.getBoundingClientRect();
                if (this.alignCenter) {
                    this.positionX = left + (width / 2 - elWidth / 2);
                }
                else {
                    switch (this.anchorOriginHorizontal) {
                        case 'left': {
                            this.positionX = left;
                            break;
                        }
                        case 'center': {
                            this.positionX = left + width / 2;
                            break;
                        }
                        case 'right': {
                            this.positionX = left + width;
                            break;
                        }
                    }
                }
                switch (this.anchorOriginVertical) {
                    case 'top': {
                        this.positionY = top;
                        break;
                    }
                    case 'center': {
                        this.positionY = top + height / 2;
                        break;
                    }
                    case 'bottom': {
                        this.positionY = top + height;
                        break;
                    }
                }
                if (this.positionY < this.windowPadding) {
                    this.positionY = this.windowPadding;
                }
                if (this.positionY + elHeight > windowHeight - 16) {
                    this.positionY = windowHeight - this.windowPadding - elHeight;
                }
                if (this.positionX < this.windowPadding) {
                    this.positionX = this.windowPadding;
                }
                if (this.positionX + elWidth > windowWidth - 16) {
                    this.positionX = windowWidth - this.windowPadding - elWidth;
                }
            }
        };
        this.validateEventStart = event => {
            this.startedWhenMounted = !!this.triggerEl;
            this.startedInside = this.triggerEl.contains(event.target);
            this.present();
        };
        this.handleClickOutside = (event) => {
            // Do nothing if `mousedown` or `touchstart` started inside ref element
            if (this.startedInside || !this.startedWhenMounted)
                return;
            // Do nothing if clicking ref's element or descendent elements
            if (!this.triggerEl || this.triggerEl.contains(event.target))
                return;
            if (this.open) {
                event.preventDefault();
                this.close();
            }
        };
        this.present = () => {
            if (!this.open && !this.disabled) {
                this.open = true;
                this.cpslOpen.emit();
                // Using a small timeout here to ensure the popover is open before attempting to do position calculations
                setTimeout(() => {
                    this.setPosition();
                    this.hasSetInitialPosition = true;
                }, 20);
            }
        };
        this.close = () => {
            this.open = false;
            this.startedInside = false;
            this.cpslClose.emit();
            this.hasSetInitialPosition = false;
        };
        this.open = false;
        this.hasSetInitialPosition = false;
        this.positionX = undefined;
        this.positionY = undefined;
        this.anchorEl = undefined;
        this.anchorOriginHorizontal = 'left';
        this.anchorOriginVertical = 'bottom';
        this.autoWidth = true;
        this.disabled = undefined;
        this.preventBlur = undefined;
        this.transformOriginHorizontal = 'left';
        this.transformOriginVertical = 'top';
        this.alignCenter = false;
        this.triggerAction = 'click';
        this.trigger = undefined;
        this.windowPadding = 16;
    }
    /**
     * Call to close the popover manually.
     */
    closePopover() {
        return __awaiter(this, void 0, void 0, function* () {
            this.close();
        });
    }
    onTriggerChange() {
        this.configureTriggerInteraction();
    }
    onAnchorChange() {
        this.setPosition();
    }
    onOpenChange() {
        if (typeof window !== 'undefined') {
            if (this.open) {
                window.addEventListener('mousedown', this.validateEventStart);
                window.addEventListener('touchstart', this.validateEventStart);
                window.addEventListener('click', this.handleClickOutside);
                window.addEventListener('scroll', () => this.setPosition(), true);
                window.addEventListener('resize', () => this.setPosition(), true);
            }
            else {
                window.removeEventListener('mousedown', this.validateEventStart);
                window.removeEventListener('touchstart', this.validateEventStart);
                window.removeEventListener('click', this.handleClickOutside);
                window.removeEventListener('scroll', () => this.setPosition(), true);
                window.removeEventListener('resize', () => this.setPosition(), true);
            }
        }
    }
    componentDidLoad() {
        this.configureTriggerInteraction();
    }
    get containerEl() {
        var _a, _b;
        return (_b = (_a = this.el) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.getElementById('container');
    }
    render() {
        var _a;
        return (h(Host, { key: 'b089bf481952dd5183b53929b194af4378b60f85', class: {
                'open': this.open,
                'transform-h-left': this.transformOriginHorizontal === 'left',
                'transform-h-center': this.transformOriginHorizontal === 'center',
                'transform-h-right': this.transformOriginHorizontal === 'right',
                'transform-v-top': this.transformOriginVertical === 'top',
                'transform-v-center': this.transformOriginVertical === 'center',
                'transform-v-bottom': this.transformOriginVertical === 'bottom',
            }, style: {
                top: `${this.positionY}px`,
                left: `${this.positionX}px`,
                width: !this.open ? '0px' : this.autoWidth ? 'auto' : `${(_a = this.triggerEl) === null || _a === void 0 ? void 0 : _a.clientWidth}px`,
            } }, h("div", { key: 'ffd47e631fa98bda0d70b65e8dd770cb7b5ee0ba', id: "container", class: { container: true, open: this.open }, style: {
                visibility: this.hasSetInitialPosition ? 'visible' : 'hidden',
            } }, h("slot", { key: 'f43b727062744846e24a775321dd1220e20595bc' }))));
    }
    static get is() { return "cpsl-popover"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["cpsl-popover.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["cpsl-popover.css"]
        };
    }
    static get properties() {
        return {
            "anchorEl": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "HTMLElement",
                    "resolved": "HTMLElement",
                    "references": {
                        "HTMLElement": {
                            "location": "global",
                            "id": "global::HTMLElement"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "ID for the element that the popover anchors to."
                }
            },
            "anchorOriginHorizontal": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'left' | 'center' | 'right'",
                    "resolved": "\"center\" | \"left\" | \"right\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Vertical anchor origin.\nOptions are: `\"left\"`, `\"center\"`, `\"right\"`.\nDefault is: `\"left\"`."
                },
                "attribute": "anchor-origin-horizontal",
                "reflect": false,
                "defaultValue": "'left'"
            },
            "anchorOriginVertical": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'top' | 'center' | 'bottom'",
                    "resolved": "\"bottom\" | \"center\" | \"top\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Vertical anchor origin.\nOptions are: `\"top\"`, `\"center\"`, `\"bottom\"`.\nDefault is: `\"bottom\"`."
                },
                "attribute": "anchor-origin-vertical",
                "reflect": false,
                "defaultValue": "'bottom'"
            },
            "autoWidth": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true` the container will use the width of the content, else it will be set to the width of the trigger.\nDefault is `true`"
                },
                "attribute": "auto-width",
                "reflect": false,
                "defaultValue": "true"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Whether or not to disable to popover."
                },
                "attribute": "disabled",
                "reflect": false
            },
            "preventBlur": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Used internally to prevent select from blurring unintentionally."
                },
                "attribute": "prevent-blur",
                "reflect": false
            },
            "transformOriginHorizontal": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'left' | 'center' | 'right'",
                    "resolved": "\"center\" | \"left\" | \"right\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Vertical transformation origin.\nOptions are: `\"left\"`, `\"center\"`, `\"right\"`.\nDefault is: `\"left\"`."
                },
                "attribute": "transform-origin-horizontal",
                "reflect": false,
                "defaultValue": "'left'"
            },
            "transformOriginVertical": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'top' | 'center' | 'bottom'",
                    "resolved": "\"bottom\" | \"center\" | \"top\"",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Vertical transformation origin.\nOptions are: `\"top\"`, `\"center\"`, `\"bottom\"`.\nDefault is: `\"bottom\"`."
                },
                "attribute": "transform-origin-vertical",
                "reflect": false,
                "defaultValue": "'top'"
            },
            "alignCenter": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the popover will be aligned to the center of the trigger element.\nDefault is `false`."
                },
                "attribute": "align-center",
                "reflect": false,
                "defaultValue": "false"
            },
            "triggerAction": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'click' | 'hover'",
                    "resolved": "\"click\" | \"hover\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Which trigger causes the popover to open.\nOptions are: `\"click\"`, `\"hover\"`.\nDefault is: `\"click\"`."
                },
                "attribute": "trigger-action",
                "reflect": false,
                "defaultValue": "'click'"
            },
            "trigger": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "ID for the element that triggers the popover to open."
                },
                "attribute": "trigger",
                "reflect": false
            },
            "windowPadding": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Padding from edge of window for the popover container."
                },
                "attribute": "window-padding",
                "reflect": false,
                "defaultValue": "16"
            }
        };
    }
    static get states() {
        return {
            "open": {},
            "hasSetInitialPosition": {},
            "positionX": {},
            "positionY": {}
        };
    }
    static get events() {
        return [{
                "method": "cpslOpen",
                "name": "cpslOpen",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the popover opens."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "cpslClose",
                "name": "cpslClose",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the popover closes."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "closePopover": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Call to close the popover manually.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "trigger",
                "methodName": "onTriggerChange"
            }, {
                "propName": "triggerAction",
                "methodName": "onTriggerChange"
            }, {
                "propName": "preventBlur",
                "methodName": "onTriggerChange"
            }, {
                "propName": "anchorOriginHorizontal",
                "methodName": "onAnchorChange"
            }, {
                "propName": "anchorOriginVertical",
                "methodName": "onAnchorChange"
            }, {
                "propName": "alignCenter",
                "methodName": "onAnchorChange"
            }, {
                "propName": "open",
                "methodName": "onOpenChange"
            }];
    }
}
//# sourceMappingURL=cpsl-popover.js.map
