Skip to content

Commit 6f3fd7a

Browse files
Fix move/close menu not showing on draggable video tile when ctrl+alt+space shortcut is used (#5652)
1 parent 0c21167 commit 6f3fd7a

3 files changed

Lines changed: 43 additions & 15 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "",
5+
"comment": "Bug Fix: Fix move/close menu not showing on draggable video tile when ctrl+alt+space shortcut is used",
6+
"packageName": "@azure/communication-react",
7+
"email": "2684369+JamesBurnside@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "",
5+
"comment": "Bug Fix: Fix move/close menu not showing on draggable video tile when ctrl+alt+space shortcut is used",
6+
"packageName": "@azure/communication-react",
7+
"email": "2684369+JamesBurnside@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}

packages/react-components/src/components/ModalClone/ModalClone.tsx

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
useResponsiveMode,
4040
ZIndexes
4141
} from '@fluentui/react';
42-
import { useWindow } from '@fluentui/react-window-provider';
4342

4443
// @TODO - need to change this to a panel whenever the breakpoint is under medium (verify the spec)
4544

@@ -48,6 +47,13 @@ export interface _ExtendedIModalProps extends IModalProps {
4847
minDragPosition?: _ICoordinates;
4948
maxDragPosition?: _ICoordinates;
5049
dataUiId?: string;
50+
51+
/**
52+
* Originally the FluentUI modal used window to capture key events that trigger the move/close menu.
53+
* As we want to avoid global listeners, we are allowing the user to pass in a specific element
54+
* to capture the key events.
55+
*/
56+
keyEventElement?: HTMLElement | Window;
5157
}
5258

5359
const animationDuration = AnimationVariables.durationValue2;
@@ -84,7 +90,7 @@ const DEFAULT_PROPS: Partial<_ExtendedIModalProps> = {
8490

8591
const getModalClassNames = classNamesFunction<IModalStyleProps, IModalStyles>();
8692

87-
const getMoveDelta = (ev: React.KeyboardEvent<HTMLElement>): number => {
93+
const getMoveDelta = (ev: KeyboardEvent): number => {
8894
let delta = 10;
8995
if (ev.shiftKey) {
9096
if (!ev.ctrlKey) {
@@ -144,7 +150,8 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
144150
onDismissed,
145151
minDragPosition,
146152
maxDragPosition,
147-
dataUiId
153+
dataUiId,
154+
keyEventElement = window
148155
} = props;
149156

150157
const rootRef = React.useRef<HTMLDivElement>(null);
@@ -156,16 +163,17 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
156163

157164
const focusTrapZoneId = useId('ModalFocusTrapZone');
158165

159-
const win = useWindow();
160-
161166
const { setTimeout, clearTimeout } = useSetTimeout();
162167

163168
const [isModalOpen, setIsModalOpen] = React.useState(isOpen);
164169
const [isVisible, setIsVisible] = React.useState(isOpen);
165170
const [coordinates, setCoordinates] = React.useState<_ICoordinates>(ZERO);
166171
const [modalRectangleTop, setModalRectangleTop] = React.useState<number | undefined>();
167172

168-
const [isModalMenuOpen, { toggle: toggleModalMenuOpen, setFalse: setModalMenuClose }] = useBoolean(false);
173+
const [isModalMenuOpen, { setTrue: setModalMenuOpen, setFalse: setModalMenuClose }] = useBoolean(false);
174+
175+
const [_, forceUpdate] = React.useState(0);
176+
const forceUpdateCallback = React.useCallback(() => forceUpdate((prev) => prev + 1), []);
169177

170178
const internalState = useConst<IModalInternalState>(() => ({
171179
onModalCloseTimer: 0,
@@ -192,7 +200,7 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
192200
topOffsetFixed,
193201
isModeless,
194202
layerClassName,
195-
windowInnerHeight: win?.innerHeight,
203+
windowInnerHeight: window?.innerHeight,
196204
isDefaultDragHandle: dragOptions && !dragOptions.dragHandleSelector
197205
});
198206

@@ -300,7 +308,8 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
300308
const handleEnterKeyboardMoveMode = () => {
301309
// We need a global handleKeyDown event when we are in the move mode so that we can
302310
// handle the key presses and the components inside the modal do not get the events
303-
const handleKeyDown = (ev: React.KeyboardEvent<HTMLElement>): void => {
311+
const handleKeyDown = (event: Event): void => {
312+
const ev = event as KeyboardEvent;
304313
if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) {
305314
// CTRL + ALT + SPACE is handled during keyUp
306315
ev.preventDefault();
@@ -315,6 +324,7 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
315324

316325
if (internalState.isInKeyboardMoveMode && (ev.keyCode === KeyCodes.escape || ev.keyCode === KeyCodes.enter)) {
317326
internalState.isInKeyboardMoveMode = false;
327+
forceUpdateCallback();
318328
ev.preventDefault();
319329
ev.stopPropagation();
320330
}
@@ -364,10 +374,9 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
364374
internalState.lastSetCoordinates = coordinates;
365375
setModalMenuClose();
366376
internalState.isInKeyboardMoveMode = true;
367-
368-
internalState.events.on(win, 'keydown', handleKeyDown, true /* useCapture */);
377+
keyEventElement.addEventListener('keydown', handleKeyDown, true /* useCapture */);
369378
internalState.disposeOnKeyDown = () => {
370-
internalState.events.off(win, 'keydown', handleKeyDown, true /* useCapture */);
379+
keyEventElement.removeEventListener('keydown', handleKeyDown, true /* useCapture */);
371380
internalState.disposeOnKeyDown = undefined;
372381
};
373382
};
@@ -379,22 +388,23 @@ const ModalBase: React.FunctionComponent<_ExtendedIModalProps> = React.forwardRe
379388
};
380389

381390
const registerForKeyUp = (): void => {
382-
const handleKeyUp = (ev: React.KeyboardEvent<HTMLElement>): void => {
391+
const handleKeyUp = (event: Event): void => {
392+
const ev = event as KeyboardEvent;
383393
// Needs to handle the CTRL + ALT + SPACE key during keyup due to FireFox bug:
384394
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
385395
if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) {
386396
if (elementContains(internalState.scrollableContent, ev.target as HTMLElement)) {
387-
toggleModalMenuOpen();
397+
setModalMenuOpen();
388398
ev.preventDefault();
389399
ev.stopPropagation();
390400
}
391401
}
392402
};
393403

394404
if (!internalState.disposeOnKeyUp) {
395-
internalState.events.on(win, 'keyup', handleKeyUp, true /* useCapture */);
405+
keyEventElement.addEventListener('keyup', handleKeyUp, true /* useCapture */);
396406
internalState.disposeOnKeyUp = () => {
397-
internalState.events.off(win, 'keyup', handleKeyUp, true /* useCapture */);
407+
keyEventElement.removeEventListener('keyup', handleKeyUp, true /* useCapture */);
398408
internalState.disposeOnKeyUp = undefined;
399409
};
400410
}

0 commit comments

Comments
 (0)