{"mappings":"AAEA,cAAc,sBAA0C;AAGxD,OAAO,WAAW;;;;;;;;;;AA4BlB,cAiCM,eAAe,MAAM;CACzB,AACA;CAEA,AACA;CAEA,AACA;CAEA,AACA,QAAQ;EACN;EACA;;CAGF,AACA,UAAU;CAEV,UAAU,aAAa;CACvB,UAAU;CACV,UAAU;CAEV,UAAU,UAAU,eAAe;CAuCnC,UAAU,iBAAiB,eAAe;CAM1C,UAAU;CAkBV,UAAU;CAMV;CAKA,OAAO,eAAe,gBAAgB,IAAI;CAiB1C;CAOA;CAeA;CAQA,MAAM,UAAU;CAMhB;;AAOF,eAAe;AACf,SAAS","names":[],"sources":["../../../../src/web-components/select/component.ts"],"sourcesContent":["import { type HandlerEvent, attr, godown, htmlSlot, styles } from \"@godown/element\";\nimport svgCaretDown from \"../../internal/icons/caret-down.js\";\nimport { type TemplateResult, css, html, nothing } from \"lit\";\nimport { property, query } from \"lit/decorators.js\";\n\nimport Input from \"../input/component.js\";\nimport { hidePopover, showPopover } from \"../../internal/popover.js\";\nimport { memoize } from \"../../internal/utils.js\";\n\nconst supportsPositionArea = memoize(() => CSS.supports(\"position-area:top\"));\n\nfunction updateSelected(element: HTMLElement | null, operation: 0 | 1) {\n  if (element) {\n    const name = \"selected\";\n    if (operation) {\n      element.setAttribute(name, \"\");\n    } else {\n      element.removeAttribute(name);\n    }\n  }\n}\n\nconst protoName = \"select\";\n\n/**\n * {@linkcode Select} is similar to `<select>`.\n *\n * @fires input - Fires when the input value changes.\n * @fires change - Fires when the input value changes.\n * @fires select - Fires when select an option.\n * @slot - Options.\n * @category input\n */\n@godown(protoName)\n@styles(css`\n  [part=\"root\"] {\n    position: relative;\n    anchor-name: --select;\n  }\n\n  label {\n    display: contents;\n  }\n\n  [part=\"popover\"] {\n    border: 0;\n    width: 100%;\n    background: none;\n    position-anchor: --select;\n    position-area: bottom center;\n    position-try-fallbacks: flip-block;\n  }\n\n  [part=\"input\"] {\n    text-overflow: ellipsis;\n  }\n\n  @supports not (position-area: top) {\n    [part=\"popover\"] {\n      left: 0;\n      top: 100%;\n      display: none;\n      position: absolute;\n    }\n  }\n`)\nclass Select extends Input {\n  @property()\n  text: string;\n\n  @property({ type: Boolean })\n  multiple = false;\n\n  @property({ type: Boolean })\n  noEdit = false;\n\n  @property({ type: Array })\n  values: {\n    value: string;\n    label?: string;\n  }[] = [];\n\n  @query(\"[part=popover]\")\n  _popover: HTMLElement;\n\n  protected lastChecked: HTMLElement;\n  protected defaultText: string;\n  protected optionsVisible = false;\n\n  protected render(): TemplateResult<1> {\n    const inputNoEdit = this.noEdit || this.disabled;\n    return html`\n      <label\n        part=\"root\"\n        ${attr(this.observedRecord)}\n      >\n        ${[\n          this._renderPrefix(),\n          this.noEdit\n            ? html`\n                <input style=\"position: absolute;inset: 0;opacity: 0;\" />\n              `\n            : \"\",\n          html`\n            <input\n              part=\"input\"\n              .value=\"${this.text}\"\n              ?autofocus=\"${this.autofocus}\"\n              ?disabled=\"${inputNoEdit}\"\n              autocapitalize=\"${this.autocapitalize || nothing}\"\n              autocomplete=\"${this.autocomplete || nothing}\"\n              placeholder=\"${this.placeholder || nothing}\"\n              @input=\"${inputNoEdit ? null : this._handleInput}\"\n              @change=\"${inputNoEdit ? null : this._handleChange}\"\n            />\n          `,\n          this._renderSuffix(),\n        ]}\n        <div\n          part=\"popover\"\n          popover=\"${supportsPositionArea() ? \"manual\" : nothing}\"\n        >\n          ${htmlSlot()}\n        </div>\n      </label>\n    `;\n  }\n\n  protected _renderSuffix(): TemplateResult<1> {\n    return html`\n      <i part=\"suffix\">${htmlSlot(\"suffix\", svgCaretDown())}</i>\n    `;\n  }\n\n  protected firstUpdated(): void {\n    this.events.add(this._slot, \"click\", (e: HandlerEvent<HTMLOptionElement>) => {\n      const { target } = e;\n      if (target.tagName !== \"OPTION\") {\n        return;\n      }\n      e.preventDefault();\n      const { label, value } = target;\n      const operation = this.select(value, label);\n      if (!this.multiple) {\n        updateSelected(this.lastChecked, 0);\n        this.hideOptions();\n      }\n      updateSelected(target, operation);\n      this.lastChecked = target;\n    });\n  }\n\n  protected _connectedInit(): void {\n    this.default = this.value ??= \"\";\n    this.defaultText = this.text ??= \"\";\n    this.events.add(this, \"focus\", this.showOptions);\n  }\n\n  reset(): void {\n    this.value = this.default;\n    this.text = this.defaultText;\n  }\n\n  select(value: string, label: string): 0 | 1 {\n    label ||= value;\n    let operation: 0 | 1 = 0;\n    const i = this.values.findIndex((s) => s.value === value);\n    if (i > -1) {\n      this.values.splice(i, 1);\n    } else {\n      this.values.push({ value, label });\n      operation = 1;\n    }\n    this.checkValues();\n    this.value = this.values.map((s) => s.value).join(\",\");\n    this.text = this.values.map((s) => s.label).join(\", \");\n    this.dispatchCustomEvent(\"select\", this.value);\n    return operation;\n  }\n\n  checkValues(): void {\n    if (!this.multiple && this.values.length > 1) {\n      this.values.splice(0, this.values.length - 1);\n      this.requestUpdate();\n    }\n  }\n\n  showOptions(): void {\n    if (this.optionsVisible) {\n      return;\n    }\n    showPopover(this._popover);\n    const listener = (e) => {\n      if (!this.contains(e.target)) {\n        this.hideOptions();\n        this.events.remove(document, \"click\", listener);\n      }\n    };\n    this.events.add(document, \"click\", listener);\n    this.optionsVisible = true;\n  }\n\n  hideOptions(): void {\n    if (!this.optionsVisible) {\n      return;\n    }\n    hidePopover(this._popover);\n    this.optionsVisible = false;\n  }\n\n  focus(options?: FocusOptions): void {\n    super.focus();\n    this._input.focus(options);\n    this.showOptions();\n  }\n\n  blur(): void {\n    super.blur();\n    this._input.blur();\n    hidePopover(this._popover);\n  }\n}\n\nexport default Select;\nexport { Select };\n"],"version":3,"file":"component.d.ts"}