Skip to content

Commit b1d5abf

Browse files
authored
[Menu] Mark certain key events as handled for MenuPopover (#2463)
### Platforms Impacted - [ ] iOS - [ ] macOS - [ ] win32 (Office) - [ ] windows - [ ] android ### Description of changes In the MenuPopover, certain key events are automatically handled by native, but the key event gets fired on the JS side anyway (this is by design for RN). This can cause bugs as keys could get double handled if a user has a separate key handler set up. Since the key events are handled on native, it would make sense to automatically mark those key events as handled. That way, they don't get handled on the JS side, too. ### Verification Tested change against client code ### Pull request checklist This PR has considered (when applicable): - [ ] Automated Tests - [ ] Documentation and examples - [ ] Keyboard Accessibility - [ ] Voiceover - [ ] Internationalization and Right-to-left Layouts
1 parent 8466c50 commit b1d5abf

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Override key handling",
4+
"packageName": "@fluentui-react-native/menu",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

packages/components/Menu/src/MenuPopover/useMenuPopover.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { MenuPopoverProps, MenuPopoverState } from './MenuPopover.types';
66

77
const controlledDismissBehaviors = ['preventDismissOnKeyDown', 'preventDismissOnClickOutside'] as DismissBehaviors[];
88

9-
export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
9+
export const useMenuPopover = (props: MenuPopoverProps): MenuPopoverState => {
1010
const context = useMenuContext();
1111
const {
1212
setOpen,
@@ -21,6 +21,8 @@ export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
2121
triggerHoverOutTimer,
2222
} = context;
2323

24+
const { onKeyDown: onKeyDownProp, onKeyUp: onKeyUpProp } = props;
25+
2426
const onDismiss = React.useCallback(() => setOpen(undefined, false /* isOpen */), [setOpen]);
2527
const dismissBehaviors = isControlled ? controlledDismissBehaviors : undefined;
2628
const directionalHint = getDirectionalHint(isSubmenu, I18nManager.isRTL);
@@ -36,6 +38,7 @@ export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
3638
clearTimeout(popoverHoverOutTimer);
3739
clearTimeout(parentPopoverHoverOutTimer);
3840
}, [parentPopoverHoverOutTimer, popoverHoverOutTimer, triggerHoverOutTimer]);
41+
3942
const onMouseLeave = React.useCallback(() => {
4043
if (!openOnHover) {
4144
return;
@@ -47,6 +50,42 @@ export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
4750
setPopoverHoverOutTimer(timer);
4851
}, [openOnHover, setOpen, setPopoverHoverOutTimer]);
4952

53+
const onKeyDown = React.useCallback(
54+
(e) => {
55+
onKeyDownProp && onKeyDownProp(e);
56+
57+
// Mark key events that move selection as handled.
58+
// These key events are handled on the native side.
59+
switch (e.nativeEvent.key) {
60+
case 'ArrowUp':
61+
case 'ArrowDown':
62+
case 'Tab':
63+
case 'Home':
64+
case 'End':
65+
e.stopPropagation();
66+
}
67+
},
68+
[onKeyDownProp],
69+
);
70+
71+
const onKeyUp = React.useCallback(
72+
(e) => {
73+
onKeyUpProp && onKeyUpProp(e);
74+
75+
// Mark key events that move selection as handled.
76+
// These key events are handled on the native side.
77+
switch (e.nativeEvent.key) {
78+
case 'ArrowUp':
79+
case 'ArrowDown':
80+
case 'Tab':
81+
case 'Home':
82+
case 'End':
83+
e.stopPropagation();
84+
}
85+
},
86+
[onKeyUpProp],
87+
);
88+
5089
const [canFocusOnPopover, setCanFocusOnPopover] = React.useState<boolean>(shouldFocusOnContainer);
5190
const onBlur = React.useCallback(() => {
5291
setCanFocusOnPopover(false);
@@ -71,6 +110,8 @@ export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
71110
innerView: {
72111
onMouseEnter,
73112
onMouseLeave,
113+
onKeyDown,
114+
onKeyUp,
74115
accessible: shouldFocusOnContainer,
75116
focusable: canFocusOnPopover,
76117
onBlur,

packages/components/Menu/src/__tests__/__snapshots__/Menu.test.tsx.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ Array [
196196
accessible={false}
197197
focusable={false}
198198
onBlur={[Function]}
199+
onKeyDown={[Function]}
200+
onKeyUp={[Function]}
199201
onMouseEnter={[Function]}
200202
onMouseLeave={[Function]}
201203
>
@@ -465,6 +467,8 @@ Array [
465467
accessible={false}
466468
focusable={false}
467469
onBlur={[Function]}
470+
onKeyDown={[Function]}
471+
onKeyUp={[Function]}
468472
onMouseEnter={[Function]}
469473
onMouseLeave={[Function]}
470474
>
@@ -666,6 +670,8 @@ Array [
666670
accessible={false}
667671
focusable={false}
668672
onBlur={[Function]}
673+
onKeyDown={[Function]}
674+
onKeyUp={[Function]}
669675
onMouseEnter={[Function]}
670676
onMouseLeave={[Function]}
671677
>
@@ -1067,6 +1073,8 @@ Array [
10671073
accessible={false}
10681074
focusable={false}
10691075
onBlur={[Function]}
1076+
onKeyDown={[Function]}
1077+
onKeyUp={[Function]}
10701078
onMouseEnter={[Function]}
10711079
onMouseLeave={[Function]}
10721080
>
@@ -1468,6 +1476,8 @@ Array [
14681476
accessible={false}
14691477
focusable={false}
14701478
onBlur={[Function]}
1479+
onKeyDown={[Function]}
1480+
onKeyUp={[Function]}
14711481
onMouseEnter={[Function]}
14721482
onMouseLeave={[Function]}
14731483
>
@@ -1869,6 +1879,8 @@ Array [
18691879
accessible={false}
18701880
focusable={false}
18711881
onBlur={[Function]}
1882+
onKeyDown={[Function]}
1883+
onKeyUp={[Function]}
18721884
onMouseEnter={[Function]}
18731885
onMouseLeave={[Function]}
18741886
>
@@ -2258,6 +2270,8 @@ Array [
22582270
accessible={false}
22592271
focusable={false}
22602272
onBlur={[Function]}
2273+
onKeyDown={[Function]}
2274+
onKeyUp={[Function]}
22612275
onMouseEnter={[Function]}
22622276
onMouseLeave={[Function]}
22632277
>

0 commit comments

Comments
 (0)