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

Menu#4640 #4722

Merged
merged 10 commits into from
Jan 25, 2024
92 changes: 66 additions & 26 deletions components/menu/__tests__/index-spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Expand Down Expand Up @@ -105,10 +105,7 @@ describe('Menu', () => {
</SubMenu>
</Menu>
);
const innerHTML = wrapper
.find('.next-menu')
.at(0)
.instance().innerHTML;
const innerHTML = wrapper.find('.next-menu').at(0).instance().innerHTML;
assert(innerHTML.match('test-group-string'));
assert(innerHTML.match('test-submenu-string'));
});
Expand Down Expand Up @@ -203,7 +200,11 @@ describe('Menu', () => {

it('paddingleft should only be related to inline mode', () => {
wrapper = mount(
<Menu direction="hoz" mode="popup" defaultOpenKeys={['sub', 'sub1', 'sub2', 'suba', 'suba1', 'suba2']}>
<Menu
direction="hoz"
mode="popup"
defaultOpenKeys={['sub', 'sub1', 'sub2', 'suba', 'suba1', 'suba2']}
>
<SubMenu label="submenu1" key="sub">
<Item>1</Item>
<SubMenu label="submenu2" mode="inline" key="sub1">
Expand All @@ -224,14 +225,8 @@ describe('Menu', () => {
</SubMenu>
</Menu>
);
const item1Level = wrapper
.find('#sub2-item')
.at(0)
.props().inlineLevel;
const item2Level = wrapper
.find('#suba2-item')
.at(0)
.props().inlineLevel;
const item1Level = wrapper.find('#sub2-item').at(0).props().inlineLevel;
const item2Level = wrapper.find('#suba2-item').at(0).props().inlineLevel;

assert(item1Level === 3);
assert(item2Level === 2);
Expand Down Expand Up @@ -506,7 +501,12 @@ describe('Menu', () => {
};

wrapper = mount(
<Menu selectMode="multiple" selectedKeys={['0']} defaultOpenKeys={['sub-menu']} onSelect={handleSelect}>
<Menu
selectMode="multiple"
selectedKeys={['0']}
defaultOpenKeys={['sub-menu']}
onSelect={handleSelect}
>
<Item key="0">0</Item>
<Item key="1">1</Item>
<SubMenu key="sub-menu" label="Sub menu">
Expand All @@ -516,10 +516,7 @@ describe('Menu', () => {
</Menu>
);

wrapper
.find('.next-menu-sub-menu .next-menu-item')
.at(0)
.simulate('click');
wrapper.find('.next-menu-sub-menu .next-menu-item').at(0).simulate('click');
assert(called);
assert.deepEqual(selectedKeys, ['0', '2']);
assert(item.props._key === '2');
Expand Down Expand Up @@ -578,10 +575,7 @@ describe('Menu', () => {
</Menu>
);

wrapper
.find('.next-menu-sub-menu .next-menu-item')
.at(0)
.simulate('click');
wrapper.find('.next-menu-sub-menu .next-menu-item').at(0).simulate('click');
assertUnselected(wrapper.find('.next-menu-sub-menu .next-menu-item').at(0));
});

Expand Down Expand Up @@ -922,7 +916,9 @@ describe('Menu', () => {
try {
assert(menu.querySelectorAll('li.next-menu-more').length === 2);

const indicator = menu.querySelectorAll('li.next-menu-more')[0].querySelector('.next-menu-item-inner');
const indicator = menu
.querySelectorAll('li.next-menu-more')[0]
.querySelector('.next-menu-item-inner');
indicator.click();
const overlay = document.querySelector('.next-overlay-wrapper');

Expand Down Expand Up @@ -978,12 +974,54 @@ describe('Menu', () => {
document.body.removeChild(div);
});

it('should show renderMore when hozInLine & async load more items ', done => {
const div = document.createElement('div');
document.body.appendChild(div);

const items = [];
for (let i = 0; i < 50; i++) {
items.push(i);
}
function App() {
const [categoryList, setCategoryList] = useState([]);
useEffect(() => {
setCategoryList(items);
}, []);

return (
<Menu hozInLine direction="hoz" triggerType="hover" mode="popup" popupAutoWidth>
{categoryList.map((index, v) => (
<SubMenu label="Sub Nav" key={index}>
<Item key="sub-12">Sub option 1</Item>
<Item key="sub-22">Sub option 2</Item>
</SubMenu>
))}
</Menu>
);
}
ReactDOM.render(<App />, div);
const menu = document.querySelector('.next-menu');
assert(menu.querySelectorAll('li.next-menu-item').length === 52);
assert(menu.querySelectorAll('li.next-menu-item.next-menu-more').length === 2);
assert(menu.querySelectorAll('li.menuitem-overflowed').length > 1);
ReactDOM.unmountComponentAtNode(div);
document.body.removeChild(div);
done();
});

it('should support hozInLine with header&footer in hoz', () => {
const div = document.createElement('div');
document.body.appendChild(div);

ReactDOM.render(
<Menu direction="hoz" style={{ width: 300 }} mode="popup" header="header" footer="footer" hozInLine>
<Menu
direction="hoz"
style={{ width: 300 }}
mode="popup"
header="header"
footer="footer"
hozInLine
>
<Item key="0" style={{ width: 100 }}>
0
</Item>
Expand All @@ -1006,7 +1044,9 @@ describe('Menu', () => {
const menu = document.querySelector('.next-menu.next-hoz');
assert(menu.querySelectorAll('li.next-menu-more').length === 2);

const indicator = menu.querySelectorAll('li.next-menu-more')[0].querySelector('.next-menu-item-inner');
const indicator = menu
.querySelectorAll('li.next-menu-more')[0]
.querySelector('.next-menu-item-inner');
indicator.click();
const overlay = document.querySelector('.next-overlay-wrapper');

Expand Down
72 changes: 58 additions & 14 deletions components/menu/view/menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import { polyfill } from 'react-lifecycles-compat';
import SubMenu from './sub-menu';
import ConfigProvider from '../../config-provider';
import { func, obj, dom, events, KEYCODE } from '../../util';
import { getWidth, normalizeToArray, isSibling, isAncestor, isAvailablePos, getFirstAvaliablelChildKey } from './util';
import {
getWidth,
normalizeToArray,
isSibling,
isAncestor,
isAvailablePos,
getFirstAvaliablelChildKey,
} from './util';

const { bindCtx } = func;
const { pickOthers, isNil } = obj;
Expand Down Expand Up @@ -83,7 +90,15 @@ const addIndicators = ({ children, lastVisibleIndex, prefix, renderMore }) => {
return arr;
};

const getNewChildren = ({ children, root, mode, lastVisibleIndex, hozInLine, prefix, renderMore }) => {
const getNewChildren = ({
children,
root,
mode,
lastVisibleIndex,
hozInLine,
prefix,
renderMore,
}) => {
const k2n = {};
const p2n = {};

Expand Down Expand Up @@ -149,7 +164,11 @@ const getNewChildren = ({ children, root, mode, lastVisibleIndex, hozInLine, pre

switch (child.type.menuChildType) {
case 'submenu':
newChild = cloneElement(child, props, loop(child.props.children, pos, undefined, childLevel));
newChild = cloneElement(
child,
props,
loop(child.props.children, pos, undefined, childLevel)
);
break;
case 'group':
newChild = cloneElement(
Expand Down Expand Up @@ -420,7 +439,11 @@ class Menu extends Component {
tabbableKey,
openKeys: this.getInitOpenKeys(props, _k2n, _p2n),
selectedKeys: normalizeToArray(selectedKeys || defaultSelectedKeys),
focusedKey: !isNil(this.props.focusedKey) ? focusedKey : focusable && autoFocus ? tabbableKey : null,
focusedKey: !isNil(this.props.focusedKey)
? focusedKey
: focusable && autoFocus
? tabbableKey
: null,
};

bindCtx(this, [
Expand All @@ -441,7 +464,11 @@ class Menu extends Component {
if ('openKeys' in nextProps) {
state.openKeys = normalizeToArray(nextProps.openKeys);
// 从展开状态变为收起状态,才需要清空openKeys
} else if ('mode' in nextProps && nextProps.mode === 'popup' && prevState.lastMode === 'inline') {
} else if (
'mode' in nextProps &&
nextProps.mode === 'popup' &&
prevState.lastMode === 'inline'
) {
state.openKeys = [];
}

Expand Down Expand Up @@ -479,7 +506,6 @@ class Menu extends Component {

componentDidMount() {
this.menuNode = findDOMNode(this);

this.adjustChildrenWidth();

if (this.props.hozInLine) {
Expand All @@ -488,7 +514,11 @@ class Menu extends Component {
}

componentDidUpdate(prevProps, prevState) {
if (prevState.lastVisibleIndex !== this.state.lastVisibleIndex) {
if (
prevState.lastVisibleIndex !== this.state.lastVisibleIndex ||
React.Children.toArray(this.props.children).length !==
React.Children.toArray(prevProps.children).length
) {
this.adjustChildrenWidth();
}
}
Expand All @@ -512,7 +542,8 @@ class Menu extends Component {

if (header || footer) {
children = this.menuContent.children;
spaceWidth = getWidth(this.menuNode) - getWidth(this.menuHeader) - getWidth(this.menuFooter);
spaceWidth =
getWidth(this.menuNode) - getWidth(this.menuHeader) - getWidth(this.menuFooter);
} else {
children = this.menuNode.children;
spaceWidth = getWidth(this.menuNode);
Expand Down Expand Up @@ -556,7 +587,10 @@ class Menu extends Component {

this.menuItemSizes.forEach((liWidth, i) => {
currentSumWidth += liWidth;
if ((i >= totalLen - 1 && currentSumWidth <= spaceWidth) || currentSumWidth + moreWidth <= spaceWidth) {
if (
(i >= totalLen - 1 && currentSumWidth <= spaceWidth) ||
currentSumWidth + moreWidth <= spaceWidth
) {
lastVisibleIndex++;
}
});
Expand Down Expand Up @@ -614,7 +648,9 @@ class Menu extends Component {
if (open && index === -1) {
if (mode === 'inline') {
if (openMode === 'single') {
newOpenKeys = openKeys.filter(k => _k2n[k] && !isSibling(_k2n[key].pos, _k2n[k].pos));
newOpenKeys = openKeys.filter(
k => _k2n[k] && !isSibling(_k2n[key].pos, _k2n[k].pos)
);
newOpenKeys.push(key);
} else {
newOpenKeys = openKeys.concat(key);
Expand Down Expand Up @@ -735,7 +771,9 @@ class Menu extends Component {

this.props.onOpen([], {
key: this.state.openKeys.sort(
(prevKey, nextKey) => _k2n[nextKey].pos.split('-').length - _k2n[prevKey].pos.split('-').length
(prevKey, nextKey) =>
_k2n[nextKey].pos.split('-').length -
_k2n[prevKey].pos.split('-').length
)[0],
open: false,
});
Expand Down Expand Up @@ -769,9 +807,15 @@ class Menu extends Component {

handleItemKeyDown(key, type, item, e) {
if (
[KEYCODE.UP, KEYCODE.DOWN, KEYCODE.RIGHT, KEYCODE.LEFT, KEYCODE.ENTER, KEYCODE.ESC, KEYCODE.SPACE].indexOf(
e.keyCode
) > -1
[
KEYCODE.UP,
KEYCODE.DOWN,
KEYCODE.RIGHT,
KEYCODE.LEFT,
KEYCODE.ENTER,
KEYCODE.ESC,
KEYCODE.SPACE,
].indexOf(e.keyCode) > -1
) {
e.preventDefault();
e.stopPropagation();
Expand Down
Loading