diff --git a/src/KeyCode.ts b/src/KeyCode.ts index 2746f9e9..2f1dd427 100644 --- a/src/KeyCode.ts +++ b/src/KeyCode.ts @@ -517,6 +517,26 @@ const KeyCode = { return false; } }, + + isEditableTarget: function isEditableTarget(e: KeyboardEvent) { + const target = e.target; + + if (!(target instanceof HTMLElement)) { + return false; + } + + const tagName = target.tagName; + if ( + tagName === 'INPUT' || + tagName === 'TEXTAREA' || + tagName === 'SELECT' || + target.isContentEditable + ) { + return true; + } + + return false; + }, }; export default KeyCode; diff --git a/tests/KeyCode.test.ts b/tests/KeyCode.test.ts new file mode 100644 index 00000000..25f00ac3 --- /dev/null +++ b/tests/KeyCode.test.ts @@ -0,0 +1,48 @@ +import KeyCode from '../src/KeyCode'; +import { createEvent } from '@testing-library/react'; + +describe('KeyCode.isEditableTarget', () => { + it('check editable target', () => { + const eleList = [ + { + element: 'window', + expected: false, + }, + { + element: 'div', + expected: false, + }, + { + element: 'input', + expected: true, + }, + { + element: 'textarea', + expected: true, + }, + { + element: 'select', + expected: true, + }, + { + element: 'div', + isContentEditable: true, + expected: true, + }, + ]; + + eleList.forEach(({ element, isContentEditable, expected }) => { + const target = + element === 'window' ? window : document.createElement(element); + if (isContentEditable) { + // mock isContentEditable cause JSDOM don't support it + Object.defineProperty(target, 'isContentEditable', { value: true }); + } + const event = createEvent.keyDown(target) as KeyboardEvent; + target.dispatchEvent(event); + const result = KeyCode.isEditableTarget(event); + + expect(result).toBe(expected); + }); + }); +});