'use strict';

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

var vue = require('vue');
require('../../../utils/index.cjs');
var contextTypes = require('./contextTypes.cjs');
var util = require('./util.cjs');
var treeUtil = require('./utils/treeUtil.cjs');
var NodeList = require('./NodeList.cjs');
var conductUtil = require('./utils/conductUtil.cjs');
var DropIndicator = require('./DropIndicator.cjs');
var props = require('./props.cjs');
var useMaxLevel = require('./useMaxLevel.cjs');
var initDefaultProps = require('../../../utils/vue/initDefaultProps.cjs');
var log = require('../../../utils/log.cjs');
var KeyCode = require('../../../utils/KeyCode.cjs');
var pickAttrs = require('../../../utils/lang/pickAttrs.cjs');
var _class = require('../../../utils/dom/class.cjs');

const MAX_RETRY_TIMES = 10;
var VcTree = /* @__PURE__ */ vue.defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "Tree",
  inheritAttrs: false,
  props: initDefaultProps.initDefaultProps(props.treeProps(), {
    prefixCls: "vc-tree",
    showLine: false,
    showIcon: true,
    selectable: true,
    multiple: false,
    checkable: false,
    disabled: false,
    checkStrictly: false,
    draggable: false,
    expandAction: false,
    defaultExpandParent: true,
    autoExpandParent: false,
    defaultExpandAll: false,
    defaultExpandedKeys: [],
    defaultCheckedKeys: [],
    defaultSelectedKeys: [],
    dropIndicatorRender: DropIndicator.default,
    allowDrop: () => true
  }),
  setup(props, {
    attrs,
    slots,
    expose
  }) {
    const destroyed = vue.shallowRef(false);
    let delayedDragEnterLogic = {};
    const indent = vue.shallowRef();
    const selectedKeys = vue.shallowRef([]);
    const checkedKeys = vue.shallowRef([]);
    const halfCheckedKeys = vue.shallowRef([]);
    const loadedKeys = vue.shallowRef([]);
    const loadingKeys = vue.shallowRef([]);
    const expandedKeys = vue.shallowRef([]);
    const loadingRetryTimes = {};
    const dragState = vue.reactive({
      draggingNodeKey: null,
      dragChildrenKeys: [],
      // dropTargetKey is the key of abstract-drop-node
      // the abstract-drop-node is the real drop node when drag and drop
      // not the DOM drag over node
      dropTargetKey: null,
      dropPosition: null,
      // the drop position of abstract-drop-node, inside 0, top -1, bottom 1
      dropContainerKey: null,
      // the container key of abstract-drop-node if dropPosition is -1 or 1
      dropLevelOffset: null,
      // the drop level offset of abstract-drag-over-node
      dropTargetPos: null,
      // the pos of abstract-drop-node
      dropAllowed: true,
      // if drop to abstract-drop-node is allowed
      // the abstract-drag-over-node
      // if mouse is on the bottom of top dom node or no the top of the bottom dom node
      // abstract-drag-over-node is the top node
      dragOverNodeKey: null
    });
    const treeData = vue.shallowRef([]);
    vue.watch([() => props.treeData, () => props.children], () => {
      treeData.value = props.treeData !== void 0 ? vue.toRaw(props.treeData).slice() : treeUtil.convertTreeToData(vue.toRaw(props.children));
    }, {
      immediate: true,
      deep: true
    });
    const keyEntities = vue.shallowRef({});
    const focused = vue.shallowRef(false);
    const activeKey = vue.shallowRef(null);
    const listChanging = vue.shallowRef(false);
    const fieldNames = vue.computed(() => treeUtil.fillFieldNames(props.fieldNames));
    const listRef = vue.shallowRef();
    let dragStartMousePosition = null;
    let dragNode = null;
    let currentMouseOverDroppableNodeKey = null;
    const treeNodeRequiredProps = vue.computed(() => {
      return {
        expandedKeysSet: expandedKeysSet.value,
        selectedKeysSet: selectedKeysSet.value,
        loadedKeysSet: loadedKeysSet.value,
        loadingKeysSet: loadingKeysSet.value,
        checkedKeysSet: checkedKeysSet.value,
        halfCheckedKeysSet: halfCheckedKeysSet.value,
        dragOverNodeKey: dragState.dragOverNodeKey,
        dropPosition: dragState.dropPosition,
        keyEntities: keyEntities.value
      };
    });
    const expandedKeysSet = vue.computed(() => {
      return new Set(expandedKeys.value);
    });
    const selectedKeysSet = vue.computed(() => {
      return new Set(selectedKeys.value);
    });
    const loadedKeysSet = vue.computed(() => {
      return new Set(loadedKeys.value);
    });
    const loadingKeysSet = vue.computed(() => {
      return new Set(loadingKeys.value);
    });
    const checkedKeysSet = vue.computed(() => {
      return new Set(checkedKeys.value);
    });
    const halfCheckedKeysSet = vue.computed(() => {
      return new Set(halfCheckedKeys.value);
    });
    vue.watchEffect(() => {
      if (treeData.value) {
        const entitiesMap = treeUtil.convertDataToEntities(treeData.value, {
          fieldNames: fieldNames.value
        });
        keyEntities.value = {
          [NodeList.MOTION_KEY]: NodeList.MotionEntity,
          ...entitiesMap.keyEntities
        };
      }
    });
    let init = false;
    vue.watch([() => props.expandedKeys, () => props.autoExpandParent, keyEntities], ([_newKeys, newAutoExpandParent], [_oldKeys, oldAutoExpandParent]) => {
      let keys = expandedKeys.value;
      if (props.expandedKeys !== void 0 || init && newAutoExpandParent !== oldAutoExpandParent) {
        keys = props.autoExpandParent || !init && props.defaultExpandParent ? util.conductExpandParent(props.expandedKeys, keyEntities.value) : props.expandedKeys;
      } else if (!init && props.defaultExpandAll) {
        const cloneKeyEntities = {
          ...keyEntities.value
        };
        delete cloneKeyEntities[NodeList.MOTION_KEY];
        keys = Object.keys(cloneKeyEntities).map((key) => cloneKeyEntities[key].key);
      } else if (!init && props.defaultExpandedKeys) {
        keys = props.autoExpandParent || props.defaultExpandParent ? util.conductExpandParent(props.defaultExpandedKeys, keyEntities.value) : props.defaultExpandedKeys;
      }
      if (keys)
        expandedKeys.value = keys;
      init = true;
    }, {
      immediate: true
    });
    const flattenNodes = vue.shallowRef([]);
    vue.watchEffect(() => {
      flattenNodes.value = treeUtil.flattenTreeData(treeData.value, expandedKeys.value, fieldNames.value);
    });
    vue.watchEffect(() => {
      if (props.selectable) {
        if (props.selectedKeys !== void 0)
          selectedKeys.value = util.calcSelectedKeys(props.selectedKeys, props);
        else if (!init && props.defaultSelectedKeys)
          selectedKeys.value = util.calcSelectedKeys(props.defaultSelectedKeys, props);
      }
    });
    const {
      maxLevel,
      levelEntities
    } = useMaxLevel.default(keyEntities);
    vue.watchEffect(() => {
      if (props.checkable) {
        let checkedKeyEntity;
        if (props.checkedKeys !== void 0) {
          checkedKeyEntity = util.parseCheckedKeys(props.checkedKeys) || {};
        } else if (!init && props.defaultCheckedKeys) {
          checkedKeyEntity = util.parseCheckedKeys(props.defaultCheckedKeys) || {};
        } else if (treeData.value) {
          checkedKeyEntity = util.parseCheckedKeys(props.checkedKeys) || {
            checkedKeys: checkedKeys.value,
            halfCheckedKeys: halfCheckedKeys.value
          };
        }
        if (checkedKeyEntity) {
          let {
            checkedKeys: newCheckedKeys = [],
            halfCheckedKeys: newHalfCheckedKeys = []
          } = checkedKeyEntity;
          if (!props.checkStrictly) {
            const conductKeys = conductUtil.conductCheck(newCheckedKeys, true, keyEntities.value, maxLevel.value, levelEntities.value);
            ({
              checkedKeys: newCheckedKeys,
              halfCheckedKeys: newHalfCheckedKeys
            } = conductKeys);
          }
          checkedKeys.value = newCheckedKeys;
          halfCheckedKeys.value = newHalfCheckedKeys;
        }
      }
    });
    vue.watchEffect(() => {
      if (props.loadedKeys)
        loadedKeys.value = props.loadedKeys;
    });
    const resetDragState = () => {
      Object.assign(dragState, {
        dragOverNodeKey: null,
        dropPosition: null,
        dropLevelOffset: null,
        dropTargetKey: null,
        dropContainerKey: null,
        dropTargetPos: null,
        dropAllowed: false
      });
    };
    const scrollTo = (scroll) => {
      listRef.value.scrollTo(scroll);
    };
    vue.watch(() => props.activeKey, () => {
      if (props.activeKey !== void 0)
        activeKey.value = props.activeKey;
    }, {
      immediate: true
    });
    vue.watch(activeKey, (val) => {
      vue.nextTick(() => {
        if (val !== null)
          scrollTo({
            key: val
          });
      });
    }, {
      immediate: true,
      flush: "post"
    });
    const setExpandedKeys = (keys) => {
      if (props.expandedKeys === void 0)
        expandedKeys.value = keys;
    };
    const cleanDragState = () => {
      if (dragState.draggingNodeKey !== null) {
        Object.assign(dragState, {
          draggingNodeKey: null,
          dropPosition: null,
          dropContainerKey: null,
          dropTargetKey: null,
          dropLevelOffset: null,
          dropAllowed: true,
          dragOverNodeKey: null
        });
      }
      dragStartMousePosition = null;
      currentMouseOverDroppableNodeKey = null;
    };
    const onNodeDragEnd = (event, node) => {
      const {
        onDragend
      } = props;
      dragState.dragOverNodeKey = null;
      cleanDragState();
      onDragend == null ? void 0 : onDragend({
        event,
        node: node.eventData
      });
      dragNode = null;
    };
    const onWindowDragEnd = (event) => {
      onNodeDragEnd(event, null, true);
      window.removeEventListener("dragend", onWindowDragEnd);
    };
    const onNodeDragStart = (event, node) => {
      const {
        onDragstart
      } = props;
      const {
        eventKey,
        eventData
      } = node;
      dragNode = node;
      dragStartMousePosition = {
        x: event.clientX,
        y: event.clientY
      };
      const newExpandedKeys = util.arrDel(expandedKeys.value, eventKey);
      dragState.draggingNodeKey = eventKey;
      dragState.dragChildrenKeys = util.getDragChildrenKeys(eventKey, keyEntities.value);
      indent.value = listRef.value.getIndentWidth();
      setExpandedKeys(newExpandedKeys);
      window.addEventListener("dragend", onWindowDragEnd);
      if (onDragstart)
        onDragstart({
          event,
          node: eventData
        });
    };
    const onNodeDragEnter = (event, node) => {
      const {
        onDragenter,
        onExpand,
        allowDrop,
        direction
      } = props;
      const {
        pos,
        eventKey
      } = node;
      if (currentMouseOverDroppableNodeKey !== eventKey)
        currentMouseOverDroppableNodeKey = eventKey;
      if (!dragNode) {
        resetDragState();
        return;
      }
      const {
        dropPosition,
        dropLevelOffset,
        dropTargetKey,
        dropContainerKey,
        dropTargetPos,
        dropAllowed,
        dragOverNodeKey
      } = util.calcDropPosition(event, dragNode, node, indent.value, dragStartMousePosition, allowDrop, flattenNodes.value, keyEntities.value, expandedKeysSet.value, direction);
      if (
        // don't allow drop inside its children
        dragState.dragChildrenKeys.includes(dropTargetKey) || !dropAllowed
      ) {
        resetDragState();
        return;
      }
      if (!delayedDragEnterLogic)
        delayedDragEnterLogic = {};
      Object.keys(delayedDragEnterLogic).forEach((key) => {
        clearTimeout(delayedDragEnterLogic[key]);
      });
      if (dragNode.eventKey !== node.eventKey) {
        delayedDragEnterLogic[pos] = window.setTimeout(() => {
          if (dragState.draggingNodeKey === null)
            return;
          let newExpandedKeys = expandedKeys.value.slice();
          const entity = keyEntities.value[node.eventKey];
          if (entity && (entity.children || []).length)
            newExpandedKeys = util.arrAdd(expandedKeys.value, node.eventKey);
          setExpandedKeys(newExpandedKeys);
          if (onExpand) {
            onExpand(newExpandedKeys, {
              node: node.eventData,
              expanded: true,
              nativeEvent: event
            });
          }
        }, 800);
      }
      if (dragNode.eventKey === dropTargetKey && dropLevelOffset === 0) {
        resetDragState();
        return;
      }
      Object.assign(dragState, {
        dragOverNodeKey,
        dropPosition,
        dropLevelOffset,
        dropTargetKey,
        dropContainerKey,
        dropTargetPos,
        dropAllowed
      });
      if (onDragenter) {
        onDragenter({
          event,
          node: node.eventData,
          expandedKeys: expandedKeys.value
        });
      }
    };
    const onNodeDragOver = (event, node) => {
      const {
        onDragover,
        allowDrop,
        direction
      } = props;
      if (!dragNode)
        return;
      const {
        dropPosition,
        dropLevelOffset,
        dropTargetKey,
        dropContainerKey,
        dropAllowed,
        dropTargetPos,
        dragOverNodeKey
      } = util.calcDropPosition(event, dragNode, node, indent.value, dragStartMousePosition, allowDrop, flattenNodes.value, keyEntities.value, expandedKeysSet.value, direction);
      if (dragState.dragChildrenKeys.includes(dropTargetKey) || !dropAllowed) {
        return;
      }
      if (dragNode.eventKey === dropTargetKey && dropLevelOffset === 0) {
        if (!(dragState.dropPosition === null && dragState.dropLevelOffset === null && dragState.dropTargetKey === null && dragState.dropContainerKey === null && dragState.dropTargetPos === null && dragState.dropAllowed === false && dragState.dragOverNodeKey === null))
          resetDragState();
      } else if (!(dropPosition === dragState.dropPosition && dropLevelOffset === dragState.dropLevelOffset && dropTargetKey === dragState.dropTargetKey && dropContainerKey === dragState.dropContainerKey && dropTargetPos === dragState.dropTargetPos && dropAllowed === dragState.dropAllowed && dragOverNodeKey === dragState.dragOverNodeKey)) {
        Object.assign(dragState, {
          dropPosition,
          dropLevelOffset,
          dropTargetKey,
          dropContainerKey,
          dropTargetPos,
          dropAllowed,
          dragOverNodeKey
        });
      }
      if (onDragover)
        onDragover({
          event,
          node: node.eventData
        });
    };
    const onNodeDragLeave = (event, node) => {
      if (currentMouseOverDroppableNodeKey === node.eventKey && !event.currentTarget.contains(event.relatedTarget)) {
        resetDragState();
        currentMouseOverDroppableNodeKey = null;
      }
      const {
        onDragleave
      } = props;
      if (onDragleave)
        onDragleave({
          event,
          node: node.eventData
        });
    };
    const onNodeDrop = (event, _node, outsideTree = false) => {
      var _a;
      const {
        dragChildrenKeys,
        dropPosition,
        dropTargetKey,
        dropTargetPos,
        dropAllowed
      } = dragState;
      if (!dropAllowed)
        return;
      const {
        onDrop
      } = props;
      dragState.dragOverNodeKey = null;
      cleanDragState();
      if (dropTargetKey === null)
        return;
      const abstractDropNodeProps = {
        ...treeUtil.getTreeNodeProps(dropTargetKey, vue.toRaw(treeNodeRequiredProps.value)),
        active: ((_a = activeItem.value) == null ? void 0 : _a.key) === dropTargetKey,
        data: keyEntities.value[dropTargetKey].node
      };
      const dropToChild = dragChildrenKeys.includes(dropTargetKey);
      log.warning(!dropToChild, "Can not drop to dragNode's children node. Maybe this is a bug of ant-design-vue. Please report an issue.");
      const posArr = util.posToArr(dropTargetPos);
      const dropResult = {
        event,
        node: treeUtil.convertNodePropsToEventData(abstractDropNodeProps),
        dragNode: dragNode ? dragNode.eventData : null,
        dragNodesKeys: [dragNode.eventKey].concat(dragChildrenKeys),
        dropToGap: dropPosition !== 0,
        dropPosition: dropPosition + Number(posArr[posArr.length - 1])
      };
      if (!outsideTree)
        onDrop == null ? void 0 : onDrop(dropResult);
      dragNode = null;
    };
    const triggerExpandActionExpand = (e, treeNode) => {
      const {
        expanded,
        key
      } = treeNode;
      const node = flattenNodes.value.filter((nodeItem) => nodeItem.key === key)[0];
      const eventNode = treeUtil.convertNodePropsToEventData({
        ...treeUtil.getTreeNodeProps(key, treeNodeRequiredProps.value),
        data: node.data
      });
      setExpandedKeys(expanded ? util.arrDel(expandedKeys.value, key) : util.arrAdd(expandedKeys.value, key));
      onNodeExpand(e, eventNode);
    };
    const onNodeClick = (e, treeNode) => {
      const {
        onClick,
        expandAction
      } = props;
      if (expandAction === "click")
        triggerExpandActionExpand(e, treeNode);
      if (onClick)
        onClick(e, treeNode);
    };
    const onNodeDoubleClick = (e, treeNode) => {
      const {
        onDblclick,
        expandAction
      } = props;
      if (expandAction === "doubleclick" || expandAction === "dblclick")
        triggerExpandActionExpand(e, treeNode);
      if (onDblclick)
        onDblclick(e, treeNode);
    };
    const onNodeSelect = (e, treeNode) => {
      let newSelectedKeys = selectedKeys.value;
      const {
        onSelect,
        multiple
      } = props;
      const {
        selected
      } = treeNode;
      const key = treeNode[fieldNames.value.key];
      const targetSelected = !selected;
      if (!targetSelected)
        newSelectedKeys = util.arrDel(newSelectedKeys, key);
      else if (!multiple)
        newSelectedKeys = [key];
      else
        newSelectedKeys = util.arrAdd(newSelectedKeys, key);
      const keyEntitiesValue = keyEntities.value;
      const selectedNodes = newSelectedKeys.map((selectedKey) => {
        const entity = keyEntitiesValue[selectedKey];
        if (!entity)
          return null;
        return entity.node;
      }).filter((node) => node);
      if (props.selectedKeys === void 0)
        selectedKeys.value = newSelectedKeys;
      if (onSelect) {
        onSelect(newSelectedKeys, {
          event: "select",
          selected: targetSelected,
          node: treeNode,
          selectedNodes,
          nativeEvent: e
        });
      }
    };
    const onNodeCheck = (e, treeNode, checked) => {
      const {
        checkStrictly,
        onCheck
      } = props;
      const key = treeNode[fieldNames.value.key];
      let checkedObj;
      const eventObj = {
        event: "check",
        node: treeNode,
        checked,
        nativeEvent: e
      };
      const keyEntitiesValue = keyEntities.value;
      if (checkStrictly) {
        const newCheckedKeys = checked ? util.arrAdd(checkedKeys.value, key) : util.arrDel(checkedKeys.value, key);
        const newHalfCheckedKeys = util.arrDel(halfCheckedKeys.value, key);
        checkedObj = {
          checked: newCheckedKeys,
          halfChecked: newHalfCheckedKeys
        };
        eventObj.checkedNodes = newCheckedKeys.map((checkedKey) => keyEntitiesValue[checkedKey]).filter((entity) => entity).map((entity) => entity.node);
        if (props.checkedKeys === void 0)
          checkedKeys.value = newCheckedKeys;
      } else {
        let {
          checkedKeys: newCheckedKeys,
          halfCheckedKeys: newHalfCheckedKeys
        } = conductUtil.conductCheck([...checkedKeys.value, key], true, keyEntitiesValue, maxLevel.value, levelEntities.value);
        if (!checked) {
          const keySet = new Set(newCheckedKeys);
          keySet.delete(key);
          ({
            checkedKeys: newCheckedKeys,
            halfCheckedKeys: newHalfCheckedKeys
          } = conductUtil.conductCheck(Array.from(keySet), {
            checked: false,
            halfCheckedKeys: newHalfCheckedKeys
          }, keyEntitiesValue, maxLevel.value, levelEntities.value));
        }
        checkedObj = newCheckedKeys;
        eventObj.checkedNodes = [];
        eventObj.checkedNodesPositions = [];
        eventObj.halfCheckedKeys = newHalfCheckedKeys;
        newCheckedKeys.forEach((checkedKey) => {
          const entity = keyEntitiesValue[checkedKey];
          if (!entity)
            return;
          const {
            node,
            pos
          } = entity;
          eventObj.checkedNodes.push(node);
          eventObj.checkedNodesPositions.push({
            node,
            pos
          });
        });
        if (props.checkedKeys === void 0) {
          checkedKeys.value = newCheckedKeys;
          halfCheckedKeys.value = newHalfCheckedKeys;
        }
      }
      if (onCheck)
        onCheck(checkedObj, eventObj);
    };
    const onNodeLoad = (treeNode) => {
      const key = treeNode[fieldNames.value.key];
      const loadPromise = new Promise((resolve, reject) => {
        const {
          loadData,
          onLoad
        } = props;
        if (!loadData || loadedKeysSet.value.has(key) || loadingKeysSet.value.has(key))
          return null;
        const promise = loadData(treeNode);
        promise.then(() => {
          const newLoadedKeys = util.arrAdd(loadedKeys.value, key);
          const newLoadingKeys = util.arrDel(loadingKeys.value, key);
          if (onLoad) {
            onLoad(newLoadedKeys, {
              event: "load",
              node: treeNode
            });
          }
          if (props.loadedKeys === void 0)
            loadedKeys.value = newLoadedKeys;
          loadingKeys.value = newLoadingKeys;
          resolve();
        }).catch((e) => {
          const newLoadingKeys = util.arrDel(loadingKeys.value, key);
          loadingKeys.value = newLoadingKeys;
          loadingRetryTimes[key] = (loadingRetryTimes[key] || 0) + 1;
          if (loadingRetryTimes[key] >= MAX_RETRY_TIMES) {
            log.warning(false, "Retry for `loadData` many times but still failed. No more retry.");
            const newLoadedKeys = util.arrAdd(loadedKeys.value, key);
            if (props.loadedKeys === void 0)
              loadedKeys.value = newLoadedKeys;
            resolve();
          }
          reject(e);
        });
        loadingKeys.value = util.arrAdd(loadingKeys.value, key);
      });
      loadPromise.catch(() => {
      });
      return loadPromise;
    };
    const onNodeMouseEnter = (event, node) => {
      const {
        onMouseenter
      } = props;
      if (onMouseenter)
        onMouseenter({
          event,
          node
        });
    };
    const onNodeMouseLeave = (event, node) => {
      const {
        onMouseleave
      } = props;
      if (onMouseleave)
        onMouseleave({
          event,
          node
        });
    };
    const onNodeContextMenu = (event, node) => {
      const {
        onRightClick
      } = props;
      if (onRightClick) {
        event.preventDefault();
        onRightClick({
          event,
          node
        });
      }
    };
    const onFocus = (e) => {
      const {
        onFocus: onFocus2
      } = props;
      focused.value = true;
      if (onFocus2)
        onFocus2(e);
    };
    const onBlur = (e) => {
      const {
        onBlur: onBlur2
      } = props;
      focused.value = false;
      onActiveChange(null);
      if (onBlur2)
        onBlur2(e);
    };
    const onNodeExpand = (e, treeNode) => {
      let newExpandedKeys = expandedKeys.value;
      const {
        onExpand,
        loadData
      } = props;
      const {
        expanded
      } = treeNode;
      const key = treeNode[fieldNames.value.key];
      if (listChanging.value)
        return;
      const index = newExpandedKeys.indexOf(key);
      const targetExpanded = !expanded;
      log.warning(expanded && index !== -1 || !expanded && index === -1, "Expand state not sync with index check");
      if (targetExpanded)
        newExpandedKeys = util.arrAdd(newExpandedKeys, key);
      else
        newExpandedKeys = util.arrDel(newExpandedKeys, key);
      setExpandedKeys(newExpandedKeys);
      if (onExpand) {
        onExpand(newExpandedKeys, {
          node: treeNode,
          expanded: targetExpanded,
          nativeEvent: e
        });
      }
      if (targetExpanded && loadData) {
        const loadPromise = onNodeLoad(treeNode);
        if (loadPromise) {
          loadPromise.then(() => {
          }).catch((e2) => {
            const expandedKeysToRestore = util.arrDel(expandedKeys.value, key);
            setExpandedKeys(expandedKeysToRestore);
            Promise.reject(e2);
          });
        }
      }
    };
    const onListChangeStart = () => {
      listChanging.value = true;
    };
    const onListChangeEnd = () => {
      setTimeout(() => {
        listChanging.value = false;
      });
    };
    const onActiveChange = (newActiveKey) => {
      const {
        onActiveChange: onActiveChange2
      } = props;
      if (activeKey.value === newActiveKey)
        return;
      if (props.activeKey !== void 0)
        activeKey.value = newActiveKey;
      if (newActiveKey !== null)
        scrollTo({
          key: newActiveKey
        });
      if (onActiveChange2)
        onActiveChange2(newActiveKey);
    };
    const activeItem = vue.computed(() => {
      if (activeKey.value === null)
        return null;
      return flattenNodes.value.find(({
        key
      }) => key === activeKey.value) || null;
    });
    const offsetActiveKey = (offset) => {
      let index = flattenNodes.value.findIndex(({
        key
      }) => key === activeKey.value);
      if (index === -1 && offset < 0)
        index = flattenNodes.value.length;
      index = (index + offset + flattenNodes.value.length) % flattenNodes.value.length;
      const item = flattenNodes.value[index];
      if (item) {
        const {
          key
        } = item;
        onActiveChange(key);
      } else {
        onActiveChange(null);
      }
    };
    const activeItemEventNode = vue.computed(() => {
      return treeUtil.convertNodePropsToEventData({
        ...treeUtil.getTreeNodeProps(activeKey.value, treeNodeRequiredProps.value),
        data: activeItem.value.data,
        active: true
      });
    });
    const onKeydown = (event) => {
      const {
        onKeydown: onKeydown2,
        checkable,
        selectable
      } = props;
      switch (event.which) {
        case KeyCode.KeyCode.UP: {
          offsetActiveKey(-1);
          event.preventDefault();
          break;
        }
        case KeyCode.KeyCode.DOWN: {
          offsetActiveKey(1);
          event.preventDefault();
          break;
        }
      }
      const item = activeItem.value;
      if (item && item.data) {
        const expandable = item.data.isLeaf === false || !!(item.data.children || []).length;
        const eventNode = activeItemEventNode.value;
        switch (event.which) {
          case KeyCode.KeyCode.LEFT: {
            if (expandable && expandedKeysSet.value.has(activeKey.value))
              onNodeExpand({}, eventNode);
            else if (item.parent)
              onActiveChange(item.parent.key);
            event.preventDefault();
            break;
          }
          case KeyCode.KeyCode.RIGHT: {
            if (expandable && !expandedKeysSet.value.has(activeKey.value))
              onNodeExpand({}, eventNode);
            else if (item.children && item.children.length)
              onActiveChange(item.children[0].key);
            event.preventDefault();
            break;
          }
          case KeyCode.KeyCode.ENTER:
          case KeyCode.KeyCode.SPACE: {
            if (checkable && !eventNode.disabled && eventNode.checkable !== false && !eventNode.disableCheckbox)
              onNodeCheck({}, eventNode, !checkedKeysSet.value.has(activeKey.value));
            else if (!checkable && selectable && !eventNode.disabled && eventNode.selectable !== false)
              onNodeSelect({}, eventNode);
            break;
          }
        }
      }
      if (onKeydown2)
        onKeydown2(event);
    };
    expose({
      onNodeExpand,
      scrollTo,
      onKeydown,
      selectedKeys: vue.computed(() => selectedKeys.value),
      checkedKeys: vue.computed(() => checkedKeys.value),
      halfCheckedKeys: vue.computed(() => halfCheckedKeys.value),
      loadedKeys: vue.computed(() => loadedKeys.value),
      loadingKeys: vue.computed(() => loadingKeys.value),
      expandedKeys: vue.computed(() => expandedKeys.value)
    });
    vue.onUnmounted(() => {
      window.removeEventListener("dragend", onWindowDragEnd);
      destroyed.value = true;
    });
    contextTypes.useProvideKeysState({
      expandedKeys,
      selectedKeys,
      loadedKeys,
      loadingKeys,
      checkedKeys,
      halfCheckedKeys,
      expandedKeysSet,
      selectedKeysSet,
      loadedKeysSet,
      loadingKeysSet,
      checkedKeysSet,
      halfCheckedKeysSet,
      flattenNodes
    });
    return () => {
      const {
        // focused,
        // flattenNodes,
        // keyEntities,
        draggingNodeKey,
        // activeKey,
        dropLevelOffset,
        dropContainerKey,
        dropTargetKey,
        dropPosition,
        dragOverNodeKey
        // indent,
      } = dragState;
      const {
        prefixCls,
        showLine,
        focusable,
        tabindex = 0,
        selectable,
        showIcon,
        icon = slots.icon,
        switcherIcon,
        draggable,
        checkable,
        checkStrictly,
        disabled,
        motion,
        loadData,
        filterTreeNode,
        height,
        itemHeight,
        virtual,
        dropIndicatorRender,
        onContextmenu,
        onScroll,
        direction,
        rootClassName,
        rootStyle
      } = props;
      const {
        class: className,
        style
      } = attrs;
      const domProps = pickAttrs.pickAttrs({
        ...props,
        ...attrs
      }, {
        aria: true,
        data: true
      });
      let draggableConfig;
      if (draggable) {
        if (typeof draggable === "object") {
          draggableConfig = draggable;
        } else if (typeof draggable === "function") {
          draggableConfig = {
            nodeDraggable: draggable
          };
        } else {
          draggableConfig = {};
        }
      } else {
        draggableConfig = false;
      }
      return vue.createVNode(contextTypes.TreeContext, {
        "value": {
          prefixCls,
          selectable,
          showIcon,
          icon,
          switcherIcon,
          draggable: draggableConfig,
          draggingNodeKey,
          checkable,
          customCheckable: slots.checkable,
          checkStrictly,
          disabled,
          keyEntities: keyEntities.value,
          dropLevelOffset,
          dropContainerKey,
          dropTargetKey,
          dropPosition,
          dragOverNodeKey,
          dragging: draggingNodeKey !== null,
          indent: indent.value,
          direction,
          dropIndicatorRender,
          loadData,
          filterTreeNode,
          onNodeClick,
          onNodeDoubleClick,
          onNodeExpand,
          onNodeSelect,
          onNodeCheck,
          onNodeLoad,
          onNodeMouseEnter,
          onNodeMouseLeave,
          onNodeContextMenu,
          onNodeDragStart,
          onNodeDragEnter,
          onNodeDragOver,
          onNodeDragLeave,
          onNodeDragEnd,
          onNodeDrop,
          slots
        }
      }, {
        default: () => [vue.createVNode("div", {
          "role": "tree",
          "class": _class.classNames(prefixCls, className, rootClassName, {
            [`${prefixCls}-show-line`]: showLine,
            [`${prefixCls}-focused`]: focused.value,
            [`${prefixCls}-active-focused`]: activeKey.value !== null
          }),
          "style": rootStyle
        }, [vue.createVNode(NodeList.default, {
          "ref": listRef,
          "prefixCls": prefixCls,
          "style": style,
          "disabled": disabled,
          "selectable": selectable,
          "checkable": !!checkable,
          "motion": motion,
          "height": height,
          "itemHeight": itemHeight,
          "virtual": virtual,
          "focusable": focusable,
          "focused": focused.value,
          "tabindex": tabindex,
          "activeItem": activeItem.value,
          "onFocus": onFocus,
          "onBlur": onBlur,
          "onKeydown": onKeydown,
          "onActiveChange": onActiveChange,
          "onListChangeStart": onListChangeStart,
          "onListChangeEnd": onListChangeEnd,
          "onContextmenu": onContextmenu,
          "onScroll": onScroll,
          ...domProps
        }, null)])]
      });
    };
  }
});

exports.default = VcTree;
//# sourceMappingURL=Tree.cjs.map
