fix: menu

pull/2468/head
tangjinzhou 2020-06-18 00:19:14 +08:00
parent adad60e933
commit 5c425cec90
10 changed files with 38 additions and 28 deletions

View File

@ -69,8 +69,8 @@ const getSlots = ele => {
};
const getSlot = (self, name = 'default', options = {}) => {
let res = self.$slots[name] && self.$slots[name](options);
while (res && res.length === 1 && res[0].type === Fragment) {
res = res[0].children;
while (res && res.length === 1 && (res[0].type === Fragment || Array.isArray(res[0]))) {
res = res[0].children || res[0];
}
return res;
};
@ -105,12 +105,15 @@ const getOptionProps = instance => {
}
});
} else if (isVNode(instance) && typeof instance.type === 'object') {
const props = instance.props || {};
const originProps = instance.props || {};
const props = {};
Object.keys(originProps).forEach(key => {
props[camelize(key)] = originProps[key];
});
const options = instance.type.props;
Object.keys(options).forEach(k => {
const hyphenateKey = hyphenate(k);
const v = resolvePropValue(options, props, k, props[hyphenateKey], hyphenateKey);
if (v !== undefined || hyphenateKey in props) {
const v = resolvePropValue(options, props, k, props[k]);
if (v !== undefined || k in props) {
res[k] = v;
}
});

View File

@ -17,7 +17,6 @@ export default function wrapWithConnect(WrappedComponent) {
const ProxyWrappedComponent = {
props,
inheritAttrs: false,
model: WrappedComponent.model,
name: `Proxy_${getDisplayName(WrappedComponent)}`,
methods: {
getProxyWrappedInstance() {
@ -25,17 +24,16 @@ export default function wrapWithConnect(WrappedComponent) {
},
},
render() {
const { $slots = {} } = this;
const { $slots = {}, $attrs } = this;
const props = getOptionProps(this);
const wrapProps = {
...props,
...$attrs,
__propsSymbol__: Symbol(),
componentWillReceiveProps: { ...props },
children: props.children || $slots?.default() || [],
slots: $slots,
ref: 'wrappedInstance',
};
return createVNode(WrappedComponent, wrapProps);
return createVNode(WrappedComponent, wrapProps, $slots);
// return (
// <WrappedComponent {...wrapProps} ref="wrappedInstance">
// </WrappedComponent>

View File

@ -92,10 +92,9 @@ export default function connect(mapStateToProps) {
...subscribed,
...$attrs,
store,
slots: $slots,
ref: 'wrappedInstance',
};
return createVNode(WrappedComponent, wrapProps);
return createVNode(WrappedComponent, wrapProps, $slots);
// return <WrappedComponent {...wrapProps} ref="wrappedInstance"></WrappedComponent>;
},
};

View File

@ -27,7 +27,7 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
// change from vue sourcecode
function resolvePropValue(options, props, key, value, hyphenateKey) {
function resolvePropValue(options, props, key, value) {
const opt = options[key];
if (opt != null) {
const hasDefault = hasOwn(opt, 'default');
@ -38,9 +38,9 @@ function resolvePropValue(options, props, key, value, hyphenateKey) {
}
// boolean casting
if (opt[0 /* shouldCast */]) {
if (!hasOwn(props, hyphenateKey) && !hasDefault) {
if (!hasOwn(props, key) && !hasDefault) {
value = false;
} else if (opt[1 /* shouldCastTrue */] && (value === '' || value === hyphenateKey)) {
} else if (opt[1 /* shouldCastTrue */] && (value === '' || value === hyphenate(key))) {
value = true;
}
}

View File

@ -23,10 +23,10 @@ export default {
render() {
const props = getOptionProps(this);
const { level, title, rootPrefixCls } = props;
const { getInlineCollapsed, $slots, $attrs: attrs } = this;
const { getInlineCollapsed, $attrs: attrs } = this;
const inlineCollapsed = getInlineCollapsed();
const tooltipProps = {
title: title || (level === 1 ? $slots.default : ''),
title: title || (level === 1 ? getSlot(this) : ''),
};
const siderCollapsed = this.layoutSiderContext.sCollapsed;
if (!siderCollapsed && !inlineCollapsed) {

View File

@ -4,7 +4,7 @@ import SubMenu from './SubMenu';
import BaseMixin from '../_util/BaseMixin';
import { getWidth, setStyle, menuAllProps } from './util';
import { cloneElement } from '../_util/vnode';
import { getPropsData, getSlot, getAllProps } from '../_util/props-util';
import { getPropsData, getAllProps, getSlot } from '../_util/props-util';
const canUseDOM = !!(
typeof window !== 'undefined' &&
@ -241,7 +241,10 @@ const DOMWrap = {
const eventKey = getPropsData(childNode).eventKey;
if (this.mode === 'horizontal') {
let overflowed = this.getOverflowedSubMenuItem(eventKey, []);
if (lastVisibleIndex !== undefined && className[`${this.prefixCls}-root`] !== -1) {
if (
lastVisibleIndex !== undefined &&
className.indexOf(`${this.prefixCls}-root`) !== -1
) {
if (index > lastVisibleIndex) {
item = cloneElement(
childNode,
@ -299,7 +302,6 @@ DOMWrap.props = {
visible: PropTypes.bool,
hiddenClassName: PropTypes.string,
tag: PropTypes.string.def('div'),
children: PropTypes.any,
};
export default DOMWrap;

View File

@ -183,14 +183,13 @@ const MenuItem = {
if (props.mode === 'inline') {
style.paddingLeft = `${props.inlineIndent * props.level}px`;
}
[...menuAllProps, 'children', 'slots', '__propsSymbol__', 'componentWillReceiveProps'].forEach(
key => delete props[key],
);
menuAllProps.forEach(key => delete props[key]);
const liProps = {
...props,
...attrs,
...mouseEvent,
};
delete liProps.children;
return (
<li {...liProps} style={style} class={className}>
{getSlot(this)}

View File

@ -274,7 +274,7 @@ const SubPopupMenu = {
const state = this.$props.store.getState();
const props = this.$props;
const key = getKeyFromChildrenIndex(child, props.eventKey, i);
const childProps = { ...getOptionProps(child), ...child.props }; // child.props
const childProps = child.props; //
const isActive = key === state.activeKey[getEventKey(this.$props)];
if (!childProps.disabled) {
@ -337,11 +337,15 @@ const SubPopupMenu = {
},
render() {
const props = { ...this.$props };
const { onEvents } = splitAttrs(this.$attrs);
const { onEvents, extraAttrs } = splitAttrs(this.$attrs);
const { eventKey, prefixCls, visible, level, mode, theme } = props;
this.instanceArray = [];
this.instanceArrayKeyIndexMap = {};
const className = classNames(props.class, props.prefixCls, `${props.prefixCls}-${props.mode}`);
const className = classNames(
extraAttrs.class,
props.prefixCls,
`${props.prefixCls}-${props.mode}`,
);
menuAllProps.forEach(key => delete props[key]);
// Otherwise, the propagated click event will trigger another onClick
delete onEvents.onClick;
@ -357,6 +361,7 @@ const SubPopupMenu = {
overflowedIndicator: getComponent(this, 'overflowedIndicator'),
role: props.role || 'menu',
class: className,
style: extraAttrs.style,
...onEvents,
};
// if (props.id) {
@ -366,6 +371,7 @@ const SubPopupMenu = {
domWrapProps.tabIndex = '0';
domWrapProps.onKeydown = this.onKeyDown;
}
delete domWrapProps.children;
return (
// ESLint is not smart enough to know that the type of `children` was checked.
/* eslint-disable */

View File

@ -37,5 +37,4 @@ export default {
itemIcon: PropTypes.any,
expandIcon: PropTypes.any,
overflowedIndicator: PropTypes.any,
children: PropTypes.any,
};

View File

@ -110,6 +110,10 @@ export const menuAllProps = [
'onTitleMouseleave',
'onTitleClick',
'__propsSymbol__',
'slots',
'ref',
'componentWillReceiveProps',
'isRootMenu',
];
// ref: https://github.com/ant-design/ant-design/issues/14007