UNPKG

naive-ui

Version:

A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast

149 lines (148 loc) 6.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const treemate_1 = require("treemate"); const vdirs_1 = require("vdirs"); const vue_1 = require("vue"); const _internal_1 = require("../../_internal"); const _utils_1 = require("../../_utils"); const utils_1 = require("../../select/src/utils"); const interface_1 = require("./interface"); const utils_2 = require("./utils"); exports.default = (0, vue_1.defineComponent)({ name: 'NCascaderSelectMenu', props: { value: { type: [String, Number, Array], default: null }, show: Boolean, pattern: { type: String, default: '' }, multiple: Boolean, tmNodes: { type: Array, default: () => [] }, filter: Function, labelField: { type: String, required: true }, separator: { type: String, required: true } }, setup(props) { const { isMountedRef, mergedValueRef, mergedClsPrefixRef, mergedThemeRef, mergedCheckStrategyRef, slots: cascaderSlots, syncSelectMenuPosition, closeMenu, handleSelectMenuClickOutside, doUncheck: cascaderDoUncheck, doCheck: cascaderDoCheck, clearPattern } = (0, vue_1.inject)(interface_1.cascaderInjectionKey); const menuInstRef = (0, vue_1.ref)(null); const selectOptionsRef = (0, vue_1.computed)(() => { return (0, utils_2.createSelectOptions)(props.tmNodes, mergedCheckStrategyRef.value === 'child', props.labelField, props.separator); }); const mergedFilterRef = (0, vue_1.computed)(() => { const { filter } = props; if (filter) return filter; const { labelField } = props; return (pattern, _, path) => path.some(option => option[labelField] && ~option[labelField] .toLowerCase() .indexOf(pattern.toLowerCase())); }); const filteredSelectOptionsRef = (0, vue_1.computed)(() => { const { pattern } = props; const { value: mergedFilter } = mergedFilterRef; return (pattern ? selectOptionsRef.value.filter((option) => { return mergedFilter(pattern, option.rawNode, option.path); }) : selectOptionsRef.value).map(option => ({ value: option.value, label: option.label })); }); const selectTreeMateRef = (0, vue_1.computed)(() => { return (0, treemate_1.createTreeMate)(filteredSelectOptionsRef.value, (0, utils_1.createTmOptions)('value', 'children')); }); function handleResize() { syncSelectMenuPosition(); } function handleToggle(tmNode) { doCheck(tmNode); } // We don't care what type the tmNode is, we only care about its key function doCheck(tmNode) { if (props.multiple) { const { value: mergedValue } = mergedValueRef; if (Array.isArray(mergedValue)) { if (!mergedValue.includes(tmNode.key)) { cascaderDoCheck(tmNode.key); } else { cascaderDoUncheck(tmNode.key); } } else if (mergedValue === null) { cascaderDoCheck(tmNode.key); } clearPattern(); } else { cascaderDoCheck(tmNode.key); // currently the select menu is set to focusable // however just leave it here closeMenu(true); } } function prev() { var _a; (_a = menuInstRef.value) === null || _a === void 0 ? void 0 : _a.prev(); } function next() { var _a; (_a = menuInstRef.value) === null || _a === void 0 ? void 0 : _a.next(); } function enter() { var _a; if (menuInstRef) { const pendingOptionTmNode = (_a = menuInstRef.value) === null || _a === void 0 ? void 0 : _a.getPendingTmNode(); if (pendingOptionTmNode) { doCheck(pendingOptionTmNode); } return true; } return false; } function handleClickOutside(e) { handleSelectMenuClickOutside(e); } const exposedRef = { prev, next, enter }; return Object.assign({ isMounted: isMountedRef, mergedTheme: mergedThemeRef, mergedClsPrefix: mergedClsPrefixRef, menuInstRef, selectTreeMate: selectTreeMateRef, handleResize, handleToggle, handleClickOutside, cascaderSlots }, exposedRef); }, render() { const { mergedClsPrefix, isMounted, mergedTheme, cascaderSlots } = this; return ((0, vue_1.h)(vue_1.Transition, { name: "fade-in-scale-up-transition", appear: isMounted }, { default: () => this.show ? (0, vue_1.withDirectives)((0, vue_1.h)(_internal_1.NInternalSelectMenu, { ref: "menuInstRef", onResize: this.handleResize, clsPrefix: mergedClsPrefix, class: `${mergedClsPrefix}-cascader-menu`, autoPending: true, themeOverrides: mergedTheme.peerOverrides.InternalSelectMenu, theme: mergedTheme.peers.InternalSelectMenu, treeMate: this.selectTreeMate, multiple: this.multiple, value: this.value, onToggle: this.handleToggle }, { empty: () => (0, _utils_1.resolveSlot)(cascaderSlots['not-found'], () => []) }), [ [ vdirs_1.clickoutside, this.handleClickOutside, undefined, { capture: true } ] ]) : null })); } });