microsoft/keyborg

KeyborgState not updated when render two react projects

Closed this issue · 3 comments

Describe the issue:

There are two separate React projects, each bundled with the FluentUI library. Consequently, the Keyborg library is also divided and bundled separately in these two projects on the same page.

Both projects feature a Dialog component. However, when attempting to open the Dialog in the second project (which loaded after the first project), the buttons inside it cannot be focused using the tab key. This issue arises because the focus ring style is lost.

Reproduction in Codepen: https://codesandbox.io/s/fluentui-bug-report-dqkq5q?file=/example.tsx
image

The related Bug item in Azure Board: Bug 16980: [Dialog]: [button in dialog do not have focus ring] button in dialog do not have focus ring when render two react project

Root cause I found:

Quick summary:
There are two Keyborg scripts bundled separately on the same page, and both bundles share the same global variable window.__keyborg, as well as the same KeyborgCore instance, KeyborgCore adds focus event listeners to the document to control the updation of _isNavigatingWithKeyboard variable in KeyborgState. However, the KeyborgState is not designed to be shared between the two projects. As a result, when a focus event occurs in the second project, it triggers a change of state in the first project instead of affecting the second project itself.

Proposal:
To resolve the issue, make KeyborgState sharable by converting it into a private variable within the KeyborgCore class.

image

@ling1726 Would you help to follow up?

A partner is hitting this issue, as @Hchyeria mentions Fluent UI uses this function:

image

and as our partner is using keyborg in two different bundles, focus is not shown with the outline causing accessibility violations.

Small nit to the issue description: the buttons can be focused with keyboard, but the focus state is not visible. Can be verified using document.activeElement. But it's still an accessibility violation.

My project is also facing the same problem with Fluent UI v9. Fluent UI uses isNavigatingWithKeyboard() to determine whether to draw a focus state. If the focus event is from a mouse or other pointer device, then no focus state will be drawn. If the focus event is from keyboard navigation, then a focus outline will be drawn.