ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
242 lines (204 loc) • 8.71 kB
JavaScript
import { resolveDirective as _resolveDirective, createVNode as _createVNode, createTextVNode as _createTextVNode } from "vue";
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import PropTypes from '../_util/vue-types';
import { default as SubPopupMenu } from './SubPopupMenu';
import BaseMixin from '../_util/BaseMixin';
import hasProp, { getOptionProps, getComponent } from '../_util/props-util';
import commonPropsType from './commonPropsType';
import { computed, defineComponent, getCurrentInstance, provide, reactive, ref, toRaw, watch } from 'vue';
import isEqual from 'lodash-es/isEqual';
var Menu = {
name: 'Menu',
inheritAttrs: false,
props: _extends(_extends({}, commonPropsType), {
onClick: PropTypes.func,
selectable: PropTypes.looseBool.def(true)
}),
mixins: [BaseMixin],
setup: function setup(props) {
var menuChildrenInfo = reactive({});
var selectedKeys = ref(props.selectedKeys || props.defaultSelectedKeys || []);
var openKeys = ref(props.openKeys || props.defaultOpenKeys || []); // computed(() => {
// return props.openKeys || props.defaultOpenKeys || [];
// });
watch(function () {
return props.selectedKeys;
}, function () {
selectedKeys.value = props.selectedKeys || [];
});
watch(function () {
return props.openKeys;
}, function () {
openKeys.value = props.openKeys || [];
});
var activeKey = reactive({
'0-menu-': props.activeKey
});
var defaultActiveFirst = reactive({});
var addChildrenInfo = function addChildrenInfo(key, info) {
menuChildrenInfo[key] = info;
};
var removeChildrenInfo = function removeChildrenInfo(key) {
delete menuChildrenInfo[key];
};
var getActiveKey = function getActiveKey(key) {
return key;
}; // TODO
var selectedParentUniKeys = ref([]);
watch(menuChildrenInfo, function () {
var keys = Object.values(menuChildrenInfo).filter(function (info) {
return info.isSelected;
}).reduce(function (allKeys, _ref) {
var _ref$parentUniKeys = _ref.parentUniKeys,
parentUniKeys = _ref$parentUniKeys === void 0 ? [] : _ref$parentUniKeys;
return [].concat(_toConsumableArray(allKeys), _toConsumableArray(toRaw(parentUniKeys)));
}, []);
if (!isEqual(selectedParentUniKeys.value, keys)) {
selectedParentUniKeys.value = keys || [];
}
});
var store = reactive({
selectedKeys: selectedKeys,
openKeys: openKeys,
activeKey: activeKey,
defaultActiveFirst: defaultActiveFirst,
menuChildrenInfo: menuChildrenInfo,
selectedParentUniKeys: selectedParentUniKeys,
addChildrenInfo: addChildrenInfo,
removeChildrenInfo: removeChildrenInfo,
getActiveKey: getActiveKey
});
var ins = getCurrentInstance();
var getEl = function getEl() {
return ins.vnode.el;
};
provide('menuStore', store);
provide('parentMenu', reactive({
isRootMenu: computed(function () {
return props.isRootMenu;
}),
getPopupContainer: computed(function () {
return props.getPopupContainer;
}),
getEl: getEl
}));
return {
store: store
};
},
methods: {
handleSelect: function handleSelect(selectInfo) {
var props = this.$props;
if (props.selectable) {
// root menu
var selectedKeys = this.store.selectedKeys;
var selectedKey = selectInfo.key;
if (props.multiple) {
selectedKeys = selectedKeys.concat([selectedKey]);
} else {
selectedKeys = [selectedKey];
}
if (!hasProp(this, 'selectedKeys')) {
this.store.selectedKeys = selectedKeys;
}
this.__emit('select', _extends(_extends({}, selectInfo), {
selectedKeys: selectedKeys
}));
}
},
handleClick: function handleClick(e) {
this.__emit('click', e);
},
// onKeyDown needs to be exposed as a instance method
// e.g., in rc-select, we need to navigate menu item while
// current active item is rc-select input box rather than the menu itself
onKeyDown: function onKeyDown(e, callback) {
this.innerMenu.getWrappedInstance().onKeyDown(e, callback);
},
onOpenChange: function onOpenChange(event) {
var openKeys = this.store.openKeys.concat();
var changed = false;
var processSingle = function processSingle(e) {
var oneChanged = false;
if (e.open) {
oneChanged = openKeys.indexOf(e.key) === -1;
if (oneChanged) {
openKeys.push(e.key);
}
} else {
var index = openKeys.indexOf(e.key);
oneChanged = index !== -1;
if (oneChanged) {
openKeys.splice(index, 1);
}
}
changed = changed || oneChanged;
};
if (Array.isArray(event)) {
// batch change call
event.forEach(processSingle);
} else {
processSingle(event);
}
if (changed) {
if (!hasProp(this, 'openKeys')) {
this.store.openKeys = openKeys;
}
this.__emit('openChange', openKeys);
}
},
handleDeselect: function handleDeselect(selectInfo) {
var props = this.$props;
if (props.selectable) {
var selectedKeys = this.store.selectedKeys.concat();
var selectedKey = selectInfo.key;
var index = selectedKeys.indexOf(selectedKey);
if (index !== -1) {
selectedKeys.splice(index, 1);
}
if (!hasProp(this, 'selectedKeys')) {
this.store.selectedKeys = selectedKeys;
}
this.__emit('deselect', _extends(_extends({}, selectInfo), {
selectedKeys: selectedKeys
}));
}
},
getOpenTransitionName: function getOpenTransitionName() {
var props = this.$props;
var transitionName = props.openTransitionName;
var animationName = props.openAnimation;
if (!transitionName && typeof animationName === 'string') {
transitionName = "".concat(props.prefixCls, "-open-").concat(animationName);
}
return transitionName;
},
saveInnerMenu: function saveInnerMenu(ref) {
this.innerMenu = ref;
}
},
render: function render() {
var props = _extends(_extends({}, getOptionProps(this)), this.$attrs);
props.class = props.class ? "".concat(props.class, " ").concat(props.prefixCls, "-root") : "".concat(props.prefixCls, "-root");
var subPopupMenuProps = _extends(_extends({}, props), {
itemIcon: getComponent(this, 'itemIcon', props),
expandIcon: getComponent(this, 'expandIcon', props),
overflowedIndicator: getComponent(this, 'overflowedIndicator', props) || _createVNode("span", null, [_createTextVNode("\xB7\xB7\xB7")]),
openTransitionName: this.getOpenTransitionName(),
onClick: this.handleClick,
onOpenChange: this.onOpenChange,
onDeselect: this.handleDeselect,
onSelect: this.handleSelect,
ref: this.saveInnerMenu,
store: this.store
});
return _createVNode(SubPopupMenu, subPopupMenuProps, this.$slots);
}
};
export default defineComponent(Menu);