From 1c24915b9d84d7c73a747f30d1354d17fadf4038 Mon Sep 17 00:00:00 2001 From: Oleksandr Fediashov Date: Wed, 19 Aug 2020 11:36:43 +0200 Subject: [PATCH] fix(Dropdown): fix handling of "Space" key (#4041) * fix(Dropdown): fix handling of "Space" key * fix UTs, add a test --- .babel-preset.js | 1 + src/modules/Dropdown/Dropdown.js | 18 +++++++++++---- test/specs/modules/Dropdown/Dropdown-test.js | 23 +++++++++++++++++--- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/.babel-preset.js b/.babel-preset.js index 2cafb2933f..5054527696 100644 --- a/.babel-preset.js +++ b/.babel-preset.js @@ -17,6 +17,7 @@ const browsers = [ const plugins = [ ['@babel/plugin-proposal-class-properties', { loose: true }], + ['@babel/plugin-proposal-optional-chaining', { loose: true }], '@babel/plugin-proposal-export-default-from', '@babel/plugin-proposal-export-namespace-from', '@babel/plugin-syntax-dynamic-import', diff --git a/src/modules/Dropdown/Dropdown.js b/src/modules/Dropdown/Dropdown.js index 600871fc79..ed3353aa96 100644 --- a/src/modules/Dropdown/Dropdown.js +++ b/src/modules/Dropdown/Dropdown.js @@ -239,10 +239,20 @@ export default class Dropdown extends Component { openOnSpace = (e) => { debug('openOnSpace()') - if (keyboardKey.getCode(e) !== keyboardKey.Spacebar) return + const shouldHandleEvent = + this.state.focus && !this.state.open && keyboardKey.getCode(e) === keyboardKey.Spacebar + const shouldPreventDefault = + e.target?.tagName !== 'INPUT' && + e.target?.tagName !== 'TEXTAREA' && + e.target?.isContentEditable !== true + + if (shouldHandleEvent) { + if (shouldPreventDefault) { + e.preventDefault() + } - e.preventDefault() - this.open(e) + this.open(e) + } } openOnArrow = (e) => { @@ -549,6 +559,7 @@ export default class Dropdown extends Component { handleKeyDown = (e) => { this.moveSelectionOnKeyDown(e) this.openOnArrow(e) + this.openOnSpace(e) this.selectItemOnEnter(e) _.invoke(this.props, 'onKeyDown', e) @@ -1089,7 +1100,6 @@ export default class Dropdown extends Component { {open && } {focus && } - {focus && !open && } ) diff --git a/test/specs/modules/Dropdown/Dropdown-test.js b/test/specs/modules/Dropdown/Dropdown-test.js index f5d40a4a7e..e49d0236df 100644 --- a/test/specs/modules/Dropdown/Dropdown-test.js +++ b/test/specs/modules/Dropdown/Dropdown-test.js @@ -530,7 +530,7 @@ describe('Dropdown', () => { document.activeElement.blur() // doesn't open on space - domEvent.keyDown(document, { key: ' ' }) + wrapper.simulate('keydown', { key: 'Spacebar' }) wrapper.update() dropdownMenuIsClosed() }) @@ -1263,6 +1263,7 @@ describe('Dropdown', () => { }) it('opens on space when focused', () => { + const preventDefault = sandbox.spy() wrapperMount() // Note: This mousedown is necessary to get the Dropdown focused @@ -1271,8 +1272,24 @@ describe('Dropdown', () => { wrapper.simulate('focus') dropdownMenuIsClosed() - domEvent.keyDown(document, { key: ' ' }) + wrapper.simulate('keydown', { key: 'Spacebar', preventDefault }) dropdownMenuIsOpen() + preventDefault.should.have.been.calledOnce() + }) + + it('opens on space in search input when focused', () => { + const preventDefault = sandbox.spy() + wrapperMount() + + // Note: This mousedown is necessary to get the Dropdown focused + // without it being open. + wrapper.simulate('mousedown') + wrapper.simulate('focus') + dropdownMenuIsClosed() + + wrapper.find('input.search').simulate('keydown', { key: 'Spacebar', preventDefault }) + dropdownMenuIsOpen() + preventDefault.should.have.not.been.called() }) it('does not open on arrow down when not focused', () => { @@ -1287,7 +1304,7 @@ describe('Dropdown', () => { wrapperMount() dropdownMenuIsClosed() - domEvent.keyDown(document, { key: ' ' }) + wrapper.simulate('keydown', { key: 'Spacebar' }) dropdownMenuIsClosed() })