-
-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ARIA MenuBar keyboard interaction improvements #477
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -29,6 +29,7 @@ import { | |||||||||||||||||||||
VirtualDOM, | ||||||||||||||||||||||
VirtualElement | ||||||||||||||||||||||
} from '@lumino/virtualdom'; | ||||||||||||||||||||||
import { MenuBar } from './menubar'; | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This lets the code reader know that we're not actually creating |
||||||||||||||||||||||
|
||||||||||||||||||||||
import { Widget } from './widget'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -234,6 +235,30 @@ export class Menu extends Widget { | |||||||||||||||||||||
return this._items; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Activate the first selectable item in the menu. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
activateFirstItem(): void { | ||||||||||||||||||||||
this.activeIndex = ArrayExt.findFirstIndex( | ||||||||||||||||||||||
this._items, | ||||||||||||||||||||||
Private.canActivate, | ||||||||||||||||||||||
0, | ||||||||||||||||||||||
this._items.length | ||||||||||||||||||||||
); | ||||||||||||||||||||||
Comment on lines
+242
to
+247
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Activate the first selectable item in the menu. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
activateLastItem(): void { | ||||||||||||||||||||||
this.activeIndex = ArrayExt.findFirstIndex( | ||||||||||||||||||||||
this._items, | ||||||||||||||||||||||
Private.canActivate, | ||||||||||||||||||||||
this._items.length, | ||||||||||||||||||||||
0 | ||||||||||||||||||||||
); | ||||||||||||||||||||||
Comment on lines
+254
to
+259
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Activate the next selectable item in the menu. | ||||||||||||||||||||||
* | ||||||||||||||||||||||
|
@@ -319,6 +344,23 @@ export class Menu extends Widget { | |||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Close the menu completely. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
closeMenu(): void { | ||||||||||||||||||||||
// Bail if the menu is not attached. | ||||||||||||||||||||||
if (!this.isAttached) { | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Cancel the pending timers. | ||||||||||||||||||||||
this._cancelOpenTimer(); | ||||||||||||||||||||||
this._cancelCloseTimer(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Close the root menu before executing the command. | ||||||||||||||||||||||
this.rootMenu.close(); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+350
to
+362
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I'm familiar enough with the Menu class to adequately review this method. |
||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Add a menu item to the end of the menu. | ||||||||||||||||||||||
* | ||||||||||||||||||||||
|
@@ -502,6 +544,13 @@ export class Menu extends Widget { | |||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Set the parent MenuBar, if the Menu is contained within one. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
set parentMenuBar(value: MenuBar) { | ||||||||||||||||||||||
this._parentMenuBar = value; | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably need to set this to |
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* A message handler invoked on a `'before-attach'` message. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
|
@@ -607,25 +656,44 @@ export class Menu extends Widget { | |||||||||||||||||||||
* This listener is attached to the menu node. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
private _evtKeyDown(event: KeyboardEvent): void { | ||||||||||||||||||||||
// A menu handles all keydown events. | ||||||||||||||||||||||
event.preventDefault(); | ||||||||||||||||||||||
event.stopPropagation(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Fetch the key code for the event. | ||||||||||||||||||||||
let kc = event.keyCode; | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Enter | ||||||||||||||||||||||
if (kc === 13) { | ||||||||||||||||||||||
// A menu handles all keydown events, except for tab, which we let propagate. | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
if (kc === 9) { | ||||||||||||||||||||||
this.closeMenu(); | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
event.preventDefault(); | ||||||||||||||||||||||
event.stopPropagation(); | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Enter or Space | ||||||||||||||||||||||
if (kc === 13 || kc === 32) { | ||||||||||||||||||||||
this.triggerActiveItem(); | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Escape | ||||||||||||||||||||||
if (kc === 27) { | ||||||||||||||||||||||
this.close(); | ||||||||||||||||||||||
// If this menu is in a menubar, refocus the menubar. | ||||||||||||||||||||||
if (this._parentMenuBar) { | ||||||||||||||||||||||
this._parentMenuBar.activate(); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
return; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Home | ||||||||||||||||||||||
if (kc === 36) { | ||||||||||||||||||||||
this.activateFirstItem(); | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// End | ||||||||||||||||||||||
if (kc === 35) { | ||||||||||||||||||||||
this.activateLastItem(); | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Left Arrow | ||||||||||||||||||||||
if (kc === 37) { | ||||||||||||||||||||||
if (this._parentMenu) { | ||||||||||||||||||||||
|
@@ -938,6 +1006,7 @@ export class Menu extends Widget { | |||||||||||||||||||||
private _items: Menu.IItem[] = []; | ||||||||||||||||||||||
private _childMenu: Menu | null = null; | ||||||||||||||||||||||
private _parentMenu: Menu | null = null; | ||||||||||||||||||||||
private _parentMenuBar: MenuBar | null = null; | ||||||||||||||||||||||
private _aboutToClose = new Signal<this, void>(this); | ||||||||||||||||||||||
private _menuRequested = new Signal<this, 'next' | 'previous'>(this); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
@@ -1175,7 +1244,7 @@ export namespace Menu { | |||||||||||||||||||||
{ | ||||||||||||||||||||||
className, | ||||||||||||||||||||||
dataset, | ||||||||||||||||||||||
tabindex: '0', | ||||||||||||||||||||||
tabindex: '-1', | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In other words, the user will navigate to menu items via the left/right arrow keys? |
||||||||||||||||||||||
onfocus: data.onfocus, | ||||||||||||||||||||||
...aria | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -383,7 +383,7 @@ export class MenuBar extends Widget { | |||||
*/ | ||||||
protected onActivateRequest(msg: Message): void { | ||||||
if (this.isAttached) { | ||||||
this.activeIndex = 0; | ||||||
this.activeIndex = this._tabFocusIndex; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice |
||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -446,8 +446,18 @@ export class MenuBar extends Widget { | |||||
// Escape | ||||||
if (kc === 27) { | ||||||
this._closeChildMenu(); | ||||||
this.activeIndex = -1; | ||||||
this.node.blur(); | ||||||
return; | ||||||
} | ||||||
|
||||||
// Home | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if (kc === 36) { | ||||||
this.activeIndex = 0; | ||||||
return; | ||||||
} | ||||||
|
||||||
// End | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if (kc === 35) { | ||||||
this.activeIndex = this._menus.length - 1; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
return; | ||||||
} | ||||||
|
||||||
|
@@ -625,6 +635,9 @@ export class MenuBar extends Widget { | |||||
// Swap the internal menu reference. | ||||||
this._childMenu = newMenu; | ||||||
|
||||||
// Set the reference to this MenuBar that contains the menu. | ||||||
this._childMenu.parentMenuBar = this; | ||||||
|
||||||
// Close the current menu, or setup for the new menu. | ||||||
if (oldMenu) { | ||||||
oldMenu.close(); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readability: