@fe6/water-pro
Version:
An enterprise-class UI design language and Vue-based implementation
600 lines (500 loc) • 22.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _omit = _interopRequireDefault(require("omit.js"));
var _vueTypes = _interopRequireDefault(require("../_util/vue-types"));
var _vcTrigger = _interopRequireDefault(require("../vc-trigger"));
var _KeyCode = _interopRequireDefault(require("../_util/KeyCode"));
var _SubPopupMenu = _interopRequireDefault(require("./SubPopupMenu"));
var _placements = _interopRequireDefault(require("./placements"));
var _BaseMixin = _interopRequireDefault(require("../_util/BaseMixin"));
var _propsUtil = require("../_util/props-util");
var _requestAnimationTimeout = require("../_util/requestAnimationTimeout");
var _util = require("./util");
var _transition = require("../_util/transition");
var _InjectExtraProps = _interopRequireDefault(require("./InjectExtraProps"));
var _defineComponent;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
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); }
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; }
var guid = 0;
var popupPlacementMap = {
horizontal: 'bottomLeft',
vertical: 'rightTop',
'vertical-left': 'rightTop',
'vertical-right': 'leftTop'
};
var updateDefaultActiveFirst = function updateDefaultActiveFirst(store, eventKey, defaultActiveFirst) {
var menuId = (0, _util.getMenuIdFromSubMenuEventKey)(eventKey);
store.defaultActiveFirst[menuId] = defaultActiveFirst;
};
var indexGuid = 0;
var SubMenu = (0, _vue.defineComponent)((_defineComponent = {
name: 'SubMenu',
mixins: [_BaseMixin.default],
inheritAttrs: false,
isSubMenu: true,
props: {
title: _vueTypes.default.any,
openKeys: _vueTypes.default.array.def([]),
openChange: _vueTypes.default.func.def(_util.noop),
rootPrefixCls: _vueTypes.default.string,
eventKey: _vueTypes.default.oneOfType([_vueTypes.default.string, _vueTypes.default.number]),
multiple: _vueTypes.default.looseBool,
isRootMenu: _vueTypes.default.looseBool.def(false),
index: _vueTypes.default.number,
triggerSubMenuAction: _vueTypes.default.string,
popupClassName: _vueTypes.default.string,
getPopupContainer: _vueTypes.default.func,
forceSubMenuRender: _vueTypes.default.looseBool.def(false),
openAnimation: _vueTypes.default.oneOfType([_vueTypes.default.string, _vueTypes.default.object]),
disabled: _vueTypes.default.looseBool,
subMenuOpenDelay: _vueTypes.default.number.def(0.1),
subMenuCloseDelay: _vueTypes.default.number.def(0.1),
level: _vueTypes.default.number.def(1),
inlineIndent: _vueTypes.default.number.def(24),
openTransitionName: _vueTypes.default.string,
popupOffset: _vueTypes.default.array,
mode: _vueTypes.default.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
manualRef: _vueTypes.default.func.def(_util.noop),
builtinPlacements: _vueTypes.default.object.def(function () {
return {};
}),
itemIcon: _vueTypes.default.any,
expandIcon: _vueTypes.default.any,
subMenuKey: _vueTypes.default.string,
theme: _vueTypes.default.string,
parentUniKeys: _vueTypes.default.array.def(function () {
return [];
}),
parentUniKey: _vueTypes.default.string,
isOverflowedSubMenu: _vueTypes.default.looseBool.def(false)
}
}, _defineProperty(_defineComponent, "isSubMenu", true), _defineProperty(_defineComponent, "setup", function setup(props) {
var uniKey = props.isOverflowedSubMenu ? 'MENUITEM_OVERFLOWED_UNI_KEY' : "sub_menu_".concat(++indexGuid);
var store = (0, _vue.inject)('menuStore', function () {
return {};
});
(0, _vue.onMounted)(function () {
store.addChildrenInfo(uniKey, (0, _vue.computed)(function () {
return {
parentUniKeys: props.parentUniKeys,
parentUniKey: props.parentUniKey,
eventKey: props.eventKey,
disabled: props.disabled
};
}));
});
(0, _vue.onBeforeUnmount)(function () {
store.removeChildrenInfo(uniKey);
});
var isChildrenSelected = (0, _vue.computed)(function () {
return store.selectedParentUniKeys.includes(uniKey);
});
var ins = (0, _vue.getCurrentInstance)();
var getEl = function getEl() {
return ins.vnode.el;
};
(0, _vue.provide)('parentMenu', (0, _vue.reactive)({
isRootMenu: (0, _vue.computed)(function () {
return props.isRootMenu;
}),
getPopupContainer: props.getPopupContainer,
getEl: getEl
}));
return {
parentMenu: (0, _vue.inject)('parentMenu', undefined),
store: store,
isChildrenSelected: isChildrenSelected,
childrenUniKeys: [].concat(_toConsumableArray(props.parentUniKeys), [uniKey]),
uniKey: uniKey,
isOpen: (0, _vue.computed)(function () {
return store.openKeys.includes(props.eventKey);
}),
active: (0, _vue.computed)(function () {
return store.activeKey[props.subMenuKey] === props.eventKey;
})
};
}), _defineProperty(_defineComponent, "data", function data() {
var props = this.$props;
var store = this.store;
var eventKey = props.eventKey;
var defaultActiveFirst = store.defaultActiveFirst;
var value = false;
if (defaultActiveFirst) {
value = defaultActiveFirst[eventKey];
}
updateDefaultActiveFirst(store, eventKey, value);
this.internalMenuId = undefined;
this.haveRendered = undefined;
this.haveOpened = undefined;
this.subMenuTitle = undefined;
return {};
}), _defineProperty(_defineComponent, "mounted", function mounted() {
var _this = this;
this.$nextTick(function () {
_this.handleUpdated();
});
}), _defineProperty(_defineComponent, "updated", function updated() {
var _this2 = this;
this.$nextTick(function () {
_this2.handleUpdated();
});
}), _defineProperty(_defineComponent, "beforeUnmount", function beforeUnmount() {
var eventKey = this.eventKey;
this.__emit('destroy', eventKey);
/* istanbul ignore if */
if (this.minWidthTimeout) {
(0, _requestAnimationTimeout.cancelAnimationTimeout)(this.minWidthTimeout);
this.minWidthTimeout = null;
}
/* istanbul ignore if */
if (this.mouseenterTimeout) {
(0, _requestAnimationTimeout.cancelAnimationTimeout)(this.mouseenterTimeout);
this.mouseenterTimeout = null;
}
}), _defineProperty(_defineComponent, "methods", {
isChildrenSelected2: function isChildrenSelected2() {
if (this.haveOpened) {
return this.isChildrenSelected;
}
var ret = {
find: false
};
(0, _util.loopMenuItemRecursively)((0, _propsUtil.getSlot)(this), this.store.selectedKeys, ret);
return ret.find;
},
handleUpdated: function handleUpdated() {
var _this3 = this;
var _this$$props = this.$props,
mode = _this$$props.mode,
manualRef = _this$$props.manualRef; // invoke customized ref to expose component to mixin
if (manualRef) {
manualRef(this);
}
if (mode !== 'horizontal' || !this.parentMenu.isRootMenu || !this.isOpen) {
return;
}
this.minWidthTimeout = (0, _requestAnimationTimeout.requestAnimationTimeout)(function () {
return _this3.adjustWidth();
}, 0);
},
onKeyDown: function onKeyDown(e) {
var keyCode = e.keyCode;
var menu = this.menuInstance;
var isOpen = this.isOpen;
if (keyCode === _KeyCode.default.ENTER) {
this.onTitleClick(e);
updateDefaultActiveFirst(this.store, this.$props.eventKey, true);
return true;
}
if (keyCode === _KeyCode.default.RIGHT) {
if (isOpen) {
menu.onKeyDown(e);
} else {
this.triggerOpenChange(true); // need to update current menu's defaultActiveFirst value
updateDefaultActiveFirst(this.store, this.$props.eventKey, true);
}
return true;
}
if (keyCode === _KeyCode.default.LEFT) {
var handled;
if (isOpen) {
handled = menu.onKeyDown(e);
} else {
return undefined;
}
if (!handled) {
this.triggerOpenChange(false);
handled = true;
}
return handled;
}
if (isOpen && (keyCode === _KeyCode.default.UP || keyCode === _KeyCode.default.DOWN)) {
return menu.onKeyDown(e);
}
return undefined;
},
onPopupVisibleChange: function onPopupVisibleChange(visible) {
this.triggerOpenChange(visible, visible ? 'mouseenter' : 'mouseleave');
},
onMouseEnter: function onMouseEnter(e) {
var key = this.$props.eventKey;
updateDefaultActiveFirst(this.store, key, false);
this.__emit('mouseenter', {
key: key,
domEvent: e
});
},
onMouseLeave: function onMouseLeave(e) {
var eventKey = this.$props.eventKey;
this.__emit('mouseleave', {
key: eventKey,
domEvent: e
});
},
onTitleMouseEnter: function onTitleMouseEnter(domEvent) {
var key = this.$props.eventKey;
this.__emit('itemHover', {
key: key,
hover: true
});
this.__emit('titleMouseenter', {
key: key,
domEvent: domEvent
});
},
onTitleMouseLeave: function onTitleMouseLeave(e) {
var eventKey = this.$props.eventKey;
this.__emit('itemHover', {
key: eventKey,
hover: false
});
this.__emit('titleMouseleave', {
key: eventKey,
domEvent: e
});
},
onTitleClick: function onTitleClick(e) {
var _this$$props2 = this.$props,
triggerSubMenuAction = _this$$props2.triggerSubMenuAction,
eventKey = _this$$props2.eventKey;
this.__emit('titleClick', {
key: eventKey,
domEvent: e
});
if (triggerSubMenuAction === 'hover') {
return;
}
this.triggerOpenChange(!this.isOpen, 'click');
updateDefaultActiveFirst(this.store, eventKey, false);
},
onSubMenuClick: function onSubMenuClick(info) {
this.__emit('click', this.addKeyPath(info));
},
getPrefixCls: function getPrefixCls() {
return "".concat(this.$props.rootPrefixCls, "-submenu");
},
getActiveClassName: function getActiveClassName() {
return "".concat(this.getPrefixCls(), "-active");
},
getDisabledClassName: function getDisabledClassName() {
return "".concat(this.getPrefixCls(), "-disabled");
},
getSelectedClassName: function getSelectedClassName() {
return "".concat(this.getPrefixCls(), "-selected");
},
getOpenClassName: function getOpenClassName() {
return "".concat(this.$props.rootPrefixCls, "-submenu-open");
},
saveMenuInstance: function saveMenuInstance(c) {
// children menu instance
this.menuInstance = c;
},
addKeyPath: function addKeyPath(info) {
return _extends(_extends({}, info), {
keyPath: (info.keyPath || []).concat(this.$props.eventKey)
});
},
triggerOpenChange: function triggerOpenChange(open, type) {
var _this4 = this;
var key = this.$props.eventKey;
var openChange = function openChange() {
_this4.__emit('openChange', {
key: key,
item: _this4.$props,
trigger: type,
open: open
});
};
if (type === 'mouseenter') {
// make sure mouseenter happen after other menu item's mouseleave
this.mouseenterTimeout = (0, _requestAnimationTimeout.requestAnimationTimeout)(function () {
openChange();
}, 0);
} else {
openChange();
}
},
adjustWidth: function adjustWidth() {
/* istanbul ignore if */
if (!this.subMenuTitle || !this.menuInstance) {
return;
}
var popupMenu = (0, _propsUtil.findDOMNode)(this.menuInstance);
if (popupMenu.offsetWidth >= this.subMenuTitle.offsetWidth) {
return;
}
/* istanbul ignore next */
popupMenu.style.minWidth = "".concat(this.subMenuTitle.offsetWidth, "px");
},
saveSubMenuTitle: function saveSubMenuTitle(subMenuTitle) {
this.subMenuTitle = subMenuTitle;
},
renderChildren: function renderChildren() {
var _this5 = this;
var props = _extends(_extends({}, this.$props), this.$attrs);
var subPopupMenuProps = {
mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
visible: this.isOpen,
level: props.level + 1,
inlineIndent: props.inlineIndent,
focusable: false,
eventKey: "".concat(props.eventKey, "-menu-"),
openKeys: props.openKeys,
openTransitionName: props.openTransitionName,
openAnimation: props.openAnimation,
subMenuOpenDelay: props.subMenuOpenDelay,
subMenuCloseDelay: props.subMenuCloseDelay,
forceSubMenuRender: props.forceSubMenuRender,
triggerSubMenuAction: props.triggerSubMenuAction,
builtinPlacements: props.builtinPlacements,
multiple: props.multiple,
prefixCls: props.rootPrefixCls,
manualRef: this.saveMenuInstance,
itemIcon: (0, _propsUtil.getComponent)(this, 'itemIcon'),
expandIcon: (0, _propsUtil.getComponent)(this, 'expandIcon'),
onClick: this.onSubMenuClick,
onSelect: props.onSelect || _util.noop,
onDeselect: props.onDeselect || _util.noop,
onOpenChange: props.onOpenChange || _util.noop,
id: this.internalMenuId,
parentUniKeys: this.childrenUniKeys,
parentUniKey: this.uniKey
};
var haveRendered = this.haveRendered;
this.haveRendered = true;
this.haveOpened = this.haveOpened || subPopupMenuProps.visible || subPopupMenuProps.forceSubMenuRender; // never rendered not planning to, don't render
if (!this.haveOpened) {
return (0, _vue.createVNode)("div", null, null);
} // don't show transition on first rendering (no animation for opened menu)
// show appear transition if it's not visible (not sure why)
// show appear transition if it's not inline mode
var transitionAppear = haveRendered || !subPopupMenuProps.visible || !subPopupMenuProps.mode === 'inline';
subPopupMenuProps.class = " ".concat(subPopupMenuProps.prefixCls, "-sub");
var transitionProps = {
appear: transitionAppear,
css: false
};
if (subPopupMenuProps.openTransitionName) {
transitionProps = (0, _transition.getTransitionProps)(subPopupMenuProps.openTransitionName, {
appear: transitionAppear
});
} else if (_typeof(subPopupMenuProps.openAnimation) === 'object') {
transitionProps = _extends(_extends({}, transitionProps), subPopupMenuProps.openAnimation || {});
if (!transitionAppear) {
transitionProps.appear = false;
}
} else if (typeof subPopupMenuProps.openAnimation === 'string') {
transitionProps = (0, _transition.getTransitionProps)(subPopupMenuProps.openAnimation, {
appear: transitionAppear
});
}
return (0, _vue.createVNode)(_transition.Transition, transitionProps, {
default: function _default() {
return [(0, _vue.withDirectives)((0, _vue.createVNode)(_SubPopupMenu.default, subPopupMenuProps, _this5.$slots), [[_vue.vShow, _this5.isOpen]])];
}
});
}
}), _defineProperty(_defineComponent, "render", function render() {
var _className, _createVNode2;
var props = _extends(_extends({}, this.$props), this.$attrs);
var _splitAttrs = (0, _propsUtil.splitAttrs)(props),
onEvents = _splitAttrs.onEvents;
var isOpen = this.isOpen;
var prefixCls = this.getPrefixCls();
var isInlineMode = props.mode === 'inline';
if (!this.internalMenuId) {
if (props.eventKey) {
this.internalMenuId = "".concat(props.eventKey, "$Menu");
} else {
this.internalMenuId = "$__$".concat(++guid, "$Menu");
}
}
var children = this.renderChildren();
var className = (_className = {}, _defineProperty(_className, prefixCls, true), _defineProperty(_className, "".concat(prefixCls, "-").concat(props.mode), true), _defineProperty(_className, props.class, !!props.class), _defineProperty(_className, this.getOpenClassName(), isOpen), _defineProperty(_className, this.getActiveClassName(), this.active || isOpen && !isInlineMode), _defineProperty(_className, this.getDisabledClassName(), props.disabled), _defineProperty(_className, this.getSelectedClassName(), this.isChildrenSelected || this.isChildrenSelected2()), _className);
var mouseEvents = {};
var titleClickEvents = {};
var titleMouseEvents = {};
if (!props.disabled) {
mouseEvents = {
onMouseleave: this.onMouseLeave,
onMouseenter: this.onMouseEnter
}; // only works in title, not outer li
titleClickEvents = {
onClick: this.onTitleClick
};
titleMouseEvents = {
onMouseenter: this.onTitleMouseEnter,
onMouseleave: this.onTitleMouseLeave
};
}
var style = {};
if (isInlineMode) {
style.paddingLeft = "".concat(props.inlineIndent * props.level, "px");
}
var ariaOwns = {}; // only set aria-owns when menu is open
// otherwise it would be an invalid aria-owns value
// since corresponding node cannot be found
if (isOpen) {
ariaOwns = {
'aria-owns': this.internalMenuId
};
}
var titleProps = _extends(_extends(_extends(_extends(_extends({
'aria-expanded': isOpen
}, ariaOwns), {
'aria-haspopup': 'true',
title: typeof props.title === 'string' ? props.title : undefined
}), titleMouseEvents), titleClickEvents), {
style: style,
class: "".concat(prefixCls, "-title"),
ref: this.saveSubMenuTitle
}); // expand custom icon should NOT be displayed in menu with horizontal mode.
var icon = null;
if (props.mode !== 'horizontal') {
icon = (0, _propsUtil.getComponent)(this, 'expandIcon', props);
}
var title = (0, _vue.createVNode)("div", titleProps, [(0, _propsUtil.getComponent)(this, 'title'), icon || (0, _vue.createVNode)("i", {
"class": "".concat(prefixCls, "-arrow")
}, null)]);
var getPopupContainer = this.parentMenu.isRootMenu ? this.parentMenu.getPopupContainer : function (triggerNode) {
return triggerNode.parentNode;
};
var popupPlacement = popupPlacementMap[props.mode];
var popupAlign = props.popupOffset ? {
offset: props.popupOffset
} : {};
var popupClassName = props.mode === 'inline' ? '' : props.popupClassName || '';
popupClassName = "".concat(prefixCls, "-popup ").concat(popupClassName);
var liProps = _extends(_extends(_extends({}, (0, _omit.default)(onEvents, ['onClick'])), mouseEvents), {
class: className,
style: props.style
});
return (0, _vue.createVNode)("li", _objectSpread(_objectSpread({}, liProps), {}, {
"role": "menuitem"
}), [isInlineMode && title, isInlineMode && children, !isInlineMode && (0, _vue.createVNode)(_vcTrigger.default, (_createVNode2 = {
"prefixCls": prefixCls,
"popupClassName": popupClassName,
"getPopupContainer": getPopupContainer,
"builtinPlacements": _placements.default
}, _defineProperty(_createVNode2, "builtinPlacements", _extends({}, _placements.default, props.builtinPlacements)), _defineProperty(_createVNode2, "popupPlacement", popupPlacement), _defineProperty(_createVNode2, "popupVisible", isOpen), _defineProperty(_createVNode2, "popupAlign", popupAlign), _defineProperty(_createVNode2, "action", props.disabled ? [] : [props.triggerSubMenuAction]), _defineProperty(_createVNode2, "mouseEnterDelay", props.subMenuOpenDelay), _defineProperty(_createVNode2, "mouseLeaveDelay", props.subMenuCloseDelay), _defineProperty(_createVNode2, "onPopupVisibleChange", this.onPopupVisibleChange), _defineProperty(_createVNode2, "forceRender", props.forceSubMenuRender), _defineProperty(_createVNode2, "popup", children), _createVNode2), {
default: function _default() {
return [title];
}
})]);
}), _defineComponent));
var _default2 = (0, _InjectExtraProps.default)(SubMenu);
exports.default = _default2;