@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
464 lines (463 loc) • 20.4 kB
JavaScript
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
import classNames from "classnames";
import { chooseImage, chooseMedia, getEnv } from "@tarojs/taro";
import { Failure, Photograph } from "@nutui/icons-react-taro";
import { View } from "@tarojs/components";
import Button from "../button/index";
import { useConfig } from "../configprovider/index";
import { funcInterceptor } from "../../utils/interceptor";
import { ComponentDefaults } from "../../utils/typings";
import { usePropsValue } from "../../hooks/use-props-value";
import { Preview } from "./preview";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
maxCount: Number.MAX_VALUE,
sizeType: [
'original',
'compressed'
],
sourceType: [
'album',
'camera'
],
mediaType: [
'image',
'video'
],
camera: 'back',
uploadIcon: /*#__PURE__*/ React.createElement(Photograph, {
size: "20px",
color: "#808080"
}),
deleteIcon: /*#__PURE__*/ React.createElement(Failure, {
color: "rgba(0,0,0,0.6)"
}),
uploadLabel: '',
previewType: 'picture',
fit: 'cover',
name: 'file',
accept: '*',
disabled: false,
autoUpload: true,
multiple: false,
maxFileSize: Number.MAX_VALUE,
previewUrl: '',
preview: true,
deletable: true,
maxDuration: 10,
beforeDelete: function(file, files) {
return true;
}
});
var InternalUploader = function(props, ref) {
var locale = useConfig().locale;
var _ref = _object_spread({}, defaultProps, props), children = _ref.children, uploadIcon = _ref.uploadIcon, deleteIcon = _ref.deleteIcon, uploadLabel = _ref.uploadLabel, listUploadRender = _ref.listUploadRender, accept = _ref.accept, name = _ref.name, camera = _ref.camera, defaultValue = _ref.defaultValue, value = _ref.value, previewType = _ref.previewType, fit = _ref.fit, disabled = _ref.disabled, multiple = _ref.multiple, previewUrl = _ref.previewUrl, preview = _ref.preview, deletable = _ref.deletable, maxCount = _ref.maxCount, maxFileSize = _ref.maxFileSize, mediaType = _ref.mediaType, className = _ref.className, autoUpload = _ref.autoUpload, sizeType = _ref.sizeType, sourceType = _ref.sourceType, maxDuration = _ref.maxDuration, onDelete = _ref.onDelete, onChange = _ref.onChange, onFileItemClick = _ref.onFileItemClick, onOversize = _ref.onOversize, onOverCount = _ref.onOverCount, beforeUpload = _ref.beforeUpload, upload = _ref.upload, beforeDelete = _ref.beforeDelete, onUploadQueueChange = _ref.onUploadQueueChange, restProps = _object_without_properties(_ref, [
"children",
"uploadIcon",
"deleteIcon",
"uploadLabel",
"listUploadRender",
"accept",
"name",
"camera",
"defaultValue",
"value",
"previewType",
"fit",
"disabled",
"multiple",
"previewUrl",
"preview",
"deletable",
"maxCount",
"maxFileSize",
"mediaType",
"className",
"autoUpload",
"sizeType",
"sourceType",
"maxDuration",
"onDelete",
"onChange",
"onFileItemClick",
"onOversize",
"onOverCount",
"beforeUpload",
"upload",
"beforeDelete",
"onUploadQueueChange"
]);
var _usePropsValue = _sliced_to_array(usePropsValue({
value: value,
defaultValue: defaultValue,
finalValue: [],
onChange: function(v) {
onChange === null || onChange === void 0 ? void 0 : onChange(v);
}
}), 2), fileList = _usePropsValue[0], setFileList = _usePropsValue[1];
var _useState = _sliced_to_array(useState([]), 2), uploadQueue = _useState[0], setUploadQueue = _useState[1];
var fileListRef = useRef([]);
var classes = classNames(className, 'nut-uploader');
useImperativeHandle(ref, function() {
return {
submit: function() {
return _async_to_generator(function() {
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
return [
4,
uploadAction(uploadQueue)
];
case 1:
_state.sent();
return [
2
];
}
});
})();
},
clear: function() {
clearUploadQueue();
}
};
});
useEffect(function() {
fileListRef.current = fileList;
}, [
fileList
]);
useEffect(function() {
onUploadQueueChange === null || onUploadQueueChange === void 0 ? void 0 : onUploadQueueChange(uploadQueue);
}, [
uploadQueue
]);
var clearUploadQueue = function() {
var index = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : -1;
if (index > -1) {
uploadQueue.splice(index, 1);
setUploadQueue(uploadQueue);
} else {
setUploadQueue([]);
setFileList([]);
}
};
var _chooseImage = function() {
if (disabled) {
return;
}
var env = getEnv();
if (env === 'WEB') {
var el = document.getElementById('taroChooseImage');
if (el) {
el === null || el === void 0 ? void 0 : el.setAttribute('accept', accept);
} else {
var obj = document.createElement('input');
obj.setAttribute('type', 'file');
obj.setAttribute('id', 'taroChooseImage');
obj.setAttribute('accept', accept);
obj.setAttribute('style', 'position: fixed; top: -4000px; left: -3000px; z-index: -300;');
document.body.appendChild(obj);
}
}
if ([
'WEAPP',
'JD',
'WEB',
'ASCF'
].includes(env) && chooseMedia) {
chooseMedia({
count: multiple ? maxCount * 1 - fileList.length : 1,
/** 文件类型 */ mediaType: mediaType,
/** 图片和视频选择的来源 */ sourceType: sourceType,
/** 拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 30s 之间 */ maxDuration: maxDuration,
/** 仅对 mediaType 为 image 时有效,是否压缩所选文件 */ sizeType: sizeType,
/** 仅在 sourceType 为 camera 时生效,使用前置或后置摄像头 */ camera: camera,
success: onChangeMedia
});
} else {
chooseImage({
count: multiple ? maxCount * 1 - fileList.length : 1,
// 可以指定是原图还是压缩图,默认二者都有
sizeType: sizeType,
sourceType: sourceType,
success: onChangeImage
});
}
};
var uploadAction = function(tasks) {
return _async_to_generator(function() {
var taskIds, list;
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
taskIds = tasks.map(function(task) {
return task.uid;
});
list = fileListRef.current.map(function(file) {
if (taskIds.includes(file.uid)) {
return _object_spread_props(_object_spread({}, file), {
status: 'uploading',
message: locale.uploader.uploading
});
}
return file;
});
setFileList(list);
return [
4,
Promise.all(tasks.map(function(currentTask, index) {
return _async_to_generator(function() {
var result, list, e, list1;
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
_state.trys.push([
0,
2,
,
3
]);
return [
4,
upload(currentTask.file)
];
case 1:
result = _state.sent();
list = fileListRef.current.map(function(item) {
if (item.uid === currentTask.uid) {
item.status = 'success';
item.message = locale.uploader.success;
item.url = result.url;
}
return item;
});
setFileList(list);
return [
3,
3
];
case 2:
e = _state.sent();
list1 = fileListRef.current.map(function(item) {
if (item.uid === currentTask.uid) {
item.status = 'error';
item.message = locale.uploader.error;
}
return item;
});
setFileList(list1);
throw e;
case 3:
return [
2
];
}
});
})();
})).catch(function(errs) {
return console.error(errs);
})
];
case 1:
_state.sent();
return [
2
];
}
});
})();
};
var idCountRef = useRef(0);
var readFile = function(files) {
return _async_to_generator(function() {
var tasks;
return _ts_generator(this, function(_state) {
switch(_state.label){
case 0:
tasks = files.map(function(file) {
var _file_originalFileObj, _file_originalFileObj1;
var fileType = file.type;
var filepath = file.tempFilePath || file.path;
if (file.fileType) {
fileType = file.fileType;
} else {
var imgReg = /\.(png|jpeg|jpg|webp|gif)$/i;
if (!fileType && (imgReg.test(filepath) || filepath.includes('data:image'))) {
fileType = 'image';
}
}
var info = {
uid: idCountRef.current++,
status: autoUpload ? 'uploading' : 'ready',
file: file,
message: autoUpload ? locale.uploader.uploading : locale.uploader.waitingUpload,
name: getEnv() === 'WEB' ? (_file_originalFileObj = file.originalFileObj) === null || _file_originalFileObj === void 0 ? void 0 : _file_originalFileObj.name : filepath,
path: filepath,
type: getEnv() === 'WEB' ? (_file_originalFileObj1 = file.originalFileObj) === null || _file_originalFileObj1 === void 0 ? void 0 : _file_originalFileObj1.type : fileType
};
if (preview) {
info.url = fileType === 'video' ? file.thumbTempFilePath : filepath;
}
fileListRef.current = _to_consumable_array(fileListRef.current).concat([
info
]);
setFileList(fileListRef.current);
return info;
});
if (!!autoUpload) return [
3,
1
];
setUploadQueue(tasks);
return [
3,
3
];
case 1:
return [
4,
uploadAction(tasks)
];
case 2:
_state.sent();
_state.label = 3;
case 3:
return [
2
];
}
});
})();
};
var filterFiles = function(files) {
var maximum = maxCount * 1;
var maximize = maxFileSize * 1;
var oversizes = new Array();
var filterFile = files.filter(function(file) {
if (file.size > maximize) {
oversizes.push(file);
return false;
}
return true;
});
oversizes.length && (onOversize === null || onOversize === void 0 ? void 0 : onOversize(files));
var currentFileLength = filterFile.length + fileList.length;
if (currentFileLength > maximum) {
onOverCount === null || onOverCount === void 0 ? void 0 : onOverCount(filterFile.length);
filterFile.splice(filterFile.length - (currentFileLength - maximum));
}
return filterFile;
};
var deleted = function(file, index) {
var deletedFileList = fileList.filter(function(file, idx) {
return idx !== index;
});
onDelete === null || onDelete === void 0 ? void 0 : onDelete(file, deletedFileList);
setFileList(deletedFileList);
};
var onDeleteItem = function(file, index) {
clearUploadQueue(index);
funcInterceptor(beforeDelete, {
args: [
file,
fileList
],
done: function() {
return deleted(file, index);
}
});
};
var onChangeMedia = function(res) {
return _async_to_generator(function() {
var tempFiles, _files;
return _ts_generator(this, function(_state) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
tempFiles = res.tempFiles;
_files = filterFiles(tempFiles);
if (beforeUpload) {
beforeUpload(new Array().slice.call(_files)).then(function(f) {
var _files = filterFiles(new Array().slice.call(f));
if (!_files.length) res.tempFiles = [];
readFile(_files);
});
} else {
readFile(_files);
}
return [
2
];
});
})();
};
var onChangeImage = function(res) {
return _async_to_generator(function() {
var tempFiles, _files;
return _ts_generator(this, function(_state) {
tempFiles = res.tempFiles;
_files = filterFiles(tempFiles);
if (beforeUpload) {
beforeUpload(new Array().slice.call(_files)).then(function(f) {
var _files = filterFiles(new Array().slice.call(f));
if (!_files.length) res.tempFiles = [];
readFile(_files);
});
} else {
readFile(_files);
}
return [
2
];
});
})();
};
var handleItemClick = function(file, index) {
onFileItemClick === null || onFileItemClick === void 0 ? void 0 : onFileItemClick(file, index);
};
var renderListUploader = function() {
if (previewType !== 'list') return null;
return /*#__PURE__*/ React.createElement(View, {
className: "nut-uploader-slot"
}, listUploadRender || /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Button, {
size: "small",
type: "primary"
}, locale.uploader.list), Number(maxCount) > fileList.length && /*#__PURE__*/ React.createElement(Button, {
className: "nut-uploader-input",
onClick: _chooseImage
})));
};
var renderImageUploader = function() {
var shouldShow = Number(maxCount) > fileList.length && previewType === 'picture';
return shouldShow && /*#__PURE__*/ React.createElement(View, {
className: "nut-uploader-upload ".concat(previewType, " ").concat(disabled ? 'nut-uploader-upload-disabled' : '')
}, /*#__PURE__*/ React.createElement(View, {
className: "nut-uploader-icon"
}, uploadIcon, /*#__PURE__*/ React.createElement("span", {
className: "nut-uploader-icon-tip"
}, uploadLabel)), /*#__PURE__*/ React.createElement(Button, {
className: "nut-uploader-input",
onClick: _chooseImage
}));
};
return /*#__PURE__*/ React.createElement(View, _object_spread({
className: classes
}, restProps), renderListUploader(), /*#__PURE__*/ React.createElement(Preview, {
fileList: fileList,
previewType: previewType,
deletable: deletable,
onDeleteItem: onDeleteItem,
handleItemClick: handleItemClick,
previewUrl: previewUrl,
deleteIcon: deleteIcon,
children: children
}), renderImageUploader());
};
export var Uploader = /*#__PURE__*/ React.forwardRef(InternalUploader);
Uploader.displayName = 'NutUploader';