diff --git a/docs/demo/modes.md b/docs/demo/modes.md new file mode 100644 index 00000000..ff76f07a --- /dev/null +++ b/docs/demo/modes.md @@ -0,0 +1,3 @@ +## modes + + diff --git a/docs/examples/modes.tsx b/docs/examples/modes.tsx new file mode 100644 index 00000000..730cc0a4 --- /dev/null +++ b/docs/examples/modes.tsx @@ -0,0 +1,49 @@ +/* eslint no-console:0 */ + +import React from 'react'; +import Menu, { SubMenu, Item as MenuItem } from 'rc-menu'; +import { MenuMode } from '@/interface'; +import '../../assets/index.less'; + +export default () => { + + const [mode, setMode] = React.useState("horizontal") + + const [width, setWidth] = React.useState(400) + + function handleSelect(info) { + console.log('selected ', info); + } + + function handleClick(info) { + console.log('click ', info); + } + + return ( +
+ + + setWidth(Number(e.target.value))} /> + +
+ + item 1 + disabled + item 3 + item 4 + + item 5-1 + item 5-2 + + item 6 + +
+
+ ); +}; diff --git a/src/Menu.tsx b/src/Menu.tsx index 8eeeed12..b24e276a 100644 --- a/src/Menu.tsx +++ b/src/Menu.tsx @@ -111,6 +111,7 @@ class Menu extends React.Component { selectedKeys, openKeys, activeKey: { '0-menu-': getActiveKey(props, props.activeKey) }, + focused: false }); this.state = { @@ -123,6 +124,8 @@ class Menu extends React.Component { isRootMenu: boolean; + blurTimeout: number; + store: MiniStore; innerMenu: typeof SubPopupMenu; @@ -344,6 +347,21 @@ class Menu extends React.Component { } }; + onFocus =() => { + clearTimeout(this.blurTimeout) + this.store.setState({ + focused: true + }); + } + + onBlur =() => { + this.blurTimeout = setTimeout(() => { + this.store.setState({ + focused: false + }); + }) + } + onTransitionEnd = (e: React.TransitionEvent) => { // when inlineCollapsed menu width animation finished // https://github.com/ant-design/ant-design/issues/12864 @@ -418,6 +436,8 @@ class Menu extends React.Component { onSelect: this.onSelect, onMouseEnter: this.onMouseEnter, onTransitionEnd: this.onTransitionEnd, + onFocus: this.onFocus, + onBlur: this.onBlur, parentMenu: this, motion: getMotion(this.props, this.state, mode), }; diff --git a/src/MenuItem.tsx b/src/MenuItem.tsx index 0e96386f..c9d446b4 100644 --- a/src/MenuItem.tsx +++ b/src/MenuItem.tsx @@ -67,10 +67,22 @@ export class MenuItem extends React.Component { componentDidMount() { // invoke customized ref to expose component to mixin this.callRef(); + if (this.props.active && this.props.focused) { + setTimeout(() => { + this.node.focus() + console.log("focus menuitem mount"); + }); + } } componentDidUpdate() { this.callRef(); + if (this.props.active && this.props.focused) { + setTimeout(() => { + this.node.focus() + console.log("focus menuitem"); + }); + } } componentWillUnmount() { @@ -240,6 +252,7 @@ export class MenuItem extends React.Component { {...mouseEvent} style={style} ref={this.saveNode} + tabIndex={this.props.active ? 0 : -1} > {props.children} {icon} @@ -249,9 +262,10 @@ export class MenuItem extends React.Component { } const connected = connect( - ({ activeKey, selectedKeys }, { eventKey, subMenuKey }) => ({ + ({ activeKey, selectedKeys, focused }, { eventKey, subMenuKey }) => ({ active: activeKey[subMenuKey] === eventKey, isSelected: selectedKeys.indexOf(eventKey) !== -1, + focused }), )(MenuItem); diff --git a/src/SubMenu.tsx b/src/SubMenu.tsx index b6a89114..d27fad6e 100644 --- a/src/SubMenu.tsx +++ b/src/SubMenu.tsx @@ -197,6 +197,10 @@ export class SubMenu extends React.Component { manualRef(this); } + if (this.props.active && this.props.focused) { + this.node?.focus() + } + if (mode !== 'horizontal' || !parentMenu?.isRootMenu || !isOpen) { return; } @@ -620,9 +624,6 @@ export class SubMenu extends React.Component { role="button" {...titleMouseEvents} {...titleClickEvents} - aria-expanded={visible} - {...ariaOwns} - aria-haspopup="true" title={typeof props.title === 'string' ? props.title : undefined} > {props.title} @@ -668,8 +669,13 @@ export class SubMenu extends React.Component {
  • this.node = elem} + aria-expanded={visible} + aria-haspopup="true" > { } const connected = connect( - ({ openKeys, activeKey, selectedKeys }, { eventKey, subMenuKey }) => ({ + ({ openKeys, activeKey, selectedKeys, focused }, { eventKey, subMenuKey }) => ({ isOpen: openKeys.indexOf(eventKey) > -1, active: activeKey[subMenuKey] === eventKey, selectedKeys, + focused }), )(SubMenu as any); diff --git a/src/SubPopupMenu.tsx b/src/SubPopupMenu.tsx index 14a35170..eda2d4a4 100644 --- a/src/SubPopupMenu.tsx +++ b/src/SubPopupMenu.tsx @@ -327,7 +327,7 @@ export class SubPopupMenu extends React.Component { do { const child = children[i]; - if (!child || child.props.disabled) { + if (!child || child.props.disabled || child.props.style?.display === 'none') { i = (i + 1) % len; } else { return child; @@ -435,7 +435,6 @@ export class SubPopupMenu extends React.Component { domProps.id = props.id; } if (props.focusable) { - domProps.tabIndex = 0; domProps.onKeyDown = this.onKeyDown as any; } const {