diff --git a/common/changes/office-ui-fabric-react/users-demarcey-anchorMenuItems_2018-03-06-21-28.json b/common/changes/office-ui-fabric-react/users-demarcey-anchorMenuItems_2018-03-06-21-28.json new file mode 100644 index 00000000000000..93a460742b19cb --- /dev/null +++ b/common/changes/office-ui-fabric-react/users-demarcey-anchorMenuItems_2018-03-06-21-28.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "ContextualMenu: Allow anchor menu items to have sub menus. Added prop for sub menu hover delay.", + "type": "patch" + } + ], + "packageName": "office-ui-fabric-react", + "email": "demarcey@microsoft.com" +} diff --git a/packages/office-ui-fabric-react/src/components/ContextualMenu/ContextualMenu.tsx b/packages/office-ui-fabric-react/src/components/ContextualMenu/ContextualMenu.tsx index 7ee3a403044c85..855c6e3f44f971 100644 --- a/packages/office-ui-fabric-react/src/components/ContextualMenu/ContextualMenu.tsx +++ b/packages/office-ui-fabric-react/src/components/ContextualMenu/ContextualMenu.tsx @@ -470,6 +470,7 @@ export class ContextualMenu extends BaseComponent ) { const targetElement = ev.currentTarget as HTMLElement; + const { subMenuHoverDelay: timeoutDuration = this._navigationIdleDelay } = this.props; if (item.key === this.state.expandedMenuItemKey) { return; @@ -812,12 +819,12 @@ export class ContextualMenu extends BaseComponent { targetElement.focus(); this._onItemSubMenuExpand(item, targetElement); - }, this._navigationIdleDelay); + }, timeoutDuration); } else { this._enterTimerId = this._async.setTimeout(() => { this._onSubMenuDismiss(ev); targetElement.focus(); - }, this._navigationIdleDelay); + }, timeoutDuration); } } @@ -853,13 +860,14 @@ export class ContextualMenu extends BaseComponent, IWith /** * Click handler which is invoked if onClick is not passed for individual contextual - * menu item + * menu item. + * Returning true will dismiss the menu even if ev.preventDefault() was called. */ - onItemClick?: (ev?: React.MouseEvent, item?: IContextualMenuItem) => void; + onItemClick?: (ev?: React.MouseEvent, item?: IContextualMenuItem) => boolean | void; /** * CSS class to apply to the context menu. @@ -221,6 +222,11 @@ export interface IContextualMenuProps extends React.Props, IWith /** Method to call when trying to render a submenu. */ onRenderSubMenu?: IRenderFunction; + /** + * Delay (in milliseconds) to wait before expanding / dismissing a submenu on mouseEnter or mouseLeave + */ + subMenuHoverDelay?: number; + /** * Method to override the render of the individual menu items * @default ContextualMenuItem @@ -320,9 +326,10 @@ export interface IContextualMenuItem { data?: any; /** - * Callback issued when the menu item is invoked. If ev.preventDefault() is called in onClick, click will not close menu + * Callback issued when the menu item is invoked. If ev.preventDefault() is called in onClick, click will not close menu. + * Returning true will dismiss the menu even if ev.preventDefault() was called. */ - onClick?: (ev?: React.MouseEvent, item?: IContextualMenuItem) => void; + onClick?: (ev?: React.MouseEvent, item?: IContextualMenuItem) => boolean | void; /** * An optional URL to navigate to upon selection diff --git a/packages/office-ui-fabric-react/src/components/ContextualMenu/examples/ContextualMenu.Submenu.Example.tsx b/packages/office-ui-fabric-react/src/components/ContextualMenu/examples/ContextualMenu.Submenu.Example.tsx index 5fc9baa0101fae..1a3171c052837e 100644 --- a/packages/office-ui-fabric-react/src/components/ContextualMenu/examples/ContextualMenu.Submenu.Example.tsx +++ b/packages/office-ui-fabric-react/src/components/ContextualMenu/examples/ContextualMenu.Submenu.Example.tsx @@ -1,17 +1,32 @@ import * as React from 'react'; import { DefaultButton } from 'office-ui-fabric-react/lib/Button'; +import { TextField } from 'office-ui-fabric-react/lib/TextField'; import './ContextualMenuExample.scss'; -export class ContextualMenuSubmenuExample extends React.Component { +export interface IContextualMenuSubmenuExampleState { + hoverDelay: number; +} + +export class ContextualMenuSubmenuExample extends React.Component { + + constructor(props: any) { + super(props); + + this.state = { + hoverDelay: 250 + }; + } public render() { return (
+ { } ], }, + href: 'https://bing.com', name: 'New' }, { @@ -72,4 +88,10 @@ export class ContextualMenuSubmenuExample extends React.Component {
); } + + private _onHoverDelayChanged = (newValue: string) => { + this.setState({ + hoverDelay: +newValue + }); + } }