Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "ContextualMenu: SplitButtons in ContextualMenus are incorrectly using the menuLauncher portion of the splitButton for the tagrate when the menuLauncher portion is activated. This can lead to weird overhangs of the parent menu even if directionalHintFixed is not true (e.g. it will overlap the primary portion of the splitButton and potentially other items in the parent menu)",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "[email protected]"
}
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
private _renderSplitIconButton(item: IContextualMenuItem, classNames: IMenuItemClassNames, index: number) {
const { contextualMenuItemAs: ChildrenRenderer = ContextualMenuItem } = this.props;
const itemProps = {
onClick: this._onItemClick.bind(this, item),
onClick: this._onSplitItemClick.bind(this, item),
disabled: this._isItemDisabled(item),
className: classNames.splitMenu,
subMenuProps: item.subMenuProps,
Expand Down Expand Up @@ -810,7 +810,7 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
* As part of updating focus, This function will also update
* the expand/collapse state accordingly.
*/
private _updateFocusOnMouseEvent(item: any, ev: React.MouseEvent<HTMLElement>) {
private _updateFocusOnMouseEvent(item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) {
const targetElement = ev.currentTarget as HTMLElement;
const { subMenuHoverDelay: timeoutDuration = this._navigationIdleDelay } = this.props;

Expand All @@ -833,8 +833,10 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
if (hasSubmenu(item)) {
this._enterTimerId = this._async.setTimeout(() => {
targetElement.focus();
this._onItemSubMenuExpand(item, targetElement);
}, timeoutDuration);
const splitButtonContainer = this._splitButtonContainers.get(item.key);
this._onItemSubMenuExpand(item,
((item.split && splitButtonContainer) ? splitButtonContainer : targetElement) as HTMLElement);
}, this._navigationIdleDelay);
} else {
this._enterTimerId = this._async.setTimeout(() => {
this._onSubMenuDismiss(ev);
Expand All @@ -850,6 +852,17 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
}

private _onItemClick(item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) {
this._onItemClickBase(item, ev, ev.currentTarget as HTMLElement);
}

private _onSplitItemClick(item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>) {
const splitButtonContainer = this._splitButtonContainers.get(item.key);
// get the whole splitButton container to base the menu off of
this._onItemClickBase(item, ev,
(splitButtonContainer ? splitButtonContainer : ev.currentTarget) as HTMLElement);
}

private _onItemClickBase(item: IContextualMenuItem, ev: React.MouseEvent<HTMLElement>, target: HTMLElement) {
const items = getSubmenuItems(item);

if (!hasSubmenu(item) && (!items || !items.length)) { // This is an item without a menu. Click it.
Expand All @@ -858,7 +871,7 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
if (item.key === this.state.expandedMenuItemKey) { // This has an expanded sub menu. collapse it.
this._onSubMenuDismiss(ev);
} else { // This has a collapsed sub menu. Expand it.
this._onItemSubMenuExpand(item, ev.currentTarget as HTMLElement);
this._onItemSubMenuExpand(item, target);
}
}

Expand Down Expand Up @@ -901,11 +914,8 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
this._onSubMenuDismiss();
}

// focus the container so when we close the menu, we focus on the split button container.
const el = this._splitButtonContainers.get(item.key);
if (el) {
el.focus();
}
// Focus the target to ensure when we close it, we're focusing on the correct element.
target.focus();
this.setState({
expandedMenuItemKey: item.key,
submenuTarget: target
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as React from 'react';
import { IContextualMenuItem, ContextualMenuItemType } from 'office-ui-fabric-react/lib/ContextualMenu';
import { IContextualMenuItem, ContextualMenuItemType, DirectionalHint } from 'office-ui-fabric-react/lib/ContextualMenu';
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import './ContextualMenuExample.scss';

export interface IContextualMenuMultiselectExampleState {
selection?: { [key: string]: boolean };
}

const keys: string[] = ['newItem', 'share', 'mobile', 'enablePrint', 'enableMusic', 'newSub', 'emailMessage', 'calendarEvent', 'disabledNewSub', 'disabledEmailMessage', 'disabledCalendarEvent'];
const keys: string[] = ['newItem', 'share', 'mobile', 'enablePrint', 'enableMusic', 'newSub', 'emailMessage', 'calendarEvent', 'disabledNewSub', 'disabledEmailMessage', 'disabledCalendarEvent', 'splitButtonSubMenuLeftDirection', 'emailMessageLeft', 'calendarEventLeft'];

export class ContextualMenuCheckmarksExample extends React.Component<{}, IContextualMenuMultiselectExampleState> {

Expand Down Expand Up @@ -110,14 +110,14 @@ export class ContextualMenuCheckmarksExample extends React.Component<{}, IContex
subMenuProps: {
items: [
{
key: keys[6],
key: keys[9],
name: 'Email message',
canCheck: true,
isChecked: selection![keys[9]],
onClick: this._onToggleSelect
},
{
key: keys[7],
key: keys[10],
name: 'Calendar event',
canCheck: true,
isChecked: selection![keys[10]],
Expand All @@ -132,6 +132,36 @@ export class ContextualMenuCheckmarksExample extends React.Component<{}, IContex
onClick: this._onToggleSelect,
disabled: true
},
{
key: keys[11],
iconProps: {
iconName: 'MusicInCollectionFill'
},
subMenuProps: {
directionalHint: DirectionalHint.leftCenter,
items: [
{
key: keys[12],
name: 'Email message',
canCheck: true,
isChecked: selection![keys[12]],
onClick: this._onToggleSelect
},
{
key: keys[13],
name: 'Calendar event',
canCheck: true,
isChecked: selection![keys[13]],
onClick: this._onToggleSelect
}
],
},
name: 'Split Button Left Menu',
canCheck: true,
isChecked: selection![keys[11]],
split: true,
onClick: this._onToggleSelect,
},
]
}
}
Expand Down