Open ContextMenu at correct location via keyboard

This commit is contained in:
Josh Perez 2022-10-28 12:41:50 -04:00 committed by GitHub
parent 06c9ca9d24
commit fd40322002
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 19 deletions

View file

@ -28,6 +28,12 @@
right: 63px; right: 63px;
top: 0px; top: 0px;
width: 22px; width: 22px;
&:focus {
@include keyboard-mode {
background-color: $color-ultramarine;
}
}
} }
&__settings__button { &__settings__button {
@ -44,6 +50,12 @@
right: 16px; right: 16px;
top: 0px; top: 0px;
width: 22px; width: 22px;
&:focus {
@include keyboard-mode {
background-color: $color-ultramarine;
}
}
} }
&__header { &__header {

View file

@ -129,14 +129,24 @@ export function ContextMenu<T>({
}, [isMenuShowing, referenceElement, popperElement]); }, [isMenuShowing, referenceElement, popperElement]);
const handleKeyDown = (ev: KeyboardEvent) => { const handleKeyDown = (ev: KeyboardEvent) => {
if (!isMenuShowing) { if ((ev.key === 'Enter' || ev.key === 'Space') && !isMenuShowing) {
if (ev.key === 'Enter') { closeCurrentOpenContextMenu?.();
setFocusedIndex(0); closeCurrentOpenContextMenu = () => setIsMenuShowing(false);
if (referenceElement) {
const box = referenceElement.getBoundingClientRect();
virtualElement.current = generateVirtualElement(box.x, box.y);
} }
setIsMenuShowing(true);
setFocusedIndex(0);
ev.preventDefault();
ev.stopPropagation();
}
if (!isMenuShowing) {
return; return;
} }
if (ev.key === 'ArrowDown') { if (ev.key === 'ArrowDown' || ev.key === 'Tab') {
const currFocusedIndex = focusedIndex || 0; const currFocusedIndex = focusedIndex || 0;
const nextFocusedIndex = const nextFocusedIndex =
currFocusedIndex >= menuOptions.length - 1 ? 0 : currFocusedIndex + 1; currFocusedIndex >= menuOptions.length - 1 ? 0 : currFocusedIndex + 1;
@ -272,19 +282,19 @@ export function ContextMenu<T>({
} }
return ( return (
<div <FocusTrap
className={classNames( focusTrapOptions={{
getClassName('__container'), allowOutsideClick: true,
theme ? themeClassName(theme) : undefined }}
)}
> >
{buttonNode} <div
{isMenuShowing && ( className={classNames(
<FocusTrap getClassName('__container'),
focusTrapOptions={{ theme ? themeClassName(theme) : undefined
allowOutsideClick: true, )}
}} >
> {buttonNode}
{isMenuShowing && (
<div className={theme ? themeClassName(theme) : undefined}> <div className={theme ? themeClassName(theme) : undefined}>
<div <div
className={classNames( className={classNames(
@ -301,8 +311,8 @@ export function ContextMenu<T>({
{optionElements} {optionElements}
</div> </div>
</div> </div>
</FocusTrap> )}
)} </div>
</div> </FocusTrap>
); );
} }