'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
var lodashUnified = require('lodash-unified');
require('../../../utils/index.js');
require('../../virtual-list/index.js');
var index$2 = require('../../checkbox/index.js');
require('../../../hooks/index.js');
require('../../../constants/index.js');
var groupItem = require('./group-item.js');
var optionItem = require('./option-item.js');
var optionItemCheckbox = require('./option-item-checkbox.js');
var token = require('./token.js');
var index = require('../../../hooks/use-namespace/index.js');
var index$1 = require('../../../hooks/use-locale/index.js');
var types = require('../../../utils/types.js');
var shared = require('@vue/shared');
var aria = require('../../../constants/aria.js');
var fixedSizeList = require('../../virtual-list/src/components/fixed-size-list.js');
var dynamicSizeList = require('../../virtual-list/src/components/dynamic-size-list.js');

function _isSlot(s) {
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !vue.isVNode(s);
}
var ElSelectMenu = vue.defineComponent({
  name: "ElSelectDropdown",
  props: {
    data: {
      type: Array,
      required: true
    },
    hoveringIndex: Number,
    width: Number
  },
  setup(props, {
    slots,
    expose
  }) {
    const select = vue.inject(token.selectV2InjectionKey);
    const ns = index.useNamespace("select");
    const customStyle = vue.inject("$custom-style-filter", {});
    const {
      t
    } = index$1.useLocale();
    const cachedHeights = vue.ref([]);
    const listRef = vue.ref();
    const {
      props: {
        modelValue,
        showChecked,
        valueKey
      }
    } = select;
    const checkAll = vue.ref(false);
    const isIndeterminate = vue.ref(false);
    const handleCheckAllChange = (val) => {
      checkAll.value = val;
      props.data.forEach((element) => {
        element.checked = val;
      });
      isIndeterminate.value = false;
      onSelectCheckbox(0);
    };
    const size = vue.computed(() => props.data.length);
    vue.watch(() => size.value, () => {
      var _a, _b;
      if (showChecked) {
        setCheckStatus();
      }
      (_b = (_a = select.popper.value).updatePopper) == null ? void 0 : _b.call(_a);
    });
    vue.watch(() => select.props.modelValue, (val) => {
      var _a, _b;
      if (showChecked) {
        props.data.forEach((element) => {
          element.checked = val.includes(lodashUnified.get(element, valueKey));
        });
        const checkedCount = val.length;
        checkAll.value = checkedCount === size.value;
        isIndeterminate.value = checkedCount > 0 && checkedCount < size.value;
      }
      (_b = (_a = select.popper.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
    }, {
      deep: true
    });
    if (showChecked) {
      props.data.forEach((element) => {
        element.checked = modelValue.includes(lodashUnified.get(element, valueKey));
      });
      const checkedCount = modelValue.length;
      checkAll.value = checkedCount === size.value;
      isIndeterminate.value = checkedCount > 0 && checkedCount < size.value;
    }
    const onSelectCheckbox = (index) => {
      select.onHover(index - 1);
      vue.nextTick(() => {
        select.onHover(index);
        setCheckStatus();
      });
    };
    const setCheckStatus = () => {
      const checkedCount = props.data.filter((ele) => ele.checked).length;
      checkAll.value = checkedCount === size.value;
      isIndeterminate.value = checkedCount > 0 && checkedCount < size.value;
    };
    const confirm = () => {
      select.onSelectMultiple((select.props.options || []).filter((ele) => ele.checked));
      select.handleClickOutside();
    };
    const clear = () => {
      handleCheckAllChange(false);
    };
    const isSized = vue.computed(() => types.isUndefined(select.props.estimatedOptionHeight));
    const listProps = vue.computed(() => {
      if (isSized.value) {
        return {
          itemSize: select.props.itemHeight
        };
      }
      return {
        estimatedSize: select.props.estimatedOptionHeight,
        itemSize: (idx) => cachedHeights.value[idx]
      };
    });
    const contains = (arr = [], target) => {
      const {
        props: {
          valueKey: valueKey2
        }
      } = select;
      if (!shared.isObject(target)) {
        return arr.includes(target);
      }
      return arr && arr.some((item) => {
        return lodashUnified.get(item, valueKey2) === lodashUnified.get(target, valueKey2);
      });
    };
    const isEqual = (selected, target) => {
      if (!shared.isObject(target)) {
        return selected === target;
      } else {
        const {
          valueKey: valueKey2
        } = select.props;
        return lodashUnified.get(selected, valueKey2) === lodashUnified.get(target, valueKey2);
      }
    };
    const isItemSelected = (modelValue2, target) => {
      const {
        valueKey: valueKey2
      } = select.props;
      if (select.props.multiple) {
        return contains(modelValue2, lodashUnified.get(target, valueKey2));
      }
      return isEqual(modelValue2, lodashUnified.get(target, valueKey2));
    };
    const isItemDisabled = (modelValue2, selected) => {
      const {
        disabled,
        multiple,
        multipleLimit
      } = select.props;
      return disabled || !selected && (multiple ? multipleLimit > 0 && modelValue2.length >= multipleLimit : false);
    };
    const isItemHovering = (target) => props.hoveringIndex === target;
    const scrollToItem = (index) => {
      const list = listRef.value;
      if (list) {
        list.scrollToItem(index);
      }
    };
    const resetScrollTop = () => {
      const list = listRef.value;
      if (list) {
        list.resetScrollTop();
      }
    };
    expose({
      listRef,
      isSized,
      isItemDisabled,
      isItemHovering,
      isItemSelected,
      scrollToItem,
      resetScrollTop
    });
    const Item = (itemProps) => {
      const {
        index,
        data,
        style
      } = itemProps;
      const sized = vue.unref(isSized);
      const {
        itemSize,
        estimatedSize
      } = vue.unref(listProps);
      const {
        modelValue: modelValue2,
        showChecked: showChecked2,
        radio
      } = select.props;
      const {
        onSelect,
        onHover
      } = select;
      const item = data[index];
      if (item.type === "Group") {
        return vue.createVNode(groupItem["default"], {
          "item": item,
          "style": style,
          "height": sized ? itemSize : estimatedSize
        }, null);
      }
      const isSelected = isItemSelected(modelValue2, item);
      const isDisabled = isItemDisabled(modelValue2, isSelected);
      const isHovering = isItemHovering(index);
      if (showChecked2) {
        return vue.createVNode(optionItemCheckbox["default"], vue.mergeProps(itemProps, {
          "disabled": item.disabled || isDisabled,
          "created": !!item.created,
          "hovering": isHovering,
          "item": item,
          "onSelect": onSelectCheckbox,
          "onHover": onHover
        }), {
          default: (props2) => {
            var _a;
            return ((_a = slots.default) == null ? void 0 : _a.call(slots, props2)) || vue.createVNode("span", null, [item.label]);
          }
        });
      }
      return vue.createVNode(optionItem["default"], vue.mergeProps(itemProps, {
        "radio": radio,
        "selected": isSelected,
        "disabled": item.disabled || isDisabled,
        "created": !!item.created,
        "hovering": isHovering,
        "item": item,
        "onSelect": onSelect,
        "onHover": onHover
      }), {
        default: (props2) => {
          var _a;
          return ((_a = slots.default) == null ? void 0 : _a.call(slots, props2)) || vue.createVNode("span", null, [item.label]);
        }
      });
    };
    const {
      onKeyboardNavigate,
      onKeyboardSelect
    } = select;
    const onForward = () => {
      onKeyboardNavigate("forward");
    };
    const onBackward = () => {
      onKeyboardNavigate("backward");
    };
    const onEscOrTab = () => {
      select.expanded = false;
    };
    const onKeydown = (e) => {
      const {
        code
      } = e;
      const {
        tab,
        esc,
        down,
        up,
        enter
      } = aria.EVENT_CODE;
      if (code !== tab) {
        e.preventDefault();
        e.stopPropagation();
      }
      switch (code) {
        case tab:
        case esc: {
          onEscOrTab();
          break;
        }
        case down: {
          onForward();
          break;
        }
        case up: {
          onBackward();
          break;
        }
        case enter: {
          onKeyboardSelect();
          break;
        }
      }
    };
    return () => {
      var _a;
      let _slot;
      const {
        data,
        width
      } = props;
      const {
        height,
        multiple,
        scrollbarAlwaysOn,
        showChecked: showChecked2
      } = select.props;
      if (data.length === 0) {
        return vue.createVNode("div", {
          "class": ns.b("dropdown"),
          "style": {
            width: `${width}px`
          }
        }, [(_a = slots.empty) == null ? void 0 : _a.call(slots)]);
      }
      const List = vue.unref(isSized) ? fixedSizeList["default"] : dynamicSizeList["default"];
      return vue.createVNode("div", {
        "class": [ns.b("dropdown"), ns.is("multiple", multiple)]
      }, [showChecked2 ? vue.createVNode("div", {
        "class": ns.b("dropdown__option-item")
      }, [vue.createVNode(index$2.ElCheckbox, {
        "modelValue": checkAll.value,
        "indeterminate": isIndeterminate.value,
        "onChange": handleCheckAllChange
      }, _isSlot(_slot = t("el.colorpicker.selectAll")) ? _slot : {
        default: () => [_slot]
      })]) : null, vue.createVNode(List, vue.mergeProps({
        "ref": listRef
      }, vue.unref(listProps), {
        "className": ns.be("dropdown", "list"),
        "scrollbarAlwaysOn": scrollbarAlwaysOn,
        "data": data,
        "height": height,
        "width": width,
        "total": data.length,
        "onKeydown": onKeydown
      }), {
        default: (props2) => vue.createVNode(Item, props2, null)
      }), showChecked2 ? vue.createVNode("div", {
        "class": [ns.b("btn-group")],
        "style": types.formatterStyle(customStyle, ["border"])
      }, [vue.createVNode("div", {
        "onClick": clear,
        "class": [ns.b("btn")],
        "style": types.formatterStyle(customStyle, ["text"])
      }, [t("el.datepicker.clear")]), vue.createVNode("div", {
        "onClick": confirm,
        "class": [ns.b("btn")],
        "style": types.formatterStyle(customStyle, ["text", "border"])
      }, [t("el.datepicker.confirm")])]) : null]);
    };
  }
});

exports["default"] = ElSelectMenu;
//# sourceMappingURL=select-dropdown.js.map
