Browse Source

Fix dialog windows ignoring buttons focus (#10532)

* Fix dialog windows ignoring buttons focus

* Add a test to ensure that the focused button is used
Michał Krassowski 3 years ago
parent
commit
66f826cea6
2 changed files with 34 additions and 2 deletions
  1. 11 2
      packages/apputils/src/dialog.tsx
  2. 23 0
      packages/apputils/test/dialog.spec.tsx

+ 11 - 2
packages/apputils/src/dialog.tsx

@@ -351,11 +351,20 @@ export class Dialog<T> extends Widget {
         }
         break;
       }
-      case 13: // Enter.
+      case 13: {
+        // Enter.
         event.stopPropagation();
         event.preventDefault();
-        this.resolve();
+
+        const activeEl = document.activeElement;
+        let index: number | undefined;
+
+        if (activeEl instanceof HTMLButtonElement) {
+          index = this._buttonNodes.indexOf(activeEl as HTMLElement);
+        }
+        this.resolve(index);
         break;
+      }
       default:
         break;
     }

+ 23 - 0
packages/apputils/test/dialog.spec.tsx

@@ -182,6 +182,29 @@ describe('@jupyterlab/apputils', () => {
           expect((await prompt).button.accept).toBe(true);
         });
 
+        it('should resolve with currently focused button', async () => {
+          const dialog = new TestDialog({
+            buttons: [
+              Dialog.createButton({ label: 'first' }),
+              Dialog.createButton({ label: 'second' }),
+              Dialog.createButton({ label: 'third' }),
+              Dialog.createButton({ label: 'fourth' })
+            ],
+            // focus on "first"
+            defaultButton: 0
+          });
+          const prompt = dialog.launch();
+
+          await waitForDialog();
+          // press right arrow twice (focusing on "third")
+          simulate(dialog.node, 'keydown', { keyCode: 39 });
+          simulate(dialog.node, 'keydown', { keyCode: 39 });
+          // press enter
+          simulate(dialog.node, 'keydown', { keyCode: 13 });
+          expect((await prompt).button.label).toBe('third');
+          dialog.dispose();
+        });
+
         it('should cycle to the first button on a tab key', async () => {
           const prompt = dialog.launch();