"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cascaderProps = void 0;
const vue_1 = require("vue");
const treemate_1 = require("treemate");
const vueuc_1 = require("vueuc");
const seemly_1 = require("seemly");
const vooks_1 = require("vooks");
const _internal_1 = require("../../_internal");
const _mixins_1 = require("../../_mixins");
const _utils_1 = require("../../_utils");
const styles_1 = require("../styles");
const utils_1 = require("./utils");
const CascaderMenu_1 = __importDefault(require("./CascaderMenu"));
const CascaderSelectMenu_1 = __importDefault(require("./CascaderSelectMenu"));
const interface_1 = require("./interface");
const index_cssr_1 = __importDefault(require("./styles/index.cssr"));
exports.cascaderProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { allowCheckingNotLoaded: Boolean, to: _utils_1.useAdjustedTo.propTo, bordered: {
        type: Boolean,
        default: undefined
    }, options: {
        type: Array,
        default: () => []
    }, value: [String, Number, Array], defaultValue: {
        type: [String, Number, Array],
        default: null
    }, placeholder: String, multiple: Boolean, size: String, filterable: Boolean, disabled: {
        type: Boolean,
        default: undefined
    }, disabledField: {
        type: String,
        default: 'disabled'
    }, expandTrigger: {
        type: String,
        default: 'click'
    }, clearable: Boolean, clearFilterAfterSelect: {
        type: Boolean,
        default: true
    }, remote: Boolean, onLoad: Function, separator: {
        type: String,
        default: ' / '
    }, filter: Function, placement: {
        type: String,
        default: 'bottom-start'
    }, cascade: {
        type: Boolean,
        default: true
    }, leafOnly: Boolean, showPath: {
        type: Boolean,
        default: true
    }, show: {
        type: Boolean,
        default: undefined
    }, maxTagCount: [String, Number], ellipsisTagPopoverProps: Object, menuProps: Object, filterMenuProps: Object, virtualScroll: {
        type: Boolean,
        default: true
    }, checkStrategy: {
        type: String,
        default: 'all'
    }, valueField: {
        type: String,
        default: 'value'
    }, labelField: {
        type: String,
        default: 'label'
    }, childrenField: {
        type: String,
        default: 'children'
    }, renderLabel: Function, status: String, 'onUpdate:value': [Function, Array], onUpdateValue: [Function, Array], 'onUpdate:show': [Function, Array], onUpdateShow: [Function, Array], onBlur: Function, onFocus: Function, getColumnStyle: Function, renderPrefix: Function, renderSuffix: Function, 
    // deprecated
    onChange: [Function, Array] });
