Fix positioning of the thread context menu (#7918)

This commit is contained in:
Michael Telatynski 2022-03-01 08:32:29 +00:00 committed by GitHub
parent b02d5ecb97
commit 115e17b097
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 38 deletions

View file

@ -260,10 +260,11 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
const { windowWidth, windowHeight } = UIStore.instance;
if (contextMenuRect) {
if (position.top !== undefined) {
position.top = Math.min(
position.top,
windowHeight - contextMenuRect.height - WINDOW_PADDING,
);
let maxTop = windowHeight - WINDOW_PADDING;
if (!this.props.bottomAligned) {
maxTop -= contextMenuRect.height;
}
position.top = Math.min(position.top, maxTop);
// Adjust the chevron if necessary
if (chevronOffset.top !== undefined) {
chevronOffset.top = props.chevronOffset + props.top - position.top;
@ -278,10 +279,11 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
}
}
if (position.left !== undefined) {
position.left = Math.min(
position.left,
windowWidth - contextMenuRect.width - WINDOW_PADDING,
);
let maxLeft = windowWidth - WINDOW_PADDING;
if (!this.props.rightAligned) {
maxLeft -= contextMenuRect.width;
}
position.left = Math.min(position.left, maxLeft);
if (chevronOffset.left !== undefined) {
chevronOffset.left = props.chevronOffset + props.left - position.left;
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { RefObject, useCallback, useEffect } from "react";
import React, { useCallback, useEffect } from "react";
import { MatrixEvent } from "matrix-js-sdk/src";
import { ButtonEvent } from "../elements/AccessibleButton";
@ -27,7 +27,6 @@ import { _t } from "../../../languageHandler";
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "./IconizedContextMenu";
import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
@ -36,13 +35,6 @@ interface IProps {
onMenuToggle?: (open: boolean) => void;
}
interface IExtendedProps extends IProps {
// Props for making the button into a roving one
tabIndex?: number;
inputRef?: RefObject<HTMLElement>;
onFocus?(): void;
}
const contextMenuBelow = (elementRect: DOMRect) => {
// align the context menu's icons with the icon which opened the context menu
const left = elementRect.left + window.pageXOffset + elementRect.width;
@ -51,27 +43,13 @@ const contextMenuBelow = (elementRect: DOMRect) => {
return { left, top, chevronFace };
};
export const RovingThreadListContextMenu: React.FC<IProps> = (props) => {
const [onFocus, isActive, ref] = useRovingTabIndex();
return <ThreadListContextMenu
{...props}
onFocus={onFocus}
tabIndex={isActive ? 0 : -1}
inputRef={ref}
/>;
};
const ThreadListContextMenu: React.FC<IExtendedProps> = ({
const ThreadListContextMenu: React.FC<IProps> = ({
mxEvent,
permalinkCreator,
onMenuToggle,
onFocus,
inputRef,
...props
}) => {
const [menuDisplayed, _ref, openMenu, closeThreadOptions] = useContextMenu();
const button = inputRef ?? _ref; // prefer the ref we receive via props in case we are being controlled
const [menuDisplayed, button, openMenu, closeThreadOptions] = useContextMenu();
const viewInRoom = useCallback((evt: ButtonEvent): void => {
evt.preventDefault();
@ -95,11 +73,8 @@ const ThreadListContextMenu: React.FC<IExtendedProps> = ({
}, [mxEvent, closeThreadOptions, permalinkCreator]);
useEffect(() => {
if (onMenuToggle) {
onMenuToggle(menuDisplayed);
}
onFocus?.();
}, [menuDisplayed, onMenuToggle, onFocus]);
onMenuToggle?.(menuDisplayed);
}, [menuDisplayed, onMenuToggle]);
const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget(
MatrixClientPeg.get().getRoom(mxEvent.getRoomId()),