diff --git a/src/AjaxUploader.tsx b/src/AjaxUploader.tsx index 0244c3be..be41699b 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); } }; @@ -363,15 +364,20 @@ class AjaxUploader extends Component { ? {} : { onClick: openFileDialogOnClick ? this.onClick : () => {}, - onKeyDown: openFileDialogOnClick ? this.onKeyDown : () => {}, + onKeyDown: openFileDialogOnClick && !hasControlInside ? this.onKeyDown : () => {}, onMouseEnter, onMouseLeave, onDrop: this.onFileDrop, onDragOver: this.onFileDragOver, - tabIndex: hasControlInside ? undefined : '0', + tabIndex: hasControlInside || !openFileDialogOnClick ? undefined : '0', }; return ( - + { 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(); @@ -1320,6 +1335,32 @@ 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 when click upload is disabled", () => { + const { container } = render(); + + expect(container.querySelector('span')!.tabIndex).not.toBe(0); + expect(container.querySelector('span')!).not.toHaveAttribute('role', 'button'); + }); + it('should receive same defaultRequest as src', done => { const { default: srcRequest } = require('../src/request'); let receivedDefaultRequest: any;