import { Component, h, Host, Element, Prop, State, Method, Event, Watch } from '@stencil/core';
export class Select {
  constructor() {
    this.isDropdownOpen = false;
    this.textToScrollTo = '';
    /**
     * If `true` the filtering of the options is done outside of the component.
     */
    this.remote = false;
    /**
     * If `true` the component uses the whole width.
     */
    this.expanded = false;
    /**
     * Set this to `true` when the component is placed on a dark background.
     */
    this.inverted = false;
    /**
     * If `true` the component is diabled.
     */
    this.disabled = false;
    /**
     * If `true` the user can search by typing into the input field.
     */
    this.typeahead = false;
    /**
     * If `true` the component shows a loading spinner and sets the input to readonly.
     */
    this.loading = false;
    /**
     * Defines the placeholder of the input element.
     */
    this.placeholder = '';
    /**
     * Defines the height of the dropdown list.
     */
    this.scrollable = 250;
    /**
     * List of the options.
     */
    this.options = [];
  }
  optionsChanged() {
    if (this.typeahead && this.remote) {
      if (this.options.length === 0) {
        this.dropdownElement.close();
      }
      else {
        if (this.inputElement.value.length > 0) {
          this.dropdownElement.open();
        }
      }
    }
  }
  async open() {
    if (this.disabled) {
      return undefined;
    }
    this.dropdownElement.open();
  }
  async close() {
    if (this.disabled) {
      return undefined;
    }
    this.dropdownElement.close();
  }
  /**
   *
   */
  async select(option) {
    var _a, _b;
    this.value = option;
    this.balChange.emit(this.value);
    this.inputElement.value = (_a = this.value) === null || _a === void 0 ? void 0 : _a.text;
    await ((_b = this.dropdownElement) === null || _b === void 0 ? void 0 : _b.toggle());
    this.updateOptionProps();
  }
  /**
   * Sets the value to null and resets the value of the input.
   */
  async clear() {
    this.value = null;
    this.inputElement.value = '';
    this.updateOptionProps();
  }
  async setFocus() {
    if (this.inputElement) {
      this.inputElement.focus();
    }
  }
  async onInputClick(event) {
    var _a;
    if (this.disabled) {
      return undefined;
    }
    this.balClick.emit(event);
    if (!this.typeahead) {
      await ((_a = this.dropdownElement) === null || _a === void 0 ? void 0 : _a.toggle());
    }
  }
  onDropdownChange(event) {
    this.isDropdownOpen = event.detail;
    event.stopPropagation();
  }
  onInput(event) {
    const inputValue = event.target.value;
    this.balInput.emit(inputValue);
    if (!this.remote) {
      this.updateOptionProps();
    }
    if (this.typeahead && inputValue.length === 0) {
      this.dropdownElement.close();
    }
    if (this.typeahead && !this.remote && inputValue.length > 0) {
      this.dropdownElement.open();
    }
  }
  updateOptionProps() {
    const inputValue = this.inputElement.value;
    this.childOptions.forEach(option => {
      if (!this.remote && this.typeahead) {
        const didMatch = this.compareForFilter(`${option.value.text}` || '', `${inputValue}`);
        option.setAttribute('hidden', `${!didMatch}`);
      }
      const isSelected = !!this.value && this.value.value === option.value.value;
      option.setAttribute('selected', `${isSelected}`);
    });
  }
  compareForFilter(text, input) {
    text = text.toLocaleLowerCase();
    input = input.toLocaleLowerCase();
    return text.indexOf(input) >= 0;
  }
  onKeyPress(event) {
    this.balKeyPress.emit(event);
    if (!this.typeahead) {
      this.textToScrollTo = this.textToScrollTo + event.key;
      clearTimeout(this.clearScrollToValue);
      this.clearScrollToValue = setTimeout(() => {
        this.scrollToText(this.textToScrollTo);
        this.textToScrollTo = '';
      }, 600);
    }
  }
  async scrollToText(input) {
    const dropdownContentElement = await this.dropdownElement.getContentElement();
    const optionElement = this.childOptions.find(o => this.compareForFilter(o.value.text, input));
    if (optionElement) {
      dropdownContentElement.scrollTop = optionElement.offsetTop;
    }
  }
  get childOptions() {
    return Array.from(this.element.querySelectorAll('bal-select-option'));
  }
  render() {
    var _a;
    return (h(Host, { role: "listbox" },
      h("bal-dropdown", { expanded: this.expanded, scrollable: this.scrollable, onBalCollapse: e => this.onDropdownChange(e), ref: el => (this.dropdownElement = el) },
        h("div", { class: "control has-icons-right", slot: "trigger" },
          h("input", { class: {
              'input': true,
              'clickable': true,
              'is-inverted': this.inverted,
            }, readonly: !this.typeahead || this.loading, autoComplete: "off", disabled: this.disabled, placeholder: this.placeholder, value: (_a = this.value) === null || _a === void 0 ? void 0 : _a.text, onInput: e => this.onInput(e), onClick: e => this.onInputClick(e), onKeyPress: e => this.onKeyPress(e), onBlur: e => this.balBlur.emit(e), onFocus: e => this.balFocus.emit(e), ref: el => (this.inputElement = el) }),
          h("bal-icon", { size: "medium", "is-right": true, turn: !this.loading && !this.typeahead && this.isDropdownOpen, rotate: this.loading, color: this.inverted ? 'white' : 'blue', name: this.loading ? 'refresh' : this.typeahead ? 'search' : 'caret-down' })),
        this.options.map(option => (h("bal-select-option", { value: option }))))));
  }
  static get is() { return "bal-select"; }
  static get encapsulation() { return "scoped"; }
  static get originalStyleUrls() { return {
    "$": ["bal-select.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["bal-select.css"]
  }; }
  static get properties() { return {
    "remote": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "If `true` the filtering of the options is done outside of the component."
      },
      "attribute": "remote",
      "reflect": false,
      "defaultValue": "false"
    },
    "expanded": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "If `true` the component uses the whole width."
      },
      "attribute": "expanded",
      "reflect": false,
      "defaultValue": "false"
    },
    "inverted": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Set this to `true` when the component is placed on a dark background."
      },
      "attribute": "inverted",
      "reflect": false,
      "defaultValue": "false"
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "If `true` the component is diabled."
      },
      "attribute": "disabled",
      "reflect": false,
      "defaultValue": "false"
    },
    "typeahead": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "If `true` the user can search by typing into the input field."
      },
      "attribute": "typeahead",
      "reflect": false,
      "defaultValue": "false"
    },
    "loading": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "If `true` the component shows a loading spinner and sets the input to readonly."
      },
      "attribute": "loading",
      "reflect": false,
      "defaultValue": "false"
    },
    "placeholder": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Defines the placeholder of the input element."
      },
      "attribute": "placeholder",
      "reflect": false,
      "defaultValue": "''"
    },
    "scrollable": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Defines the height of the dropdown list."
      },
      "attribute": "scrollable",
      "reflect": false,
      "defaultValue": "250"
    },
    "value": {
      "type": "unknown",
      "mutable": true,
      "complexType": {
        "original": "BalOptionValue<any>",
        "resolved": "BalOptionValue<any>",
        "references": {
          "BalOptionValue": {
            "location": "import",
            "path": "../bal-select-option/bal-select-option.type"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "Selected option value."
      }
    },
    "options": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "BalOptionValue<any>[]",
        "resolved": "BalOptionValue<any>[]",
        "references": {
          "BalOptionValue": {
            "location": "import",
            "path": "../bal-select-option/bal-select-option.type"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [],
        "text": "List of the options."
      },
      "defaultValue": "[]"
    }
  }; }
  static get states() { return {
    "isDropdownOpen": {},
    "textToScrollTo": {}
  }; }
  static get events() { return [{
      "method": "balChange",
      "name": "balChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when a option got selected."
      },
      "complexType": {
        "original": "BalOptionValue<any>",
        "resolved": "BalOptionValue<any>",
        "references": {
          "BalOptionValue": {
            "location": "import",
            "path": "../bal-select-option/bal-select-option.type"
          }
        }
      }
    }, {
      "method": "balInput",
      "name": "balInput",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when a keyboard input occurred."
      },
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      }
    }, {
      "method": "balCancel",
      "name": "balCancel",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the selection is cancelled."
      },
      "complexType": {
        "original": "void",
        "resolved": "void",
        "references": {}
      }
    }, {
      "method": "balBlur",
      "name": "balBlur",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the input loses focus."
      },
      "complexType": {
        "original": "FocusEvent",
        "resolved": "FocusEvent",
        "references": {
          "FocusEvent": {
            "location": "global"
          }
        }
      }
    }, {
      "method": "balFocus",
      "name": "balFocus",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the input has focus."
      },
      "complexType": {
        "original": "FocusEvent",
        "resolved": "FocusEvent",
        "references": {
          "FocusEvent": {
            "location": "global"
          }
        }
      }
    }, {
      "method": "balClick",
      "name": "balClick",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the input got clicked."
      },
      "complexType": {
        "original": "MouseEvent",
        "resolved": "MouseEvent",
        "references": {
          "MouseEvent": {
            "location": "global"
          }
        }
      }
    }, {
      "method": "balKeyPress",
      "name": "balKeyPress",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [],
        "text": "Emitted when the input has focus and key from the keyboard go hit."
      },
      "complexType": {
        "original": "KeyboardEvent",
        "resolved": "KeyboardEvent",
        "references": {
          "KeyboardEvent": {
            "location": "global"
          }
        }
      }
    }]; }
  static get methods() { return {
    "open": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    },
    "close": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    },
    "select": {
      "complexType": {
        "signature": "(option: BalOptionValue<any>) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          },
          "BalOptionValue": {
            "location": "import",
            "path": "../bal-select-option/bal-select-option.type"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    },
    "clear": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Sets the value to null and resets the value of the input.",
        "tags": []
      }
    },
    "setFocus": {
      "complexType": {
        "signature": "() => Promise<void>",
        "parameters": [],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "",
        "tags": []
      }
    }
  }; }
  static get elementRef() { return "element"; }
  static get watchers() { return [{
      "propName": "options",
      "methodName": "optionsChanged"
    }]; }
}
