diff --git a/README.md b/README.md index 29c60c3..54d3dbd 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ React.render(, container); |beforeUpload| function |null| before upload check, return false or a rejected Promise will stop upload, only for modern browsers| |customRequest | function | null | provide an override for the default xhr behavior for additional customization| |withCredentials | boolean | false | ajax upload with cookie send | -|openFileDialogOnClick | boolean | true | useful for drag only upload as it does not trigger on enter key or click event | +|openFileDialogOnClick | boolean/function():boolean | true | useful for drag only upload as it does not trigger on enter key or click event | |pastable | boolean | false | support paste upload | #### onError arguments diff --git a/src/AjaxUploader.tsx b/src/AjaxUploader.tsx index 0de6c29..2994182 100644 --- a/src/AjaxUploader.tsx +++ b/src/AjaxUploader.tsx @@ -305,6 +305,11 @@ class AjaxUploader extends Component { this.fileInput = node; }; + eventHandler = (fn: (() => boolean) | boolean, originFn: (e: React.MouseEvent | React.KeyboardEvent) => void, e: React.MouseEvent | React.KeyboardEvent) => { + if (typeof fn === 'function' ? fn() : fn) { + originFn(e); + } + }; render() { const { component: Tag, @@ -339,8 +344,8 @@ class AjaxUploader extends Component { const events = disabled ? {} : { - onClick: openFileDialogOnClick ? this.onClick : () => {}, - onKeyDown: openFileDialogOnClick ? this.onKeyDown : () => {}, + onClick: (e) => this.eventHandler(openFileDialogOnClick, this.onClick, e), + onKeyDown: (e) => this.eventHandler(openFileDialogOnClick, this.onKeyDown, e), onMouseEnter, onMouseLeave, onDrop: this.onFileDrop, diff --git a/src/interface.tsx b/src/interface.tsx index 2f182ff..864f2e1 100644 --- a/src/interface.tsx +++ b/src/interface.tsx @@ -31,7 +31,7 @@ export interface UploadProps ) => BeforeUploadFileType | Promise | void; customRequest?: (option: UploadRequestOption) => void | { abort: () => void }; withCredentials?: boolean; - openFileDialogOnClick?: boolean; + openFileDialogOnClick?: boolean | (() => boolean); prefixCls?: string; id?: string; onMouseEnter?: (e: React.MouseEvent) => void; diff --git a/tests/uploader.spec.tsx b/tests/uploader.spec.tsx index 44a4771..a7b25a5 100644 --- a/tests/uploader.spec.tsx +++ b/tests/uploader.spec.tsx @@ -1187,6 +1187,53 @@ describe('uploader', () => { }); }); + describe('openFileDialogOnClick', () => { + it('should block click when set to false', () => { + const onClick = jest.fn(); + const { container } = render(); + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should allow click when set to true', () => { + const onClick = jest.fn(); + const { container } = render(); + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).toHaveBeenCalled(); + }); + + it('should block click when function returns false', () => { + const onClick = jest.fn(); + const { container } = render( false} onClick={onClick} />); + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).not.toHaveBeenCalled(); + }); + + it('should allow click when function returns true', () => { + const onClick = jest.fn(); + const { container } = render( true} onClick={onClick} />); + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).toHaveBeenCalled(); + }); + + it('should support dynamic function return value', () => { + let shouldOpen = false; + const onClick = jest.fn(); + const { container, rerender } = render( shouldOpen} onClick={onClick} />); + + // first click (shouldOpen = false) + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).not.toHaveBeenCalled(); + + shouldOpen = true; + rerender( shouldOpen} onClick={onClick} />); + + // second click (shouldOpen = true) + fireEvent.click(container.querySelector('.rc-upload')!); + expect(onClick).toHaveBeenCalled(); + }); + }); + it('dynamic change action in beforeUpload should work', async () => { const Test = () => { const [action, setAction] = React.useState('light');