From ec3db0ce22cf11d2002c349f69d52099547cd7a8 Mon Sep 17 00:00:00 2001 From: ChenYong Date: Thu, 23 Apr 2020 17:15:03 +0800 Subject: [PATCH 1/3] provide hooks API uploadTrigger; alpha release --- example/pages/upload-wrapper.tsx | 27 ++++++++- package.json | 2 +- src/component/upload-wrapper.tsx | 96 +++++++++++++++++++------------- 3 files changed, 83 insertions(+), 42 deletions(-) diff --git a/example/pages/upload-wrapper.tsx b/example/pages/upload-wrapper.tsx index 983ea36..cb2a51f 100644 --- a/example/pages/upload-wrapper.tsx +++ b/example/pages/upload-wrapper.tsx @@ -1,12 +1,20 @@ import React, { FC } from "react"; import { css } from "emotion"; import { DocDemo, DocSnippet, DocBlock } from "@jimengio/doc-frame"; -import { UploadWrapper } from "../../src"; +import UploadWrapper, { useUploadTrigger } from "../../src/component/upload-wrapper"; import { Button } from "antd"; import { JimoButton } from "@jimengio/jimo-basics"; let PageUploadWrapper: FC<{}> = React.memo((props) => { /** Plugins */ + + let uploadPlugin = useUploadTrigger({ + acceptedFileTypes: ["jpg", "png"], + onChange: async (files) => { + console.log("files", files); + }, + }); + /** Methods */ /** Effects */ /** Renderers */ @@ -24,6 +32,12 @@ let PageUploadWrapper: FC<{}> = React.memo((props) => { {}}> + + + + + {uploadPlugin.ui} + ); }); @@ -43,3 +57,14 @@ let code = ` let content = ` UploadWrapper 可以包裹一个区域, 用来获取 File 对象. 得到 File 对象之后, 再通过 API 手动发送. `; + +let hooksCode = ` +let uploadPlugin = useUploadTrigger({ + acceptedFileTypes: ["jpg", "png"], + onChange: async (files) => { + console.log("files", files); + }, +}); + + +`; diff --git a/package.json b/package.json index c8ad5f1..029aecc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jimengio/files-picker", - "version": "0.0.1-a12", + "version": "0.0.1-a13", "description": "", "main": "lib/index.js", "scripts": { diff --git a/src/component/upload-wrapper.tsx b/src/component/upload-wrapper.tsx index 437deaa..901dcda 100644 --- a/src/component/upload-wrapper.tsx +++ b/src/component/upload-wrapper.tsx @@ -29,7 +29,7 @@ interface IProps { onError?: (error: EUploadError) => void; } -let UploadWrapper: FC = React.memo((props) => { +export let useUploadTrigger = (props: IProps) => { let inputElement = useRef(null); let inputAccepts = props.accept; @@ -40,6 +40,59 @@ let UploadWrapper: FC = React.memo((props) => { } } + let ui = ( + { + if (props.onChange) { + const fileList = Array.from(e.target.files); // copy to array before resetting + + e.target.files = null; // without resetting, not able to trigger a change after failed + + if (fileList.length > 0) { + const files: File[] = []; + + fileList.forEach((file) => { + const fileExtension = file.name.split(".").pop(); + if (props.acceptedFileTypes && !props.acceptedFileTypes.includes(fileExtension)) { + if (props.onError) { + props.onError(EUploadError.unsupportedFileType); + } + message.error(interpolateLocale(uploadingLocales.unsupportedFileType, { type: props.acceptedFileTypes.join(", ") })); + return; + } + files.push(file); + }); + + props.onChange(files); + } + } + }} + /> + ); + + let onUpload = () => { + if (inputElement.current != null) { + inputElement.current.click(); + } else { + console.error("input element for files is not mounted!"); + } + }; + + return { + ui, + onUpload, + }; +}; + +let UploadWrapper: FC = React.memo((props) => { + let uploadPlugin = useUploadTrigger(props); + /** Plugins */ /** Methods */ /** Effects */ @@ -48,48 +101,11 @@ let UploadWrapper: FC = React.memo((props) => {
{ - if (inputElement.current != null) { - inputElement.current.click(); - } else { - console.error("Input element is missing in upload wrapper"); - } + uploadPlugin.onUpload(); }} > {props.children} - - { - if (props.onChange) { - const fileList = Array.from(e.target.files); // copy to array before resetting - - e.target.files = null; // without resetting, not able to trigger a change after failed - - if (fileList.length > 0) { - const files: File[] = []; - - fileList.forEach((file) => { - const fileExtension = file.name.split(".").pop(); - if (props.acceptedFileTypes && !props.acceptedFileTypes.includes(fileExtension)) { - if (props.onError) { - props.onError(EUploadError.unsupportedFileType); - } - message.error(interpolateLocale(uploadingLocales.unsupportedFileType, { type: props.acceptedFileTypes.join(", ") })); - return; - } - files.push(file); - }); - - props.onChange(files); - } - } - }} - /> + {uploadPlugin.ui}
); }); From 94611bc030ab001e5760b50084b4ad1bb699dc7f Mon Sep 17 00:00:00 2001 From: ChenYong Date: Thu, 23 Apr 2020 17:22:15 +0800 Subject: [PATCH 2/3] expose useUploadTrigger; alpha release --- package.json | 2 +- src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 029aecc..3839250 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jimengio/files-picker", - "version": "0.0.1-a13", + "version": "0.0.1-a14", "description": "", "main": "lib/index.js", "scripts": { diff --git a/src/index.ts b/src/index.ts index f223938..a29b230 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ export { default as BaseUpload } from "./component/base-upload"; export { default as BaseDisplay } from "./component/base-display"; -export { default as UploadWrapper } from "./component/upload-wrapper"; +export { default as UploadWrapper, useUploadTrigger } from "./component/upload-wrapper"; export { default as Dropzone } from "./component/dropzone"; export { uploadByUrl, getDownloadUrl, uploadSign } from "./api"; From 1dd2aa104a94b48f672ff302a4912235616cbd62 Mon Sep 17 00:00:00 2001 From: ChenYong Date: Thu, 23 Apr 2020 17:38:19 +0800 Subject: [PATCH 3/3] handle files data in trigger function; alpha release --- example/pages/upload-wrapper.tsx | 24 ++++++++++++++++-------- package.json | 2 +- src/component/upload-wrapper.tsx | 19 ++++++++++++------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/example/pages/upload-wrapper.tsx b/example/pages/upload-wrapper.tsx index cb2a51f..1836e00 100644 --- a/example/pages/upload-wrapper.tsx +++ b/example/pages/upload-wrapper.tsx @@ -10,9 +10,6 @@ let PageUploadWrapper: FC<{}> = React.memo((props) => { let uploadPlugin = useUploadTrigger({ acceptedFileTypes: ["jpg", "png"], - onChange: async (files) => { - console.log("files", files); - }, }); /** Methods */ @@ -34,7 +31,14 @@ let PageUploadWrapper: FC<{}> = React.memo((props) => { - + { + uploadPlugin.onUpload((files) => { + console.log("files", files); + }); + }} + > {uploadPlugin.ui} @@ -61,10 +65,14 @@ UploadWrapper 可以包裹一个区域, 用来获取 File 对象. 得到 File let hooksCode = ` let uploadPlugin = useUploadTrigger({ acceptedFileTypes: ["jpg", "png"], - onChange: async (files) => { - console.log("files", files); - }, }); - + { + uploadPlugin.onUpload((files) => { + console.log("files", files); + }); + }} +> `; diff --git a/package.json b/package.json index 3839250..3cfbb26 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@jimengio/files-picker", - "version": "0.0.1-a14", + "version": "0.0.1-a15", "description": "", "main": "lib/index.js", "scripts": { diff --git a/src/component/upload-wrapper.tsx b/src/component/upload-wrapper.tsx index 901dcda..d42c3c8 100644 --- a/src/component/upload-wrapper.tsx +++ b/src/component/upload-wrapper.tsx @@ -25,12 +25,13 @@ interface IProps { accept?: string; multiple?: boolean; className?: string; - onChange: (fileList: File[]) => Promise; + onChange?: (fileList: File[]) => Promise; onError?: (error: EUploadError) => void; } export let useUploadTrigger = (props: IProps) => { let inputElement = useRef(null); + let filesHandlerRef = useRef<(files: File[]) => void>(null); let inputAccepts = props.accept; @@ -49,11 +50,9 @@ export let useUploadTrigger = (props: IProps) => { accept={inputAccepts} multiple={props.multiple} onChange={async (e) => { - if (props.onChange) { + if (props.onChange || filesHandlerRef.current) { const fileList = Array.from(e.target.files); // copy to array before resetting - e.target.files = null; // without resetting, not able to trigger a change after failed - if (fileList.length > 0) { const files: File[] = []; @@ -69,14 +68,20 @@ export let useUploadTrigger = (props: IProps) => { files.push(file); }); - props.onChange(files); + props.onChange?.(files); + filesHandlerRef.current?.(files); + filesHandlerRef.current = null; } } + + // reset selected files to null, or selecting same file will not trigger events + e.target.value = ""; }} /> ); - let onUpload = () => { + let onUpload = (onFiles: (files: File[]) => void) => { + filesHandlerRef.current = onFiles; if (inputElement.current != null) { inputElement.current.click(); } else { @@ -101,7 +106,7 @@ let UploadWrapper: FC = React.memo((props) => {
{ - uploadPlugin.onUpload(); + uploadPlugin.onUpload(null); }} > {props.children}