-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuseButtonRole.js
44 lines (40 loc) · 1.37 KB
/
useButtonRole.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* Mimic button element for a non-button controller.
*
* @param {Dialog|Disclosure|Popup} arg.component The component instance.
* @return {function} The cleanup function.
*/
export default function UseButtonRole({ component }) {
/**
* Treat the Spacebar and Return keys as clicks in case the controller is
* not a <button>.
*
* @param {Event} event The event object.
*/
const patchButtonKeydown = (event) => {
if ([' ', 'Enter'].includes(event.key)) {
event.preventDefault();
// Toggle, if it's available.
if (Object.prototype.hasOwnProperty.call(component, 'toggle')) {
component.toggle();
} else {
component.show();
}
}
};
// Patch button role and behavior for non-button controller.
if ('BUTTON' !== component.controller.nodeName) {
/*
* Some elements semantics conflict with the button role. You really
* should just use a button.
*/
component.addAttribute(component.controller, 'role', 'button');
component.controller.addEventListener('keydown', patchButtonKeydown);
// Ensure we can Tab to the controller even if it's not a button nor anchor.
if ('A' !== component.controller.nodeName) {
component.addAttribute(component.controller, 'tabindex', '0');
}
}
// Clean up.
return () => component.controller.removeEventListener('keydown', patchButtonKeydown);
}