diff --git a/src/AjaxUploader.tsx b/src/AjaxUploader.tsx index 7d4e73e..ec63907 100644 --- a/src/AjaxUploader.tsx +++ b/src/AjaxUploader.tsx @@ -86,7 +86,8 @@ class AjaxUploader extends Component { }; onKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); this.onClick(e); } }; @@ -378,7 +379,7 @@ class AjaxUploader extends Component { ? {} : { onClick: openFileDialogOnClick ? this.onClick : () => {}, - onKeyDown: openFileDialogOnClick ? this.onKeyDown : () => {}, + onKeyDown: openFileDialogOnClick && !hasControlInside ? this.onKeyDown : () => {}, onMouseEnter, onMouseLeave, onDrop: this.onFileDrop, diff --git a/tests/uploader.spec.tsx b/tests/uploader.spec.tsx index 5ce7d01..b6868a8 100644 --- a/tests/uploader.spec.tsx +++ b/tests/uploader.spec.tsx @@ -1392,6 +1392,21 @@ describe('uploader', () => { expect(container.querySelector('span')).toHaveAttribute('role', 'button'); }); + it.each(['Enter', ' '])('Should open the file dialog with the %p key', key => { + const { container } = render(); + const input = container.querySelector('input')!; + const clickSpy = jest.spyOn(input, 'click').mockImplementation(() => {}); + const preventDefaultSpy = jest.spyOn(Event.prototype, 'preventDefault'); + + fireEvent.keyDown(container.querySelector('span')!, { key }); + + expect(clickSpy).toHaveBeenCalledTimes(1); + expect(preventDefaultSpy).toHaveBeenCalledTimes(1); + + clickSpy.mockRestore(); + preventDefaultSpy.mockRestore(); + }); + it("Should not be focusable and doesn't have role=button with hasControlInside=true", () => { const { container } = render(); @@ -1399,6 +1414,25 @@ describe('uploader', () => { expect(container.querySelector('span')!).not.toHaveAttribute('role', 'button'); }); + it.each(['Enter', ' '])('Should leave %p activation to the child control', key => { + const { container } = render( + + + , + ); + const input = container.querySelector('input')!; + const button = container.querySelector('button')!; + const clickSpy = jest.spyOn(input, 'click').mockImplementation(() => {}); + + expect(fireEvent.keyDown(button, { key })).toBe(true); + expect(clickSpy).not.toHaveBeenCalled(); + + fireEvent.click(button); + expect(clickSpy).toHaveBeenCalledTimes(1); + + clickSpy.mockRestore(); + }); + it("Should not be focusable and doesn't have role=button with openFileDialogOnClick=false", () => { const { container } = render();