rsuite
Version:
A suite of react components
90 lines (85 loc) • 2.37 kB
JavaScript
'use client';
import { KEY_VALUES } from "../../constants/index.js";
import { useEventCallback } from "../../hooks/index.js";
/**
* A hook to control the toggle keyboard operation
* @param props
*/
const useToggleKeyDownEvent = props => {
const {
toggle = true,
trigger,
target,
overlay,
searchInput,
active,
readOnly,
disabled,
loading,
onExit,
onKeyDown,
onMenuKeyDown,
onMenuPressEnter,
onMenuPressBackspace
} = props;
const handleClose = useEventCallback(() => {
trigger.current?.close?.();
// The focus is on the trigger button after closing
trigger.current?.focus?.();
});
const handleOpen = useEventCallback(() => {
trigger.current?.open?.();
});
const handleToggleDropdown = useEventCallback(() => {
if (active) {
handleClose();
return;
}
handleOpen();
});
const onToggle = useEventCallback(event => {
// Keyboard events should not be processed when readOnly and disabled are set.
if (readOnly || disabled || loading) {
return;
}
if (event.target === target?.current) {
// enter
if (toggle && event.key === KEY_VALUES.ENTER) {
handleToggleDropdown();
}
// delete
if (event.key === KEY_VALUES.BACKSPACE) {
onExit?.(event);
}
}
if (overlay?.current) {
// The keyboard operation callback on the menu.
onMenuKeyDown?.(event);
if (event.key === KEY_VALUES.ENTER) {
onMenuPressEnter?.(event);
}
/**
* There is no callback when typing the Backspace key in the search box.
* The default is to remove search keywords
*/
if (event.key === KEY_VALUES.BACKSPACE && event.target !== searchInput?.current) {
onMenuPressBackspace?.(event);
}
// The search box gets focus when typing characters and numbers.
if (event.key.length === 1 && /\w/.test(event.key)) {
// Exclude Input
// eg: <SelectPicker renderExtraFooter={() => <Input />} />
if (event.target?.tagName !== 'INPUT') {
searchInput?.current?.focus();
}
}
}
if (event.key === KEY_VALUES.ESC || event.key === KEY_VALUES.TAB) {
handleClose();
}
// Native event callback
onKeyDown?.(event);
});
return onToggle;
};
export default useToggleKeyDownEvent;