"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _vue = require("vue");
var _comp = require("../../ui/src/comp");
var _ui = require("../../ui");
var _dom = require("../../ui/src/dom");
var _utils = require("../../ui/src/utils");
var _util = require("./util");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _list = _interopRequireDefault(require("../../list"));
var _input = _interopRequireDefault(require("../../input"));
var _button = _interopRequireDefault(require("../../button"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
 * 生成节点的唯一主键
 */
function getNodeUniqueId() {
  return _xeUtils.default.uniqueId('node_');
}
function createReactData() {
  return {
    initialized: false,
    searchValue: '',
    searchLoading: false,
    currentCunkList: [],
    currentItems: [],
    currentNode: null,
    panelIndex: 0,
    panelStyle: {},
    panelPlacement: null,
    triggerFocusPanel: false,
    visiblePanel: false,
    isAniVisible: false,
    isActivated: false,
    selectRadioKey: null,
    treeList: [],
    updateExpandedFlag: 1,
    updateCheckboxFlag: 1,
    fullOptFlag: 1,
    lazyOptFlag: 1
  };
}
function createInternalData() {
  return {
    // hpTimeout: undefined,
    listVirtualYOpts: {
      enabled: true,
      gt: 20
    },
    afterTreeList: [],
    treeFullData: [],
    afterVisibleList: [],
    nodeMaps: {},
    fullNodeMaps: {},
    lazyNodeMaps: {},
    indeterminateRowMaps: {},
    selectCheckboxMaps: {},
    treeExpandedMaps: {},
    treeExpandLazyLoadedMaps: {}
    // isUpdateMode: false
  };
}
var _default = exports.default = (0, _comp.defineVxeComponent)({
  name: 'VxeCascader',
  props: {
    modelValue: [String, Number, Array],
    clearable: Boolean,
    placeholder: {
      type: String,
      default: () => _xeUtils.default.eqNull((0, _ui.getConfig)().cascader.placeholder) ? (0, _ui.getI18n)('vxe.base.pleaseSelect') : (0, _ui.getConfig)().cascader.placeholder
    },
    readonly: {
      type: Boolean,
      default: null
    },
    loading: Boolean,
    disabled: {
      type: Boolean,
      default: null
    },
    filterable: Boolean,
    filterConfig: Object,
    showFullLabel: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showFullLabel
    },
    separator: {
      type: String,
      default: () => (0, _ui.getConfig)().cascader.separator
    },
    multiple: Boolean,
    className: [String, Function],
    prefixIcon: String,
    lazyOptions: Array,
    options: Array,
    optionProps: Object,
    size: {
      type: String,
      default: () => (0, _ui.getConfig)().cascader.size || (0, _ui.getConfig)().size
    },
    treeConfig: Object,
    showRadio: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showRadio
    },
    radioConfig: Object,
    showCheckbox: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showCheckbox
    },
    checkboxConfig: Object,
    remote: Boolean,
    remoteConfig: Function,
    popupConfig: Object,
    checkedClosable: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.checkedClosable
    },
    clearClosable: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.clearClosable
    },
    showCloseButton: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showCloseButton
    },
    showTotalButton: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showTotalButton
    },
    showCheckedButton: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showCheckedButton
    },
    showClearButton: {
      type: Boolean,
      default: () => (0, _ui.getConfig)().cascader.showClearButton
    }
  },
  emits: ['update:modelValue', 'change', 'all-change', 'clear', 'blur', 'focus', 'click', 'node-click', 'node-expand', 'current-change', 'radio-change', 'checkbox-change', 'load-success', 'load-error', 'visible-change'],
  setup(props, context) {
    const {
      emit,
      slots
    } = context;
    const $xeModal = (0, _vue.inject)('$xeModal', null);
    const $xeDrawer = (0, _vue.inject)('$xeDrawer', null);
    const $xeTable = (0, _vue.inject)('$xeTable', null);
    const $xeForm = (0, _vue.inject)('$xeForm', null);
    const formItemInfo = (0, _vue.inject)('xeFormItemInfo', null);
    const xID = _xeUtils.default.uniqueId();
    const {
      computeSize
    } = (0, _ui.useSize)(props);
    const refElem = (0, _vue.ref)();
    const refInput = (0, _vue.ref)();
    const refInpSearch = (0, _vue.ref)();
    const refChunkWrapper = (0, _vue.ref)();
    const refOptionPanel = (0, _vue.ref)();
    const reactData = (0, _vue.reactive)(createReactData());
    const internalData = createInternalData();
    const refMaps = {
      refElem
    };
    const computeFormReadonly = (0, _vue.computed)(() => {
      const {
        readonly
      } = props;
      if (readonly === null) {
        if ($xeForm) {
          return $xeForm.props.readonly;
        }
        return false;
      }
      return readonly;
    });
    const computeIsDisabled = (0, _vue.computed)(() => {
      const {
        disabled
      } = props;
      if (disabled === null) {
        if ($xeForm) {
          return $xeForm.props.disabled;
        }
        return false;
      }
      return disabled;
    });
    const computeBtnTransfer = (0, _vue.computed)(() => {
      const popupOpts = computePopupOpts.value;
      const {
        transfer
      } = popupOpts;
      if (_xeUtils.default.isBoolean(transfer)) {
        return transfer;
      }
      if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
        return true;
      }
      return false;
    });
    const computeTreeOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.treeConfig, props.treeConfig);
    });
    const computeRadioOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.radioConfig, props.radioConfig);
    });
    const computeCheckboxOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.checkboxConfig, props.checkboxConfig);
    });
    const computePopupOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.popupConfig, props.popupConfig);
    });
    const computePropsOpts = (0, _vue.computed)(() => {
      return props.optionProps || {};
    });
    const computeLabelField = (0, _vue.computed)(() => {
      const propsOpts = computePropsOpts.value;
      return propsOpts.label || 'label';
    });
    const computeValueField = (0, _vue.computed)(() => {
      const propsOpts = computePropsOpts.value;
      return propsOpts.value || 'value';
    });
    const computeKeyField = (0, _vue.computed)(() => {
      const treeOpts = computeTreeOpts.value;
      return treeOpts.keyField || 'id';
    });
    const computeParentField = (0, _vue.computed)(() => {
      const treeOpts = computeTreeOpts.value;
      return treeOpts.parentField || 'parentId';
    });
    const computeChildrenField = (0, _vue.computed)(() => {
      const treeOpts = computeTreeOpts.value;
      return treeOpts.childrenField || 'children';
    });
    const computeMapChildrenField = (0, _vue.computed)(() => {
      const treeOpts = computeTreeOpts.value;
      return treeOpts.mapChildrenField || 'mapChildren';
    });
    const computeHasChildField = (0, _vue.computed)(() => {
      const treeOpts = computeTreeOpts.value;
      return treeOpts.hasChildField || 'hasChild';
    });
    const computeRemoteOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.remoteConfig, props.remoteConfig);
    });
    const computeSelectVals = (0, _vue.computed)(() => {
      const {
        modelValue
      } = props;
      return _xeUtils.default.eqNull(modelValue) ? [] : _xeUtils.default.isArray(modelValue) ? modelValue : [modelValue];
    });
    const computeSelectLabel = (0, _vue.computed)(() => {
      const {
        showFullLabel
      } = props;
      const {
        fullOptFlag,
        lazyOptFlag
      } = reactData;
      const {
        fullNodeMaps,
        lazyNodeMaps
      } = internalData;
      const labelField = computeLabelField.value;
      const selectVals = computeSelectVals.value;
      return selectVals.map(val => {
        const cacheItem = fullNodeMaps[val];
        if (fullOptFlag && cacheItem) {
          return showFullLabel ? cacheItem.fullLabel : cacheItem.item[labelField];
        }
        if (lazyOptFlag) {
          const lazyCacheItem = lazyNodeMaps[val];
          if (lazyCacheItem) {
            return showFullLabel ? lazyCacheItem.fullLabel : lazyCacheItem.item[labelField];
          }
        }
        return val;
      }).join(', ');
    });
    const computePopupWrapperStyle = (0, _vue.computed)(() => {
      const {
        currentCunkList,
        panelStyle
      } = reactData;
      const popupOpts = computePopupOpts.value;
      const {
        height,
        nodeWidth,
        nodeHeight
      } = popupOpts;
      const stys = Object.assign(Object.assign({}, panelStyle), {
        '--vxe-ui-cascader-chunk-size': currentCunkList.length
      });
      if (height) {
        stys['--vxe-ui-cascader-chunk-height'] = (0, _dom.toCssUnit)(height);
      }
      if (nodeWidth) {
        stys['--vxe-ui-cascader-node-width'] = (0, _dom.toCssUnit)(nodeWidth);
      }
      if (nodeHeight) {
        stys['--vxe-ui-cascader-node-height'] = (0, _dom.toCssUnit)(nodeHeight);
      }
      return stys;
    });
    const computeFilterOpts = (0, _vue.computed)(() => {
      return Object.assign({}, (0, _ui.getConfig)().cascader.filterConfig, props.filterConfig);
    });
    const computeMaps = {};
    const $xeCascader = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, (0, _ui.createEvent)(evnt, {
        $cascader: $xeCascader
      }, params));
    };
    const emitModel = value => {
      emit('update:modelValue', value);
    };
    const cascaderMethods = {
      dispatchEvent
    };
    const getNodeId = node => {
      if (!node) {
        return '';
      }
      const valueField = computeValueField.value;
      const nodeKey = node[valueField];
      return (0, _util.enNodeValue)(nodeKey);
    };
    const isPathInTree = (treeData, pathIds) => {
      if (!pathIds || !pathIds.length) {
        return false;
      }
      let currentNodes = treeData;
      for (const nodeid of pathIds) {
        const found = currentNodes.find(node => getNodeId(node) === nodeid);
        if (!found) {
          return false;
        }
        currentNodes = found.children || [];
      }
      return true;
    };
    const isCheckedByCheckboxNodeId = nodeid => {
      const {
        updateCheckboxFlag
      } = reactData;
      const {
        selectCheckboxMaps
      } = internalData;
      return !!(updateCheckboxFlag && selectCheckboxMaps[nodeid]);
    };
    const handleCheckedCheckboxNode = (nodeList, checked) => {
      const {
        selectCheckboxMaps
      } = internalData;
      const mapChildrenField = computeMapChildrenField.value;
      const childrenField = computeChildrenField.value;
      const checkboxOpts = computeCheckboxOpts.value;
      const {
        checkStrictly
      } = checkboxOpts;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const handleSelect = node => {
        const nodeid = getNodeId(node);
        if (checked) {
          if (!selectCheckboxMaps[nodeid]) {
            selectCheckboxMaps[nodeid] = node;
          }
        } else {
          if (selectCheckboxMaps[nodeid]) {
            delete selectCheckboxMaps[nodeid];
          }
        }
      };
      if (checkStrictly) {
        nodeList.forEach(handleSelect);
      } else {
        _xeUtils.default.eachTree(nodeList, handleSelect, {
          children: transform ? mapChildrenField : childrenField
        });
      }
      reactData.updateCheckboxFlag++;
      updateCheckboxStatus();
    };
    const createNode = records => {
      const valueField = computeValueField.value;
      return Promise.resolve(records.map(obj => {
        const item = Object.assign({}, obj);
        let nodeid = getNodeId(item);
        if (!nodeid) {
          nodeid = getNodeUniqueId();
          _xeUtils.default.set(item, valueField, nodeid);
        }
        return item;
      }));
    };
    const handleSetCheckboxByNodeId = (nodeKeys, checked) => {
      const {
        nodeMaps
      } = internalData;
      if (nodeKeys) {
        if (!_xeUtils.default.isArray(nodeKeys)) {
          nodeKeys = [nodeKeys];
        }
        const nodeList = [];
        nodeKeys.forEach(nodeKey => {
          const nodeid = (0, _util.enNodeValue)(nodeKey);
          const nodeItem = nodeMaps[nodeid];
          if (nodeItem) {
            nodeList.push(nodeItem.item);
          }
        });
        handleCheckedCheckboxNode(nodeList, checked);
      }
      return (0, _vue.nextTick)();
    };
    const updateCheckboxChecked = nodeKeys => {
      internalData.selectCheckboxMaps = {};
      handleSetCheckboxByNodeId(nodeKeys, true);
    };
    const updateModelChecked = () => {
      const {
        modelValue
      } = props;
      const {
        nodeMaps
      } = internalData;
      const expandedMaps = {};
      if (props.multiple) {
        if (modelValue && modelValue.length) {
          updateCheckboxChecked(modelValue);
        }
      } else {
        if (modelValue) {
          const nodeid = (0, _util.enNodeValue)(_xeUtils.default.isArray(modelValue) ? modelValue[0] : modelValue);
          const itemRest = nodeMaps[nodeid];
          if (itemRest) {
            itemRest.nodes.forEach(item => {
              expandedMaps[getNodeId(item)] = true;
            });
            reactData.selectRadioKey = nodeid;
          }
        }
      }
      internalData.treeExpandedMaps = expandedMaps;
    };
    const cacheNodeMap = () => {
      const {
        separator
      } = props;
      const {
        treeFullData
      } = internalData;
      const valueField = computeValueField.value;
      const labelField = computeLabelField.value;
      const childrenField = computeChildrenField.value;
      const keyMaps = {};
      const fullMaps = {};
      _xeUtils.default.eachTree(treeFullData, (item, index, items, path, parenItem, nodes) => {
        let nodeid = getNodeId(item);
        if (!nodeid) {
          nodeid = getNodeUniqueId();
          item[valueField] = nodeid;
        }
        const nodeVal = item[valueField];
        const itemRest = {
          item,
          index,
          $index: -1,
          _index: -1,
          items,
          parent: parenItem,
          nodes,
          level: nodes.length - 1,
          treeIndex: index,
          lineCount: 0,
          treeLoaded: false,
          fullLabel: nodes.map(item => item[labelField]).join(separator || ' / ')
        };
        keyMaps[nodeid] = itemRest;
        fullMaps[nodeVal] = itemRest;
      }, {
        children: childrenField
      });
      internalData.nodeMaps = keyMaps;
      internalData.fullNodeMaps = fullMaps;
      reactData.fullOptFlag++;
    };
    const updateAfterDataIndex = () => {
      const {
        separator
      } = props;
      const {
        afterTreeList,
        nodeMaps
      } = internalData;
      const labelField = computeLabelField.value;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      let vtIndex = 0;
      _xeUtils.default.eachTree(afterTreeList, (item, index, items, path, parenItem, nodes) => {
        const nodeid = getNodeId(item);
        const nodeItem = nodeMaps[nodeid];
        if (nodeItem) {
          nodeItem.items = items;
          nodeItem.treeIndex = index;
          nodeItem._index = vtIndex;
        } else {
          const rest = {
            item,
            index,
            $index: -1,
            _index: vtIndex,
            items,
            parent: parenItem,
            nodes,
            level: nodes.length - 1,
            treeIndex: index,
            lineCount: 0,
            treeLoaded: false,
            fullLabel: nodes.map(item => item[labelField]).join(separator || ' / ')
          };
          nodeMaps[nodeid] = rest;
        }
        vtIndex++;
      }, {
        children: transform ? mapChildrenField : childrenField
      });
    };
    const updateAfterFullData = () => {
      const {
        searchValue
      } = reactData;
      const {
        treeFullData,
        lastFilterValue
      } = internalData;
      const labelField = computeLabelField.value;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const filterOpts = computeFilterOpts.value;
      const {
        beforeFilterMethod,
        filterMethod,
        afterFilterMethod
      } = filterOpts;
      let fullList = treeFullData;
      let treeList = fullList;
      let filterStr = '';
      if (searchValue) {
        filterStr = `${searchValue}`;
        const handleSearch = filterMethod ? item => {
          return filterMethod({
            $cascader: $xeCascader,
            node: item,
            filterValue: filterStr
          });
        } : item => {
          return String(item[labelField]).toLowerCase().indexOf(filterStr.toLowerCase()) > -1;
        };
        const bafParams = {
          $cascader: $xeCascader,
          filterValue: filterStr
        };
        if (beforeFilterMethod) {
          beforeFilterMethod(bafParams);
        }
        if (transform) {
          treeList = _xeUtils.default.searchTree(treeFullData, handleSearch, {
            original: true,
            isEvery: false,
            children: childrenField,
            mapChildren: mapChildrenField
          });
          fullList = treeList;
        } else {
          fullList = treeFullData.filter(handleSearch);
        }
        internalData.lastFilterValue = filterStr;
        (0, _vue.nextTick)(() => {
          if (afterFilterMethod) {
            afterFilterMethod(bafParams);
          }
        });
      } else {
        if (transform) {
          treeList = _xeUtils.default.searchTree(treeFullData, () => true, {
            original: true,
            isEvery: false,
            children: childrenField,
            mapChildren: mapChildrenField
          });
          fullList = treeList;
          if (lastFilterValue) {
            const bafParams = {
              $cascader: $xeCascader,
              filterValue: filterStr
            };
            if (beforeFilterMethod) {
              beforeFilterMethod(bafParams);
            }
            // 取消筛选时自动收起
            (0, _vue.nextTick)(() => {
              if (afterFilterMethod) {
                afterFilterMethod(bafParams);
              }
            });
          }
        }
        internalData.lastFilterValue = '';
      }
      internalData.afterVisibleList = fullList;
      internalData.afterTreeList = treeList;
      updateAfterDataIndex();
    };
    /**
     * 如果为虚拟树、则将树结构拍平
     */
    const handleTreeToList = () => {
      const {
        afterTreeList,
        treeExpandedMaps
      } = internalData;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const expandMaps = {};
      if (transform) {
        const fullData = [];
        _xeUtils.default.eachTree(afterTreeList, (item, index, items, path, parentRow) => {
          const nodeid = getNodeId(item);
          const parentNodeid = getNodeId(parentRow);
          if (!parentRow || expandMaps[parentNodeid] && treeExpandedMaps[parentNodeid]) {
            expandMaps[nodeid] = 1;
            fullData.push(item);
          }
        }, {
          children: mapChildrenField
        });
        internalData.afterVisibleList = fullData;
        return fullData;
      }
      return internalData.afterVisibleList;
    };
    const handleData = force => {
      let fullList = internalData.afterVisibleList;
      if (force) {
        // 更新数据，处理筛选和排序
        updateAfterFullData();
        // 如果为虚拟树，将树结构拍平
        fullList = handleTreeToList();
      }
      const treeList = fullList.slice(0);
      reactData.treeList = treeList;
    };
    /**
     * 获取第一个拥有子节点的节点
     */
    function handleHasChildNodeIds(treeList, type) {
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const childField = transform ? mapChildrenField : childrenField;
      const nodeIds = [];
      let currList = treeList;
      while (currList.length) {
        let targetNode = null;
        for (const item of currList) {
          const kids = item[childField];
          if (_xeUtils.default.isArray(kids) && kids.length > 0) {
            targetNode = item;
            break;
          }
        }
        if (targetNode) {
          nodeIds.push(getNodeId(targetNode));
          currList = targetNode[childField];
        } else {
          const endNode = _xeUtils.default[type](currList);
          nodeIds.push(getNodeId(endNode));
          break;
        }
      }
      return nodeIds;
    }
    const triggerSearchEvent = _xeUtils.default.debounce(() => {
      handleData(true);
      updateCheckboxStatus();
      const {
        currentItems
      } = reactData;
      const {
        afterTreeList
      } = internalData;
      const filterOpts = computeFilterOpts.value;
      const {
        autoExpandMode
      } = filterOpts;
      // 如果当前不在列表情况下，触发默认行为
      if (!isPathInTree(afterTreeList, currentItems)) {
        // 默认展开
        if (autoExpandMode === 'first' || autoExpandMode === 'last') {
          const stItems = handleHasChildNodeIds(afterTreeList, autoExpandMode);
          const expandedMaps = {};
          stItems.forEach(nodeid => {
            expandedMaps[nodeid] = true;
          });
          internalData.treeExpandedMaps = expandedMaps;
          reactData.currentItems = stItems;
        } else {
          handleCurrentItems();
        }
      }
      updateCurrentChunk();
    }, 350, {
      trailing: true
    });
    const loadData = list => {
      const treeOpts = computeTreeOpts.value;
      const keyField = computeKeyField.value;
      const parentField = computeParentField.value;
      const childrenField = computeChildrenField.value;
      const {
        rootParentValue,
        rootValues
      } = treeOpts;
      const {
        transform
      } = treeOpts;
      const fullData = transform ? _xeUtils.default.toArrayTree(list, {
        key: keyField,
        parentKey: parentField,
        mapChildren: childrenField,
        rootParentValue,
        rootValues
      }) : list ? list.slice(0) : [];
      internalData.treeFullData = fullData;
      cacheNodeMap();
      handleData(true);
      updateModelChecked();
      handleCurrentItems();
      updateCurrentChunk();
      return (0, _vue.nextTick)();
    };
    const updateCurrentChunk = () => {
      const {
        currentItems
      } = reactData;
      const {
        afterTreeList
      } = internalData;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const currentCunkList = [afterTreeList];
      if (currentItems.length) {
        let chunkIndex = 0;
        let stNodeid = currentItems[chunkIndex];
        let optList = afterTreeList;
        while (stNodeid && optList && optList.length) {
          stNodeid = currentItems[chunkIndex++];
          const currOption = optList.find(item => stNodeid === getNodeId(item));
          optList = currOption ? currOption[transform ? mapChildrenField : childrenField] : [];
          if (!optList || !optList.length) {
            break;
          }
          currentCunkList.push(optList);
        }
      }
      reactData.currentCunkList = currentCunkList;
    };
    const handleCurrentItems = () => {
      const {
        currentNode
      } = reactData;
      const {
        afterTreeList
      } = internalData;
      const selectVals = computeSelectVals.value;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const stItems = [];
      const expandedMaps = {};
      const lastVal = currentNode ? getNodeId(currentNode) : (0, _util.enNodeValue)(_xeUtils.default.last(selectVals));
      if (lastVal) {
        const stRest = _xeUtils.default.findTree(afterTreeList, item => lastVal === getNodeId(item), {
          children: transform ? mapChildrenField : childrenField
        });
        if (stRest) {
          const {
            nodes
          } = stRest;
          nodes.forEach(item => {
            const nodeid = getNodeId(item);
            expandedMaps[nodeid] = true;
            stItems.push(nodeid);
          });
        }
      }
      reactData.currentItems = stItems;
      internalData.treeExpandedMaps = expandedMaps;
    };
    const updateZindex = () => {
      const popupOpts = computePopupOpts.value;
      const {
        zIndex
      } = popupOpts;
      if (zIndex) {
        reactData.panelIndex = zIndex;
      } else if (reactData.panelIndex < (0, _utils.getLastZIndex)()) {
        reactData.panelIndex = (0, _utils.nextZIndex)();
      }
    };
    const updatePlacement = () => {
      const {
        panelIndex
      } = reactData;
      const targetElem = refElem.value;
      const panelElem = refOptionPanel.value;
      const btnTransfer = computeBtnTransfer.value;
      const popupOpts = computePopupOpts.value;
      const handleStyle = () => {
        const ppObj = (0, _dom.updatePanelPlacement)(targetElem, panelElem, {
          placement: popupOpts.placement,
          defaultPlacement: popupOpts.defaultPlacement,
          teleportTo: btnTransfer,
          isMinWidth: false
        });
        const panelStyle = Object.assign(ppObj.style, {
          zIndex: panelIndex
        });
        reactData.panelStyle = panelStyle;
        reactData.panelPlacement = ppObj.placement;
      };
      handleStyle();
      return (0, _vue.nextTick)().then(handleStyle);
    };
    const showOptionPanel = evnt => {
      const {
        loading,
        remote,
        filterable
      } = props;
      const {
        treeFullData
      } = internalData;
      const isDisabled = computeIsDisabled.value;
      const remoteOpts = computeRemoteOpts.value;
      if (!loading && !isDisabled) {
        clearTimeout(internalData.hpTimeout);
        if (!reactData.initialized) {
          reactData.initialized = true;
        }
        reactData.isActivated = true;
        reactData.isAniVisible = true;
        if (filterable) {
          if (remote && remoteOpts.enabled && remoteOpts.autoLoad && !treeFullData.length) {
            handleSearchEvent();
          }
        }
        setTimeout(() => {
          reactData.visiblePanel = true;
          handleFocusSearch();
        }, 10);
        updateZindex();
        updatePlacement();
        dispatchEvent('visible-change', {
          visible: true
        }, evnt || null);
      }
    };
    const hideOptionPanel = evnt => {
      reactData.visiblePanel = false;
      internalData.hpTimeout = setTimeout(() => {
        reactData.isAniVisible = false;
      }, 350);
      dispatchEvent('visible-change', {
        visible: false
      }, evnt || null);
    };
    const setCurrentNode = node => {
      reactData.currentNode = node;
      updateCurrentChunk();
      return (0, _vue.nextTick)();
    };
    const setAllCheckboxNode = checked => {
      const selectMaps = {};
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const checkKeys = [];
      const checkNodes = [];
      if (checked) {
        _xeUtils.default.eachTree(internalData.afterTreeList, node => {
          const nodeid = getNodeId(node);
          checkKeys.push(nodeid);
          checkNodes.push(node);
          selectMaps[nodeid] = true;
        }, {
          children: transform ? mapChildrenField : childrenField
        });
      }
      internalData.indeterminateRowMaps = {};
      internalData.selectCheckboxMaps = selectMaps;
      reactData.updateCheckboxFlag++;
      updateCheckboxStatus();
      return (0, _vue.nextTick)().then(() => {
        return {
          checkNodeKeys: checkKeys,
          checkNodes
        };
      });
    };
    const clearSelectedNode = () => {
      internalData.indeterminateRowMaps = {};
      internalData.selectCheckboxMaps = {};
      reactData.updateCheckboxFlag++;
      reactData.selectRadioKey = null;
      updateCheckboxStatus();
      return (0, _vue.nextTick)().then(() => {
        return {
          checkNodeKeys: [],
          checkNodes: []
        };
      });
    };
    const changeEvent = (evnt, selectValue, node) => {
      const value = _xeUtils.default.isArray(selectValue) ? selectValue.map(_util.deNodeValue) : (0, _util.deNodeValue)(selectValue);
      internalData.isUpdateMode = true;
      emitModel(value);
      if (value !== props.modelValue) {
        dispatchEvent('change', {
          value,
          node,
          option: node
        }, evnt);
        // 自动更新校验状态
        if ($xeForm && formItemInfo) {
          $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
        }
      }
    };
    const clearValueEvent = (evnt, selectValue) => {
      changeEvent(evnt, selectValue, null);
      dispatchEvent('clear', {
        value: selectValue
      }, evnt);
    };
    const clearEvent = (params, evnt) => {
      clearValueEvent(evnt, null);
      hideOptionPanel(evnt);
    };
    const allCheckedPanelEvent = params => {
      const {
        $event
      } = params;
      const {
        multiple,
        checkedClosable
      } = props;
      if (multiple) {
        setAllCheckboxNode(true).then(({
          checkNodeKeys,
          checkNodes
        }) => {
          changeEvent($event, checkNodeKeys, checkNodes[0]);
          dispatchEvent('all-change', {
            value: checkNodeKeys
          }, $event);
          if (checkedClosable) {
            hideOptionPanel($event);
          }
        });
      }
    };
    const clearCheckedPanelEvent = params => {
      const {
        $event
      } = params;
      const {
        multiple,
        checkedClosable
      } = props;
      const value = multiple ? [] : null;
      clearSelectedNode().then(() => {
        if (checkedClosable) {
          hideOptionPanel($event);
        }
      });
      changeEvent($event, value, null);
      dispatchEvent('clear', {
        value
      }, $event);
    };
    const closePanelEvent = params => {
      const {
        $event
      } = params;
      hideOptionPanel($event);
    };
    const handleGlobalMousewheelEvent = evnt => {
      const {
        visiblePanel
      } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (visiblePanel) {
          const panelElem = refOptionPanel.value;
          if ((0, _dom.getEventTargetNode)(evnt, panelElem).flag) {
            updatePlacement();
          } else {
            hideOptionPanel(evnt);
          }
        }
      }
    };
    const handleGlobalMousedownEvent = evnt => {
      const {
        visiblePanel
      } = reactData;
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        const el = refElem.value;
        const panelElem = refOptionPanel.value;
        reactData.isActivated = (0, _dom.getEventTargetNode)(evnt, el).flag || (0, _dom.getEventTargetNode)(evnt, panelElem).flag;
        if (visiblePanel && !reactData.isActivated) {
          hideOptionPanel(evnt);
        }
      }
    };
    const handleGlobalBlurEvent = evnt => {
      const {
        visiblePanel,
        isActivated
      } = reactData;
      if (visiblePanel) {
        hideOptionPanel(evnt);
      }
      if (isActivated) {
        reactData.isActivated = false;
      }
      if (visiblePanel || isActivated) {
        const $input = refInput.value;
        if ($input) {
          $input.blur();
        }
      }
    };
    const handleGlobalResizeEvent = () => {
      const {
        visiblePanel
      } = reactData;
      if (visiblePanel) {
        updatePlacement();
      }
    };
    const handleFocusSearch = () => {
      if (props.filterable) {
        (0, _vue.nextTick)(() => {
          const inpSearch = refInpSearch.value;
          if (inpSearch) {
            inpSearch.focus();
          }
        });
      }
    };
    const changeCurrentEvent = (evnt, node) => {
      evnt.preventDefault();
      const isChecked = true;
      reactData.currentNode = node;
      dispatchEvent('current-change', {
        node,
        checked: isChecked
      }, evnt);
    };
    const changeRadioEvent = (evnt, node, chunks, chunkIndex) => {
      evnt.preventDefault();
      evnt.stopPropagation();
      const {
        currentItems
      } = reactData;
      const {
        nodeMaps
      } = internalData;
      const radioOpts = computeRadioOpts.value;
      const childrenField = computeChildrenField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const mapChildrenField = computeMapChildrenField.value;
      const {
        checkMode,
        checkMethod
      } = radioOpts;
      const nodeid = getNodeId(node);
      const childList = node[transform ? mapChildrenField : childrenField];
      const isExistChild = childList && childList.length > 0;
      const nodeItem = nodeMaps[nodeid] || {};
      const nLevel = nodeItem.level;
      const isDisabled = checkMethod ? !checkMethod({
        $cascader: $xeCascader,
        node
      }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
      if (isDisabled) {
        return;
      }
      const value = nodeid;
      reactData.selectRadioKey = value;
      changeEvent(evnt, value, node);
      if (!currentItems.includes(nodeid)) {
        changeCurrentEvent(evnt, node);
        toggleExpandEvent(evnt, node, chunks, chunkIndex);
      }
      hideOptionPanel(evnt);
    };
    const handleAsyncTreeExpandChilds = node => {
      const checkboxOpts = computeCheckboxOpts.value;
      const treeOpts = computeTreeOpts.value;
      const {
        loadMethod
      } = treeOpts;
      const {
        checkStrictly
      } = checkboxOpts;
      return new Promise(resolve => {
        if (loadMethod) {
          const {
            nodeMaps
          } = internalData;
          const nodeid = getNodeId(node);
          const nodeItem = nodeMaps[nodeid];
          internalData.treeExpandLazyLoadedMaps[nodeid] = true;
          Promise.resolve(loadMethod({
            $cascader: $xeCascader,
            node
          })).then(childRecords => {
            const {
              treeExpandLazyLoadedMaps
            } = internalData;
            nodeItem.treeLoaded = true;
            if (treeExpandLazyLoadedMaps[nodeid]) {
              treeExpandLazyLoadedMaps[nodeid] = false;
            }
            if (!_xeUtils.default.isArray(childRecords)) {
              childRecords = [];
            }
            if (childRecords) {
              return $xeCascader.loadChildrenNode(node, childRecords).then(childRows => {
                const {
                  treeExpandedMaps
                } = internalData;
                if (childRows.length && !treeExpandedMaps[nodeid]) {
                  treeExpandedMaps[nodeid] = true;
                }
                reactData.updateExpandedFlag++;
                // 如果当前节点已选中，则展开后子节点也被选中
                if (!checkStrictly && $xeCascader.isCheckedByCheckboxNodeId(nodeid)) {
                  handleCheckedCheckboxNode(childRows, true);
                }
                dispatchEvent('load-success', {
                  node,
                  data: childRecords
                }, new Event('load-success'));
                return (0, _vue.nextTick)();
              });
            } else {
              dispatchEvent('load-success', {
                node,
                data: childRecords
              }, new Event('load-success'));
            }
          }).catch(e => {
            const {
              treeExpandLazyLoadedMaps
            } = internalData;
            nodeItem.treeLoaded = false;
            if (treeExpandLazyLoadedMaps[nodeid]) {
              treeExpandLazyLoadedMaps[nodeid] = false;
            }
            dispatchEvent('load-error', {
              node,
              data: e
            }, new Event('load-error'));
          }).finally(() => {
            handleTreeToList();
            handleData();
          });
        } else {
          resolve();
        }
      });
    };
    /**
     * 展开与收起树节点
     * @param nodeList
     * @param expanded
     * @returns
     */
    const handleBaseTreeExpand = (nodeList, expanded) => {
      const {
        treeExpandLazyLoadedMaps,
        treeExpandedMaps
      } = internalData;
      const {
        nodeMaps
      } = internalData;
      const childrenField = computeChildrenField.value;
      const hasChildField = computeHasChildField.value;
      const treeOpts = computeTreeOpts.value;
      const {
        lazy,
        toggleMethod
      } = treeOpts;
      const result = [];
      let validNodes = toggleMethod ? nodeList.filter(node => toggleMethod({
        $cascader: $xeCascader,
        expanded,
        node
      })) : nodeList;
      validNodes = validNodes.length ? [validNodes[validNodes.length - 1]] : [];
      // 同一级只能展开一个
      const nodeid = getNodeId(validNodes[0]);
      const nodeItem = nodeMaps[nodeid];
      if (nodeItem) {
        nodeItem.items.forEach(item => {
          const itemNodeId = getNodeId(item);
          if (treeExpandedMaps[itemNodeId]) {
            delete treeExpandedMaps[itemNodeId];
          }
        });
      }
      const expandNodes = [];
      if (expanded) {
        validNodes.forEach(item => {
          const itemNodeId = getNodeId(item);
          if (!treeExpandedMaps[itemNodeId]) {
            const nodeItem = nodeMaps[itemNodeId];
            const isLoad = lazy && item[hasChildField] && !nodeItem.treeLoaded && !treeExpandLazyLoadedMaps[itemNodeId];
            // 是否使用懒加载
            if (isLoad) {
              result.push(handleAsyncTreeExpandChilds(item));
            } else {
              if (item[childrenField] && item[childrenField].length) {
                treeExpandedMaps[itemNodeId] = true;
                expandNodes.push(item);
              }
            }
          }
        });
      } else {
        validNodes.forEach(item => {
          const itemNodeId = getNodeId(item);
          if (treeExpandedMaps[itemNodeId]) {
            delete treeExpandedMaps[itemNodeId];
            expandNodes.push(item);
          }
        });
      }
      reactData.updateExpandedFlag++;
      handleTreeToList();
      handleData();
      return Promise.all(result);
    };
    const toggleExpandEvent = (evnt, node, chunks, chunkIndex) => {
      const {
        currentItems
      } = reactData;
      const {
        treeExpandLazyLoadedMaps
      } = internalData;
      const treeOpts = computeTreeOpts.value;
      const {
        lazy
      } = treeOpts;
      const stItems = currentItems.slice(0, chunkIndex);
      const nodeid = getNodeId(node);
      const expanded = true;
      evnt.stopPropagation();
      stItems.push(nodeid);
      reactData.currentItems = stItems;
      if (!lazy || !treeExpandLazyLoadedMaps[nodeid]) {
        handleBaseTreeExpand([node], expanded);
      }
      setCurrentNode(node);
      dispatchEvent('node-expand', {
        node,
        expanded
      }, evnt);
    };
    const updateCheckboxStatus = () => {
      const {
        selectCheckboxMaps,
        indeterminateRowMaps,
        afterTreeList
      } = internalData;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const checkboxOpts = computeCheckboxOpts.value;
      const {
        checkStrictly,
        checkMethod
      } = checkboxOpts;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      if (!checkStrictly) {
        const childRowMaps = {};
        const childRowList = [];
        _xeUtils.default.eachTree(afterTreeList, node => {
          const nodeid = getNodeId(node);
          const childList = node[transform ? mapChildrenField : childrenField];
          if (childList && childList.length && !childRowMaps[nodeid]) {
            childRowMaps[nodeid] = 1;
            childRowList.unshift([node, nodeid, childList]);
          }
        }, {
          children: transform ? mapChildrenField : childrenField
        });
        childRowList.forEach(vals => {
          const node = vals[0];
          const nodeid = vals[1];
          const childList = vals[2];
          let sLen = 0; // 已选
          let hLen = 0; // 半选
          let vLen = 0; // 有效子行
          const cLen = childList.length; // 子行
          childList.forEach(checkMethod ? item => {
            const childNodeid = getNodeId(item);
            const isSelect = selectCheckboxMaps[childNodeid];
            if (checkMethod({
              $cascader: $xeCascader,
              node: item
            })) {
              if (isSelect) {
                sLen++;
              } else if (indeterminateRowMaps[childNodeid]) {
                hLen++;
              }
              vLen++;
            } else {
              if (isSelect) {
                sLen++;
              } else if (indeterminateRowMaps[childNodeid]) {
                hLen++;
              }
            }
          } : item => {
            const childNodeid = getNodeId(item);
            const isSelect = selectCheckboxMaps[childNodeid];
            if (isSelect) {
              sLen++;
            } else if (indeterminateRowMaps[childNodeid]) {
              hLen++;
            }
            vLen++;
          });
          let isSelected = false;
          if (cLen > 0) {
            if (vLen > 0) {
              isSelected = (sLen > 0 || hLen > 0) && sLen >= vLen;
            } else {
              // 如果存在子项禁用
              if (sLen > 0 && sLen >= vLen) {
                isSelected = true;
              } else if (selectCheckboxMaps[nodeid]) {
                isSelected = true;
              } else {
                isSelected = false;
              }
            }
          } else {
            // 如果无子项
            isSelected = selectCheckboxMaps[nodeid];
          }
          const halfSelect = !isSelected && (sLen > 0 || hLen > 0);
          if (isSelected) {
            selectCheckboxMaps[nodeid] = node;
            if (indeterminateRowMaps[nodeid]) {
              delete indeterminateRowMaps[nodeid];
            }
          } else {
            if (selectCheckboxMaps[nodeid]) {
              delete selectCheckboxMaps[nodeid];
            }
            if (halfSelect) {
              indeterminateRowMaps[nodeid] = node;
            } else {
              if (indeterminateRowMaps[nodeid]) {
                delete indeterminateRowMaps[nodeid];
              }
            }
          }
        });
        reactData.updateCheckboxFlag++;
      }
    };
    const changeCheckboxEvent = (evnt, node, chunks, chunkIndex) => {
      evnt.preventDefault();
      evnt.stopPropagation();
      // const { filterable } = props
      const {
        currentItems
      } = reactData;
      const {
        selectCheckboxMaps,
        nodeMaps
      } = internalData;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const checkboxOpts = computeCheckboxOpts.value;
      const {
        checkStrictly,
        checkMode,
        checkMethod
      } = checkboxOpts;
      const treeOpts = computeTreeOpts.value;
      const {
        transform
      } = treeOpts;
      const nodeid = getNodeId(node);
      const childList = node[transform ? mapChildrenField : childrenField];
      const isExistChild = childList && childList.length > 0;
      const nodeItem = nodeMaps[nodeid] || {};
      const nLevel = nodeItem.level;
      const isDisabled = checkMethod ? !checkMethod({
        $cascader: $xeCascader,
        node
      }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
      if (isDisabled) {
        return;
      }
      let isChecked = false;
      if (selectCheckboxMaps[nodeid]) {
        delete selectCheckboxMaps[nodeid];
      } else {
        isChecked = true;
        selectCheckboxMaps[nodeid] = node;
      }
      if (!checkStrictly) {
        _xeUtils.default.eachTree(childList, childNode => {
          const childNodeid = getNodeId(childNode);
          if (isChecked) {
            if (!selectCheckboxMaps[childNodeid]) {
              selectCheckboxMaps[childNodeid] = childNode;
            }
          } else {
            if (selectCheckboxMaps[childNodeid]) {
              delete selectCheckboxMaps[childNodeid];
            }
          }
        }, {
          children: transform ? mapChildrenField : childrenField
        });
      }
      selectCheckboxMaps[nodeid] = node;
      reactData.updateCheckboxFlag++;
      updateCheckboxStatus();
      const nodeids = _xeUtils.default.keys(selectCheckboxMaps);
      const value = nodeids;
      changeEvent(evnt, value, node);
      if (!currentItems.includes(nodeid)) {
        changeCurrentEvent(evnt, node);
        toggleExpandEvent(evnt, node, chunks, chunkIndex);
      }
    };
    const handleNodeClickEvent = (evnt, node, chunks, chunkIndex) => {
      const {
        multiple,
        showCheckbox,
        showRadio
      } = props;
      const treeOpts = computeTreeOpts.value;
      const radioOpts = computeRadioOpts.value;
      const checkboxOpts = computeCheckboxOpts.value;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const {
        transform,
        trigger
      } = treeOpts;
      const childList = node[transform ? mapChildrenField : childrenField];
      let triggerCurrent = false;
      let triggerRadio = false;
      let triggerCheckbox = false;
      let triggerExpand = false;
      triggerCurrent = true;
      changeCurrentEvent(evnt, node);
      if (trigger !== 'icon') {
        triggerExpand = true;
        toggleExpandEvent(evnt, node, chunks, chunkIndex);
      }
      if (multiple) {
        if (checkboxOpts.trigger === 'node' || !showCheckbox && (!childList || !childList.length)) {
          triggerCheckbox = true;
          changeCheckboxEvent(evnt, node, chunks, chunkIndex);
        }
      } else {
        if (radioOpts.trigger === 'node' || !showRadio && (!childList || !childList.length)) {
          triggerRadio = true;
          changeRadioEvent(evnt, node, chunks, chunkIndex);
        }
      }
      dispatchEvent('node-click', {
        node,
        triggerCurrent,
        triggerRadio,
        triggerCheckbox,
        triggerExpand
      }, evnt);
    };
    const focusEvent = evnt => {
      const isDisabled = computeIsDisabled.value;
      if (!isDisabled) {
        if (!reactData.visiblePanel) {
          reactData.triggerFocusPanel = true;
          showOptionPanel(evnt);
          setTimeout(() => {
            reactData.triggerFocusPanel = false;
          }, 150);
        }
      }
      dispatchEvent('focus', {}, evnt);
    };
    const clickEvent = evnt => {
      evnt.preventDefault();
      if (reactData.triggerFocusPanel) {
        reactData.triggerFocusPanel = false;
      } else {
        if (!reactData.visiblePanel) {
          showOptionPanel(evnt);
        }
      }
      dispatchEvent('click', {}, evnt);
    };
    const blurEvent = evnt => {
      reactData.isActivated = false;
      dispatchEvent('blur', {}, evnt);
    };
    const modelSearchEvent = value => {
      reactData.searchValue = value;
      triggerSearchEvent(new Event('filter'));
    };
    const handleSearchEvent = () => {
      const {
        modelValue,
        remote
      } = props;
      const {
        searchValue
      } = reactData;
      const remoteOpts = computeRemoteOpts.value;
      const queryMethod = remoteOpts.queryMethod;
      if (remote && queryMethod && remoteOpts.enabled) {
        reactData.searchLoading = true;
        Promise.resolve(queryMethod({
          $cascader: $xeCascader,
          searchValue,
          value: modelValue
        })).then(() => (0, _vue.nextTick)()).catch(() => (0, _vue.nextTick)()).finally(() => {
          reactData.searchLoading = false;
        });
      }
    };
    const togglePanelEvent = params => {
      const {
        $event
      } = params;
      $event.preventDefault();
      if (reactData.triggerFocusPanel) {
        reactData.triggerFocusPanel = false;
      } else {
        if (reactData.visiblePanel) {
          hideOptionPanel($event);
        } else {
          showOptionPanel($event);
        }
      }
    };
    const cascaderPrivateMethods = {
      isCheckedByCheckboxNodeId,
      /**
       * 用于树结构，给行数据加载子节点
       */
      loadChildrenNode(node, childRecords) {
        const {
          separator
        } = props;
        const {
          nodeMaps
        } = internalData;
        const treeOpts = computeTreeOpts.value;
        const labelField = computeLabelField.value;
        const {
          lazy,
          transform
        } = treeOpts;
        if (!lazy) {
          return Promise.resolve([]);
        }
        const childrenField = computeChildrenField.value;
        const mapChildrenField = computeMapChildrenField.value;
        const parentNodeItem = nodeMaps[getNodeId(node)];
        const parentLevel = parentNodeItem ? parentNodeItem.level : 0;
        const parentNodes = parentNodeItem ? parentNodeItem.nodes : [];
        return createNode(childRecords).then(nodeList => {
          _xeUtils.default.eachTree(nodeList, (childRow, index, items, path, parent, nodes) => {
            const itemNodeId = getNodeId(childRow);
            nodeMaps[itemNodeId] = {
              item: childRow,
              index: -1,
              $index: -1,
              _index: -1,
              items,
              parent: parent || parentNodeItem.item,
              nodes: parentNodes.concat(nodes),
              level: parentLevel + nodes.length,
              treeIndex: -1,
              lineCount: 0,
              treeLoaded: false,
              fullLabel: nodes.map(item => item[labelField]).join(separator || ' / ')
            };
          }, {
            children: childrenField
          });
          node[childrenField] = nodeList;
          if (transform) {
            node[mapChildrenField] = nodeList;
          }
          updateAfterDataIndex();
          return nodeList;
        });
      }
    };
    Object.assign($xeCascader, cascaderMethods, cascaderPrivateMethods);
    const handleVisibleOrCheckMode = (mode, isExistChild, nLevel) => {
      if (mode) {
        if (mode === 'first') {
          return !nLevel;
        }
        if (mode === 'last') {
          return !isExistChild;
        }
      }
      return true;
    };
    const renderRadio = (node, isExistChild, nLevel, isChecked, chunks, chunkIndex) => {
      const {
        showRadio
      } = props;
      const radioOpts = computeRadioOpts.value;
      const {
        checkMode,
        checkMethod,
        visibleMode,
        visibleMethod
      } = radioOpts;
      const isVisible = visibleMethod ? visibleMethod({
        $cascader: $xeCascader,
        node
      }) : handleVisibleOrCheckMode(visibleMode, isExistChild, nLevel);
      if (showRadio && isVisible) {
        const isDisabled = checkMethod ? !checkMethod({
          $cascader: $xeCascader,
          node
        }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
        return (0, _vue.h)('div', {
          class: ['vxe-tree--radio-option', {
            'is--checked': isChecked,
            'is--disabled': isDisabled
          }],
          onClick: evnt => {
            if (!isDisabled) {
              changeRadioEvent(evnt, node, chunks, chunkIndex);
            }
          }
        }, [(0, _vue.h)('span', {
          class: ['vxe-radio--icon', isChecked ? (0, _ui.getIcon)().RADIO_CHECKED : (0, _ui.getIcon)().RADIO_UNCHECKED]
        })]);
      }
      return (0, _ui.renderEmptyElement)($xeCascader);
    };
    const renderCheckbox = (node, isExistChild, nLevel, isChecked, isIndeterminate, chunks, chunkIndex) => {
      const {
        showCheckbox
      } = props;
      const checkboxOpts = computeCheckboxOpts.value;
      const {
        checkMode,
        checkMethod,
        visibleMode,
        visibleMethod
      } = checkboxOpts;
      const isVisible = visibleMethod ? visibleMethod({
        $cascader: $xeCascader,
        node
      }) : handleVisibleOrCheckMode(visibleMode, isExistChild, nLevel);
      if (showCheckbox && isVisible) {
        const isDisabled = checkMethod ? !checkMethod({
          $cascader: $xeCascader,
          node
        }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
        return (0, _vue.h)('div', {
          class: ['vxe-cascader--checkbox-option', {
            'is--checked': isChecked,
            'is--indeterminate': isIndeterminate,
            'is--disabled': isDisabled
          }],
          onClick: evnt => {
            if (!isDisabled) {
              changeCheckboxEvent(evnt, node, chunks, chunkIndex);
            }
          }
        }, [(0, _vue.h)('span', {
          class: ['vxe-checkbox--icon', isIndeterminate ? (0, _ui.getIcon)().CHECKBOX_INDETERMINATE : isChecked ? (0, _ui.getIcon)().CHECKBOX_CHECKED : (0, _ui.getIcon)().CHECKBOX_UNCHECKED]
        })]);
      }
      return (0, _ui.renderEmptyElement)($xeCascader);
    };
    const renderNode = (node, nodeid, nodeIndex, chunks, chunkIndex) => {
      const {
        multiple
      } = props;
      const {
        currentNode,
        selectRadioKey,
        updateCheckboxFlag,
        updateExpandedFlag
      } = reactData;
      const {
        nodeMaps,
        selectCheckboxMaps,
        indeterminateRowMaps,
        treeExpandedMaps,
        treeExpandLazyLoadedMaps
      } = internalData;
      const treeOpts = computeTreeOpts.value;
      const {
        lazy,
        transform,
        iconLoaded,
        iconOpen,
        iconClose
      } = treeOpts;
      const childrenField = computeChildrenField.value;
      const mapChildrenField = computeMapChildrenField.value;
      const labelField = computeLabelField.value;
      const hasChildField = computeHasChildField.value;
      const childList = node[transform ? mapChildrenField : childrenField];
      const isExistChild = childList && childList.length > 0;
      const iconSlot = slots.icon;
      const titleSlot = slots.title;
      const isExpand = updateExpandedFlag && treeExpandedMaps[nodeid];
      const nodeItem = nodeMaps[nodeid] || {};
      const nodeTitle = node[labelField];
      const nLevel = nodeItem.level;
      let isRadioChecked = false;
      if (!multiple) {
        isRadioChecked = nodeid === selectRadioKey;
      }
      let isCheckboxChecked = false;
      let isIndeterminate = false;
      if (multiple) {
        isCheckboxChecked = !!(updateCheckboxFlag && selectCheckboxMaps[nodeid]);
        isIndeterminate = !!(updateCheckboxFlag && indeterminateRowMaps[nodeid]);
      }
      let hasLazyChilds = false;
      let isLazyLoading = false;
      let isLazyLoaded = false;
      if (lazy) {
        isLazyLoading = !!treeExpandLazyLoadedMaps[nodeid];
        hasLazyChilds = node[hasChildField];
        isLazyLoaded = !!nodeItem.treeLoaded;
      }
      const nParams = {
        node
      };
      return (0, _vue.h)('div', {
        key: `${chunkIndex}_${nodeIndex}`,
        class: ['vxe-cascader-chunk--node-item', {
          'is--current': currentNode && (currentNode === node || getNodeId(currentNode) === nodeid),
          'is-radio--checked': isRadioChecked,
          'is-checkbox--checked': isCheckboxChecked,
          'is-checkbox--indeterminate': isIndeterminate,
          'is--expand': isExpand
        }],
        title: nodeTitle,
        onMousedown: evnt => {
          const isLeftBtn = evnt.button === 0;
          if (isLeftBtn) {
            evnt.stopPropagation();
          }
        },
        onClick(evnt) {
          handleNodeClickEvent(evnt, node, chunks, chunkIndex);
        }
      }, [multiple ? renderCheckbox(node, isExistChild, nLevel, isCheckboxChecked, isIndeterminate, chunks, chunkIndex) : renderRadio(node, isExistChild, nLevel, isRadioChecked, chunks, chunkIndex), (0, _vue.h)('div', {
        class: 'vxe-cascader-chunk--node-item-inner'
      }, [(0, _vue.h)('div', {
        class: 'vxe-cascader-chunk--node-item-title'
      }, titleSlot ? (0, _ui.getSlotVNs)(titleSlot(nParams)) : nodeTitle)]), treeOpts.showIcon && (lazy ? isLazyLoaded ? isExistChild : hasLazyChilds : isExistChild) ? (0, _vue.h)('div', {
        class: 'vxe-cascader-chunk--node-item-switcher'
      }, [[(0, _vue.h)('div', {
        class: 'vxe-cascader--node-item-icon',
        onClick(evnt) {
          if (treeOpts.trigger === 'icon') {
            toggleExpandEvent(evnt, node, chunks, chunkIndex);
          }
        }
      }, iconSlot ? (0, _ui.getSlotVNs)(iconSlot(nParams)) : [(0, _vue.h)('i', {
        class: isLazyLoading ? iconLoaded || (0, _ui.getIcon)().CASCADER_NODE_LOADED : isExpand ? iconOpen || (0, _ui.getIcon)().CASCADER_NODE_OPEN : iconClose || (0, _ui.getIcon)().CASCADER_NODE_CLOSE
      })])]]) : (0, _ui.renderEmptyElement)($xeCascader)]);
    };
    const renderVN = () => {
      const {
        className,
        modelValue,
        multiple,
        loading,
        filterable,
        showTotalButton,
        showCheckedButton,
        showClearButton,
        showCloseButton
      } = props;
      const {
        initialized,
        isActivated,
        isAniVisible,
        visiblePanel,
        searchValue,
        currentCunkList
      } = reactData;
      const {
        listVirtualYOpts
      } = internalData;
      const vSize = computeSize.value;
      const isDisabled = computeIsDisabled.value;
      const selectLabel = computeSelectLabel.value;
      const btnTransfer = computeBtnTransfer.value;
      const formReadonly = computeFormReadonly.value;
      const popupWrapperStyle = computePopupWrapperStyle.value;
      const headerSlot = slots.header;
      const footerSlot = slots.footer;
      const prefixSlot = slots.prefix;
      const popupOpts = computePopupOpts.value;
      const popupClassName = popupOpts.className;
      if (formReadonly) {
        return (0, _vue.h)('div', {
          ref: refElem,
          class: ['vxe-cascader--readonly', className]
        }, [(0, _vue.h)('span', {
          class: 'vxe-cascader-label'
        }, selectLabel)]);
      }
      const selectVals = _xeUtils.default.eqNull(modelValue) ? [] : _xeUtils.default.isArray(modelValue) ? modelValue : [modelValue];
      return (0, _vue.h)('div', {
        ref: refElem,
        class: ['vxe-cascader', className ? _xeUtils.default.isFunction(className) ? className({
          $cascader: $xeCascader
        }) : className : '', {
          [`size--${vSize}`]: vSize,
          'is--filterable': filterable,
          'is--visible': visiblePanel,
          'is--disabled': isDisabled,
          'is--loading': loading,
          'is--active': isActivated
        }]
      }, [(0, _vue.h)(_input.default, {
        ref: refInput,
        clearable: props.clearable,
        placeholder: loading ? (0, _ui.getI18n)('vxe.select.loadingText') : props.placeholder,
        editable: false,
        disabled: isDisabled,
        type: 'text',
        prefixIcon: props.prefixIcon,
        suffixIcon: loading ? (0, _ui.getIcon)().TREE_SELECT_LOADED : visiblePanel ? (0, _ui.getIcon)().TREE_SELECT_OPEN : (0, _ui.getIcon)().TREE_SELECT_CLOSE,
        modelValue: loading ? '' : selectLabel,
        title: selectLabel,
        onClear: clearEvent,
        onClick: clickEvent,
        onFocus: focusEvent,
        onBlur: blurEvent,
        onSuffixClick: togglePanelEvent
      }, prefixSlot ? {
        prefix: () => prefixSlot({})
      } : {}), (0, _vue.h)(_vue.Teleport, {
        to: 'body',
        disabled: btnTransfer ? !initialized : true
      }, [(0, _vue.h)('div', {
        ref: refOptionPanel,
        class: ['vxe-table--ignore-clear vxe-cascader--panel', popupClassName ? _xeUtils.default.isFunction(popupClassName) ? popupClassName({
          $cascader: $xeCascader
        }) : popupClassName : '', {
          [`size--${vSize}`]: vSize,
          'is--transfer': btnTransfer,
          'ani--leave': !loading && isAniVisible,
          'ani--enter': !loading && visiblePanel
        }],
        placement: reactData.panelPlacement,
        style: popupWrapperStyle
      }, initialized ? [(0, _vue.h)('div', {
        class: 'vxe-cascader--panel-wrapper'
      }, [filterable ? (0, _vue.h)('div', {
        class: 'vxe-cascader--panel-search'
      }, [(0, _vue.h)(_input.default, {
        ref: refInpSearch,
        class: 'vxe-cascader-search--input',
        modelValue: searchValue,
        clearable: true,
        disabled: false,
        readonly: false,
        placeholder: (0, _ui.getI18n)('vxe.cascader.search'),
        prefixIcon: (0, _ui.getIcon)().INPUT_SEARCH,
        'onUpdate:modelValue': modelSearchEvent
      })]) : (0, _ui.renderEmptyElement)($xeCascader), showCheckedButton && multiple || showClearButton || headerSlot ? (0, _vue.h)('div', {
        class: 'vxe-cascader--panel-header'
      }, headerSlot ? headerSlot({}) : [(0, _vue.h)('div', {
        class: 'vxe-cascader--header-button'
      }, [showCheckedButton && multiple || showClearButton ? (0, _vue.h)('div', {
        class: 'vxe-cascader--selected-btns'
      }, [showCheckedButton && multiple ? (0, _vue.h)(_button.default, {
        content: (0, _ui.getI18n)('vxe.treeSelect.allChecked'),
        mode: 'text',
        onClick: allCheckedPanelEvent
      }) : (0, _ui.renderEmptyElement)($xeCascader), showClearButton ? (0, _vue.h)(_button.default, {
        content: (0, _ui.getI18n)('vxe.treeSelect.clearChecked'),
        mode: 'text',
        onClick: clearCheckedPanelEvent
      }) : (0, _ui.renderEmptyElement)($xeCascader)]) : (0, _ui.renderEmptyElement)($xeCascader)])]) : (0, _ui.renderEmptyElement)($xeCascader), (0, _vue.h)('div', {
        class: 'vxe-cascader--panel-body'
      }, [(0, _vue.h)('div', {
        ref: refChunkWrapper,
        class: 'vxe-cascader-chunk--wrapper'
      }, [currentCunkList.map((chunks, chunkIndex) => {
        return (0, _vue.h)('div', {
          key: chunkIndex,
          class: 'vxe-cascader-chunk--item-wrapper'
        }, [(0, _vue.h)(_list.default, {
          data: chunks,
          virtualYConfig: listVirtualYOpts
        }, {
          default(slotParams) {
            const {
              items
            } = slotParams;
            return items.map((node, nodeIndex) => {
              const nodeid = getNodeId(node);
              return renderNode(node, nodeid, nodeIndex, chunks, chunkIndex);
            });
          }
        })]);
      })])]), footerSlot || showTotalButton || showCloseButton ? (0, _vue.h)('div', {
        class: 'vxe-cascader--panel-footer'
      }, footerSlot ? footerSlot({}) : [(0, _vue.h)('div', {
        class: 'vxe-cascader--footer-button'
      }, [showTotalButton ? (0, _vue.h)('div', {
        class: 'vxe-cascader--total-btns'
      }, (0, _ui.getI18n)('vxe.treeSelect.total', [selectVals.length])) : (0, _ui.renderEmptyElement)($xeCascader), showCloseButton ? (0, _vue.h)('div', {
        class: 'vxe-cascader--oper-btns'
      }, [(0, _vue.h)(_button.default, {
        content: (0, _ui.getI18n)('vxe.select.close'),
        mode: 'text',
        onClick: closePanelEvent
      })]) : (0, _ui.renderEmptyElement)($xeCascader)])]) : (0, _ui.renderEmptyElement)($xeCascader)])] : [])])]);
    };
    (0, _vue.watch)(() => props.modelValue, () => {
      if (!internalData.isUpdateMode) {
        updateModelChecked();
        handleCurrentItems();
        updateCurrentChunk();
      }
      internalData.isUpdateMode = false;
    });
    (0, _vue.watch)(() => props.options, () => {
      cacheNodeMap();
    });
    const dataFlag = (0, _vue.ref)(0);
    (0, _vue.watch)(() => props.options ? props.options.length : 0, () => {
      dataFlag.value++;
    });
    (0, _vue.watch)(() => props.options, () => {
      dataFlag.value++;
    });
    (0, _vue.watch)(dataFlag, () => {
      loadData(props.options || []);
    });
    loadData(props.options || []);
    (0, _vue.onMounted)(() => {
      _ui.globalEvents.on($xeCascader, 'mousewheel', handleGlobalMousewheelEvent);
      _ui.globalEvents.on($xeCascader, 'mousedown', handleGlobalMousedownEvent);
      _ui.globalEvents.on($xeCascader, 'blur', handleGlobalBlurEvent);
      _ui.globalEvents.on($xeCascader, 'resize', handleGlobalResizeEvent);
    });
    (0, _vue.onUnmounted)(() => {
      _ui.globalEvents.off($xeCascader, 'mousewheel');
      _ui.globalEvents.off($xeCascader, 'mousedown');
      _ui.globalEvents.off($xeCascader, 'blur');
      _ui.globalEvents.off($xeCascader, 'resize');
      _xeUtils.default.assign(reactData, createReactData());
      _xeUtils.default.assign(internalData, createInternalData());
    });
    (0, _vue.provide)('$xeCascader', $xeCascader);
    $xeCascader.renderVN = renderVN;
    return $xeCascader;
  },
  render() {
    return this.renderVN();
  }
});