'use strict';

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

var vue = require('vue');
require('../../../utils/index.cjs');
require('../../../hooks/index.cjs');
var List = require('../../vc-virtual-list/src/List.cjs');
var TransBtn = require('./TransBtn.cjs');
var platformUtil = require('./utils/platformUtil.cjs');
var useBaseProps = require('./hooks/useBaseProps.cjs');
var SelectContext = require('./SelectContext.cjs');
var index = require('../../../hooks/use-memo/index.cjs');
var createRef = require('../../../utils/vue/createRef.cjs');
var pickAttrs = require('../../../utils/lang/pickAttrs.cjs');
var KeyCode = require('../../../utils/KeyCode.cjs');
var _class = require('../../../utils/dom/class.cjs');
var omit = require('../../../utils/lang/omit.cjs');
var is = require('../../../utils/is.cjs');

function isTitleType(content) {
  return typeof content === "string" || typeof content === "number";
}
const OptionList = /* @__PURE__ */ vue.defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "OptionList",
  inheritAttrs: false,
  setup(_, {
    expose,
    slots
  }) {
    const baseProps = useBaseProps.default();
    const props = SelectContext.default();
    const itemPrefixCls = vue.computed(() => `${baseProps.prefixCls}-item`);
    const memoFlattenOptions = index.useMemo(() => props.flattenOptions, [() => baseProps.open, () => props.flattenOptions], (next) => next[0]);
    const listRef = createRef.createRef();
    const onListMouseDown = (event) => {
      event.preventDefault();
    };
    const scrollIntoView = (args) => {
      if (listRef.current)
        listRef.current.scrollTo(typeof args === "number" ? {
          index: args
        } : args);
    };
    const getEnabledActiveIndex = (index, offset = 1) => {
      const len = memoFlattenOptions.value.length;
      for (let i = 0; i < len; i += 1) {
        const current = (index + i * offset + len) % len;
        const {
          group,
          data
        } = memoFlattenOptions.value[current];
        if (!group && !data.disabled)
          return current;
      }
      return -1;
    };
    const state = vue.reactive({
      activeIndex: getEnabledActiveIndex(0)
    });
    const setActive = (index, fromKeyboard = false) => {
      state.activeIndex = index;
      const info = {
        source: fromKeyboard ? "keyboard" : "mouse"
      };
      const flattenItem = memoFlattenOptions.value[index];
      if (!flattenItem) {
        props.onActiveValue(null, -1, info);
        return;
      }
      props.onActiveValue(flattenItem.value, index, info);
    };
    vue.watch([() => memoFlattenOptions.value.length, () => baseProps.searchValue], () => {
      setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
    }, {
      immediate: true
    });
    const isSelected = (value) => props.rawValues.has(value) && baseProps.mode !== "combobox";
    vue.watch([() => baseProps.open, () => baseProps.searchValue], () => {
      if (!baseProps.multiple && baseProps.open && props.rawValues.size === 1) {
        const value = Array.from(props.rawValues)[0];
        const index = vue.toRaw(memoFlattenOptions.value).findIndex(({
          data
        }) => data[props.fieldNames.value] === value);
        if (index !== -1) {
          setActive(index);
          vue.nextTick(() => {
            scrollIntoView(index);
          });
        }
      }
      if (baseProps.open) {
        vue.nextTick(() => {
          var _a;
          (_a = listRef.current) == null ? void 0 : _a.scrollTo(void 0);
        });
      }
    }, {
      immediate: true,
      flush: "post"
    });
    const onSelectValue = (value) => {
      if (value !== void 0)
        props.onSelect(value, {
          selected: !props.rawValues.has(value)
        });
      if (!baseProps.multiple)
        baseProps.toggleOpen(false);
    };
    const getLabel = (item) => typeof item.label === "function" ? item.label() : item.label;
    function renderItem(index) {
      const item = memoFlattenOptions.value[index];
      if (!item)
        return null;
      const itemData = item.data || {};
      const {
        value
      } = itemData;
      const {
        group
      } = item;
      const attrs = pickAttrs.pickAttrs(itemData, true);
      const mergedLabel = getLabel(item);
      return item ? vue.createVNode("div", {
        "aria-label": typeof mergedLabel === "string" && !group ? mergedLabel : null,
        ...attrs,
        "key": index,
        "role": group ? "presentation" : "option",
        "id": `${baseProps.id}_list_${index}`,
        "aria-selected": isSelected(value)
      }, [value]) : null;
    }
    const onKeydown = (event) => {
      const {
        which,
        ctrlKey
      } = event;
      switch (which) {
        case KeyCode.KeyCode.N:
        case KeyCode.KeyCode.P:
        case KeyCode.KeyCode.UP:
        case KeyCode.KeyCode.DOWN: {
          let offset = 0;
          if (which === KeyCode.KeyCode.UP) {
            offset = -1;
          } else if (which === KeyCode.KeyCode.DOWN) {
            offset = 1;
          } else if (platformUtil.isPlatformMac() && ctrlKey) {
            if (which === KeyCode.KeyCode.N)
              offset = 1;
            else if (which === KeyCode.KeyCode.P)
              offset = -1;
          }
          if (offset !== 0) {
            const nextActiveIndex = getEnabledActiveIndex(state.activeIndex + offset, offset);
            scrollIntoView(nextActiveIndex);
            setActive(nextActiveIndex, true);
          }
          break;
        }
        case KeyCode.KeyCode.ENTER: {
          const item = memoFlattenOptions.value[state.activeIndex];
          if (item && !item.data.disabled)
            onSelectValue(item.value);
          else
            onSelectValue(void 0);
          if (baseProps.open)
            event.preventDefault();
          break;
        }
        case KeyCode.KeyCode.ESC: {
          baseProps.toggleOpen(false);
          if (baseProps.open)
            event.stopPropagation();
        }
      }
    };
    const onKeyup = () => {
    };
    const scrollTo = (index) => {
      scrollIntoView(index);
    };
    expose({
      onKeydown,
      onKeyup,
      scrollTo
    });
    return () => {
      const {
        id,
        notFoundContent,
        onPopupScroll
      } = baseProps;
      const {
        menuItemSelectedIcon,
        fieldNames,
        virtual,
        listHeight,
        listItemHeight
      } = props;
      const renderOption = slots.option;
      const {
        activeIndex
      } = state;
      const omitFieldNameList = Object.keys(fieldNames).map((key) => fieldNames[key]);
      if (memoFlattenOptions.value.length === 0) {
        return vue.createVNode("div", {
          "role": "listbox",
          "id": `${id}_list`,
          "class": `${itemPrefixCls.value}-empty`,
          "onMousedown": onListMouseDown
        }, [notFoundContent]);
      }
      return vue.createVNode(vue.Fragment, null, [vue.createVNode("div", {
        "role": "listbox",
        "id": `${id}_list`,
        "style": {
          height: 0,
          width: 0,
          overflow: "hidden"
        }
      }, [renderItem(activeIndex - 1), renderItem(activeIndex), renderItem(activeIndex + 1)]), vue.createVNode(List.default, {
        "itemKey": "key",
        "ref": listRef,
        "data": memoFlattenOptions.value,
        "height": listHeight,
        "itemHeight": listItemHeight,
        "fullHeight": false,
        "onMousedown": onListMouseDown,
        "onScroll": onPopupScroll,
        "virtual": virtual
      }, {
        default: (item, itemIndex) => {
          var _a;
          const {
            group,
            groupOption,
            data,
            value
          } = item;
          const {
            key
          } = data;
          const label = typeof item.label === "function" ? item.label() : item.label;
          if (group) {
            const groupTitle = (_a = data.title) != null ? _a : isTitleType(label) && label;
            return vue.createVNode("div", {
              "class": _class.classNames(itemPrefixCls.value, `${itemPrefixCls.value}-group`),
              "title": groupTitle
            }, [renderOption ? renderOption(data) : label !== void 0 ? label : key]);
          }
          const {
            disabled,
            title,
            children,
            style,
            class: cls,
            className,
            ...otherProps
          } = data;
          const passedProps = omit.omit(otherProps, omitFieldNameList);
          const selected = isSelected(value);
          const optionPrefixCls = `${itemPrefixCls.value}-option`;
          const optionClassName = _class.classNames(itemPrefixCls.value, optionPrefixCls, cls, className, {
            [`${optionPrefixCls}-grouped`]: groupOption,
            [`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled,
            [`${optionPrefixCls}-disabled`]: disabled,
            [`${optionPrefixCls}-selected`]: selected
          });
          const mergedLabel = getLabel(item);
          const iconVisible = !menuItemSelectedIcon || typeof menuItemSelectedIcon === "function" || selected;
          const content = typeof mergedLabel === "number" ? mergedLabel : mergedLabel || value;
          let optionTitle = isTitleType(content) ? content.toString() : void 0;
          if (title !== void 0)
            optionTitle = title;
          return vue.createVNode("div", {
            ...passedProps,
            "aria-selected": selected,
            "class": optionClassName,
            "title": optionTitle,
            "onMousemove": (e) => {
              if (otherProps.onMousemove)
                otherProps.onMousemove(e);
              if (activeIndex === itemIndex || disabled)
                return;
              setActive(itemIndex);
            },
            "onClick": (e) => {
              if (!disabled)
                onSelectValue(value);
              if (otherProps.onClick)
                otherProps.onClick(e);
            },
            "style": style
          }, [vue.createVNode("div", {
            "class": `${optionPrefixCls}-content`
          }, [renderOption ? renderOption(data) : content]), is.isValidElement(menuItemSelectedIcon) || selected, iconVisible && vue.createVNode(TransBtn.default, {
            "class": `${itemPrefixCls.value}-option-state`,
            "customizeIcon": menuItemSelectedIcon,
            "customizeIconProps": {
              isSelected: selected
            }
          }, {
            default: () => [selected ? "\u2713" : null]
          })]);
        }
      })]);
    };
  }
});

exports.default = OptionList;
//# sourceMappingURL=OptionList.cjs.map
