diff --git a/spec/__snapshots__/menu-button.spec.tsx.snap b/spec/__snapshots__/menu-button.spec.tsx.snap
index 783e7c45..8befe9f8 100644
--- a/spec/__snapshots__/menu-button.spec.tsx.snap
+++ b/spec/__snapshots__/menu-button.spec.tsx.snap
@@ -9,6 +9,7 @@ exports[`Menu Button should show all elements 1`] = `
className="menu-button"
data-testid="undefined_MENU_BUTTON"
onClick={[Function]}
+ onKeyUp={[Function]}
>
{
await waitForPromisesToResolve();
expect(wrapper.find('.menu').exists()).toBeFalsy();
});
+
+ it('should focus menu list on up', async () => {
+ const wrapper = mount(
+ ,
+ );
+
+ wrapper.find('[data-testid="snipping-tool_MENU_BUTTON"]').simulate('click');
+ wrapper.update();
+ wrapper
+ .find('[data-testid="snipping-tool_MENU_BUTTON"]')
+ .simulate('keyup', { key: 'ArrowUp' });
+ wrapper.update();
+ expect(
+ (wrapper.find('[data-testid="snipping-tool_SAVE_AS"]').instance() as any)
+ .dataset.isfocused,
+ ).toBe('true');
+ });
+
+ it('should focus menu list on down', async () => {
+ const wrapper = mount(
+ ,
+ );
+
+ wrapper.find('[data-testid="snipping-tool_MENU_BUTTON"]').simulate('click');
+ wrapper.update();
+ wrapper
+ .find('[data-testid="snipping-tool_MENU_BUTTON"]')
+ .simulate('keyup', { key: 'ArrowDown' });
+ wrapper.update();
+ expect(
+ (
+ wrapper
+ .find('[data-testid="snipping-tool_COPY_TO_CLIPBOARD"]')
+ .instance() as any
+ ).dataset.isfocused,
+ ).toBe('true');
+ });
+
+ it('should go down on press down', async () => {
+ const wrapper = mount(
+ ,
+ );
+
+ wrapper.find('[data-testid="snipping-tool_MENU_BUTTON"]').simulate('click');
+ wrapper.update();
+ wrapper
+ .find('[data-testid="snipping-tool_MENU_BUTTON"]')
+ .simulate('keyup', { key: 'ArrowDown' });
+ wrapper.update();
+ wrapper
+ .find('[data-testid="snipping-tool_LIST"]')
+ .simulate('keyup', { key: 'ArrowDown' });
+ wrapper.update();
+ expect(
+ (wrapper.find('[data-testid="snipping-tool_SAVE_AS"]').instance() as any)
+ .dataset.isfocused,
+ ).toBe('true');
+ });
+
+ it('should go up on press up', async () => {
+ const wrapper = mount(
+ ,
+ );
+
+ wrapper.find('[data-testid="snipping-tool_MENU_BUTTON"]').simulate('click');
+ wrapper.update();
+ wrapper
+ .find('[data-testid="snipping-tool_MENU_BUTTON"]')
+ .simulate('keyup', { key: 'ArrowUp' });
+ wrapper
+ .find('[data-testid="snipping-tool_LIST"]')
+ .simulate('keyup', { key: 'ArrowUp' });
+ wrapper.update();
+ expect(
+ (
+ wrapper
+ .find('[data-testid="snipping-tool_COPY_TO_CLIPBOARD"]')
+ .instance() as any
+ ).dataset.isfocused,
+ ).toBe('true');
+ });
});
diff --git a/src/renderer/components/menu-button.tsx b/src/renderer/components/menu-button.tsx
index f91799c5..e331503b 100644
--- a/src/renderer/components/menu-button.tsx
+++ b/src/renderer/components/menu-button.tsx
@@ -16,6 +16,8 @@ const MenuButton: React.FunctionComponent = ({
}) => {
//#region State
const [isDisplay, setDisplay] = useState(false);
+ const [currentFocusedItem, setCurrentFocusedItem] =
+ useState();
const listRef = useRef(document.createElement('div'));
const menuButtonRef = useRef(
document.createElement('button'),
@@ -25,6 +27,7 @@ const MenuButton: React.FunctionComponent = ({
//#region Variables
const testId = {
menu: `${id}_MENU_BUTTON`,
+ list: `${id}_LIST`,
};
//#endregion
@@ -32,6 +35,55 @@ const MenuButton: React.FunctionComponent = ({
const onClickMenuButton = () => {
setDisplay(!isDisplay);
};
+
+ const onMenuKeyUp = (event: React.KeyboardEvent) => {
+ let item: HTMLButtonElement | null = null;
+
+ if (event.key === 'ArrowDown') {
+ item = listRef.current.children[0] as HTMLButtonElement;
+ }
+
+ if (event.key === 'ArrowUp') {
+ item = listRef.current.children[
+ listRef.current.children.length - 1
+ ] as HTMLButtonElement;
+ }
+
+ if (item) {
+ item.focus();
+ item.setAttribute('data-isfocused', 'true'); // UT Purpose
+ setCurrentFocusedItem(item);
+ }
+ };
+
+ const onListKeyUp = (event: React.KeyboardEvent) => {
+ let item: HTMLButtonElement | null = null;
+ if (!listRef.current) {
+ return;
+ }
+
+ currentFocusedItem?.setAttribute('data-isfocused', 'false'); // UT Purpose
+
+ if (event.key === 'ArrowUp') {
+ item =
+ (currentFocusedItem?.previousElementSibling as HTMLButtonElement) ||
+ (listRef.current.children[
+ listRef.current.children.length - 1
+ ] as HTMLButtonElement);
+ }
+
+ if (event.key === 'ArrowDown') {
+ item =
+ (currentFocusedItem?.nextElementSibling as HTMLButtonElement) ||
+ (listRef.current.children[0] as HTMLButtonElement);
+ }
+
+ if (item) {
+ item.focus();
+ item.setAttribute('data-isfocused', 'true'); // UT Purpose
+ setCurrentFocusedItem(item);
+ }
+ };
//#endregion
//#region UseEffect
@@ -94,6 +146,7 @@ const MenuButton: React.FunctionComponent = ({
<>
{isDisplay && (
-