/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { ref } from "lit/directives/ref.js";
import { css, html } from "lit";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { useDirection } from "@arcgis/lumina/controllers";
import { u as nextFrame } from "../../chunks/dom.js";
import { d as defaultMenuPlacement, r as reposition, c as connectFloatingUI, a as disconnectFloatingUI, f as filterValidFlipPlacements, h as hideFloatingUI, F as FloatingCSS } from "../../chunks/floating-ui.js";
import { i as isActivationKey } from "../../chunks/key.js";
import { c as createObserver, u as updateRefObserver } from "../../chunks/observers.js";
import { t as toggleOpenClose } from "../../chunks/openCloseComponent.js";
import { g as getDimensionClass } from "../../chunks/dynamicClasses.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
import { u as useInteractive } from "../../chunks/useInteractive.js";
import { u as useTopLayer } from "../../chunks/useTopLayer.js";
import { u as useReferenceElement, r as referenceElementManager } from "../../chunks/manager.js";
const SLOTS = {
  trigger: "trigger"
};
const CSS = {
  content: "content",
  wrapper: "wrapper",
  triggerContainer: "trigger-container"
};
const styles = css`:host([disabled]){cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-opacity-disabled)}:host([disabled]) *,:host([disabled]) ::slotted(*){pointer-events:none}:host{display:inline-block}.wrapper{inline-size:max-content;display:none;max-inline-size:100vw;max-block-size:100vh;inset-block-start:0;left:0;z-index:var(--calcite-floating-ui-z-index)}@starting-style{.wrapper{opacity:0;inset-block-start:0;left:0}}:host([top-layer-disabled]) .wrapper{--calcite-floating-ui-z-index: var(--calcite-z-index-dropdown)}.wrapper[popover]{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;display:none}.wrapper:popover-open{display:block}.wrapper .calcite-floating-ui-anim{position:relative;transition-duration:var(--calcite-floating-ui-transition);transition-property:inset-block-start,left,opacity,display;transition-behavior:allow-discrete;opacity:0;box-shadow:0 0 16px #00000029;z-index:var(--calcite-z-index);border-radius:.25rem}.wrapper[data-placement^=bottom] .calcite-floating-ui-anim{inset-block-start:-5px}.wrapper[data-placement^=top] .calcite-floating-ui-anim{inset-block-start:5px}.wrapper[data-placement^=left] .calcite-floating-ui-anim{left:5px}.wrapper[data-placement^=right] .calcite-floating-ui-anim{left:-5px}.wrapper[data-placement] .calcite-floating-ui-anim--active{opacity:1;inset-block-start:0;left:0}@starting-style{.wrapper[data-placement] .calcite-floating-ui-anim--active{opacity:0}}.wrapper .calcite-floating-ui-anim{box-shadow:var(--calcite-shadow-md)}.content{max-height:45vh;width:auto;overflow-y:auto;overflow-x:hidden;inline-size:var(--calcite-dropdown-width, var(--calcite-internal-dropdown-width));background-color:var(--calcite-dropdown-background-color, var(--calcite-color-foreground-1))}.trigger-container{position:relative;display:flex;height:100%;flex:1 1 auto;word-wrap:break-word;word-break:break-word}.width-s{--calcite-internal-dropdown-width: 12rem}.width-m{--calcite-internal-dropdown-width: 14rem}.width-l{--calcite-internal-dropdown-width: 16rem}@media(forced-colors:active){:host([open]) .wrapper{border:var(--calcite-border-width-sm) solid canvasText}}:host([hidden]){display:none}[hidden]{display:none}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}`;
const manager = referenceElementManager({ click: true, hover: true });
class Dropdown extends LitElement {
  constructor() {
    super();
    this.referenceElementController = useReferenceElement({ manager })(this);
    this.direction = useDirection();
    this.focusLastDropdownItem = false;
    this.activeItemIndex = -1;
    this.groups = [];
    this.items = [];
    this.mutationObserver = createObserver("mutation", () => this.updateItems());
    this.transitionProp = "opacity";
    this.resizeObserver = createObserver("resize", (entries) => this.resizeObserverCallback(entries));
    this.onReferenceElementKeyDown = (event) => this.keyDownHandler(event);
    this.focusSetter = useSetFocus()(this);
    this.interactiveContainer = useInteractive(this);
    this.topLayer = useTopLayer({
      target: () => this.floatingEl
    })(this);
    this.closeOnSelectDisabled = false;
    this.disabled = false;
    this.maxItems = 0;
    this.offsetDistance = 0;
    this.offsetSkidding = 0;
    this.open = false;
    this.overlayPositioning = "absolute";
    this.placement = defaultMenuPlacement;
    this.scale = "m";
    this.selectedItems = [];
    this.topLayerDisabled = false;
    this.type = "click";
    this.calciteDropdownBeforeClose = createEvent({ cancelable: false });
    this.calciteDropdownBeforeOpen = createEvent({ cancelable: false });
    this.calciteDropdownClose = createEvent({ cancelable: false });
    this.calciteDropdownOpen = createEvent({ cancelable: false });
    this.calciteDropdownSelect = createEvent({ cancelable: false });
    this.listenOn(window, "click", this.closeCalciteDropdownOnClick);
    this.listenOn(window, "calciteDropdownOpen", this.closeCalciteDropdownOnOpenEvent);
    this.listen("pointerenter", this.pointerEnterHandler);
    this.listen("pointerleave", this.pointerLeaveHandler);
    this.listen("calciteInternalDropdownItemSelect", this.handleItemSelect);
  }
  static {
    this.properties = { activeDescendantElement: [16, {}, { state: true }], referenceEl: [16, {}, { state: true }], closeOnSelectDisabled: [7, {}, { reflect: true, type: Boolean }], disabled: [7, {}, { reflect: true, type: Boolean }], flipPlacements: [0, {}, { attribute: false }], maxItems: [11, {}, { reflect: true, type: Number }], offsetDistance: [11, {}, { type: Number, reflect: true }], offsetSkidding: [11, {}, { reflect: true, type: Number }], open: [7, {}, { reflect: true, type: Boolean }], overlayPositioning: [3, {}, { reflect: true }], placement: [3, {}, { reflect: true }], referenceElement: 1, scale: [3, {}, { reflect: true }], selectedItems: [0, {}, { attribute: false }], topLayerDisabled: [7, {}, { reflect: true, type: Boolean }], type: [3, {}, { reflect: true }], widthScale: [3, {}, { reflect: true }], width: [3, {}, { reflect: true }] };
  }
  static {
    this.shadowRootOptions = { mode: "open", delegatesFocus: true };
  }
  static {
    this.styles = styles;
  }
  get referenceElementType() {
    return this.referenceElement ? this.type : null;
  }
  async reposition(delayed = false) {
    const { filteredFlipPlacements, floatingEl, offsetDistance, offsetSkidding, overlayPositioning, placement, referenceEl } = this;
    return reposition(this, {
      direction: this.direction,
      floatingEl,
      referenceEl,
      offsetDistance,
      offsetSkidding,
      overlayPositioning,
      placement,
      flipPlacements: filteredFlipPlacements,
      type: "menu"
    }, delayed);
  }
  async setFocus(options) {
    return this.focusSetter(() => this.referenceEl instanceof HTMLElement ? this.referenceEl : this.floatingEl, options);
  }
  connectedCallback() {
    super.connectedCallback();
    this.mutationObserver?.observe(this.el, { childList: true, subtree: true });
    this.setFilteredPlacements();
    this.updateItems();
    connectFloatingUI(this);
  }
  willUpdate(changes) {
    if (changes.has("open") && (this.hasUpdated || this.open !== false)) {
      this.openHandler();
    }
    if (changes.has("disabled") && (this.hasUpdated || this.disabled !== false)) {
      this.handleDisabledChange(this.disabled);
    }
    if (changes.has("flipPlacements")) {
      this.flipPlacementsHandler();
    }
    if (changes.has("maxItems") && this.hasUpdated) {
      this.setMaxScrollerHeight();
    }
    if (this.hasUpdated && (changes.has("offsetDistance") && this.offsetDistance !== 0 || changes.has("offsetSkidding") && this.offsetSkidding !== 0 || changes.has("overlayPositioning") && this.overlayPositioning !== "absolute" || changes.has("placement") && this.placement !== defaultMenuPlacement)) {
      this.reposition(true);
    }
    if (changes.has("scale") && (this.hasUpdated || this.scale !== "m")) {
      this.handlePropsChange();
    }
    if (changes.has("referenceElement") && !this.referenceElement && this.open) {
      this.topLayer.hide();
    }
  }
  updated(changes) {
    if (changes.has("referenceEl") && this.referenceElementType) {
      connectFloatingUI(this);
    }
  }
  loaded() {
    this.updateSelectedItems();
    connectFloatingUI(this);
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.mutationObserver?.disconnect();
    this.resizeObserver?.disconnect();
    disconnectFloatingUI(this);
  }
  openHandler() {
    if (this.disabled) {
      return;
    }
    toggleOpenClose(this);
    this.reposition(true);
  }
  handleDisabledChange(value) {
    if (!value) {
      this.open = false;
    }
  }
  flipPlacementsHandler() {
    this.setFilteredPlacements();
    this.reposition(true);
  }
  handlePropsChange() {
    this.updateItems();
    this.updateGroupProps();
  }
  closeCalciteDropdownOnClick(event) {
    if (this.referenceElementType || this.disabled || !this.open || event.composedPath().includes(this.el)) {
      return;
    }
    this.closeCalciteDropdown();
  }
  closeCalciteDropdownOnOpenEvent(event) {
    if (this.referenceElementType || event.composedPath().includes(this.el)) {
      return;
    }
    this.closeCalciteDropdown();
  }
  pointerEnterHandler() {
    if (this.referenceElementType || this.disabled || this.type !== "hover") {
      return;
    }
    this.open = true;
  }
  pointerLeaveHandler() {
    if (this.referenceElementType || this.disabled || this.type !== "hover") {
      return;
    }
    this.closeCalciteDropdown();
  }
  getTraversableItems() {
    return this.items.filter((item) => !item.disabled && !item.hidden);
  }
  async handleItemSelect(event) {
    this.updateSelectedItems();
    this.syncActiveItemFromTraversableItems();
    event.stopPropagation();
    this.calciteDropdownSelect.emit();
    await this.setFocus();
    if (!this.closeOnSelectDisabled) {
      this.closeCalciteDropdown();
    }
  }
  setFilteredPlacements() {
    const { el, flipPlacements } = this;
    this.filteredFlipPlacements = flipPlacements ? filterValidFlipPlacements(flipPlacements, el) : null;
  }
  updateItems() {
    this.items = this.groups.map((group) => Array.from(group?.querySelectorAll("calcite-dropdown-item"))).reduce((previousValue, currentValue) => [...previousValue, ...currentValue], []);
    this.updateSelectedItems();
    this.syncActiveItemFromTraversableItems();
    this.reposition(true);
    this.items.forEach((item) => item.scale = this.scale);
  }
  updateGroups(event) {
    const groups = event.target.assignedElements({ flatten: true }).filter((el) => el?.matches("calcite-dropdown-group"));
    this.groups = groups;
    this.updateItems();
    this.updateGroupProps();
  }
  updateGroupProps() {
    this.groups.forEach((group, index) => {
      group.scale = this.scale;
      group.position = index;
    });
  }
  resizeObserverCallback(entries) {
    entries.forEach(({ target }) => {
      if (target === this.referenceEl) {
        this.setDropdownWidth();
      } else if (target === this.scrollerEl) {
        this.setMaxScrollerHeight();
      }
    });
  }
  setDropdownWidth() {
    const { referenceEl, scrollerEl } = this;
    if (!scrollerEl || !(referenceEl instanceof HTMLElement)) {
      return;
    }
    scrollerEl.style.minWidth = `${referenceEl.clientWidth}px`;
  }
  setMaxScrollerHeight() {
    const { maxItems, items, scrollerEl } = this;
    if (!scrollerEl) {
      return;
    }
    const maxScrollerHeight = items.length >= maxItems && maxItems > 0 ? this.getYDistanceFromScroller(items.at(maxItems - 1)) : 0;
    scrollerEl.style.maxBlockSize = maxScrollerHeight > 0 ? `${maxScrollerHeight}px` : "";
    this.reposition(true);
  }
  setScrollerAndTransitionEl(el) {
    updateRefObserver(this.resizeObserver, this.scrollerEl, el);
    this.scrollerEl = el;
    this.transitionEl = el;
  }
  onBeforeOpen() {
    this.setInitialActiveItem();
    this.calciteDropdownBeforeOpen.emit();
    this.topLayer.show();
  }
  onOpen() {
    this.calciteDropdownOpen.emit();
  }
  onBeforeClose() {
    this.calciteDropdownBeforeClose.emit();
  }
  onClose() {
    this.calciteDropdownClose.emit();
    hideFloatingUI(this);
    this.topLayer.hide();
  }
  setReferenceEl(el) {
    const previousReferenceEl = this.referenceEl instanceof HTMLElement ? this.referenceEl : null;
    const nextReferenceEl = el instanceof HTMLElement ? el : null;
    updateRefObserver(this.resizeObserver, previousReferenceEl, nextReferenceEl);
    if (this.referenceElementType || !nextReferenceEl) {
      return;
    }
    this.referenceEl = el;
    connectFloatingUI(this);
  }
  setFloatingEl(el) {
    this.floatingEl = el;
    connectFloatingUI(this);
  }
  keyDownHandler(event) {
    if (!(this.referenceEl instanceof HTMLElement) || !event.composedPath().includes(this.referenceEl)) {
      return;
    }
    const { defaultPrevented, key } = event;
    if (defaultPrevented) {
      return;
    }
    if (this.open && key === "Escape") {
      this.closeCalciteDropdown();
      event.preventDefault();
      return;
    }
    if (!this.open && isActivationKey(key)) {
      this.open = true;
      event.preventDefault();
      return;
    }
    if (!this.open && (key === "ArrowDown" || key === "ArrowUp")) {
      event.preventDefault();
      this.focusLastDropdownItem = key === "ArrowUp";
      this.open = true;
      return;
    }
    if (!this.open) {
      return;
    }
    if (key === "Tab") {
      this.closeCalciteDropdown();
      return;
    }
    if (key === "ArrowDown") {
      event.preventDefault();
      this.navigateActiveItem("next");
      return;
    }
    if (key === "ArrowUp") {
      event.preventDefault();
      this.navigateActiveItem("previous");
      return;
    }
    if (key === "Home") {
      event.preventDefault();
      this.navigateActiveItem("first");
      return;
    }
    if (key === "End") {
      event.preventDefault();
      this.navigateActiveItem("last");
      return;
    }
    if (isActivationKey(key)) {
      event.preventDefault();
      this.activateActiveItem();
    }
  }
  updateSelectedItems() {
    this.selectedItems = this.items.filter((item) => item.selected);
  }
  getYDistanceFromScroller(last) {
    const style = last.getBoundingClientRect();
    return last.offsetTop + style.height;
  }
  closeCalciteDropdown() {
    this.open = false;
    this.setActiveItemByIndex(-1);
  }
  async setInitialActiveItem() {
    const traversableItems = this.getTraversableItems();
    const target = this.focusLastDropdownItem ? traversableItems.at(-1) : traversableItems[0];
    this.focusLastDropdownItem = false;
    if (!target) {
      this.setActiveItemByIndex(-1);
      return;
    }
    const targetIndex = traversableItems.findIndex((item) => item === target);
    this.setActiveItemByIndex(targetIndex);
    await this.scrollActiveItemIntoView(target);
  }
  syncActiveItemFromTraversableItems() {
    const traversableItems = this.getTraversableItems();
    if (!traversableItems.length) {
      this.setActiveItemByIndex(-1);
      return;
    }
    if (this.activeItemIndex < 0 || this.activeItemIndex >= traversableItems.length) {
      this.setActiveItemByIndex(0);
      return;
    }
    this.updateActiveDescendantElement(traversableItems[this.activeItemIndex]);
  }
  setActiveItemByIndex(index) {
    this.activeItemIndex = index;
    const traversableItems = this.getTraversableItems();
    const activeItem = index >= 0 ? traversableItems[index] : null;
    this.updateActiveDescendantElement(activeItem);
  }
  updateActiveDescendantElement(activeItem) {
    this.items.forEach((item) => {
      item.activeDescendant = item === activeItem;
    });
    this.activeDescendantElement = activeItem ?? null;
  }
  navigateActiveItem(direction) {
    const traversableItems = this.getTraversableItems();
    if (!traversableItems.length) {
      return;
    }
    const totalItems = traversableItems.length;
    let index = this.activeItemIndex;
    if (index < 0 || index >= totalItems) {
      index = direction === "previous" || direction === "last" ? totalItems - 1 : 0;
    } else if (direction === "next") {
      index = (index + 1) % totalItems;
    } else if (direction === "previous") {
      index = (index - 1 + totalItems) % totalItems;
    } else if (direction === "first") {
      index = 0;
    } else if (direction === "last") {
      index = totalItems - 1;
    }
    const activeItem = traversableItems[index];
    this.setActiveItemByIndex(index);
    void this.scrollActiveItemIntoView(activeItem);
  }
  async scrollActiveItemIntoView(target) {
    if (!target) {
      return;
    }
    await this.updateComplete;
    await nextFrame();
    await nextFrame();
    target.scrollIntoView({ block: "nearest" });
  }
  activateActiveItem() {
    const traversableItems = this.getTraversableItems();
    const activeItem = traversableItems[this.activeItemIndex] || traversableItems[0];
    if (!activeItem) {
      return;
    }
    this.setActiveItemByIndex(traversableItems.findIndex((item) => item === activeItem));
    activeItem.activateItem();
  }
  openHoverDropdown() {
    if (this.open || this.disabled || this.type !== "hover") {
      return;
    }
    this.open = true;
  }
  closeHoverDropdown(event) {
    if (!this.open || this.disabled || this.type !== "hover") {
      return;
    }
    const relatedTarget = event.relatedTarget;
    if (relatedTarget && (this.el.contains(relatedTarget) || this.referenceEl != null && this.referenceEl instanceof HTMLElement && this.referenceEl.contains(relatedTarget))) {
      return;
    }
    this.closeCalciteDropdown();
  }
  toggleClickDropdown() {
    if (this.disabled || this.type !== "click") {
      return;
    }
    this.open = !this.open;
  }
  render() {
    const { open } = this;
    return this.interactiveContainer({ disabled: this.disabled, children: html`${!this.referenceElementType ? html`<div class=${safeClassMap(CSS.triggerContainer)} @click=${this.toggleClickDropdown} @focusin=${this.openHoverDropdown} @focusout=${this.closeHoverDropdown} @keydown=${this.keyDownHandler} ${ref(this.setReferenceEl)}><slot .ariaActiveDescendantElement=${this.activeDescendantElement ?? null} .ariaControlsElements=${this.scrollerEl ? [this.scrollerEl] : void 0} .ariaExpanded=${open} aria-haspopup=menu name=${SLOTS.trigger}></slot></div>` : null}<div class=${safeClassMap({
      [CSS.wrapper]: true,
      [getDimensionClass("width", this.width, this.widthScale)]: !!(this.width || this.widthScale)
    })} .inert=${!open} popover=manual ${ref(this.setFloatingEl)}><div .ariaLabelledByElements=${this.referenceEl instanceof HTMLElement ? [this.referenceEl] : void 0} class=${safeClassMap({
      [CSS.content]: true,
      [FloatingCSS.animation]: true,
      [FloatingCSS.animationActive]: open
    })} role=menu ${ref(this.setScrollerAndTransitionEl)}><slot @slotchange=${this.updateGroups}></slot></div></div>` });
  }
}
customElement("calcite-dropdown", Dropdown);
export {
  Dropdown
};
