useDocSearchKeyboardEvents.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import React from 'react';
  2. function isEditingContent(event) {
  3. var element = event.target;
  4. var tagName = element.tagName;
  5. return element.isContentEditable || tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
  6. }
  7. export function useDocSearchKeyboardEvents(_ref) {
  8. var isOpen = _ref.isOpen,
  9. onOpen = _ref.onOpen,
  10. onClose = _ref.onClose,
  11. onInput = _ref.onInput,
  12. searchButtonRef = _ref.searchButtonRef;
  13. React.useEffect(function () {
  14. function onKeyDown(event) {
  15. function open() {
  16. // We check that no other DocSearch modal is showing before opening
  17. // another one.
  18. if (!document.body.classList.contains('DocSearch--active')) {
  19. onOpen();
  20. }
  21. }
  22. if (event.keyCode === 27 && isOpen || // The `Cmd+K` shortcut both opens and closes the modal.
  23. event.key === 'k' && (event.metaKey || event.ctrlKey) || // The `/` shortcut opens but doesn't close the modal because it's
  24. // a character.
  25. !isEditingContent(event) && event.key === '/' && !isOpen) {
  26. event.preventDefault();
  27. if (isOpen) {
  28. onClose();
  29. } else if (!document.body.classList.contains('DocSearch--active')) {
  30. open();
  31. }
  32. }
  33. if (searchButtonRef && searchButtonRef.current === document.activeElement && onInput) {
  34. if (/[a-zA-Z0-9]/.test(String.fromCharCode(event.keyCode))) {
  35. onInput(event);
  36. }
  37. }
  38. }
  39. window.addEventListener('keydown', onKeyDown);
  40. return function () {
  41. window.removeEventListener('keydown', onKeyDown);
  42. };
  43. }, [isOpen, onOpen, onClose, onInput, searchButtonRef]);
  44. }