exports.default = (0, vue_1.defineComponent)({
    name: 'Cascader',
    props: exports.cascaderProps,
    setup(props, { slots }) {
        if (process.env.NODE_ENV !== 'production') {
            (0, vue_1.watchEffect)(() => {
                if (props.leafOnly) {
                    (0, _utils_1.warnOnce)('cascader', '`leaf-only` is deprecated, please use `check-strategy="child"` instead');
                }
                if (props.onChange !== undefined) {
                    (0, _utils_1.warnOnce)('cascader', '`on-change` is deprecated, please use `on-update:value` instead.');
                }
            });
        }
        const { mergedBorderedRef, mergedClsPrefixRef, namespaceRef, inlineThemeDisabled } = (0, _mixins_1.useConfig)(props);
        const themeRef = (0, _mixins_1.useTheme)('Cascader', '-cascader', index_cssr_1.default, styles_1.cascaderLight, props, mergedClsPrefixRef);
        const { localeRef } = (0, _mixins_1.useLocale)('Cascader');
        const uncontrolledValueRef = (0, vue_1.ref)(props.defaultValue);
        const controlledValueRef = (0, vue_1.computed)(() => props.value);
        const mergedValueRef = (0, vooks_1.useMergedState)(controlledValueRef, uncontrolledValueRef);
        const mergedCheckStrategyRef = (0, vue_1.computed)(() => {
            return props.leafOnly ? 'child' : props.checkStrategy;
        });
        const patternRef = (0, vue_1.ref)('');
        const formItem = (0, _mixins_1.useFormItem)(props);
        const { mergedSizeRef, mergedDisabledRef, mergedStatusRef } = formItem;
        const cascaderMenuInstRef = (0, vue_1.ref)(null);
        const selectMenuInstRef = (0, vue_1.ref)(null);
        const triggerInstRef = (0, vue_1.ref)(null);
        const keyboardKeyRef = (0, vue_1.ref)(null);
        const hoverKeyRef = (0, vue_1.ref)(null);
        const loadingKeySetRef = (0, vue_1.ref)(new Set());
        const selectMenuFollowerRef = (0, vue_1.ref)(null);
        const cascaderMenuFollowerRef = (0, vue_1.ref)(null);
        const adjustedToRef = (0, _utils_1.useAdjustedTo)(props);
        const focusedRef = (0, vue_1.ref)(false);
        const addLoadingKey = (key) => {
            loadingKeySetRef.value.add(key);
        };
        const deleteLoadingKey = (key) => {
            loadingKeySetRef.value.delete(key);
        };
        const treeMateRef = (0, vue_1.computed)(() => {
            const { valueField, childrenField, disabledField } = props;
            return (0, treemate_1.createTreeMate)(props.options, {
                getDisabled(node) {
                    return node[disabledField];
                },
                getKey(node) {
                    return node[valueField];
                },
                getChildren(node) {
                    return node[childrenField];
                }
            });
        });
        const mergedKeysRef = (0, vue_1.computed)(() => {
            const { cascade, multiple } = props;
            if (multiple && Array.isArray(mergedValueRef.value)) {
                return treeMateRef.value.getCheckedKeys(mergedValueRef.value, {
                    cascade,
                    allowNotLoaded: props.allowCheckingNotLoaded
                });
            }
            else {
                return {
                    checkedKeys: [],
                    indeterminateKeys: []
                };
            }
        });
        const checkedKeysRef = (0, vue_1.computed)(() => mergedKeysRef.value.checkedKeys);
        const indeterminateKeysRef = (0, vue_1.computed)(() => mergedKeysRef.value.indeterminateKeys);
        const menuModelRef = (0, vue_1.computed)(() => {
            const { treeNodePath, treeNode } = treeMateRef.value.getPath(hoverKeyRef.value);
            let ret;
            if (treeNode === null) {
                ret = [treeMateRef.value.treeNodes];
            }
            else {
                ret = treeNodePath.map(treeNode => treeNode.siblings);
                if (!treeNode.isLeaf
                    && !loadingKeySetRef.value.has(treeNode.key)
                    && treeNode.children) {
                    ret.push(treeNode.children);
                }
            }
            return ret;
        });
        const hoverKeyPathRef = (0, vue_1.computed)(() => {
            const { keyPath } = treeMateRef.value.getPath(hoverKeyRef.value);
            return keyPath;
        });
        const optionHeightRef = (0, vue_1.computed)(() => {
            return themeRef.value.self.optionHeight;
        });
        if ((0, vue_1.isReactive)(props.options)) {
            (0, vue_1.watch)(props.options, (value, oldValue) => {
                if (!(value === oldValue)) {
                    hoverKeyRef.value = null;
                    keyboardKeyRef.value = null;
                }
            });
        }
        const uncontrolledShowRef = (0, vue_1.ref)(false);
        function doUpdateShow(value) {
            const { onUpdateShow, 'onUpdate:show': _onUpdateShow } = props;
            if (onUpdateShow) {
                (0, _utils_1.call)(onUpdateShow, value);
            }
            if (_onUpdateShow) {
                (0, _utils_1.call)(_onUpdateShow, value);
            }
            uncontrolledShowRef.value = value;
        }
        function doUpdateValue(value, option, optionPath) {
            const { onUpdateValue, 'onUpdate:value': _onUpdateValue, onChange } = props;
            const { nTriggerFormInput, nTriggerFormChange } = formItem;
            if (onUpdateValue) {
                (0, _utils_1.call)(onUpdateValue, value, option, optionPath);
            }
            if (_onUpdateValue) {
                (0, _utils_1.call)(_onUpdateValue, value, option, optionPath);
            }
            if (onChange) {
                (0, _utils_1.call)(onChange, value, option, optionPath);
            }
            uncontrolledValueRef.value = value;
            nTriggerFormInput();
            nTriggerFormChange();
        }
        function updateKeyboardKey(key) {
            keyboardKeyRef.value = key;
        }
        function updateHoverKey(key) {
            hoverKeyRef.value = key;
        }
        function getOptionsByKeys(keys) {
            const { value: { getNode } } = treeMateRef;
            return keys.map(keys => { var _a; return ((_a = getNode(keys)) === null || _a === void 0 ? void 0 : _a.rawNode) || null; });
        }
        function doCheck(key) {
            var _a;
            const { cascade, multiple, filterable } = props;
            const { value: { check, getNode, getPath } } = treeMateRef;
            if (multiple) {
                try {
                    const { checkedKeys } = check(key, mergedKeysRef.value.checkedKeys, {
                        cascade,
                        checkStrategy: mergedCheckStrategyRef.value,
                        allowNotLoaded: props.allowCheckingNotLoaded
                    });
                    doUpdateValue(checkedKeys, getOptionsByKeys(checkedKeys), checkedKeys.map(checkedKey => { var _a; return (0, utils_1.getRawNodePath)((_a = getPath(checkedKey)) === null || _a === void 0 ? void 0 : _a.treeNodePath); }));
                    if (filterable)
                        focusSelectionInput();
                    keyboardKeyRef.value = key;
                    hoverKeyRef.value = key;
                }
                catch (err) {
                    if (err instanceof treemate_1.SubtreeNotLoadedError) {
                        if (cascaderMenuInstRef.value) {
                            const tmNode = getNode(key);
                            if (tmNode !== null) {
                                cascaderMenuInstRef.value.showErrorMessage(tmNode.rawNode[props.labelField]);
                            }
                        }
                    }
                    else {
                        throw err;
                    }
                }
            }
            else {
                if (mergedCheckStrategyRef.value === 'child') {
                    const tmNode = getNode(key);
                    if (tmNode === null || tmNode === void 0 ? void 0 : tmNode.isLeaf) {
                        doUpdateValue(key, tmNode.rawNode, (0, utils_1.getRawNodePath)(getPath(key).treeNodePath));
                    }
                    else {
                        return false;
                    }
                }
                else {
                    const tmNode = getNode(key);
                    doUpdateValue(key, (tmNode === null || tmNode === void 0 ? void 0 : tmNode.rawNode) || null, (0, utils_1.getRawNodePath)((_a = getPath(key)) === null || _a === void 0 ? void 0 : _a.treeNodePath));
                }
            }
            return true;
        }
        function doUncheck(key) {
            const { cascade, multiple } = props;
            if (multiple) {
                const { value: { uncheck, getNode, getPath } } = treeMateRef;
                const { checkedKeys } = uncheck(key, mergedKeysRef.value.checkedKeys, {
                    cascade,
                    checkStrategy: mergedCheckStrategyRef.value,
                    allowNotLoaded: props.allowCheckingNotLoaded
                });
                doUpdateValue(checkedKeys, checkedKeys.map(checkedKey => { var _a; return ((_a = getNode(checkedKey)) === null || _a === void 0 ? void 0 : _a.rawNode) || null; }), checkedKeys.map(checkedKey => { var _a; return (0, utils_1.getRawNodePath)((_a = getPath(checkedKey)) === null || _a === void 0 ? void 0 : _a.treeNodePath); }));
                keyboardKeyRef.value = key;
                hoverKeyRef.value = key;
            }
        }
        const selectedOptionsRef = (0, vue_1.computed)(() => {
            if (props.multiple) {
                const { showPath, separator, labelField, cascade } = props;
                const { getCheckedKeys, getNode } = treeMateRef.value;
                const value = getCheckedKeys(checkedKeysRef.value, {
                    cascade,
                    checkStrategy: mergedCheckStrategyRef.value,
                    allowNotLoaded: props.allowCheckingNotLoaded
                }).checkedKeys;
                return value.map((key) => {
                    const node = getNode(key);
                    if (node === null) {
                        return {
                            label: String(key),
                            value: key
                        };
                    }
                    else {
                        return {
                            label: showPath
                                ? (0, utils_1.getPathLabel)(node, separator, labelField)
                                : node.rawNode[labelField],
                            value: node.key
                        };
                    }
                });
            }
            else {
                return [];
            }
        });
        const selectedOptionRef = (0, vue_1.computed)(() => {
            const { multiple, showPath, separator, labelField } = props;
            const { value } = mergedValueRef;
            if (!multiple && !Array.isArray(value)) {
                const { getNode } = treeMateRef.value;
                if (value === null) {
                    return null;
                }
                const node = getNode(value);
                if (node === null) {
                    return {
                        label: String(value),
                        value
                    };
                }
                else {
                    return {
                        label: showPath
                            ? (0, utils_1.getPathLabel)(node, separator, labelField)
                            : node.rawNode[labelField],
                        value: node.key
                    };
                }
            }
            else {
                return null;
            }
        });
        const controlledShowRef = (0, vue_1.toRef)(props, 'show');
        const mergedShowRef = (0, vooks_1.useMergedState)(controlledShowRef, uncontrolledShowRef);
        const localizedPlaceholderRef = (0, vue_1.computed)(() => {
            const { placeholder } = props;
            if (placeholder !== undefined)
                return placeholder;
            return localeRef.value.placeholder;
        });
        // select option related
        const showSelectMenuRef = (0, vue_1.computed)(() => {
            return !!(props.filterable && patternRef.value);
        });
        // init hover key
        (0, vue_1.watch)(mergedShowRef, (show) => {
            if (!show)
                return;
            if (props.multiple)
                return;
            const { value } = mergedValueRef;
            if (!Array.isArray(value) && value !== null) {
                keyboardKeyRef.value = value;
                hoverKeyRef.value = value;
                void (0, vue_1.nextTick)(() => {
                    var _a;
                    if (!mergedShowRef.value)
                        return;
                    const { value: hoverKey } = hoverKeyRef;
                    if (mergedValueRef.value !== null) {
                        const node = treeMateRef.value.getNode(hoverKey);
                        if (node) {
                            (_a = cascaderMenuInstRef.value) === null || _a === void 0 ? void 0 : _a.scroll(node.level, node.index, (0, seemly_1.depx)(optionHeightRef.value));
                        }
                    }
                });
            }
            else {
                keyboardKeyRef.value = null;
                hoverKeyRef.value = null;
            }
        }, {
            immediate: true
        });
        // --- methods
        function doBlur(e) {
            const { onBlur } = props;
            const { nTriggerFormBlur } = formItem;
            if (onBlur)
                (0, _utils_1.call)(onBlur, e);
            nTriggerFormBlur();
        }
        function doFocus(e) {
            const { onFocus } = props;
            const { nTriggerFormFocus } = formItem;
            if (onFocus)
                (0, _utils_1.call)(onFocus, e);
            nTriggerFormFocus();
        }
        function focusSelectionInput() {
            var _a;
            (_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.focusInput();
        }
        function focusSelection() {
            var _a;
            (_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.focus();
        }
        function openMenu() {
            if (!mergedDisabledRef.value) {
                patternRef.value = '';
                doUpdateShow(true);
                if (props.filterable) {
                    focusSelectionInput();
                }
            }
        }
        function closeMenu(returnFocus = false) {
            if (returnFocus) {
                focusSelection();
            }
            doUpdateShow(false);
            patternRef.value = '';
        }
        function handleCascaderMenuClickOutside(e) {
            var _a;
            if (showSelectMenuRef.value)
                return;
            if (mergedShowRef.value) {
                if (!((_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.$el.contains((0, seemly_1.getPreciseEventTarget)(e)))) {
                    closeMenu();
                }
            }
        }
        function handleSelectMenuClickOutside(e) {
            if (!showSelectMenuRef.value)
                return;
            handleCascaderMenuClickOutside(e);
        }
        function clearPattern() {
            if (props.clearFilterAfterSelect)
                patternRef.value = '';
        }
        // --- keyboard
        function move(direction) {
            var _a, _b, _c;
            const { value: keyboardKey } = keyboardKeyRef;
            const { value: treeMate } = treeMateRef;
            switch (direction) {
                case 'prev':
                    if (keyboardKey !== null) {
                        const node = treeMate.getPrev(keyboardKey, { loop: true });
                        if (node !== null) {
                            updateKeyboardKey(node.key);
                            (_a = cascaderMenuInstRef.value) === null || _a === void 0 ? void 0 : _a.scroll(node.level, node.index, (0, seemly_1.depx)(optionHeightRef.value));
                        }
                    }
                    break;
                case 'next':
                    if (keyboardKey === null) {
                        const node = treeMate.getFirstAvailableNode();
                        if (node !== null) {
                            updateKeyboardKey(node.key);
                            (_b = cascaderMenuInstRef.value) === null || _b === void 0 ? void 0 : _b.scroll(node.level, node.index, (0, seemly_1.depx)(optionHeightRef.value));
                        }
                    }
                    else {
                        const node = treeMate.getNext(keyboardKey, { loop: true });
                        if (node !== null) {
                            updateKeyboardKey(node.key);
                            (_c = cascaderMenuInstRef.value) === null || _c === void 0 ? void 0 : _c.scroll(node.level, node.index, (0, seemly_1.depx)(optionHeightRef.value));
                        }
                    }
                    break;
                case 'child':
                    if (keyboardKey !== null) {
                        const currentNode = treeMate.getNode(keyboardKey);
                        if (currentNode !== null) {
                            if (currentNode.shallowLoaded) {
                                const node = treeMate.getChild(keyboardKey);
                                if (node !== null) {
                                    updateHoverKey(keyboardKey);
                                    updateKeyboardKey(node.key);
                                }
                            }
                            else {
                                const { value: loadingKeySet } = loadingKeySetRef;
                                if (!loadingKeySet.has(keyboardKey)) {
                                    addLoadingKey(keyboardKey);
                                    updateHoverKey(keyboardKey);
                                    const { onLoad } = props;
                                    if (onLoad) {
                                        onLoad(currentNode.rawNode)
                                            .then(() => {
                                            deleteLoadingKey(keyboardKey);
                                        })
                                            .catch(() => {
                                            deleteLoadingKey(keyboardKey);
                                        });
                                    }
                                }
                            }
                        }
                    }
                    break;
                case 'parent':
                    if (keyboardKey !== null) {
                        const node = treeMate.getParent(keyboardKey);
                        if (node !== null) {
                            updateKeyboardKey(node.key);
                            const parentNode = node.getParent();
                            if (parentNode === null) {
                                updateHoverKey(null);
                            }
                            else {
                                updateHoverKey(parentNode.key);
                            }
                        }
                    }
                    break;
            }
        }
        function handleKeydown(e) {
            var _a, _b;
            switch (e.key) {
                case ' ':
                case 'ArrowDown':
                case 'ArrowUp':
                    if (props.filterable && mergedShowRef.value) {
                        break;
                    }
                    e.preventDefault();
                    break;
            }
            if ((0, seemly_1.happensIn)(e, 'action'))
                return;
            switch (e.key) {
                case ' ':
                    if (props.filterable)
                        return;
                // eslint-disable-next-line no-fallthrough
                case 'Enter':
                    if (!mergedShowRef.value) {
                        openMenu();
                    }
                    else {
                        const { value: showSelectMenu } = showSelectMenuRef;
                        const { value: keyboardKey } = keyboardKeyRef;
                        if (!showSelectMenu) {
                            if (keyboardKey !== null) {
                                if (checkedKeysRef.value.includes(keyboardKey)
                                    || indeterminateKeysRef.value.includes(keyboardKey)) {
                                    doUncheck(keyboardKey);
                                }
                                else {
                                    const checkIsValid = doCheck(keyboardKey);
                                    if (!props.multiple && checkIsValid) {
                                        closeMenu(true);
                                    }
                                }
                            }
                        }
                        else {
                            if (selectMenuInstRef.value) {
                                const hasCorrespondingOption = selectMenuInstRef.value.enter();
                                if (hasCorrespondingOption)
                                    clearPattern();
                            }
                        }
                    }
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    if (mergedShowRef.value) {
                        if (showSelectMenuRef.value) {
                            (_a = selectMenuInstRef.value) === null || _a === void 0 ? void 0 : _a.prev();
                        }
                        else {
                            move('prev');
                        }
                    }
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    if (mergedShowRef.value) {
                        if (showSelectMenuRef.value) {
                            (_b = selectMenuInstRef.value) === null || _b === void 0 ? void 0 : _b.next();
                        }
                        else {
                            move('next');
                        }
                    }
                    else {
                        openMenu();
                    }
                    break;
                case 'ArrowLeft':
                    e.preventDefault();
                    if (mergedShowRef.value && !showSelectMenuRef.value) {
                        move('parent');
                    }
                    break;
                case 'ArrowRight':
                    e.preventDefault();
                    if (mergedShowRef.value && !showSelectMenuRef.value) {
                        move('child');
                    }
                    break;
                case 'Escape':
                    if (mergedShowRef.value) {
                        (0, _utils_1.markEventEffectPerformed)(e);
                        closeMenu(true);
                    }
            }
        }
        function handleMenuKeydown(e) {
            handleKeydown(e);
        }
        // --- search
        function handleClear(e) {
            e.stopPropagation();
            if (props.multiple) {
                doUpdateValue([], [], []);
            }
            else {
                doUpdateValue(null, null, null);
            }
        }
        function handleTriggerFocus(e) {
            var _a;
            if (!((_a = cascaderMenuInstRef.value) === null || _a === void 0 ? void 0 : _a.$el.contains(e.relatedTarget))) {
                focusedRef.value = true;
                doFocus(e);
            }
        }
        function handleTriggerBlur(e) {
            var _a;
            if (!((_a = cascaderMenuInstRef.value) === null || _a === void 0 ? void 0 : _a.$el.contains(e.relatedTarget))) {
                focusedRef.value = false;
                doBlur(e);
                closeMenu();
            }
        }
        function handleMenuFocus(e) {
            var _a;
            if (!((_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.$el.contains(e.relatedTarget))) {
                focusedRef.value = true;
                doFocus(e);
            }
        }
        function handleMenuBlur(e) {
            var _a;
            if (!((_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.$el.contains(e.relatedTarget))) {
                focusedRef.value = false;
                doBlur(e);
            }
        }
        function handleMenuMousedown(e) {
            if (!(0, seemly_1.happensIn)(e, 'action')) {
                if (props.multiple && props.filter) {
                    e.preventDefault();
                    focusSelectionInput();
                }
            }
        }
        function handleMenuTabout() {
            closeMenu(true);
        }
        function handleTriggerClick() {
            if (props.filterable) {
                openMenu();
            }
            else {
                if (mergedShowRef.value) {
                    closeMenu(true);
                }
                else {
                    openMenu();
                }
            }
        }
        function handlePatternInput(e) {
            patternRef.value = e.target.value;
        }
        function handleDeleteOption(option) {
            const { multiple } = props;
            const { value: mergedValue } = mergedValueRef;
            if (multiple
                && Array.isArray(mergedValue)
                && option.value !== undefined) {
                doUncheck(option.value);
            }
            else {
                doUpdateValue(null, null, null);
            }
        }
        // sync position
        function syncSelectMenuPosition() {
            var _a;
            (_a = selectMenuFollowerRef.value) === null || _a === void 0 ? void 0 : _a.syncPosition();
        }
        function syncCascaderMenuPosition() {
            var _a;
            (_a = cascaderMenuFollowerRef.value) === null || _a === void 0 ? void 0 : _a.syncPosition();
        }
        function handleTriggerResize() {
            if (mergedShowRef.value) {
                if (showSelectMenuRef.value) {
                    syncSelectMenuPosition();
                }
                else {
                    syncCascaderMenuPosition();
                }
            }
        }
        const showCheckboxRef = (0, vue_1.computed)(() => {
            if (props.multiple && props.cascade)
                return true;
            if (mergedCheckStrategyRef.value !== 'child')
                return true;
            return false;
        });
        (0, vue_1.provide)(interface_1.cascaderInjectionKey, {
            slots,
            mergedClsPrefixRef,
            mergedThemeRef: themeRef,
            mergedValueRef,
            checkedKeysRef,
            indeterminateKeysRef,
            hoverKeyPathRef,
            mergedCheckStrategyRef,
            showCheckboxRef,
            cascadeRef: (0, vue_1.toRef)(props, 'cascade'),
            multipleRef: (0, vue_1.toRef)(props, 'multiple'),
            keyboardKeyRef,
            hoverKeyRef,
            remoteRef: (0, vue_1.toRef)(props, 'remote'),
            loadingKeySetRef,
            expandTriggerRef: (0, vue_1.toRef)(props, 'expandTrigger'),
            isMountedRef: (0, vooks_1.useIsMounted)(),
            onLoadRef: (0, vue_1.toRef)(props, 'onLoad'),
            virtualScrollRef: (0, vue_1.toRef)(props, 'virtualScroll'),
            optionHeightRef,
            localeRef,
            labelFieldRef: (0, vue_1.toRef)(props, 'labelField'),
            renderLabelRef: (0, vue_1.toRef)(props, 'renderLabel'),
            getColumnStyleRef: (0, vue_1.toRef)(props, 'getColumnStyle'),
            renderPrefixRef: (0, vue_1.toRef)(props, 'renderPrefix'),
            renderSuffixRef: (0, vue_1.toRef)(props, 'renderSuffix'),
            syncCascaderMenuPosition,
            syncSelectMenuPosition,
            updateKeyboardKey,
            updateHoverKey,
            addLoadingKey,
            deleteLoadingKey,
            doCheck,
            doUncheck,
            closeMenu,
            handleSelectMenuClickOutside,
            handleCascaderMenuClickOutside,
            clearPattern
        });
        const exposedMethods = {
            focus: () => {
                var _a;
                (_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.focus();
            },
            blur: () => {
                var _a;
                (_a = triggerInstRef.value) === null || _a === void 0 ? void 0 : _a.blur();
            },
            getCheckedData: () => {
                if (showCheckboxRef.value) {
                    const checkedKeys = checkedKeysRef.value;
                    return {
                        keys: checkedKeys,
                        options: getOptionsByKeys(checkedKeys)
                    };
                }
                return {
                    keys: [],
                    options: []
                };
            },
            getIndeterminateData: () => {
                if (showCheckboxRef.value) {
                    const indeterminateKeys = indeterminateKeysRef.value;
                    return {
                        keys: indeterminateKeys,
                        options: getOptionsByKeys(indeterminateKeys)
                    };
                }
                return {
                    keys: [],
                    options: []
                };
            }
        };
        const cssVarsRef = (0, vue_1.computed)(() => {
            const { self: { optionArrowColor, optionTextColor, optionTextColorActive, optionTextColorDisabled, optionCheckMarkColor, menuColor, menuBoxShadow, menuDividerColor, menuBorderRadius, menuHeight, optionColorHover, optionHeight, optionFontSize, loadingColor, columnWidth }, common: { cubicBezierEaseInOut } } = themeRef.value;
            return {
                '--n-bezier': cubicBezierEaseInOut,
                '--n-menu-border-radius': menuBorderRadius,
                '--n-menu-box-shadow': menuBoxShadow,
                '--n-menu-height': menuHeight,
                '--n-column-width': columnWidth,
                '--n-menu-color': menuColor,
                '--n-menu-divider-color': menuDividerColor,
                '--n-option-height': optionHeight,
                '--n-option-font-size': optionFontSize,
                '--n-option-text-color': optionTextColor,
                '--n-option-text-color-disabled': optionTextColorDisabled,
                '--n-option-text-color-active': optionTextColorActive,
                '--n-option-color-hover': optionColorHover,
                '--n-option-check-mark-color': optionCheckMarkColor,
                '--n-option-arrow-color': optionArrowColor,
                '--n-menu-mask-color': (0, seemly_1.changeColor)(menuColor, { alpha: 0.75 }),
                '--n-loading-color': loadingColor
            };
        });
        const themeClassHandle = inlineThemeDisabled
            ? (0, _mixins_1.useThemeClass)('cascader', undefined, cssVarsRef, props)
            : undefined;
        return Object.assign(Object.assign({}, exposedMethods), { handleTriggerResize, mergedStatus: mergedStatusRef, selectMenuFollowerRef,
            cascaderMenuFollowerRef,
            triggerInstRef,
            selectMenuInstRef,
            cascaderMenuInstRef, mergedBordered: mergedBorderedRef, mergedClsPrefix: mergedClsPrefixRef, namespace: namespaceRef, mergedValue: mergedValueRef, mergedShow: mergedShowRef, showSelectMenu: showSelectMenuRef, pattern: patternRef, treeMate: treeMateRef, mergedSize: mergedSizeRef, mergedDisabled: mergedDisabledRef, localizedPlaceholder: localizedPlaceholderRef, selectedOption: selectedOptionRef, selectedOptions: selectedOptionsRef, adjustedTo: adjustedToRef, menuModel: menuModelRef, handleMenuTabout,
            handleMenuFocus,
            handleMenuBlur,
            handleMenuKeydown,
            handleMenuMousedown,
            handleTriggerFocus,
            handleTriggerBlur,
            handleTriggerClick,
            handleClear,
            handleDeleteOption,
            handlePatternInput,
            handleKeydown, focused: focusedRef, optionHeight: optionHeightRef, mergedTheme: themeRef, cssVars: inlineThemeDisabled ? undefined : cssVarsRef, themeClass: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.themeClass, onRender: themeClassHandle === null || themeClassHandle === void 0 ? void 0 : themeClassHandle.onRender });
    },
    render() {
        const { mergedClsPrefix } = this;
        return ((0, vue_1.h)("div", { class: `${mergedClsPrefix}-cascader` },
            (0, vue_1.h)(vueuc_1.VBinder, null, {
                default: () => [
                    (0, vue_1.h)(vueuc_1.VTarget, null, {
                        default: () => ((0, vue_1.h)(_internal_1.NInternalSelection, { onResize: this.handleTriggerResize, ref: "triggerInstRef", status: this.mergedStatus, clsPrefix: mergedClsPrefix, maxTagCount: this.maxTagCount, ellipsisTagPopoverProps: this.ellipsisTagPopoverProps, bordered: this.mergedBordered, size: this.mergedSize, theme: this.mergedTheme.peers.InternalSelection, themeOverrides: this.mergedTheme.peerOverrides.InternalSelection, active: this.mergedShow, pattern: this.pattern, placeholder: this.localizedPlaceholder, selectedOption: this.selectedOption, selectedOptions: this.selectedOptions, multiple: this.multiple, filterable: this.filterable, clearable: this.clearable, disabled: this.mergedDisabled, focused: this.focused, onFocus: this.handleTriggerFocus, onBlur: this.handleTriggerBlur, onClick: this.handleTriggerClick, onClear: this.handleClear, onDeleteOption: this.handleDeleteOption, onPatternInput: this.handlePatternInput, onKeydown: this.handleKeydown }, {
                            arrow: () => { var _a, _b; return (_b = (_a = this.$slots).arrow) === null || _b === void 0 ? void 0 : _b.call(_a); }
                        }))
                    }),
                    (0, vue_1.h)(vueuc_1.VFollower, { key: "cascaderMenu", ref: "cascaderMenuFollowerRef", show: this.mergedShow && !this.showSelectMenu, containerClass: this.namespace, placement: this.placement, width: !this.options.length ? 'target' : undefined, teleportDisabled: this.adjustedTo === _utils_1.useAdjustedTo.tdkey, to: this.adjustedTo }, {
                        default: () => {
                            var _a;
                            (_a = this.onRender) === null || _a === void 0 ? void 0 : _a.call(this);
                            const { menuProps } = this;
                            return ((0, vue_1.h)(CascaderMenu_1.default, Object.assign({}, menuProps, { ref: "cascaderMenuInstRef", class: [this.themeClass, menuProps === null || menuProps === void 0 ? void 0 : menuProps.class], value: this.mergedValue, show: this.mergedShow && !this.showSelectMenu, menuModel: this.menuModel, style: [
                                    this.cssVars,
                                    menuProps === null || menuProps === void 0 ? void 0 : menuProps.style
                                ], onFocus: this.handleMenuFocus, onBlur: this.handleMenuBlur, onKeydown: this.handleMenuKeydown, onMousedown: this.handleMenuMousedown, onTabout: this.handleMenuTabout }), {
                                action: () => { var _a, _b; return (_b = (_a = this.$slots).action) === null || _b === void 0 ? void 0 : _b.call(_a); },
                                empty: () => { var _a, _b; return (_b = (_a = this.$slots).empty) === null || _b === void 0 ? void 0 : _b.call(_a); }
                            }));
                        }
                    }),
                    (0, vue_1.h)(vueuc_1.VFollower, { key: "selectMenu", ref: "selectMenuFollowerRef", show: this.mergedShow && this.showSelectMenu, containerClass: this.namespace, width: "target", placement: this.placement, to: this.adjustedTo, teleportDisabled: this.adjustedTo === _utils_1.useAdjustedTo.tdkey }, {
                        default: () => {
                            var _a;
                            (_a = this.onRender) === null || _a === void 0 ? void 0 : _a.call(this);
                            const { filterMenuProps } = this;
                            return ((0, vue_1.h)(CascaderSelectMenu_1.default, Object.assign({}, filterMenuProps, { ref: "selectMenuInstRef", class: [this.themeClass, filterMenuProps === null || filterMenuProps === void 0 ? void 0 : filterMenuProps.class], value: this.mergedValue, show: this.mergedShow && this.showSelectMenu, pattern: this.pattern, multiple: this.multiple, tmNodes: this.treeMate.treeNodes, filter: this.filter, labelField: this.labelField, separator: this.separator, style: [
                                    this.cssVars,
                                    filterMenuProps === null || filterMenuProps === void 0 ? void 0 : filterMenuProps.style
                                ] })));
                        }
                    })
                ]
            })));
    }
});
