mirror of https://github.com/vector-im/riot-web
focusLock only specific context menus
parent
b373b98d48
commit
047f182cd8
|
@ -83,6 +83,10 @@ export interface IProps extends IPosition {
|
||||||
// it will be mounted to a container at the root of the DOM.
|
// it will be mounted to a container at the root of the DOM.
|
||||||
mountAsChild?: boolean;
|
mountAsChild?: boolean;
|
||||||
|
|
||||||
|
// If specified, contents will be wrapped in a FocusLock, this is only needed if the context menu is being rendered
|
||||||
|
// within an existing FocusLock e.g inside a modal.
|
||||||
|
focusLock?: boolean;
|
||||||
|
|
||||||
// Function to be called on menu close
|
// Function to be called on menu close
|
||||||
onFinished();
|
onFinished();
|
||||||
// on resize callback
|
// on resize callback
|
||||||
|
@ -98,6 +102,8 @@ interface IState {
|
||||||
// this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines.
|
// this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines.
|
||||||
@replaceableComponent("structures.ContextMenu")
|
@replaceableComponent("structures.ContextMenu")
|
||||||
export class ContextMenu extends React.PureComponent<IProps, IState> {
|
export class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
|
private readonly initialFocus: HTMLElement;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
hasBackground: true,
|
hasBackground: true,
|
||||||
managed: true,
|
managed: true,
|
||||||
|
@ -105,9 +111,18 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
contextMenuElem: null,
|
contextMenuElem: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// persist what had focus when we got initialized so we can return it after
|
||||||
|
this.initialFocus = document.activeElement as HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
// return focus to the thing which had it before us after the unmount
|
||||||
|
this.initialFocus.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private collectContextMenuRect = (element: HTMLDivElement) => {
|
private collectContextMenuRect = (element: HTMLDivElement) => {
|
||||||
|
@ -371,6 +386,17 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let body = <>
|
||||||
|
{ chevron }
|
||||||
|
{ props.children }
|
||||||
|
</>;
|
||||||
|
|
||||||
|
if (props.focusLock) {
|
||||||
|
body = <FocusLock>
|
||||||
|
{ body }
|
||||||
|
</FocusLock>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames("mx_ContextualMenu_wrapper", this.props.wrapperClassName)}
|
className={classNames("mx_ContextualMenu_wrapper", this.props.wrapperClassName)}
|
||||||
|
@ -385,10 +411,7 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
|
||||||
ref={this.collectContextMenuRect}
|
ref={this.collectContextMenuRect}
|
||||||
role={this.props.managed ? "menu" : undefined}
|
role={this.props.managed ? "menu" : undefined}
|
||||||
>
|
>
|
||||||
<FocusLock returnFocus={true}>
|
{ body }
|
||||||
{ chevron }
|
|
||||||
{ props.children }
|
|
||||||
</FocusLock>
|
|
||||||
</div>
|
</div>
|
||||||
{ background }
|
{ background }
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -268,7 +268,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttonRect = handle.current.getBoundingClientRect();
|
const buttonRect = handle.current.getBoundingClientRect();
|
||||||
content = <ContextMenu {...inPlaceOf(buttonRect)} onFinished={closeMenu}>
|
content = <ContextMenu {...inPlaceOf(buttonRect)} onFinished={closeMenu} focusLock>
|
||||||
<div className="mx_NetworkDropdown_menu">
|
<div className="mx_NetworkDropdown_menu">
|
||||||
{ options }
|
{ options }
|
||||||
<MenuItem className="mx_NetworkDropdown_server_add" label={undefined} onClick={onClick}>
|
<MenuItem className="mx_NetworkDropdown_server_add" label={undefined} onClick={onClick}>
|
||||||
|
|
Loading…
Reference in New Issue