Avoid errant scroll on context menu hide
This commit is contained in:
parent
78cfa7eca3
commit
1d44c70393
6 changed files with 33 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
|||
diff --git a/node_modules/react-contextmenu/modules/ContextMenu.js b/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||
index 2f88213..4cf584a 100644
|
||||
index 2f88213..41e47ea 100644
|
||||
--- a/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||
+++ b/node_modules/react-contextmenu/modules/ContextMenu.js
|
||||
@@ -81,6 +81,11 @@ var ContextMenu = function (_AbstractMenu) {
|
||||
|
@ -35,13 +35,15 @@ index 2f88213..4cf584a 100644
|
|||
});
|
||||
});
|
||||
} else {
|
||||
@@ -248,6 +259,14 @@ var ContextMenu = function (_AbstractMenu) {
|
||||
@@ -248,6 +259,16 @@ var ContextMenu = function (_AbstractMenu) {
|
||||
if (!_this2.menu) return;
|
||||
_this2.menu.style.opacity = 0;
|
||||
_this2.menu.style.pointerEvents = 'none';
|
||||
+
|
||||
+ // Return to the previous focus state when dismissing the menu, unless the
|
||||
+ // menu option focused another element. This is important for keyboard mode.
|
||||
+ if (_this2.props.avoidFocusRestoreOnBlur) return;
|
||||
+
|
||||
+ var isFocusWithinMenu = _this2.menu.contains(document.activeElement);
|
||||
+ if (isFocusWithinMenu && _this2.previousFocus && _this2.previousFocus.focus) {
|
||||
+ _this2.previousFocus.focus();
|
||||
|
@ -139,3 +141,15 @@ index ad1dc70..c919be8 100644
|
|||
this.subMenu.classList.remove(_helpers.cssClasses.menuVisible);
|
||||
}
|
||||
}
|
||||
diff --git a/node_modules/react-contextmenu/src/index.d.ts b/node_modules/react-contextmenu/src/index.d.ts
|
||||
index 753ce90..c5971a4 100644
|
||||
--- a/node_modules/react-contextmenu/src/index.d.ts
|
||||
+++ b/node_modules/react-contextmenu/src/index.d.ts
|
||||
@@ -14,6 +14,7 @@ declare module "react-contextmenu" {
|
||||
preventHideOnResize?: boolean,
|
||||
preventHideOnScroll?: boolean,
|
||||
style?: React.CSSProperties,
|
||||
+ avoidFocusRestoreOnBlur?: boolean;
|
||||
}
|
||||
|
||||
export interface ContextMenuTriggerProps {
|
||||
|
|
|
@ -62,6 +62,7 @@ const getCommonProps = (options: {
|
|||
id: 'message-id',
|
||||
conversationId: conversation.id,
|
||||
i18n,
|
||||
interactionMode: 'mouse',
|
||||
isNextItemCallingNotification: false,
|
||||
onOutgoingAudioCallInConversation: action(
|
||||
'onOutgoingAudioCallInConversation'
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
import { MINUTE } from '../../util/durations';
|
||||
import { isMoreRecentThan } from '../../util/timestamp';
|
||||
import { InAnotherCallTooltip } from './InAnotherCallTooltip';
|
||||
import type { InteractionModeType } from '../../state/ducks/conversations';
|
||||
|
||||
export type PropsActionsType = {
|
||||
onOutgoingAudioCallInConversation: (conversationId: string) => void;
|
||||
|
@ -50,6 +51,7 @@ type PropsHousekeeping = {
|
|||
i18n: LocalizerType;
|
||||
id: string;
|
||||
conversationId: string;
|
||||
interactionMode: InteractionModeType;
|
||||
isNextItemCallingNotification: boolean;
|
||||
};
|
||||
|
||||
|
@ -120,6 +122,7 @@ export const CallingNotification: React.FC<PropsType> = React.memo(
|
|||
<MessageContextMenu
|
||||
i18n={i18n}
|
||||
triggerId={props.id}
|
||||
interactionMode={props.interactionMode}
|
||||
onDeleteMessage={() => {
|
||||
props.toggleDeleteMessagesModal({
|
||||
conversationId: props.conversationId,
|
||||
|
|
|
@ -5,6 +5,7 @@ import React, { type RefObject } from 'react';
|
|||
import { ContextMenu, MenuItem } from 'react-contextmenu';
|
||||
import ReactDOM from 'react-dom';
|
||||
import type { LocalizerType } from '../../types/I18N';
|
||||
import type { InteractionModeType } from '../../state/ducks/conversations';
|
||||
|
||||
export type ContextMenuTriggerType = {
|
||||
handleContextClick: (
|
||||
|
@ -16,7 +17,7 @@ type MessageContextProps = {
|
|||
i18n: LocalizerType;
|
||||
triggerId: string;
|
||||
shouldShowAdditional: boolean;
|
||||
|
||||
interactionMode: InteractionModeType;
|
||||
onDownload: (() => void) | undefined;
|
||||
onEdit: (() => void) | undefined;
|
||||
onReplyToMessage: (() => void) | undefined;
|
||||
|
@ -33,6 +34,7 @@ export const MessageContextMenu = ({
|
|||
i18n,
|
||||
triggerId,
|
||||
shouldShowAdditional,
|
||||
interactionMode,
|
||||
onDownload,
|
||||
onEdit,
|
||||
onReplyToMessage,
|
||||
|
@ -46,7 +48,14 @@ export const MessageContextMenu = ({
|
|||
onDeleteMessage,
|
||||
}: MessageContextProps): JSX.Element => {
|
||||
const menu = (
|
||||
<ContextMenu id={triggerId}>
|
||||
// We avoid restoring focus on this context menu because it is not intended for
|
||||
// keyboard use and restoring focus to the message could cause an unwanted scroll
|
||||
<ContextMenu
|
||||
id={triggerId}
|
||||
// In keyboard mode, we do want to restore focus to the message; the message is very
|
||||
// likely already scrolled into view in this case.
|
||||
avoidFocusRestoreOnBlur={interactionMode !== 'keyboard'}
|
||||
>
|
||||
{shouldShowAdditional && (
|
||||
<>
|
||||
{onDownload && (
|
||||
|
|
|
@ -286,6 +286,7 @@ export const TimelineItem = memo(function TimelineItem({
|
|||
<CallingNotification
|
||||
id={id}
|
||||
conversationId={conversationId}
|
||||
interactionMode={reducedProps.interactionMode}
|
||||
i18n={i18n}
|
||||
isNextItemCallingNotification={isNextItemCallingNotification}
|
||||
onOutgoingAudioCallInConversation={onOutgoingAudioCallInConversation}
|
||||
|
|
|
@ -365,6 +365,7 @@ export function TimelineMessage(props: Props): JSX.Element {
|
|||
i18n={i18n}
|
||||
triggerId={triggerId}
|
||||
shouldShowAdditional={shouldShowAdditional}
|
||||
interactionMode={props.interactionMode}
|
||||
onDownload={handleDownload}
|
||||
onEdit={
|
||||
canEditMessage
|
||||
|
|
Loading…
Add table
Reference in a new issue