/*!
 * (C) Ionic http://ionicframework.com - MIT License
 */
import arrowLeftRegular from "@phosphor-icons/core/assets/regular/arrow-left.svg";
import magnifyingGlassRegular from "@phosphor-icons/core/assets/regular/magnifying-glass.svg";
import xRegular from "@phosphor-icons/core/assets/regular/x.svg";
import { Host, forceUpdate, h } from "@stencil/core";
import { debounceEvent, raf, componentOnReady, inheritAttributes } from "../../utils/helpers";
import { isRTL } from "../../utils/rtl/index";
import { createColorClasses, hostContext } from "../../utils/theme";
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from "ionicons/icons";
import { config } from "../../global/config";
import { getIonTheme } from "../../global/ionic-global";
/**
 * @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
 * @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
 */
export class Searchbar {
    constructor() {
        this.isCancelVisible = false;
        this.shouldAlignLeft = true;
        this.inputId = `ion-searchbar-${searchbarIds++}`;
        this.inheritedAttributes = {};
        this.focused = false;
        this.noAnimate = true;
        /**
         * If `true`, enable searchbar animation.
         */
        this.animated = false;
        /**
         * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
         * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
         */
        this.autocapitalize = 'off';
        /**
         * Set the input's autocomplete property.
         */
        this.autocomplete = 'off';
        /**
         * Set the input's autocorrect property.
         */
        this.autocorrect = 'off';
        /**
         * Set the cancel button text. Only available when the theme is `"ios"`.
         */
        this.cancelButtonText = 'Cancel';
        /**
         * If `true`, the user cannot interact with the input.
         */
        this.disabled = false;
        /**
         * If used in a form, set the name of the control, which is submitted with the form data.
         */
        this.name = this.inputId;
        /**
         * Set the input's placeholder.
         * `placeholder` can accept either plaintext or HTML as a string.
         * To display characters normally reserved for HTML, they
         * must be escaped. For example `<Ionic>` would become
         * `&lt;Ionic&gt;`
         *
         * For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
         */
        this.placeholder = 'Search';
        /**
         * Sets the behavior for the cancel button. Defaults to `"never"`.
         * Setting to `"focus"` shows the cancel button on focus.
         * Setting to `"never"` hides the cancel button.
         * Setting to `"always"` shows the cancel button regardless
         * of focus state.
         */
        this.showCancelButton = 'never';
        /**
         * Sets the behavior for the clear button. Defaults to `"focus"`.
         * Setting to `"focus"` shows the clear button on focus if the
         * input is not empty.
         * Setting to `"never"` hides the clear button.
         * Setting to `"always"` shows the clear button regardless
         * of focus state, but only if the input is not empty.
         */
        this.showClearButton = 'always';
        /**
         * If `true`, enable spellcheck on the input.
         */
        this.spellcheck = false;
        /**
         * Set the type of the input.
         */
        this.type = 'search';
        /**
         * the value of the searchbar.
         */
        this.value = '';
        /**
         * Clears the input field and triggers the control change.
         */
        this.onClearInput = async (shouldFocus) => {
            this.ionClear.emit();
            return new Promise((resolve) => {
                // setTimeout() fixes https://github.com/ionic-team/ionic-framework/issues/7527
                // wait for 4 frames
                setTimeout(() => {
                    const value = this.getValue();
                    if (value !== '') {
                        this.value = '';
                        this.emitInputChange();
                        /**
                         * When tapping clear button
                         * ensure input is focused after
                         * clearing input so users
                         * can quickly start typing.
                         */
                        if (shouldFocus && !this.focused) {
                            this.setFocus();
                            /**
                             * The setFocus call above will clear focusedValue,
                             * but ionChange will never have gotten a chance to
                             * fire. Manually revert focusedValue so onBlur can
                             * compare against what was in the box before the clear.
                             */
                            this.focusedValue = value;
                        }
                    }
                    resolve();
                }, 16 * 4);
            });
        };
        /**
         * Clears the input field and tells the input to blur since
         * the clearInput function doesn't want the input to blur
         * then calls the custom cancel function if the user passed one in.
         */
        this.onCancelSearchbar = async (ev) => {
            if (ev) {
                ev.preventDefault();
                ev.stopPropagation();
            }
            this.ionCancel.emit();
            // get cached values before clearing the input
            const value = this.getValue();
            const focused = this.focused;
            await this.onClearInput();
            /**
             * If there used to be something in the box, and we weren't focused
             * beforehand (meaning no blur fired that would already handle this),
             * manually fire ionChange.
             */
            if (value && !focused) {
                this.emitValueChange(ev);
            }
            if (this.nativeInput) {
                this.nativeInput.blur();
            }
        };
        /**
         * Update the Searchbar input value when the input changes
         */
        this.onInput = (ev) => {
            const input = ev.target;
            if (input) {
                this.value = input.value;
            }
            this.emitInputChange(ev);
        };
        this.onChange = (ev) => {
            this.emitValueChange(ev);
        };
        /**
         * Sets the Searchbar to not focused and checks if it should align left
         * based on whether there is a value in the searchbar or not.
         */
        this.onBlur = (ev) => {
            this.focused = false;
            this.ionBlur.emit();
            this.positionElements();
            if (this.focusedValue !== this.value) {
                this.emitValueChange(ev);
            }
            this.focusedValue = undefined;
        };
        /**
         * Sets the Searchbar to focused and active on input focus.
         */
        this.onFocus = () => {
            this.focused = true;
            this.focusedValue = this.value;
            this.ionFocus.emit();
            this.positionElements();
        };
    }
    /**
     * lang and dir are globally enumerated attributes.
     * As a result, creating these as properties
     * can have unintended side effects. Instead, we
     * listen for attribute changes and inherit them
     * to the inner `<input>` element.
     */
    onLangChanged(newValue) {
        this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { lang: newValue });
        forceUpdate(this);
    }
    onDirChanged(newValue) {
        this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
        forceUpdate(this);
    }
    debounceChanged() {
        const { ionInput, debounce, originalIonInput } = this;
        /**
         * If debounce is undefined, we have to manually revert the ionInput emitter in case
         * debounce used to be set to a number. Otherwise, the event would stay debounced.
         */
        this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
    }
    valueChanged() {
        const inputEl = this.nativeInput;
        const value = this.getValue();
        if (inputEl && inputEl.value !== value) {
            inputEl.value = value;
        }
    }
    showCancelButtonChanged() {
        requestAnimationFrame(() => {
            this.positionElements();
            forceUpdate(this);
        });
    }
    connectedCallback() {
        this.emitStyle();
    }
    componentWillLoad() {
        this.inheritedAttributes = Object.assign({}, inheritAttributes(this.el, ['lang', 'dir']));
    }
    componentDidLoad() {
        this.originalIonInput = this.ionInput;
        this.positionElements();
        this.debounceChanged();
        setTimeout(() => {
            this.noAnimate = false;
        }, 300);
    }
    emitStyle() {
        this.ionStyle.emit({
            searchbar: true,
        });
    }
    /**
     * Sets focus on the native `input` in `ion-searchbar`. Use this method instead of the global
     * `input.focus()`.
     * Developers who wish to focus an input when a page enters
     * should call `setFocus()` in the `ionViewDidEnter()` lifecycle method.
     * Developers who wish to focus an input when an overlay is presented
     * should call `setFocus` after `didPresent` has resolved.
     *
     * See [managing focus](/docs/developing/managing-focus) for more information.
     */
    async setFocus() {
        if (this.nativeInput) {
            this.nativeInput.focus();
        }
    }
    /**
     * Returns the native `<input>` element used under the hood.
     */
    async getInputElement() {
        /**
         * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
         * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
         */
        if (!this.nativeInput) {
            await new Promise((resolve) => componentOnReady(this.el, resolve));
        }
        return Promise.resolve(this.nativeInput);
    }
    /**
     * Emits an `ionChange` event.
     *
     * This API should be called for user committed changes.
     * This API should not be used for external value changes.
     */
    emitValueChange(event) {
        const { value } = this;
        // Checks for both null and undefined values
        const newValue = value == null ? value : value.toString();
        // Emitting a value change should update the internal state for tracking the focused value
        this.focusedValue = newValue;
        this.ionChange.emit({ value: newValue, event });
    }
    /**
     * Emits an `ionInput` event.
     */
    emitInputChange(event) {
        const { value } = this;
        this.ionInput.emit({ value, event });
    }
    /**
     * Positions the input search icon, placeholder, and the cancel button
     * based on the input value and if it is focused. (ios only)
     */
    positionElements() {
        const value = this.getValue();
        const prevAlignLeft = this.shouldAlignLeft;
        const theme = getIonTheme(this);
        const shouldAlignLeft = !this.animated || value.trim() !== '' || !!this.focused;
        this.shouldAlignLeft = shouldAlignLeft;
        if (theme !== 'ios') {
            return;
        }
        if (prevAlignLeft !== shouldAlignLeft) {
            this.positionPlaceholder();
        }
        if (this.animated) {
            this.positionCancelButton();
        }
    }
    /**
     * Positions the input placeholder
     */
    positionPlaceholder() {
        const inputEl = this.nativeInput;
        if (!inputEl) {
            return;
        }
        const rtl = isRTL(this.el);
        const iconEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-search-icon');
        if (this.shouldAlignLeft) {
            inputEl.removeAttribute('style');
            iconEl.removeAttribute('style');
        }
        else {
            // Create a dummy span to get the placeholder width
            const doc = document;
            const tempSpan = doc.createElement('span');
            tempSpan.innerText = this.placeholder || '';
            doc.body.appendChild(tempSpan);
            // Get the width of the span then remove it
            raf(() => {
                const textWidth = tempSpan.offsetWidth;
                tempSpan.remove();
                // Calculate the input padding
                const inputLeft = 'calc(50% - ' + textWidth / 2 + 'px)';
                // Calculate the icon margin
                /**
                 * We take the icon width to account
                 * for any text scales applied to the icon
                 * such as Dynamic Type on iOS as well as 8px
                 * of padding.
                 */
                const iconLeft = 'calc(50% - ' + (textWidth / 2 + iconEl.clientWidth + 8) + 'px)';
                // Set the input padding start and icon margin start
                if (rtl) {
                    inputEl.style.paddingRight = inputLeft;
                    iconEl.style.marginRight = iconLeft;
                }
                else {
                    inputEl.style.paddingLeft = inputLeft;
                    iconEl.style.marginLeft = iconLeft;
                }
            });
        }
    }
    /**
     * Show the iOS Cancel button on focus, hide it offscreen otherwise
     */
    positionCancelButton() {
        const rtl = isRTL(this.el);
        const cancelButton = (this.el.shadowRoot || this.el).querySelector('.searchbar-cancel-button');
        const shouldShowCancel = this.shouldShowCancelButton();
        if (cancelButton !== null && shouldShowCancel !== this.isCancelVisible) {
            const cancelStyle = cancelButton.style;
            this.isCancelVisible = shouldShowCancel;
            if (shouldShowCancel) {
                if (rtl) {
                    cancelStyle.marginLeft = '0';
                }
                else {
                    cancelStyle.marginRight = '0';
                }
            }
            else {
                const offset = cancelButton.offsetWidth;
                if (offset > 0) {
                    if (rtl) {
                        cancelStyle.marginLeft = -offset + 'px';
                    }
                    else {
                        cancelStyle.marginRight = -offset + 'px';
                    }
                }
            }
        }
    }
    getValue() {
        return this.value || '';
    }
    hasValue() {
        return this.getValue() !== '';
    }
    shouldShowSearchIcon() {
        if (this.searchIcon === false || this.searchIcon === 'false') {
            return false;
        }
        return true;
    }
    /**
     * Determines whether or not the cancel button should be visible onscreen.
     * Cancel button should be shown if one of two conditions applies:
     * 1. `showCancelButton` is set to `always`.
     * 2. `showCancelButton` is set to `focus`, and the searchbar has been focused.
     */
    shouldShowCancelButton() {
        if (this.showCancelButton === 'never' || (this.showCancelButton === 'focus' && !this.focused)) {
            return false;
        }
        return true;
    }
    /**
     * Determines whether or not the clear button should be visible onscreen.
     * Clear button should be shown if one of two conditions applies:
     * 1. `showClearButton` is set to `always`.
     * 2. `showClearButton` is set to `focus`, and the searchbar has been focused.
     * Unless the `theme` is `ionic` and the searchbar is disabled.
     */
    shouldShowClearButton() {
        const theme = getIonTheme(this);
        if (this.showClearButton === 'never' || (this.showClearButton === 'focus' && !this.focused)) {
            return false;
        }
        if (theme === 'ionic' && this.disabled) {
            return false;
        }
        return true;
    }
    getShape() {
        const theme = getIonTheme(this);
        const { shape } = this;
        // TODO(ROU-11677): Remove theme check when shapes are defined for all themes.
        if (theme !== 'ionic') {
            return undefined;
        }
        if (shape === undefined) {
            return 'round';
        }
        return shape;
    }
    getSize() {
        const theme = getIonTheme(this);
        const { size } = this;
        // TODO(ROU-11678): Remove theme check when sizes are defined for all themes.
        if (theme !== 'ionic') {
            return undefined;
        }
        if (size === undefined) {
            return 'medium';
        }
        return size;
    }
    /**
     * Get the icon to use for the clear icon.
     * If an icon is set on the component, use that.
     * Otherwise, use the icon set in the config.
     * If no icon is set in the config, use the default icon.
     */
    get searchbarClearIcon() {
        // Return the icon if it is explicitly set
        if (this.clearIcon != null) {
            return this.clearIcon;
        }
        // Determine the theme and map to default icons
        const theme = getIonTheme(this);
        const defaultIcons = {
            ios: closeCircle,
            ionic: xRegular,
            md: closeSharp,
        };
        // Get the default icon based on the theme, falling back to 'md' icon if necessary
        const defaultIcon = defaultIcons[theme] || defaultIcons.md;
        // Return the configured searchbar clear icon or the default icon
        return config.get('searchbarClearIcon', defaultIcon);
    }
    /**
     * Get the icon to use for the search icon.
     * If an icon is set on the component, use that.
     * Otherwise, use the icon set in the config.
     * If no icon is set in the config, use the default icon.
     */
    get searchbarSearchIcon() {
        // Return the icon if it is explicitly set.
        // If the icon is set to a boolean or string 'true', use the default icon.
        if (this.searchIcon != null && this.searchIcon !== 'true' && typeof this.searchIcon !== 'boolean') {
            return this.searchIcon;
        }
        // Determine the theme and map to default icons
        const theme = getIonTheme(this);
        const defaultIcons = {
            ios: searchOutline,
            ionic: magnifyingGlassRegular,
            md: searchSharp,
        };
        // Get the default icon based on the theme, falling back to 'md' icon if necessary
        const defaultIcon = defaultIcons[theme] || defaultIcons.md;
        // Return the configured searchbar search icon or the default icon
        return config.get('searchbarSearchIcon', defaultIcon);
    }
    /**
     * Get the icon to use for the cancel icon.
     * If an icon is set on the component, use that.
     * Otherwise, use the icon set in the config.
     * If no icon is set in the config, use the default icon.
     */
    get searchbarCancelIcon() {
        // Return the icon if it is explicitly set
        if (this.cancelButtonIcon != null) {
            return this.cancelButtonIcon;
        }
        // Determine the theme and map to default icons
        const theme = getIonTheme(this);
        const defaultIcons = {
            ios: arrowBackSharp,
            ionic: arrowLeftRegular,
            md: arrowBackSharp,
        };
        // Get the default icon based on the theme, falling back to 'md' icon if necessary
        const defaultIcon = defaultIcons[theme] || defaultIcons.md;
        // Return the configured searchbar cancel icon, the back button icon or the default icon
        return config.get('searchbarCancelIcon', config.get('backButtonIcon', defaultIcon));
    }
    render() {
        const { cancelButtonText, autocapitalize, searchbarCancelIcon, searchbarClearIcon, searchbarSearchIcon } = this;
        const animated = this.animated && config.getBoolean('animated', true);
        const theme = getIonTheme(this);
        const shouldShowCancelButton = this.shouldShowCancelButton();
        const shape = this.getShape();
        const size = this.getSize();
        const cancelButton = this.showCancelButton !== 'never' && (h("button", { key: '3f7daa2a4ec57132e8baf591542569338e7ec9c8', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: theme === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, h("div", { key: 'f214142fec5644d91eae82644558e6b817094957', "aria-hidden": "true" }, theme === 'md' || theme === 'ionic' ? (h("ion-icon", { "aria-hidden": "true", icon: searchbarCancelIcon, lazy: false })) : (cancelButtonText))));
        return (h(Host, { key: '47e075305f28373fffab3e006ab4014da6dfb0c8', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
                [theme]: true,
                'searchbar-animated': animated,
                'searchbar-disabled': this.disabled,
                'searchbar-no-animate': animated && this.noAnimate,
                'searchbar-has-value': this.hasValue(),
                'searchbar-left-aligned': this.shouldAlignLeft,
                'searchbar-has-focus': this.focused,
                'searchbar-should-show-search-icon': this.shouldShowSearchIcon(),
                'searchbar-should-show-clear': this.shouldShowClearButton(),
                'searchbar-should-show-cancel': this.shouldShowCancelButton(),
                [`searchbar-shape-${shape}`]: shape !== undefined,
                [`searchbar-size-${size}`]: size !== undefined,
                'in-toolbar': hostContext('ion-toolbar', this.el),
            }) }, h("div", { key: '14b271ab3eebf1b651a8cfd758c7880b548bb98d', class: "searchbar-input-container" }, h("input", Object.assign({ key: 'f84a9435002eba2084ce0269fa3c926b7c03209d', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), (theme === 'md' || theme === 'ionic') && cancelButton, this.shouldShowSearchIcon() && (h("ion-icon", { key: 'e1c7a66dba99591b0e3df5966acd027a561ee0ca', "aria-hidden": "true", icon: searchbarSearchIcon, lazy: false, class: "searchbar-search-icon" })), this.shouldShowClearButton() && (h("button", { key: 'bf55ac02128e22f9d303e75b9289c251bd582cdd', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
                /**
                 * This prevents mobile browsers from
                 * blurring the input when the clear
                 * button is activated.
                 */
                ev.preventDefault();
            }, onClick: () => this.onClearInput(true) }, h("ion-icon", { key: '1ce87193499ccb682ad115a64cc5579e9bb586c9', "aria-hidden": "true", icon: searchbarClearIcon, lazy: false, class: "searchbar-clear-icon" })))), theme === 'ios' && cancelButton));
    }
    static get is() { return "ion-searchbar"; }
    static get encapsulation() { return "scoped"; }
    static get originalStyleUrls() {
        return {
            "ios": ["searchbar.ios.scss"],
            "md": ["searchbar.md.scss"],
            "ionic": ["searchbar.ionic.scss"]
        };
    }
    static get styleUrls() {
        return {
            "ios": ["searchbar.ios.css"],
            "md": ["searchbar.md.css"],
            "ionic": ["searchbar.ionic.css"]
        };
    }
    static get properties() {
        return {
            "color": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Color",
                    "resolved": "\"danger\" | \"dark\" | \"light\" | \"medium\" | \"primary\" | \"secondary\" | \"success\" | \"tertiary\" | \"warning\" | string & Record<never, never> | undefined",
                    "references": {
                        "Color": {
                            "location": "import",
                            "path": "../../interface",
                            "id": "src/interface.d.ts::Color"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The color to use from your application's color palette.\nDefault options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`.\nFor more information on colors, see [theming](/docs/theming/basics)."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "color"
            },
            "animated": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, enable searchbar animation."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "animated",
                "defaultValue": "false"
            },
            "autocapitalize": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.\nAvailable options: `\"off\"`, `\"none\"`, `\"on\"`, `\"sentences\"`, `\"words\"`, `\"characters\"`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "autocapitalize",
                "defaultValue": "'off'"
            },
            "autocomplete": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "AutocompleteTypes",
                    "resolved": "\"name\" | \"url\" | \"off\" | \"on\" | \"additional-name\" | \"address-level1\" | \"address-level2\" | \"address-level3\" | \"address-level4\" | \"address-line1\" | \"address-line2\" | \"address-line3\" | \"bday-day\" | \"bday-month\" | \"bday-year\" | \"cc-csc\" | \"cc-exp\" | \"cc-exp-month\" | \"cc-exp-year\" | \"cc-family-name\" | \"cc-given-name\" | \"cc-name\" | \"cc-number\" | \"cc-type\" | \"country\" | \"country-name\" | \"current-password\" | \"family-name\" | \"given-name\" | \"honorific-prefix\" | \"honorific-suffix\" | \"new-password\" | \"one-time-code\" | \"organization\" | \"postal-code\" | \"street-address\" | \"transaction-amount\" | \"transaction-currency\" | \"username\" | \"email\" | \"tel\" | \"tel-area-code\" | \"tel-country-code\" | \"tel-extension\" | \"tel-local\" | \"tel-national\" | \"nickname\" | \"organization-title\" | \"cc-additional-name\" | \"language\" | \"bday\" | \"sex\" | \"impp\" | \"photo\"",
                    "references": {
                        "AutocompleteTypes": {
                            "location": "import",
                            "path": "../../interface",
                            "id": "src/interface.d.ts::AutocompleteTypes"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the input's autocomplete property."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "autocomplete",
                "defaultValue": "'off'"
            },
            "autocorrect": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'on' | 'off'",
                    "resolved": "\"off\" | \"on\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the input's autocorrect property."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "autocorrect",
                "defaultValue": "'off'"
            },
            "cancelButtonIcon": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set the cancel button icon. Only available when the theme is `\"md\"`.\nDefaults to `\"arrow-back-sharp\"`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "cancel-button-icon"
            },
            "cancelButtonText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the cancel button text. Only available when the theme is `\"ios\"`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "cancel-button-text",
                "defaultValue": "'Cancel'"
            },
            "clearIcon": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set the clear icon. Defaults to `\"close-circle\"` for `\"ios\"` theme and `\"close-sharp\"` for `\"md\"` and `\"ionic\"` theme."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "clear-icon"
            },
            "debounce": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke."
                },
                "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`, the user cannot interact with the input."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "inputmode": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search'",
                    "resolved": "\"decimal\" | \"email\" | \"none\" | \"numeric\" | \"search\" | \"tel\" | \"text\" | \"url\" | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A hint to the browser for which keyboard to display.\nPossible values: `\"none\"`, `\"text\"`, `\"tel\"`, `\"url\"`,\n`\"email\"`, `\"numeric\"`, `\"decimal\"`, and `\"search\"`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "inputmode"
            },
            "enterkeyhint": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send'",
                    "resolved": "\"done\" | \"enter\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A hint to the browser for which enter key to display.\nPossible values: `\"enter\"`, `\"done\"`, `\"go\"`, `\"next\"`,\n`\"previous\"`, `\"search\"`, and `\"send\"`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "enterkeyhint"
            },
            "maxlength": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "This attribute specifies the maximum number of characters that the user can enter."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "maxlength"
            },
            "minlength": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "This attribute specifies the minimum number of characters that the user can enter."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "minlength"
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If used in a form, set the name of the control, which is submitted with the form data."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "name",
                "defaultValue": "this.inputId"
            },
            "placeholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the input's placeholder.\n`placeholder` can accept either plaintext or HTML as a string.\nTo display characters normally reserved for HTML, they\nmust be escaped. For example `<Ionic>` would become\n`&lt;Ionic&gt;`\n\nFor more information: [Security Documentation](https://ionicframework.com/docs/faq/security)"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "placeholder",
                "defaultValue": "'Search'"
            },
            "searchIcon": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "string | boolean",
                    "resolved": "boolean | string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The icon to use as the search icon. Defaults to `\"search-outline\"` in\nthe `\"ios\"` theme and `\"search-sharp\"` in the `\"md\"` and `\"ionic\"` themes.\nIf `false`, no search icon will be displayed."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "search-icon"
            },
            "showCancelButton": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'never' | 'focus' | 'always'",
                    "resolved": "\"always\" | \"focus\" | \"never\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the behavior for the cancel button. Defaults to `\"never\"`.\nSetting to `\"focus\"` shows the cancel button on focus.\nSetting to `\"never\"` hides the cancel button.\nSetting to `\"always\"` shows the cancel button regardless\nof focus state."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "show-cancel-button",
                "defaultValue": "'never'"
            },
            "showClearButton": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'never' | 'focus' | 'always'",
                    "resolved": "\"always\" | \"focus\" | \"never\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Sets the behavior for the clear button. Defaults to `\"focus\"`.\nSetting to `\"focus\"` shows the clear button on focus if the\ninput is not empty.\nSetting to `\"never\"` hides the clear button.\nSetting to `\"always\"` shows the clear button regardless\nof focus state, but only if the input is not empty."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "show-clear-button",
                "defaultValue": "'always'"
            },
            "spellcheck": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, enable spellcheck on the input."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "spellcheck",
                "defaultValue": "false"
            },
            "type": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'text' | 'password' | 'email' | 'number' | 'search' | 'tel' | 'url'",
                    "resolved": "\"email\" | \"number\" | \"password\" | \"search\" | \"tel\" | \"text\" | \"url\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set the type of the input."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "type",
                "defaultValue": "'search'"
            },
            "value": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string | null",
                    "resolved": "null | string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "the value of the searchbar."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value",
                "defaultValue": "''"
            },
            "shape": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'soft' | 'round' | 'rectangular'",
                    "resolved": "\"rectangular\" | \"round\" | \"soft\" | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set to `\"soft\"` for a searchbar with slightly rounded corners,\n`\"round\"` for a searchbar with fully rounded corners,\nor `\"rectangular\"` for a searchbar without rounded corners.\n\nDefaults to `\"round\"` for the ionic theme, and `undefined` for all other themes."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "shape"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'small' | 'medium' | 'large'",
                    "resolved": "\"large\" | \"medium\" | \"small\" | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Set to `\"large\"` for a searchbar with an increase in height,\nwhile \"small\" and \"medium\" provide progressively smaller heights.\n\nDefaults to `\"medium\"` for the ionic theme, and `undefined` for all other themes."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "size"
            }
        };
    }
    static get states() {
        return {
            "focused": {},
            "noAnimate": {}
        };
    }
    static get events() {
        return [{
                "method": "ionInput",
                "name": "ionInput",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the `value` of the `ion-searchbar` element has changed."
                },
                "complexType": {
                    "original": "SearchbarInputEventDetail",
                    "resolved": "SearchbarInputEventDetail",
                    "references": {
                        "SearchbarInputEventDetail": {
                            "location": "import",
                            "path": "./searchbar-interface",
                            "id": "src/components/searchbar/searchbar-interface.ts::SearchbarInputEventDetail"
                        }
                    }
                }
            }, {
                "method": "ionChange",
                "name": "ionChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "The `ionChange` event is fired for `<ion-searchbar>` elements when the user\nmodifies the element's value. Unlike the `ionInput` event, the `ionChange`\nevent is not necessarily fired for each alteration to an element's value.\n\nThe `ionChange` event is fired when the value has been committed\nby the user. This can happen when the element loses focus or\nwhen the \"Enter\" key is pressed. `ionChange` can also fire\nwhen clicking the clear or cancel buttons.\n\nThis event will not emit when programmatically setting the `value` property."
                },
                "complexType": {
                    "original": "SearchbarChangeEventDetail",
                    "resolved": "SearchbarChangeEventDetail",
                    "references": {
                        "SearchbarChangeEventDetail": {
                            "location": "import",
                            "path": "./searchbar-interface",
                            "id": "src/components/searchbar/searchbar-interface.ts::SearchbarChangeEventDetail"
                        }
                    }
                }
            }, {
                "method": "ionCancel",
                "name": "ionCancel",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the cancel button is clicked."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "ionClear",
                "name": "ionClear",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the clear input button is clicked."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "ionBlur",
                "name": "ionBlur",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the input loses focus."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "ionFocus",
                "name": "ionFocus",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when the input has focus."
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "ionStyle",
                "name": "ionStyle",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": "Emitted when the styles change."
                },
                "complexType": {
                    "original": "StyleEventDetail",
                    "resolved": "StyleEventDetail",
                    "references": {
                        "StyleEventDetail": {
                            "location": "import",
                            "path": "../../interface",
                            "id": "src/interface.d.ts::StyleEventDetail"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets focus on the native `input` in `ion-searchbar`. Use this method instead of the global\n`input.focus()`.\nDevelopers who wish to focus an input when a page enters\nshould call `setFocus()` in the `ionViewDidEnter()` lifecycle method.\nDevelopers who wish to focus an input when an overlay is presented\nshould call `setFocus` after `didPresent` has resolved.\n\nSee [managing focus](/docs/developing/managing-focus) for more information.",
                    "tags": []
                }
            },
            "getInputElement": {
                "complexType": {
                    "signature": "() => Promise<HTMLInputElement>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "HTMLInputElement": {
                            "location": "global",
                            "id": "global::HTMLInputElement"
                        }
                    },
                    "return": "Promise<HTMLInputElement>"
                },
                "docs": {
                    "text": "Returns the native `<input>` element used under the hood.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "lang",
                "methodName": "onLangChanged"
            }, {
                "propName": "dir",
                "methodName": "onDirChanged"
            }, {
                "propName": "debounce",
                "methodName": "debounceChanged"
            }, {
                "propName": "value",
                "methodName": "valueChanged"
            }, {
                "propName": "showCancelButton",
                "methodName": "showCancelButtonChanged"
            }];
    }
}
let searchbarIds = 0;
