ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
236 lines (202 loc) • 7.32 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _raf = require('raf');
var _raf2 = _interopRequireDefault(_raf);
var _vueTypes = require('../_util/vue-types');
var _vueTypes2 = _interopRequireDefault(_vueTypes);
var _vcMenu = require('../vc-menu');
var _vcMenu2 = _interopRequireDefault(_vcMenu);
var _domScrollIntoView = require('dom-scroll-into-view');
var _domScrollIntoView2 = _interopRequireDefault(_domScrollIntoView);
var _util = require('./util');
var _vnode = require('../_util/vnode');
var _BaseMixin = require('../_util/BaseMixin');
var _BaseMixin2 = _interopRequireDefault(_BaseMixin);
var _propsUtil = require('../_util/props-util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
exports['default'] = {
name: 'DropdownMenu',
mixins: [_BaseMixin2['default']],
props: {
defaultActiveFirstOption: _vueTypes2['default'].bool,
value: _vueTypes2['default'].any,
dropdownMenuStyle: _vueTypes2['default'].object,
multiple: _vueTypes2['default'].bool,
// onPopupFocus: PropTypes.func,
// onPopupScroll: PropTypes.func,
// onMenuDeSelect: PropTypes.func,
// onMenuSelect: PropTypes.func,
prefixCls: _vueTypes2['default'].string,
menuItems: _vueTypes2['default'].any,
inputValue: _vueTypes2['default'].string,
visible: _vueTypes2['default'].bool,
backfillValue: _vueTypes2['default'].any
},
beforeMount: function beforeMount() {
this.lastInputValue = this.$props.inputValue;
},
mounted: function mounted() {
var _this = this;
this.$nextTick(function () {
_this.scrollActiveItemToView();
});
this.lastVisible = this.$props.visible;
},
watch: {
visible: function visible(val) {
if (!val) {
this.lastVisible = val;
}
}
},
updated: function updated() {
var _this2 = this;
var props = this.$props;
if (!this.prevVisible && props.visible) {
this.$nextTick(function () {
_this2.scrollActiveItemToView();
});
}
this.lastVisible = props.visible;
this.lastInputValue = props.inputValue;
this.prevVisible = this.visible;
},
methods: {
scrollActiveItemToView: function scrollActiveItemToView() {
var _this3 = this;
// scroll into view
var itemComponent = this.firstActiveItem && this.firstActiveItem.$el;
var props = this.$props;
if (itemComponent) {
var scrollIntoViewOpts = {
onlyScrollIfNeeded: true
};
if ((!props.value || props.value.length === 0) && props.firstActiveValue) {
scrollIntoViewOpts.alignWithTop = true;
}
// Delay to scroll since current frame item position is not ready when pre view is by filter
// https://github.com/ant-design/ant-design/issues/11268#issuecomment-406634462
(0, _raf2['default'])(function () {
(0, _domScrollIntoView2['default'])(itemComponent, _this3.$refs.menuRef.$el, scrollIntoViewOpts);
});
}
},
renderMenu: function renderMenu() {
var _this4 = this;
var h = this.$createElement;
var props = this.$props;
var menuItems = props.menuItems,
defaultActiveFirstOption = props.defaultActiveFirstOption,
value = props.value,
prefixCls = props.prefixCls,
multiple = props.multiple,
inputValue = props.inputValue,
firstActiveValue = props.firstActiveValue,
dropdownMenuStyle = props.dropdownMenuStyle,
backfillValue = props.backfillValue;
var _$listeners = this.$listeners,
menuDeselect = _$listeners.menuDeselect,
menuSelect = _$listeners.menuSelect,
popupScroll = _$listeners.popupScroll;
if (menuItems && menuItems.length) {
var selectedKeys = (0, _util.getSelectKeys)(menuItems, value);
var menuProps = {
props: {
multiple: multiple,
defaultActiveFirst: defaultActiveFirstOption,
selectedKeys: selectedKeys,
prefixCls: prefixCls + '-menu'
},
on: {},
style: dropdownMenuStyle,
ref: 'menuRef',
attrs: {
role: 'listbox'
}
};
if (popupScroll) {
menuProps.on.scroll = popupScroll;
}
if (multiple) {
menuProps.on.deselect = menuDeselect;
menuProps.on.select = menuSelect;
} else {
menuProps.on.click = menuSelect;
}
var activeKeyProps = {};
var clonedMenuItems = menuItems;
if (selectedKeys.length || firstActiveValue) {
if (props.visible && !this.lastVisible) {
activeKeyProps.activeKey = selectedKeys[0] !== undefined ? selectedKeys[0] : firstActiveValue;
}
var foundFirst = false;
// set firstActiveItem via cloning menus
// for scroll into view
var clone = function clone(item) {
if (!foundFirst && selectedKeys.indexOf(item.key) !== -1 || !foundFirst && !selectedKeys.length && firstActiveValue.indexOf(item.key) !== -1) {
foundFirst = true;
return (0, _vnode.cloneElement)(item, {
directives: [{
name: 'ref',
value: function value(ref) {
_this4.firstActiveItem = ref;
}
}]
});
}
return item;
};
clonedMenuItems = menuItems.map(function (item) {
if ((0, _propsUtil.getSlotOptions)(item).isMenuItemGroup) {
var children = item.componentOptions.children.map(clone);
return (0, _vnode.cloneElement)(item, { children: children });
}
return clone(item);
});
} else {
// Clear firstActiveItem when dropdown menu items was empty
// Avoid `Unable to find node on an unmounted component`
// https://github.com/ant-design/ant-design/issues/10774
this.firstActiveItem = null;
}
// clear activeKey when inputValue change
var lastValue = value && value[value.length - 1];
if (inputValue !== this.lastInputValue && (!lastValue || lastValue !== backfillValue)) {
activeKeyProps.activeKey = '';
}
menuProps.props = (0, _extends3['default'])({}, activeKeyProps, menuProps.props);
return h(
_vcMenu2['default'],
menuProps,
[clonedMenuItems]
);
}
return null;
}
},
render: function render() {
var h = arguments[0];
var renderMenu = this.renderMenu();
var _$listeners2 = this.$listeners,
popupFocus = _$listeners2.popupFocus,
popupScroll = _$listeners2.popupScroll;
return renderMenu ? h(
'div',
{
style: { overflow: 'auto' },
on: {
'focus': popupFocus,
'mousedown': _util.preventDefaultEvent,
'scroll': popupScroll
},
ref: 'menuContainer'
},
[renderMenu]
) : null;
}
};
module.exports = exports['default'];