-
Notifications
You must be signed in to change notification settings - Fork 2
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
Add focus-trap and tab-key keyboard navigation to ModalDialog
#931
Conversation
Fix landed and has been available since preact 10.7.2.
Codecov Report
@@ Coverage Diff @@
## main #931 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 64 65 +1
Lines 807 876 +69
Branches 289 313 +24
=========================================
+ Hits 807 876 +69
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
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.
Most of these tests, or at least their structure, were copied from the tests for useArrowKeyNavigation
. I'll call out where they differ.
/** | ||
* @param {string|Partial<KeyboardEvent>} key - Either a string name of a | ||
* key (e.g. 'ArrowLeft') or a partial `KeyboardEvent` object, e.g. | ||
* `{ key: 'Tab', shiftKey: true }` | ||
*/ | ||
function pressKey(key) { |
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.
I adjusted the parameters for this utility function so it can imitate more types of KeyboardEvent
s.
it('should not respond to keys if hook is not enabled', () => { | ||
renderToolbar({ | ||
enabled: false, | ||
}); | ||
['Tab', { key: 'Tab', shiftKey: true }].forEach(key => { | ||
findElementByTestId('bold').focus(); | ||
pressKey(key); | ||
assert.equal(currentItem(), 'Bold'); | ||
}); | ||
}); |
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.
This hook can be "enabled" or "disabled", which is a feature that useArrowKeyNavigation
does not have.
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.
This implementation is very close to useArrowKeyNavigation
but slightly simpler. It does add an enabled
option.
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.
We've completed aWith these changes, most of the behavioral features of these components are in place so I'm removing the TODO list.
/** | ||
* Don't respond to any keyboard events if not enabled. This allows selective | ||
* enabling by components using this hook, as hook use itself cannot be | ||
* conditional. |
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.
as hook use itself cannot be conditional.
Which is sad, because it would be useful sometimes 😅
This PR adds a new hook,
useTabKeyNavigation
, modeled afteruseArrowKeyNavigation
, and enables it by default forModalDialog
.This establishes trap-focus behavior and tab/shift-tab keyboard navigation for
ModalDialog
s, which we need for accessibility.Note that
useTabKeyNavigation
duplicates behavior fromuseArrowKeyNavigation
, per voice discussion earlier today. The life expectancy ofuseTabKeyNavigation
is short-ish, so this time-saving measure is perhaps justifiable.This PR also contains a commit that removes a no-longer-needed testing workaround for
useArrowKeyNavigation
's tests.Part of #77