When adding keyboard support to the extension or specific part the extension, following rules should be kept in mind.
Windows Admin Center has the following short keys implemented today. You can also access them through ? -> Keyboard shortcuts on top right corner of Windows Admin Center.
Move focus forward and backward between controls.
← ↑ → ↓Moves focus between elements in a control.
Home EndMoves focus between the first and last element within a control.
Ctrl + Alt + AMoves focus to the action bar.
Alt +F1Shows additional information on an info icon.
Moves focus between rows.
← →Moves focus between focusable elements in a row.
PageUp PageDownMoves focus up and down the table by the length of one page.
Home EndMoves focus between the first and last row.
Windows Admin Center provides built in keyboard navigation functionality to all common controls designed to let users navigate to everywhere on the page using just the keyboard following the guidelines stated above.
This works by traversing the DOM using Depth First Search to change the element focus based on the key pressed, element position, and element properties.
Focus zones are the tab stops defined by our controls. Within a focus zone, the user should be able to navigate through focusable elements using arrow and home/end keys. See in the image above an example of all of the focus zones we include in our application and the order in which you will visit them when tabbing through the application.
The things that make something a focus zone are:
If there is an area of your tool that you want to behave as a focus zone, add the appropriate role or the class "sme-focus-zone" to that element.
The things that make something a focusable element are:
If any of the above are true but the element has a disabled or hidden ancestor, the element is not focusable.
In the image above we show the expected tab stop order in forms as indicated by the red boxes and numbers. Notice that all form elements are focus zones. This means that in any form, you must tab through every element in the form to navigate between inputs. We also indicate in the image that dialogs are treated as focus traps. This means that once focus is inside of a dialog, the user should not be able to navigate to other parts of the application until they are done interacting with the dialog. Dialogs are the only acceptable type of focus traps in the application.
When making your tool keyboard accessible it is important to avoid mixed use zones. A mixed use zone is a focus zone that has children on the same level that are both zones and focusable elements as shown in black in the image above. Because our tab navigation relies on locating the next zone, having mixed use zones can result in unreachable elements. The solution is to explicitly define zones around all focusable elements with zone siblings so that there is a defined tab order for all elements. This solution is shown above in red.
All of the code to manage keyboard interactions come through AccessibilityManager (core\data\accessibility-manager.ts in the SDK) in shell. Accessibility manager has a global handler for all keydown events. Based on the keydown event, we traverse the DOM to change focus appropriately. To locate the appropriate element, we have a utility class called Dom (core\dom\dom.ts in the SDK) that handles all DOM traversal and identification of properties on DOM elements. The utilities in Dom can be called from any component for any custom behavior needed for keyboard accessibility.
If necessary, you can override the global keyboard handler in favor of custom behavior for your control.
In your control, you can register a function you wrote for handling focus events with our global event handler
CoreEnvironment.accessibilityManager.registerElementFocusingEvent(this.onElementFocusing.bind(this));
Then, your function onElementFocusing(event: ElementFocusingEvent)
will be passed an ElementFocusingEvent
. The ElementFocusingEvent
will give
you information about the event and current element. You can call event.preventDefaultFocusBehavior()
and
event.preventDefaultEvent()
if you want to override global keyboard handling as well as default browser behavior in favor of your handler.
See code in core\data\accessibility-manager.ts and usage in angular\src\controls\data-table\data-table.component.ts for examples.