@mezzanine-ui/react 0.7.2 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Upload/UploadInput.js +2 -0
- package/Upload/UploadPicture.d.ts +48 -0
- package/Upload/UploadPicture.js +52 -0
- package/Upload/UploadPictureBlock.d.ts +13 -0
- package/Upload/UploadPictureBlock.js +86 -0
- package/Upload/UploadPictureWall.d.ts +71 -0
- package/Upload/UploadPictureWall.js +156 -0
- package/Upload/UploadPictureWallItem.d.ts +13 -0
- package/Upload/UploadPictureWallItem.js +19 -0
- package/Upload/index.d.ts +3 -0
- package/Upload/index.js +3 -0
- package/index.d.ts +1 -1
- package/index.js +2 -0
- package/package.json +3 -3
package/Upload/UploadInput.js
CHANGED
|
@@ -5,6 +5,8 @@ import { uploadInputClasses } from '@mezzanine-ui/core/upload';
|
|
|
5
5
|
const UploadInput = forwardRef((props, ref) => {
|
|
6
6
|
const { accept, disabled = false, multiple = false, onUpload, } = props;
|
|
7
7
|
return (jsx("input", { ref: ref, accept: accept, "aria-disabled": disabled, className: uploadInputClasses.host, disabled: disabled, multiple: multiple, onClick: (event) => {
|
|
8
|
+
// eslint-disable-next-line no-param-reassign
|
|
9
|
+
event.currentTarget.value = '';
|
|
8
10
|
event.stopPropagation();
|
|
9
11
|
event.nativeEvent.stopImmediatePropagation();
|
|
10
12
|
}, onChange: (event) => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
|
+
export declare type UploadPictureControl = {
|
|
4
|
+
getData: () => void;
|
|
5
|
+
};
|
|
6
|
+
export interface UploadPictureProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'children' | 'onChange' | 'onError' | 'value'> {
|
|
7
|
+
/**
|
|
8
|
+
* The accept attributes of native input element.
|
|
9
|
+
* @default 'image/*'
|
|
10
|
+
*/
|
|
11
|
+
accept?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Provide `controllerRef` if you need detail data of file.
|
|
14
|
+
*/
|
|
15
|
+
controllerRef?: Ref<UploadPictureControl | null>;
|
|
16
|
+
/**
|
|
17
|
+
* The default value of uploader.
|
|
18
|
+
*/
|
|
19
|
+
defaultValue?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the input which is disabled.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Fired after value changed.
|
|
27
|
+
*/
|
|
28
|
+
onChange?: (url: string) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Fired after user delete image.
|
|
31
|
+
*/
|
|
32
|
+
onDelete?: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Fired after user upload image failed.
|
|
35
|
+
*/
|
|
36
|
+
onError?: (file: File) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Fired when user upload image, need to return Promise<string>.
|
|
39
|
+
* Arg1 is target file, arg2 `setProgress` can set the progress of uploading.
|
|
40
|
+
*/
|
|
41
|
+
onUpload?: (file: File, setProgress: (progress: number) => void) => Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Fired after user upload image success.
|
|
44
|
+
*/
|
|
45
|
+
onUploadSuccess?: (file: File, url: string) => void;
|
|
46
|
+
}
|
|
47
|
+
declare const UploadPicture: import("react").ForwardRefExoticComponent<UploadPictureProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
48
|
+
export default UploadPicture;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useRef, useCallback, useImperativeHandle } from 'react';
|
|
3
|
+
import { ImageUploader, uploadPictureClasses } from '@mezzanine-ui/core/upload';
|
|
4
|
+
import UploadPictureBlock from './UploadPictureBlock.js';
|
|
5
|
+
import cx from 'clsx';
|
|
6
|
+
|
|
7
|
+
const UploadPicture = forwardRef(function UploadPicture(props, ref) {
|
|
8
|
+
const { accept = 'image/*', className, controllerRef, defaultValue, disabled = false, onChange, onDelete, onError, onUpload, onUploadSuccess, style, } = props;
|
|
9
|
+
const defaultImageUploader = new ImageUploader(undefined, defaultValue);
|
|
10
|
+
const uploadPictureImageLoader = useRef(defaultImageUploader);
|
|
11
|
+
const onImageUpload = useCallback((files) => {
|
|
12
|
+
if (files.length) {
|
|
13
|
+
const currentFile = files[0];
|
|
14
|
+
uploadPictureImageLoader.current.setNewFile(currentFile);
|
|
15
|
+
uploadPictureImageLoader.current.setPreview();
|
|
16
|
+
if (onUpload) {
|
|
17
|
+
const setProgress = (progress) => uploadPictureImageLoader.current.setPercentage(progress);
|
|
18
|
+
uploadPictureImageLoader.current.setLoadingStatus(true);
|
|
19
|
+
onUpload(currentFile, setProgress)
|
|
20
|
+
.then((url) => {
|
|
21
|
+
uploadPictureImageLoader.current.setUrl(url);
|
|
22
|
+
uploadPictureImageLoader.current.setLoadingStatus(false);
|
|
23
|
+
setProgress(100);
|
|
24
|
+
if (onUploadSuccess) {
|
|
25
|
+
onUploadSuccess(currentFile, url);
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
.catch(() => {
|
|
29
|
+
uploadPictureImageLoader.current.setErrorStatus(true);
|
|
30
|
+
uploadPictureImageLoader.current.setLoadingStatus(false);
|
|
31
|
+
setProgress(100);
|
|
32
|
+
if (onError) {
|
|
33
|
+
onError(currentFile);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}, [onUpload, onUploadSuccess, onError]);
|
|
39
|
+
const onImageDelete = useCallback(() => {
|
|
40
|
+
uploadPictureImageLoader.current.clear();
|
|
41
|
+
if (onDelete) {
|
|
42
|
+
onDelete();
|
|
43
|
+
}
|
|
44
|
+
}, [onDelete]);
|
|
45
|
+
useImperativeHandle(controllerRef, () => ({
|
|
46
|
+
getData: () => uploadPictureImageLoader.current.getAll(),
|
|
47
|
+
}));
|
|
48
|
+
return (jsx("div", Object.assign({ ref: ref, className: cx(uploadPictureClasses.host, className), style: style }, { children: jsx(UploadPictureBlock, { accept: accept, disabled: disabled, imageLoader: uploadPictureImageLoader.current, multiple: false, onDelete: onImageDelete, onUpload: onImageUpload, onValueChange: onChange }, void 0) }), void 0));
|
|
49
|
+
});
|
|
50
|
+
var UploadPicture$1 = UploadPicture;
|
|
51
|
+
|
|
52
|
+
export { UploadPicture$1 as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { MouseEventHandler } from 'react';
|
|
2
|
+
import { ImageUploader } from '@mezzanine-ui/core/upload';
|
|
3
|
+
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
4
|
+
export interface UploadPictureBlockProps extends Omit<NativeElementPropsWithoutKeyAndRef<'button'>, 'children' | 'onChange' | 'value'> {
|
|
5
|
+
accept?: string;
|
|
6
|
+
imageLoader: ImageUploader;
|
|
7
|
+
multiple?: boolean;
|
|
8
|
+
onDelete?: MouseEventHandler;
|
|
9
|
+
onUpload?: (files: File[]) => void;
|
|
10
|
+
onValueChange?: (value: string) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const UploadPictureBlock: import("react").ForwardRefExoticComponent<UploadPictureBlockProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
13
|
+
export default UploadPictureBlock;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
3
|
+
import { toUploadPictureBlockCssVars, uploadPictureBlockClasses } from '@mezzanine-ui/core/upload';
|
|
4
|
+
import { TimesIcon, SpinnerIcon, UploadIcon, TrashIcon } from '@mezzanine-ui/icons';
|
|
5
|
+
import { usePreviousValue } from '../hooks/usePreviousValue.js';
|
|
6
|
+
import UploadInput from './UploadInput.js';
|
|
7
|
+
import Icon from '../Icon/Icon.js';
|
|
8
|
+
import cx from 'clsx';
|
|
9
|
+
|
|
10
|
+
const UploadPictureBlock = forwardRef(function UploadPictureBlock(props, ref) {
|
|
11
|
+
const { accept = 'image/*', disabled = false, imageLoader, multiple = false, onDelete, onUpload, onValueChange, } = props;
|
|
12
|
+
const [previewImage, setPreviewImage] = useState(imageLoader.getPreview() || '');
|
|
13
|
+
const [value, setValue] = useState(imageLoader.getUrl() || '');
|
|
14
|
+
const [percentage, setPercentage] = useState(imageLoader.getPercentage() || 0);
|
|
15
|
+
const [isLoading, setIsLoading] = useState(imageLoader.getIsLoading() || false);
|
|
16
|
+
const [isError, setIsError] = useState(imageLoader.getIsError() || false);
|
|
17
|
+
const inputRef = useRef(null);
|
|
18
|
+
const prevValue = usePreviousValue(value);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (onValueChange && value !== prevValue) {
|
|
21
|
+
onValueChange(value);
|
|
22
|
+
}
|
|
23
|
+
}, [onValueChange, prevValue, value]);
|
|
24
|
+
const setImageUploaderData = useCallback(() => {
|
|
25
|
+
const data = imageLoader.getAll();
|
|
26
|
+
setPreviewImage(data.preview);
|
|
27
|
+
setValue(data.url);
|
|
28
|
+
setPercentage(data.percentage);
|
|
29
|
+
setIsLoading(data.isLoading);
|
|
30
|
+
setIsError(data.isError);
|
|
31
|
+
}, [imageLoader]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
imageLoader.on('fileChange', () => {
|
|
34
|
+
setImageUploaderData();
|
|
35
|
+
});
|
|
36
|
+
imageLoader.on('previewChange', () => {
|
|
37
|
+
setPreviewImage(imageLoader.getPreview());
|
|
38
|
+
});
|
|
39
|
+
imageLoader.on('percentageChange', () => {
|
|
40
|
+
setPercentage(imageLoader.getPercentage());
|
|
41
|
+
});
|
|
42
|
+
imageLoader.on('urlChange', () => {
|
|
43
|
+
setValue(imageLoader.getUrl());
|
|
44
|
+
});
|
|
45
|
+
imageLoader.on('loadingStatusChange', () => {
|
|
46
|
+
setIsLoading(imageLoader.getIsLoading());
|
|
47
|
+
});
|
|
48
|
+
imageLoader.on('errorStatusChange', () => {
|
|
49
|
+
setIsError(imageLoader.getIsError());
|
|
50
|
+
});
|
|
51
|
+
imageLoader.on('clear', () => {
|
|
52
|
+
setImageUploaderData();
|
|
53
|
+
});
|
|
54
|
+
return () => {
|
|
55
|
+
imageLoader.removeAllListeners();
|
|
56
|
+
};
|
|
57
|
+
}, [imageLoader, setImageUploaderData]);
|
|
58
|
+
const cssVars = toUploadPictureBlockCssVars({ percentage });
|
|
59
|
+
const style = {
|
|
60
|
+
...cssVars,
|
|
61
|
+
};
|
|
62
|
+
const showImage = useMemo(() => ((value || previewImage) && !isError), [previewImage, value, isError]);
|
|
63
|
+
const canDeleteImage = useMemo(() => ((showImage || isError) && !isLoading), [showImage, isError, isLoading]);
|
|
64
|
+
return (jsxs("button", Object.assign({ ref: ref, type: "button", "aria-disabled": disabled, disabled: disabled, onClick: (event) => {
|
|
65
|
+
var _a;
|
|
66
|
+
if (!showImage && !isError) {
|
|
67
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
68
|
+
}
|
|
69
|
+
if (canDeleteImage && onDelete) {
|
|
70
|
+
onDelete(event);
|
|
71
|
+
}
|
|
72
|
+
}, className: cx(uploadPictureBlockClasses.host, {
|
|
73
|
+
[uploadPictureBlockClasses.loading]: isLoading,
|
|
74
|
+
[uploadPictureBlockClasses.error]: isError,
|
|
75
|
+
[uploadPictureBlockClasses.disabled]: disabled,
|
|
76
|
+
}), style: style }, { children: [jsx(UploadInput, { ref: inputRef, accept: accept, disabled: disabled, multiple: multiple, onUpload: onUpload }, void 0),
|
|
77
|
+
isError ? (jsxs("div", Object.assign({ className: uploadPictureBlockClasses.group }, { children: [jsx(Icon, { icon: TimesIcon }, void 0),
|
|
78
|
+
jsx("span", Object.assign({ className: uploadPictureBlockClasses.status }, { children: "\u4E0A\u50B3\u932F\u8AA4" }), void 0)] }), void 0)) : (jsx(Fragment, { children: showImage ? (jsxs(Fragment, { children: [jsx("img", { alt: "", src: (value || previewImage), className: uploadPictureBlockClasses.preview }, void 0),
|
|
79
|
+
isLoading ? (jsxs("div", Object.assign({ className: uploadPictureBlockClasses.group }, { children: [jsx(Icon, { icon: SpinnerIcon, spin: true }, void 0),
|
|
80
|
+
jsx("span", Object.assign({ className: uploadPictureBlockClasses.status }, { children: "\u4E0A\u50B3\u4E2D..." }), void 0)] }), void 0)) : null] }, void 0)) : (jsxs("div", Object.assign({ className: uploadPictureBlockClasses.group }, { children: [jsx(Icon, { icon: UploadIcon }, void 0),
|
|
81
|
+
jsx("span", Object.assign({ className: uploadPictureBlockClasses.status }, { children: "\u4E0A\u50B3\u5F71\u50CF" }), void 0)] }), void 0)) }, void 0)),
|
|
82
|
+
!disabled && canDeleteImage && (jsx("div", Object.assign({ className: uploadPictureBlockClasses.delete }, { children: jsx(Icon, { icon: TrashIcon }, void 0) }), void 0))] }), void 0));
|
|
83
|
+
});
|
|
84
|
+
var UploadPictureBlock$1 = UploadPictureBlock;
|
|
85
|
+
|
|
86
|
+
export { UploadPictureBlock$1 as default };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
|
+
export declare type UploadPictureWallControl = {
|
|
4
|
+
getAllData: () => void;
|
|
5
|
+
};
|
|
6
|
+
export interface UploadPictureWallBaseProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'children' | 'onChange' | 'onError' | 'value'> {
|
|
7
|
+
/**
|
|
8
|
+
* The accept attributes of native input element.
|
|
9
|
+
* @default 'image/*'
|
|
10
|
+
*/
|
|
11
|
+
accept?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Provide `controllerRef` if you need detail data of files.
|
|
14
|
+
*/
|
|
15
|
+
controllerRef?: Ref<UploadPictureWallControl | null>;
|
|
16
|
+
/**
|
|
17
|
+
* The default values of uploader.
|
|
18
|
+
*/
|
|
19
|
+
defaultValues?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Whether the input which is disabled.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the input which is multiple.
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
multiple?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Fired after values changed.
|
|
32
|
+
*/
|
|
33
|
+
onChange?: (urls: string[]) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Fired after user delete image.
|
|
36
|
+
*/
|
|
37
|
+
onDelete?: (urls: string[]) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Fired after user upload images failed.
|
|
40
|
+
*/
|
|
41
|
+
onError?: (files: File | File[]) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Fired after user upload images success.
|
|
44
|
+
*/
|
|
45
|
+
onUploadSuccess?: (files: File | File[], urls: string | string[]) => void;
|
|
46
|
+
}
|
|
47
|
+
export interface UploadPictureWallSingleUploadProps extends UploadPictureWallBaseProps {
|
|
48
|
+
onMultiUpload?: undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Fired when user upload image, need to return Promise<string>.
|
|
51
|
+
* Arg1 is target file, arg2 `setProgress` can set the progress of uploading.
|
|
52
|
+
*/
|
|
53
|
+
onUpload?: (file: File, setProgress: (progress: number) => void) => Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the uploading which is parallel, only enabled when `onUpload` is given .
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
parallel?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface UploadPictureWallMultiUploadProps extends UploadPictureWallBaseProps {
|
|
61
|
+
/**
|
|
62
|
+
* Fired when user upload images, need to return Promise<string[]>.
|
|
63
|
+
* Arg1 is target files, arg2 `setProgress` can set the progress of uploading.
|
|
64
|
+
*/
|
|
65
|
+
onMultiUpload?: (files: File[], setProgress: (progress: number) => void) => Promise<string[]>;
|
|
66
|
+
onUpload?: undefined;
|
|
67
|
+
parallel?: undefined;
|
|
68
|
+
}
|
|
69
|
+
export declare type UploadPictureWallProps = UploadPictureWallSingleUploadProps | UploadPictureWallMultiUploadProps;
|
|
70
|
+
declare const UploadPictureWall: import("react").ForwardRefExoticComponent<(UploadPictureWallSingleUploadProps & import("react").RefAttributes<HTMLDivElement>) | (UploadPictureWallMultiUploadProps & import("react").RefAttributes<HTMLDivElement>)>;
|
|
71
|
+
export default UploadPictureWall;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useState, useMemo, useEffect, useCallback, useImperativeHandle } from 'react';
|
|
3
|
+
import { ImageUploader, uploadPictureWallClasses } from '@mezzanine-ui/core/upload';
|
|
4
|
+
import compact from 'lodash/compact';
|
|
5
|
+
import drop from 'lodash/drop';
|
|
6
|
+
import isEqual from 'lodash/isEqual';
|
|
7
|
+
import { usePreviousValue } from '../hooks/usePreviousValue.js';
|
|
8
|
+
import UploadPictureWallItem from './UploadPictureWallItem.js';
|
|
9
|
+
import cx from 'clsx';
|
|
10
|
+
|
|
11
|
+
const UploadPictureWall = forwardRef(function UploadPictureWall(props, ref) {
|
|
12
|
+
const { accept = 'image/*', className, controllerRef, defaultValues, disabled = false, multiple = true, onChange, onDelete, onError, onMultiUpload, onUpload, onUploadSuccess, parallel = false, style, } = props;
|
|
13
|
+
const [uploadPictureImageLoaders, setUploadPictureImageLoader] = useState(defaultValues ? compact(defaultValues).map((value) => new ImageUploader(undefined, value)) : []);
|
|
14
|
+
const [needUploadImageLoaders, setNeedUploadImageLoaders] = useState([]);
|
|
15
|
+
const [needUploadImageLoaderSets, setNeedUploadImageLoaderSets] = useState([]);
|
|
16
|
+
const [values, setValues] = useState(compact(defaultValues) || []);
|
|
17
|
+
const loaderList = useMemo(() => uploadPictureImageLoaders, [uploadPictureImageLoaders]);
|
|
18
|
+
const prevNeedUploadImageLoadersLength = usePreviousValue(needUploadImageLoaders.length);
|
|
19
|
+
const prevNeedUploadImageLoaderSetsLength = usePreviousValue(needUploadImageLoaderSets.length);
|
|
20
|
+
const prevValues = usePreviousValue(values);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (onChange && !isEqual(prevValues, values)) {
|
|
23
|
+
onChange(values);
|
|
24
|
+
}
|
|
25
|
+
}, [onChange, prevValues, values]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (prevNeedUploadImageLoadersLength > needUploadImageLoaders.length ||
|
|
28
|
+
prevNeedUploadImageLoaderSetsLength > needUploadImageLoaderSets.length) {
|
|
29
|
+
setValues(compact(uploadPictureImageLoaders.map((loader) => loader.getUrl())));
|
|
30
|
+
}
|
|
31
|
+
}, [
|
|
32
|
+
uploadPictureImageLoaders,
|
|
33
|
+
needUploadImageLoaders,
|
|
34
|
+
prevNeedUploadImageLoadersLength,
|
|
35
|
+
needUploadImageLoaderSets,
|
|
36
|
+
prevNeedUploadImageLoaderSetsLength,
|
|
37
|
+
]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (needUploadImageLoaderSets.length && onUpload) {
|
|
40
|
+
const imageLoaderSet = needUploadImageLoaderSets[0];
|
|
41
|
+
if (!imageLoaderSet[0].getIsLoading()) {
|
|
42
|
+
imageLoaderSet.forEach((imageLoader, index) => {
|
|
43
|
+
const setProgress = (progress) => imageLoader.setPercentage(progress);
|
|
44
|
+
imageLoader.setLoadingStatus(true);
|
|
45
|
+
onUpload(imageLoader.getFile(), setProgress)
|
|
46
|
+
.then((url) => {
|
|
47
|
+
imageLoader.setUrl(url);
|
|
48
|
+
imageLoader.setLoadingStatus(false);
|
|
49
|
+
setProgress(100);
|
|
50
|
+
if (onUploadSuccess) {
|
|
51
|
+
onUploadSuccess(imageLoader.getFile(), url);
|
|
52
|
+
}
|
|
53
|
+
if (index === imageLoaderSet.length - 1) {
|
|
54
|
+
setNeedUploadImageLoaderSets((nup) => drop(nup));
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
.catch(() => {
|
|
58
|
+
imageLoader.setErrorStatus(true);
|
|
59
|
+
imageLoader.setLoadingStatus(false);
|
|
60
|
+
setProgress(100);
|
|
61
|
+
if (index === imageLoaderSet.length - 1) {
|
|
62
|
+
setNeedUploadImageLoaderSets((nup) => drop(nup));
|
|
63
|
+
}
|
|
64
|
+
if (onError) {
|
|
65
|
+
onError(imageLoader.getFile());
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}, [needUploadImageLoaderSets, onError, onUpload, onUploadSuccess]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (needUploadImageLoaders.length && onUpload) {
|
|
74
|
+
const imageLoader = needUploadImageLoaders[0];
|
|
75
|
+
if (imageLoader && imageLoader.getFile() && !imageLoader.getIsLoading()) {
|
|
76
|
+
const setProgress = (progress) => imageLoader.setPercentage(progress);
|
|
77
|
+
imageLoader.setLoadingStatus(true);
|
|
78
|
+
onUpload(imageLoader.getFile(), setProgress)
|
|
79
|
+
.then((url) => {
|
|
80
|
+
imageLoader.setUrl(url);
|
|
81
|
+
imageLoader.setLoadingStatus(false);
|
|
82
|
+
setProgress(100);
|
|
83
|
+
setNeedUploadImageLoaders((nup) => drop(nup));
|
|
84
|
+
if (onUploadSuccess) {
|
|
85
|
+
onUploadSuccess(imageLoader.getFile(), url);
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
.catch(() => {
|
|
89
|
+
imageLoader.setErrorStatus(true);
|
|
90
|
+
imageLoader.setLoadingStatus(false);
|
|
91
|
+
setProgress(100);
|
|
92
|
+
setNeedUploadImageLoaders((nup) => drop(nup));
|
|
93
|
+
if (onError) {
|
|
94
|
+
onError(imageLoader.getFile());
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}, [needUploadImageLoaders, onError, onUpload, onUploadSuccess]);
|
|
100
|
+
const onImagesUpload = useCallback((files) => {
|
|
101
|
+
if (files.length) {
|
|
102
|
+
const imageLoaders = files.map((file) => new ImageUploader(file));
|
|
103
|
+
setUploadPictureImageLoader((ups) => [...ups, ...imageLoaders]);
|
|
104
|
+
if (onMultiUpload) {
|
|
105
|
+
const uploadFiles = imageLoaders.map((loader) => loader.getFile());
|
|
106
|
+
const setProgress = (progress) => imageLoaders.forEach((loader) => loader.setPercentage(progress));
|
|
107
|
+
imageLoaders.forEach((loader) => loader.setLoadingStatus(true));
|
|
108
|
+
onMultiUpload(uploadFiles, setProgress)
|
|
109
|
+
.then((urls) => {
|
|
110
|
+
imageLoaders.forEach((loader, index) => loader.setUrl(urls[index]));
|
|
111
|
+
imageLoaders.forEach((loader) => loader.setLoadingStatus(false));
|
|
112
|
+
setProgress(100);
|
|
113
|
+
setValues((v) => [...v, ...urls]);
|
|
114
|
+
if (onUploadSuccess) {
|
|
115
|
+
onUploadSuccess(uploadFiles, urls);
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
.catch(() => {
|
|
119
|
+
imageLoaders.forEach((loader) => loader.setErrorStatus(true));
|
|
120
|
+
imageLoaders.forEach((loader) => loader.setLoadingStatus(false));
|
|
121
|
+
setProgress(100);
|
|
122
|
+
if (onError) {
|
|
123
|
+
onError(uploadFiles);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (onUpload) {
|
|
129
|
+
if (!parallel) {
|
|
130
|
+
setNeedUploadImageLoaders((nups) => [...nups, ...imageLoaders]);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
setNeedUploadImageLoaderSets((set) => [...set, imageLoaders]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, [onError, onMultiUpload, onUpload, onUploadSuccess, parallel]);
|
|
138
|
+
const onImageDelete = useCallback((uid) => {
|
|
139
|
+
setUploadPictureImageLoader((ups) => ups.filter((up) => up.getUid() !== uid));
|
|
140
|
+
setNeedUploadImageLoaders((nUps) => nUps.filter((nUp) => nUp.getUid() !== uid));
|
|
141
|
+
const nowUploadPictureImageLoaders = uploadPictureImageLoaders.filter((up) => up.getUid() !== uid);
|
|
142
|
+
const urls = compact(nowUploadPictureImageLoaders.map((loader) => loader.getUrl()));
|
|
143
|
+
setValues(urls);
|
|
144
|
+
if (onDelete) {
|
|
145
|
+
onDelete(urls);
|
|
146
|
+
}
|
|
147
|
+
}, [onDelete, uploadPictureImageLoaders]);
|
|
148
|
+
useImperativeHandle(controllerRef, () => ({
|
|
149
|
+
getAllData: () => uploadPictureImageLoaders.map((loader) => loader.getAll()),
|
|
150
|
+
}));
|
|
151
|
+
return (jsxs("div", Object.assign({ ref: ref, className: cx(uploadPictureWallClasses.host, className), style: style }, { children: [loaderList.map((up) => (jsx(UploadPictureWallItem, { accept: accept, disabled: disabled, imageLoader: up, multiple: multiple, onDelete: () => onImageDelete(up.getUid()) }, up.getUid()))),
|
|
152
|
+
jsx(UploadPictureWallItem, { accept: accept, disabled: disabled, imageLoader: new ImageUploader(), multiple: multiple, onUpload: onImagesUpload }, void 0)] }), void 0));
|
|
153
|
+
});
|
|
154
|
+
var UploadPictureWall$1 = UploadPictureWall;
|
|
155
|
+
|
|
156
|
+
export { UploadPictureWall$1 as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { MouseEventHandler } from 'react';
|
|
2
|
+
import { ImageUploader } from '@mezzanine-ui/core/upload';
|
|
3
|
+
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
4
|
+
export interface UploadPictureWallItemProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'value' | 'onChange' | 'children'> {
|
|
5
|
+
accept?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
imageLoader: ImageUploader;
|
|
8
|
+
multiple?: boolean;
|
|
9
|
+
onDelete?: MouseEventHandler;
|
|
10
|
+
onUpload?: (files: File[]) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const UploadPictureWallItem: (props: UploadPictureWallItemProps) => JSX.Element;
|
|
13
|
+
export default UploadPictureWallItem;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
import { uploadPictureWallClasses } from '@mezzanine-ui/core/upload';
|
|
4
|
+
import UploadPictureBlock from './UploadPictureBlock.js';
|
|
5
|
+
import cx from 'clsx';
|
|
6
|
+
|
|
7
|
+
const UploadPictureWallItem = (props) => {
|
|
8
|
+
const { accept, disabled, imageLoader, multiple, onDelete, onUpload, } = props;
|
|
9
|
+
const loader = useRef(imageLoader);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!loader.current.getPreview()) {
|
|
12
|
+
loader.current.setPreview();
|
|
13
|
+
}
|
|
14
|
+
}, []);
|
|
15
|
+
return (jsx("div", Object.assign({ className: cx(uploadPictureWallClasses.item) }, { children: jsx(UploadPictureBlock, { accept: accept, disabled: disabled, imageLoader: loader.current, multiple: multiple, onDelete: onDelete, onUpload: onUpload }, void 0) }), void 0));
|
|
16
|
+
};
|
|
17
|
+
var UploadPictureWallItem$1 = UploadPictureWallItem;
|
|
18
|
+
|
|
19
|
+
export { UploadPictureWallItem$1 as default };
|
package/Upload/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export type { UploadResultSize, UploadResultStatus, } from '@mezzanine-ui/core/upload';
|
|
2
2
|
export { UploadButtonProps, default as UploadButton } from './UploadButton';
|
|
3
|
+
export { UploadPictureControl, UploadPictureProps, default as UploadPicture } from './UploadPicture';
|
|
4
|
+
export { UploadPictureBlockProps, default as UploadPictureBlock } from './UploadPictureBlock';
|
|
5
|
+
export { UploadPictureWallControl, UploadPictureWallProps, default as UploadPictureWall } from './UploadPictureWall';
|
|
3
6
|
export { UploadResultProps, default as UploadResult } from './UploadResult';
|
package/Upload/index.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export { default as UploadButton } from './UploadButton.js';
|
|
2
|
+
export { default as UploadPicture } from './UploadPicture.js';
|
|
3
|
+
export { default as UploadPictureBlock } from './UploadPictureBlock.js';
|
|
4
|
+
export { default as UploadPictureWall } from './UploadPictureWall.js';
|
|
2
5
|
export { default as UploadResult } from './UploadResult.js';
|
package/index.d.ts
CHANGED
|
@@ -67,7 +67,7 @@ export { AutoComplete, AutoCompleteProps, SelectValue, TreeSelectOption, SelectC
|
|
|
67
67
|
export { SwitchSize, SwitchProps, default as Switch, } from './Switch';
|
|
68
68
|
export { TextareaSize, TextareaProps, default as Textarea, } from './Textarea';
|
|
69
69
|
export { TextFieldSize, TextFieldProps, default as TextField, } from './TextField';
|
|
70
|
-
export { UploadButtonProps, UploadButton, UploadResultProps, UploadResultSize, UploadResultStatus, UploadResult, } from './Upload';
|
|
70
|
+
export { UploadButtonProps, UploadButton, UploadPictureControl, UploadPictureProps, UploadPicture, UploadPictureWallControl, UploadPictureWallProps, UploadPictureWall, UploadResultProps, UploadResultSize, UploadResultStatus, UploadResult, } from './Upload';
|
|
71
71
|
export { useTabKeyClose, UsePickerDocumentEventCloseProps, usePickerDocumentEventClose, UsePickerValueProps, usePickerValue, UseRangePickerValueProps, useRangePickerValue, PickerTriggerProps, PickerTrigger, RangePickerTriggerProps, RangePickerTrigger, } from './Picker';
|
|
72
72
|
export { DatePickerCalendarProps, DatePickerCalendar, DatePickerProps, default as DatePicker, } from './DatePicker';
|
|
73
73
|
export { useDateRangeCalendarControls, UseDateRangePickerValueProps, useDateRangePickerValue, DateRangePickerCalendarProps, DateRangePickerCalendar, DateRangePickerProps, default as DateRangePicker, } from './DateRangePicker';
|
package/index.js
CHANGED
|
@@ -88,6 +88,8 @@ export { default as Switch } from './Switch/Switch.js';
|
|
|
88
88
|
export { default as Textarea } from './Textarea/Textarea.js';
|
|
89
89
|
export { default as TextField } from './TextField/TextField.js';
|
|
90
90
|
export { default as UploadButton } from './Upload/UploadButton.js';
|
|
91
|
+
export { default as UploadPicture } from './Upload/UploadPicture.js';
|
|
92
|
+
export { default as UploadPictureWall } from './Upload/UploadPictureWall.js';
|
|
91
93
|
export { default as UploadResult } from './Upload/UploadResult.js';
|
|
92
94
|
export { useTabKeyClose } from './Picker/useTabKeyClose.js';
|
|
93
95
|
export { usePickerDocumentEventClose } from './Picker/usePickerDocumentEventClose.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mezzanine-ui/react",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "React components for mezzanine-ui",
|
|
5
5
|
"author": "Mezzanine",
|
|
6
6
|
"repository": {
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"react-dom": "^17.0.1"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@mezzanine-ui/core": "^0.7.
|
|
36
|
-
"@mezzanine-ui/icons": "^0.
|
|
35
|
+
"@mezzanine-ui/core": "^0.7.3",
|
|
36
|
+
"@mezzanine-ui/icons": "^0.7.3",
|
|
37
37
|
"@mezzanine-ui/system": "^0.7.0",
|
|
38
38
|
"@popperjs/core": "^2.9.2",
|
|
39
39
|
"@types/react-transition-group": "4.4.1",
|