Skip to content

Commit

Permalink
Merge pull request #132 from react-component/adding-test
Browse files Browse the repository at this point in the history
chore: improve coverage and one minor bug fix
  • Loading branch information
picodoth authored Apr 18, 2018
2 parents 92e64ae + dabb945 commit 6eb19f0
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/DOMWrap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ const DOMWrap = createReactClass({
getDefaultProps() {
return {
tag: 'div',
className: '',
};
},

render() {
const props = { ...this.props };
if (!props.visible) {
props.className = props.className || '';
props.className += ` ${props.hiddenClassName}`;
}
const Tag = props.tag;
Expand Down
20 changes: 3 additions & 17 deletions src/Menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,8 @@ const Menu = createReactClass({
return transitionName;
},

isInlineMode() {
return this.props.mode === 'inline';
},

lastOpenSubMenu() {
let lastOpen = [];
const { openKeys } = this.store.getState();
if (openKeys.length) {
lastOpen = this.getFlatInstanceArray().filter((c) => {
return c && openKeys.indexOf(c.props.eventKey) !== -1;
});
}
return lastOpen[0];
},

renderMenuItem(c, i, subIndex, subMenuKey) {
renderMenuItem(c, i, subMenuKey) {
/* istanbul ignore if */
if (!c) {
return null;
}
Expand All @@ -201,7 +187,7 @@ const Menu = createReactClass({
triggerSubMenuAction: this.props.triggerSubMenuAction,
subMenuKey,
};
return this.renderCommonMenuItem(c, i, subIndex, extraProps);
return this.renderCommonMenuItem(c, i, extraProps);
},

render() {
Expand Down
2 changes: 1 addition & 1 deletion src/MenuItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { noop } from './util';

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

const MenuItem = createReactClass({
export const MenuItem = createReactClass({
displayName: 'MenuItem',

propTypes: {
Expand Down
4 changes: 2 additions & 2 deletions src/MenuItemGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const MenuItemGroup = createReactClass({
return { disabled: true };
},

renderInnerMenuItem(item, subIndex) {
renderInnerMenuItem(item) {
const { renderMenuItem, index } = this.props;
return renderMenuItem(item, index, subIndex, this.props.subMenuKey);
return renderMenuItem(item, index, this.props.subMenuKey);
},

render() {
Expand Down
37 changes: 7 additions & 30 deletions src/MenuMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,9 @@ export function getActiveKey(props, originalActiveKey) {
return activeKey;
}

function saveRef(index, subIndex, c) {
function saveRef(index, c) {
if (c) {
if (subIndex !== undefined) {
this.instanceArray[index] = this.instanceArray[index] || [];
this.instanceArray[index][subIndex] = c;
} else {
this.instanceArray[index] = c;
}
this.instanceArray[index] = c;
}
}

Expand Down Expand Up @@ -106,6 +101,7 @@ const MenuMixin = {
},

// all keyboard events callbacks run from here at first
// FIXME: callback is currently used by rc-select, should be more explicit
onKeyDown(e, callback) {
const keyCode = e.keyCode;
let handled;
Expand All @@ -129,10 +125,6 @@ const MenuMixin = {
callback(activeItem);
}

return 1;
} else if (activeItem === undefined) {
e.preventDefault();
updateActiveKey(this.getStore(), this.getEventKey(), null);
return 1;
}
},
Expand All @@ -154,25 +146,10 @@ const MenuMixin = {
},

getFlatInstanceArray() {
let instanceArray = this.instanceArray;
const hasInnerArray = instanceArray.some((a) => {
return Array.isArray(a);
});
if (hasInnerArray) {
instanceArray = [];
this.instanceArray.forEach((a) => {
if (Array.isArray(a)) {
instanceArray.push.apply(instanceArray, a);
} else {
instanceArray.push(a);
}
});
this.instanceArray = instanceArray;
}
return instanceArray;
return this.instanceArray;
},

renderCommonMenuItem(child, i, subIndex, extraProps) {
renderCommonMenuItem(child, i, extraProps) {
const state = this.getStore().getState();
const props = this.props;
const key = getKeyFromChildrenIndex(child, props.eventKey, i);
Expand All @@ -188,7 +165,7 @@ const MenuMixin = {
parentMenu: this,
// customized ref function, need to be invoked manually in child's componentDidMount
manualRef: childProps.disabled ? undefined :
createChainedFunction(child.ref, saveRef.bind(this, i, subIndex)),
createChainedFunction(child.ref, saveRef.bind(this, i)),
eventKey: key,
active: !childProps.disabled && isActive,
multiple: props.multiple,
Expand Down Expand Up @@ -241,7 +218,7 @@ const MenuMixin = {
>
{React.Children.map(
props.children,
(c, i, subIndex) => this.renderMenuItem(c, i, subIndex, props.eventKey || '0-menu-'),
(c, i) => this.renderMenuItem(c, i, props.eventKey || '0-menu-'),
)}
</DOMWrap>
/*eslint-enable */
Expand Down
36 changes: 23 additions & 13 deletions src/SubMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SubPopupMenu from './SubPopupMenu';
import placements from './placements';
import {
noop,
loopMenuItemRecusively,
loopMenuItemRecursively,
getMenuIdFromSubMenuEventKey,
} from './util';

Expand Down Expand Up @@ -96,6 +96,20 @@ const SubMenu = createReactClass({
this.componentDidUpdate();
},

adjustWidth() {
/* istanbul ignore if */
if (!this.subMenuTitle || !this.menuInstance) {
return;
}
const popupMenu = ReactDOM.findDOMNode(this.menuInstance);
if (popupMenu.offsetWidth >= this.subMenuTitle.offsetWidth) {
return;
}

/* istanbul ignore next */
popupMenu.style.minWidth = `${this.subMenuTitle.offsetWidth}px`;
},

componentDidUpdate() {
const { mode, parentMenu, manualRef } = this.props;

Expand All @@ -108,26 +122,21 @@ const SubMenu = createReactClass({
return;
}

this.minWidthTimeout = setTimeout(() => {
if (!this.subMenuTitle || !this.menuInstance) {
return;
}
const popupMenu = ReactDOM.findDOMNode(this.menuInstance);
if (popupMenu.offsetWidth >= this.subMenuTitle.offsetWidth) {
return;
}
popupMenu.style.minWidth = `${this.subMenuTitle.offsetWidth}px`;
}, 0);
this.minWidthTimeout = setTimeout(() => this.adjustWidth(), 0);
},

componentWillUnmount() {
const { onDestroy, eventKey } = this.props;
if (onDestroy) {
onDestroy(eventKey);
}

/* istanbul ignore if */
if (this.minWidthTimeout) {
clearTimeout(this.minWidthTimeout);
}

/* istanbul ignore if */
if (this.mouseenterTimeout) {
clearTimeout(this.mouseenterTimeout);
}
Expand Down Expand Up @@ -314,7 +323,7 @@ const SubMenu = createReactClass({

isChildrenSelected() {
const ret = { find: false };
loopMenuItemRecusively(this.props.children, this.props.selectedKeys, ret);
loopMenuItemRecursively(this.props.children, this.props.selectedKeys, ret);
return ret.find;
},

Expand Down Expand Up @@ -454,7 +463,8 @@ const SubMenu = createReactClass({

SubMenu.isSubMenu = 1;

export default connect(({ openKeys, activeKey }, { eventKey, subMenuKey }) => ({
export default connect(({ openKeys, activeKey, selectedKeys }, { eventKey, subMenuKey }) => ({
isOpen: openKeys.indexOf(eventKey) > -1,
active: activeKey[subMenuKey] === eventKey,
selectedKeys,
}))(SubMenu);
18 changes: 11 additions & 7 deletions src/SubPopupMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ const SubPopupMenu = createReactClass({

componentDidMount() {
// invoke customized ref to expose component to mixin
if (this.props.manualRef) {
this.props.manualRef(this);
}
this.props.manualRef(this);
},

onDeselect(selectInfo) {
Expand All @@ -59,14 +57,16 @@ const SubPopupMenu = createReactClass({
},

onDestroy(key) {
/* istanbul ignore next */
this.props.onDestroy(key);
},

getOpenTransitionName() {
return this.props.openTransitionName;
},

renderMenuItem(c, i, subIndex, subMenuKey) {
renderMenuItem(c, i, subMenuKey) {
/* istanbul ignore next */
if (!c) {
return null;
}
Expand All @@ -77,24 +77,28 @@ const SubPopupMenu = createReactClass({
triggerSubMenuAction: props.triggerSubMenuAction,
subMenuKey,
};
return this.renderCommonMenuItem(c, i, subIndex, extraProps);
return this.renderCommonMenuItem(c, i, extraProps);
},

render() {
const props = { ...this.props };

const haveRendered = this.haveRendered;
this.haveRendered = true;

this.haveOpened = this.haveOpened || props.visible || props.forceSubMenuRender;
// never rendered not planning to, don't render
if (!this.haveOpened) {
return null;
}

const transitionAppear = !(!haveRendered && props.visible && props.mode === 'inline');
// 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
const transitionAppear = haveRendered || !props.visible || !props.mode === 'inline';

props.className += ` ${props.prefixCls}-sub`;
const animProps = {};

if (props.openTransitionName) {
animProps.transitionName = props.openTransitionName;
} else if (typeof props.openAnimation === 'object') {
Expand Down
15 changes: 8 additions & 7 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ export function loopMenuItem(children, cb) {
});
}

export function loopMenuItemRecusively(children, keys, ret) {
export function loopMenuItemRecursively(children, keys, ret) {
/* istanbul ignore if */
if (!children || ret.find) {
return;
}
React.Children.forEach(children, (c) => {
if (ret.find) {
return;
}
if (c) {
const construt = c.type;
if (!construt || !(construt.isSubMenu || construt.isMenuItem || construt.isMenuItemGroup)) {
const construct = c.type;
if (!construct
||
!(construct.isSubMenu || construct.isMenuItem || construct.isMenuItemGroup)
) {
return;
}
if (keys.indexOf(c.key) !== -1) {
ret.find = true;
} else if (c.props.children) {
loopMenuItemRecusively(c.props.children, keys, ret);
loopMenuItemRecursively(c.props.children, keys, ret);
}
}
});
Expand Down
3 changes: 1 addition & 2 deletions tests/Menu.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ describe('Menu', () => {

['vertical', 'horizontal', 'inline'].forEach((mode) => {
it(`renders ${mode} menu correctly`, () => {
const wrapper = render(createMenu({ [mode]: true }));
const wrapper = render(createMenu({ mode }));
expect(renderToJson(wrapper)).toMatchSnapshot();
});
});
});


it('set activeKey', () => {
const wrapper = mount(
<Menu activeKey="1">
Expand Down
Loading

0 comments on commit 6eb19f0

Please sign in to comment.