/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host, } from "@stencil/core";
import classNames from "classnames";
import { debounceEvent } from "../../lib/stencil";
/**
 * @slot search-icon - A slot that replaces the component's default search icon.
 * @slot clear-icon - A slot that replaces the component's default clear icon.
 */
export class SceneTreeSearch {
    constructor() {
        /**
         * If `true`, disables user interaction of the component.
         */
        this.disabled = false;
        /**
         * Placeholder text if `value` is empty.
         */
        this.placeholder = undefined;
        /**
         * The current text value of the component. Value is updated on user
         * interaction.
         */
        this.value = '';
        this.focused = false;
        this.isSearching = false;
        this.handleTextInput = (event) => {
            const input = event.target;
            this.value = input.value;
            if (this.debounce != null || this.value === '') {
                this.emitCurrentValue();
            }
        };
        this.handleTextFocus = () => {
            this.focused = true;
        };
        this.handleTextBlur = () => {
            var _a;
            this.focused = false;
            (_a = this.searchDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
            if (this.value !== this.lastEmittedValue) {
                this.emitCurrentValue();
            }
        };
        this.handleKeyPress = (event) => {
            var _a;
            if (event.key === 'Enter') {
                (_a = this.searchDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
                this.emitCurrentValue();
            }
        };
        this.handleClear = (event) => {
            var _a;
            event.preventDefault();
            this.value = '';
            (_a = this.searchDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
            this.emitCurrentValue();
            this.setFocus();
        };
    }
    /**
     * Gives focus to the component's internal text input.
     */
    async setFocus() {
        var _a, _b;
        // HTMLInputElement.focus() doesn't exist in tests.
        if (typeof ((_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.focus) === 'function') {
            (_b = this.inputEl) === null || _b === void 0 ? void 0 : _b.focus();
        }
    }
    /**
     * @ignore
     */
    controllerChanged(controller) {
        this.setupController();
    }
    /**
     * @ignore
     */
    componentDidLoad() {
        this.handleDebounceChanged();
        this.setupController();
    }
    /**
     * @ignore
     */
    disconnectedCallback() {
        var _a;
        (_a = this.onStateChangeDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
    }
    /**
     * Clears the current search term and clears any debounced filters.
     */
    async clear() {
        var _a;
        this.value = '';
        (_a = this.searchDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        this.emitCurrentValue();
    }
    /**
     * @ignore
     */
    render() {
        return (h(Host, { key: 'a147f41b6d1bee253edfea73854697fd48ce713b' }, h("div", { key: '68fb61c2e5310d6f52c696e466661fe75b8119fd', class: "root" }, h("div", { key: 'a19f9bebb23dd3c89547d36dcb251ec8525f3aae', class: "overlay icon icon-search" }, h("slot", { key: '99a2c8c0d48b01e43b2b8717a73652845298442a', name: "search-icon" }, this.isSearching ? (h("vertex-viewer-spinner", { slot: "search-icon", size: "xs" })) : (h("vertex-viewer-icon", { name: "search", size: "sm" })))), h("input", { key: 'feb34cbc91c5813bee85a32c60bf28da1d6069b0', class: classNames('input', {
                background: this.focused || this.value.length > 0,
            }), type: "text", ref: (ref) => (this.inputEl = ref), placeholder: this.placeholder, disabled: this.disabled, value: this.value, onInput: this.handleTextInput, onFocus: this.handleTextFocus, onBlur: this.handleTextBlur, onKeyPress: this.handleKeyPress }), h("div", { key: '0c06291d8c4e7b88e67b720951cd0c46ddd1daf6', class: classNames('overlay overlay-clear', {
                show: this.value.length > 0,
            }) }, h("button", { key: 'c0a1394058c36939f167d84b42070939fad85f83', class: "clear-btn icon", tabIndex: -1, onMouseDown: this.handleClear, disabled: this.disabled }, h("slot", { key: 'afa2e6eb99ddcbb2d1e53138296264ae7620dc51', name: "clear-icon" }, h("vertex-viewer-icon", { key: 'faa225a4caa66374a69e88fb9bb5c48af7a2d4ed', name: "close-circle", size: "sm" })))))));
    }
    handleDebounceChanged() {
        var _a, _b;
        (_a = this.searchDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        const emitter = debounceEvent(this.search, (_b = this.debounce) !== null && _b !== void 0 ? _b : 0);
        // Track this emitter in two separate variables to maintain the `EventEmitter` typing for
        // `this.search`. This allows for correct generation of `CustomEvent` types.
        this.search = emitter;
        this.searchDisposable = emitter;
    }
    setupController() {
        var _a, _b;
        (_a = this.onStateChangeDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        this.onStateChangeDisposable = (_b = this.controller) === null || _b === void 0 ? void 0 : _b.onStateChange.on((state) => {
            // If a search was previously being performed, but has now finished,
            // emit the event that the search has completed.
            if (this.isSearching && !state.isSearching) {
                this.searchCompleted.emit(this.value);
            }
            this.isSearching = state.isSearching;
        });
    }
    emitCurrentValue() {
        this.lastEmittedValue = this.value;
        this.search.emit(this.value);
    }
    static get is() { return "vertex-scene-tree-search"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["scene-tree-search.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["scene-tree-search.css"]
        };
    }
    static get properties() {
        return {
            "debounce": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Specifies the delay, in milliseconds, to emit `search` events after user\ninput.\n\nIf this value is specified, searches will automatically occur after a\nkeystroke has occurred and the debounce threshold has elapsed.\n\nDefaults to `undefined`, and searches only occur on an `Enter` press\nor a `blur` event."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "debounce"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, disables user interaction of the component."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "placeholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Placeholder text if `value` is empty."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "placeholder",
                "defaultValue": "undefined"
            },
            "controller": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "SceneTreeController",
                    "resolved": "SceneTreeController | undefined",
                    "references": {
                        "SceneTreeController": {
                            "location": "import",
                            "path": "../scene-tree/lib/controller",
                            "id": "src/components/scene-tree/lib/controller.ts::SceneTreeController",
                            "referenceLocation": "SceneTreeController"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The scene tree controller"
                },
                "getter": false,
                "setter": false
            },
            "value": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The current text value of the component. Value is updated on user\ninteraction."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value",
                "defaultValue": "''"
            }
        };
    }
    static get states() {
        return {
            "focused": {},
            "isSearching": {}
        };
    }
    static get events() {
        return [{
                "method": "search",
                "name": "search",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is emitted when a user has changed or cleared the search\nterm. The event may be delayed according to the current `debounce` value."
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }, {
                "method": "searchCompleted",
                "name": "searchCompleted",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is emitted when a search has completed."
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Gives focus to the component's internal text input.",
                    "tags": []
                }
            },
            "clear": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Clears the current search term and clears any debounced filters.",
                    "tags": []
                }
            }
        };
    }
    static get watchers() {
        return [{
                "propName": "controller",
                "methodName": "controllerChanged"
            }];
    }
}
//# sourceMappingURL=scene-tree-search.js.map
