Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inherit props #135

Merged
merged 16 commits into from
Apr 26, 2018
6 changes: 4 additions & 2 deletions src/MenuItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import KeyCode from 'rc-util/lib/KeyCode';
import classNames from 'classnames';
import scrollIntoView from 'dom-scroll-into-view';
import { connect } from 'mini-store';
import { noop } from './util';
import { noop, menuAllProps } from './util';

/* eslint react/no-is-mounted:0 */

Expand Down Expand Up @@ -139,7 +139,7 @@ export class MenuItem extends React.Component {
}

render() {
const props = this.props;
const props = { ...this.props };
const className = classNames(this.getPrefixCls(), props.className, {
[this.getActiveClassName()]: !props.disabled && props.active,
[this.getSelectedClassName()]: props.isSelected,
Expand Down Expand Up @@ -167,8 +167,10 @@ export class MenuItem extends React.Component {
if (props.mode === 'inline') {
style.paddingLeft = props.inlineIndent * props.level;
}
menuAllProps.forEach(key => delete props[key]);
Copy link
Member

@afc163 afc163 Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这样 MenuItem 上的 onClick、onMouseEnter、onMouseLeave 就没了,这几个可以有的。

MenuItemGroup 和 SubMenu 同理。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不对啊,,,这些事件不是在内部重写了吗???那还带上干啥???
有 { ...mouseEvent } 啊...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好像只有 group 上有用,,加着吧。。。

return (
<li
{...props}
{...attrs}
{...mouseEvent}
style={style}
Expand Down
13 changes: 8 additions & 5 deletions src/MenuItemGroup.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { menuAllProps } from './util';

class MenuItemGroup extends React.Component {
static propTypes = {
Expand All @@ -20,20 +21,22 @@ class MenuItemGroup extends React.Component {
}

render() {
const props = this.props;
const { ...props } = this.props;
const { className = '', rootPrefixCls } = props;
const titleClassName = `${rootPrefixCls}-item-group-title`;
const listClassName = `${rootPrefixCls}-item-group-list`;
const { title, children } = props;
menuAllProps.forEach(key => delete props[key]);
return (
<li className={`${className} ${rootPrefixCls}-item-group`}>
<li {...props} className={`${className} ${rootPrefixCls}-item-group`}>
<div
className={titleClassName}
title={typeof props.title === 'string' ? props.title : undefined}
title={typeof title === 'string' ? title : undefined}
>
{props.title}
{title}
</div>
<ul className={listClassName}>
{React.Children.map(props.children, this.renderInnerMenuItem)}
{React.Children.map(children, this.renderInnerMenuItem)}
</ul>
</li>
);
Expand Down
22 changes: 15 additions & 7 deletions src/SubMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
noop,
loopMenuItemRecursively,
getMenuIdFromSubMenuEventKey,
menuAllProps,
} from './util';

let guid = 0;
Expand Down Expand Up @@ -404,7 +405,7 @@ export class SubMenu extends React.Component {
}

render() {
const props = this.props;
const props = { ...this.props };
const isOpen = props.isOpen;
const prefixCls = this.getPrefixCls();
const isInlineMode = props.mode === 'inline';
Expand Down Expand Up @@ -469,9 +470,16 @@ export class SubMenu extends React.Component {
props.parentMenu.props.getPopupContainer : triggerNode => triggerNode.parentNode;
const popupPlacement = popupPlacementMap[props.mode];
const popupClassName = props.mode === 'inline' ? '' : props.popupClassName;

const {
disabled,
triggerSubMenuAction,
subMenuOpenDelay,
forceSubMenuRender,
subMenuCloseDelay,
} = props;
menuAllProps.forEach(key => delete props[key]);
return (
<li {...mouseEvents} className={className} style={props.style}>
<li {...props} {...mouseEvents} className={className}>
{isInlineMode && title}
{isInlineMode && children}
{!isInlineMode && (
Expand All @@ -483,11 +491,11 @@ export class SubMenu extends React.Component {
popupPlacement={popupPlacement}
popupVisible={isOpen}
popup={children}
action={props.disabled ? [] : [props.triggerSubMenuAction]}
mouseEnterDelay={props.subMenuOpenDelay}
mouseLeaveDelay={props.subMenuCloseDelay}
action={disabled ? [] : [triggerSubMenuAction]}
mouseEnterDelay={subMenuOpenDelay}
mouseLeaveDelay={subMenuCloseDelay}
onPopupVisibleChange={this.onPopupVisibleChange}
forceRender={props.forceSubMenuRender}
forceRender={forceSubMenuRender}
>
{title}
</Trigger>
Expand Down
21 changes: 13 additions & 8 deletions src/SubPopupMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { connect } from 'mini-store';
import KeyCode from 'rc-util/lib/KeyCode';
import createChainedFunction from 'rc-util/lib/createChainedFunction';
import classNames from 'classnames';
import { getKeyFromChildrenIndex, loopMenuItem, noop } from './util';
import { getKeyFromChildrenIndex, loopMenuItem, noop, menuAllProps } from './util';
import DOMWrap from './DOMWrap';

function allDisabled(arr) {
Expand Down Expand Up @@ -87,7 +87,7 @@ export class SubPopupMenu extends React.Component {
level: PropTypes.number,
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']),
triggerSubMenuAction: PropTypes.oneOf(['click', 'hover']),
inlineIndent: PropTypes.oneOfType(PropTypes.number, PropTypes.string),
inlineIndent: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
manualRef: PropTypes.func,
};

Expand Down Expand Up @@ -270,7 +270,10 @@ export class SubPopupMenu extends React.Component {
eventKey: key,
active: !childProps.disabled && isActive,
multiple: props.multiple,
onClick: this.onClick,
onClick: (e) => {
(childProps.onClick || noop)(e);
this.onClick(e);
},
onItemHover: this.onItemHover,
openTransitionName: this.getOpenTransitionName(),
openAnimation: props.openAnimation,
Expand Down Expand Up @@ -304,7 +307,7 @@ export class SubPopupMenu extends React.Component {
};

render() {
const props = this.props;
const { ...props } = this.props;
this.instanceArray = [];
const className = classNames(
props.prefixCls,
Expand All @@ -323,19 +326,21 @@ export class SubPopupMenu extends React.Component {
domProps.tabIndex = '0';
domProps.onKeyDown = this.onKeyDown;
}
const { prefixCls, eventKey, visible } = props;
menuAllProps.forEach(key => delete props[key]);
return (
// ESLint is not smart enough to know that the type of `children` was checked.
/* eslint-disable */
<DOMWrap
style={props.style}
{...props}
tag="ul"
hiddenClassName={`${props.prefixCls}-hidden`}
visible={props.visible}
hiddenClassName={`${prefixCls}-hidden`}
visible={visible}
{...domProps}
>
{React.Children.map(
props.children,
(c, i) => this.renderMenuItem(c, i, props.eventKey || '0-menu-'),
(c, i) => this.renderMenuItem(c, i, eventKey || '0-menu-'),
)}
</DOMWrap>
/*eslint-enable */
Expand Down
49 changes: 47 additions & 2 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export function loopMenuItemRecursively(children, keys, ret) {
if (c) {
const construct = c.type;
if (!construct
||
!(construct.isSubMenu || construct.isMenuItem || construct.isMenuItemGroup)
||
!(construct.isSubMenu || construct.isMenuItem || construct.isMenuItemGroup)
) {
return;
}
Expand All @@ -49,3 +49,48 @@ export function loopMenuItemRecursively(children, keys, ret) {
}
});
}

export const menuAllProps = [
'defaultSelectedKeys',
'selectedKeys',
'defaultOpenKeys',
'openKeys',
'mode',
'getPopupContainer',
'onSelect',
'onDeselect',
'onDestroy',
'openTransitionName',
'openAnimation',
'subMenuOpenDelay',
'subMenuCloseDelay',
'forceSubMenuRender',
'triggerSubMenuAction',
'level',
'selectable',
'multiple',
'onOpenChange',
'visible',
'focusable',
'defaultActiveFirst',
'prefixCls',
'inlineIndent',
'parentMenu',
'title',
'rootPrefixCls',
'eventKey',
'active',
'onItemHover',
'onTitleMouseEnter',
'onTitleMouseLeave',
'onTitleClick',
'isOpen',
'renderMenuItem',
'manualRef',
'subMenuKey',
'disabled',
'index',
'isSelected',
'store',
'activeKey',
];
33 changes: 32 additions & 1 deletion tests/MenuItem.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import KeyCode from 'rc-util/lib/KeyCode';
import Menu, { MenuItem } from '../src';
import Menu, { MenuItem, MenuItemGroup, SubMenu } from '../src';

import { MenuItem as NakedMenuItem } from '../src/MenuItem';

Expand Down Expand Up @@ -81,4 +81,35 @@ describe('MenuItem', () => {
expect(onMouseLeave).toHaveBeenCalledWith({ key, domEvent });
});
});

describe('rest props', () => {
it('can render all props to sub component', () => {
const onClick = jest.fn();
const restProps = {
onClick,
'data-whatever': 'whatever',
title: 'title',
className: 'className',
style: { fontSize: 20 },
};
const wrapper = mount(
<Menu mode="inline" activeKey="1">
<MenuItem key="1" {...restProps}>1</MenuItem>
<SubMenu {...restProps}>
<MenuItem key="2" {...restProps}>3</MenuItem>
</SubMenu>
<MenuItemGroup {...restProps}>
<MenuItem key="3" {...restProps}>4</MenuItem>
</MenuItemGroup>
</Menu>
);
expect(wrapper.render()).toMatchSnapshot();
wrapper.find('MenuItem').at(0).simulate('click');
expect(onClick).toHaveBeenCalledTimes(1);
wrapper.find('SubMenu').at(0).simulate('click');
expect(onClick).toHaveBeenCalledTimes(2);
wrapper.find('MenuItemGroup').at(0).simulate('click');
expect(onClick).toHaveBeenCalledTimes(3);
});
});
});
67 changes: 67 additions & 0 deletions tests/__snapshots__/MenuItem.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MenuItem rest props can render all props to sub component 1`] = `
<ul
aria-activedescendant=""
class="rc-menu rc-menu-root rc-menu-inline"
role="menu"
tabindex="0"
>
<li
aria-selected="false"
class="rc-menu-item className rc-menu-item-active"
data-whatever="whatever"
role="menuitem"
style="font-size: 20px; padding-left: 24px;"
title="title"
>
1
</li>
<li
class="rc-menu-submenu rc-menu-submenu-inline className"
data-whatever="whatever"
style="font-size: 20px;"
>
<div
aria-expanded="false"
aria-haspopup="true"
aria-owns="item_1$Menu"
class="rc-menu-submenu-title"
style="padding-left: 24px;"
title="title"
>
title
<i
class="rc-menu-submenu-arrow"
/>
</div>
<div />
</li>
<li
class="className rc-menu-item-group"
data-whatever="whatever"
style="font-size: 20px;"
>
<div
class="rc-menu-item-group-title"
title="title"
>
title
</div>
<ul
class="rc-menu-item-group-list"
>
<li
aria-selected="false"
class="rc-menu-item className"
data-whatever="whatever"
role="menuitem"
style="font-size: 20px; padding-left: 24px;"
title="title"
>
4
</li>
</ul>
</li>
</ul>
`;