UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

412 lines (411 loc) 18.1 kB
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 { Failure, Photograph } from "@nutui/icons-react"; import { useConfig } from "../configprovider"; import { funcInterceptor } from "../../utils/interceptor"; import { ComponentDefaults } from "../../utils/typings"; import Button from "../button"; import { usePropsValue } from "../../hooks/use-props-value"; import { Preview } from "./preview"; import { mergeProps } from "../../utils/merge-props"; var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), { maxCount: Number.MAX_VALUE, previewType: 'picture', fit: 'cover', name: 'file', accept: '*', disabled: false, autoUpload: true, multiple: false, maxFileSize: Number.MAX_VALUE, clearInput: true, preview: true, deletable: true, capture: false, uploadIcon: /*#__PURE__*/ React.createElement(Photograph, { width: "20px", height: "20px", color: "#808080" }), deleteIcon: /*#__PURE__*/ React.createElement(Failure, { color: "rgba(0,0,0,0.6)" }), beforeDelete: function(file, files) { return true; } }); var InternalUploader = function(props, ref) { var locale = useConfig().locale; var fileListRef = useRef([]); var _mergeProps = mergeProps(defaultProps, props), children = _mergeProps.children, uploadIcon = _mergeProps.uploadIcon, deleteIcon = _mergeProps.deleteIcon, uploadLabel = _mergeProps.uploadLabel, name = _mergeProps.name, accept = _mergeProps.accept, defaultValue = _mergeProps.defaultValue, value = _mergeProps.value, previewType = _mergeProps.previewType, fit = _mergeProps.fit, disabled = _mergeProps.disabled, multiple = _mergeProps.multiple, previewUrl = _mergeProps.previewUrl, preview = _mergeProps.preview, deletable = _mergeProps.deletable, maxCount = _mergeProps.maxCount, capture = _mergeProps.capture, maxFileSize = _mergeProps.maxFileSize, className = _mergeProps.className, autoUpload = _mergeProps.autoUpload, clearInput = _mergeProps.clearInput, upload = _mergeProps.upload, onDelete = _mergeProps.onDelete, onChange = _mergeProps.onChange, onFileItemClick = _mergeProps.onFileItemClick, onOversize = _mergeProps.onOversize, onOverCount = _mergeProps.onOverCount, beforeUpload = _mergeProps.beforeUpload, beforeDelete = _mergeProps.beforeDelete, onUploadQueueChange = _mergeProps.onUploadQueueChange, listUploadRender = _mergeProps.listUploadRender, restProps = _object_without_properties(_mergeProps, [ "children", "uploadIcon", "deleteIcon", "uploadLabel", "name", "accept", "defaultValue", "value", "previewType", "fit", "disabled", "multiple", "previewUrl", "preview", "deletable", "maxCount", "capture", "maxFileSize", "className", "autoUpload", "clearInput", "upload", "onDelete", "onChange", "onFileItemClick", "onOversize", "onOverCount", "beforeUpload", "beforeDelete", "onUploadQueueChange", "listUploadRender" ]); 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 classes = classNames(className, 'nut-uploader'); useEffect(function() { fileListRef.current = fileList; }, [ fileList ]); useEffect(function() { onUploadQueueChange === null || onUploadQueueChange === void 0 ? void 0 : onUploadQueueChange(uploadQueue); }, [ uploadQueue ]); useImperativeHandle(ref, function() { return { submit: /*#__PURE__*/ _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(); } }; }); 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 idCountRef = useRef(0); var filterFiles = function(files) { var maximum = maxCount * 1; var oversizes = new Array(); var filterFile = files.filter(function(file) { if (file.size > maxFileSize) { oversizes.push(file); return false; } return true; }); oversizes.length && (onOversize === null || onOversize === void 0 ? void 0 : onOversize(files)); if (filterFile.length > maximum) { onOverCount === null || onOverCount === void 0 ? void 0 : onOverCount(filterFile.length); filterFile.splice(maximum, filterFile.length - maximum); } if (fileList.length !== 0) { var index = maximum - fileList.length; filterFile.splice(index, filterFile.length - index); } return filterFile; }; var deleted = function(file, index) { var deletedFileList = fileListRef.current.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 fileChange = /*#__PURE__*/ function() { var _ref = _async_to_generator(function(event) { var $el, files, _files, filesArr, tasks; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: if (disabled) return [ 2 ]; $el = event.target; files = $el.files; _files = []; filesArr = new Array().slice.call(files); if (!beforeUpload) return [ 3, 2 ]; return [ 4, beforeUpload(filesArr) ]; case 1: _files = _state.sent(); if (!_files.length) { $el.value = ''; return [ 2 ]; } return [ 3, 3 ]; case 2: _files = filesArr; _state.label = 3; case 3: _files = filterFiles(_files); tasks = _files.map(function(file) { var _file_type; var info = { uid: idCountRef.current++, status: autoUpload ? 'uploading' : 'ready', file: file, message: autoUpload ? locale.uploader.uploading : locale.uploader.waitingUpload, name: file.name, type: file.type }; if (preview && ((_file_type = file.type) === null || _file_type === void 0 ? void 0 : _file_type.includes('image'))) { var reader = new FileReader(); reader.onload = function(event) { fileListRef.current = _to_consumable_array(fileListRef.current).concat([ _object_spread_props(_object_spread({}, info), { url: event.target.result }) ]); setFileList(fileListRef.current); }; reader.readAsDataURL(file); } return info; }); if (!!autoUpload) return [ 3, 4 ]; setUploadQueue(tasks); return [ 3, 6 ]; case 4: return [ 4, uploadAction(tasks) ]; case 5: _state.sent(); _state.label = 6; case 6: if (clearInput) { $el.value = ''; } return [ 2 ]; } }); }); return function fileChange(event) { return _ref.apply(this, arguments); }; }(); var uploadAction = /*#__PURE__*/ function() { var _ref = _async_to_generator(function(tasks) { var taskIds; return _ts_generator(this, function(_state) { switch(_state.label){ case 0: taskIds = tasks.map(function(task) { return task.uid; }); setFileList(fileList.map(function(file) { if (taskIds.includes(file.uid)) { return _object_spread_props(_object_spread({}, file), { status: 'uploading', message: locale.uploader.uploading }); } return file; })); return [ 4, Promise.all(tasks.map(/*#__PURE__*/ function() { var _ref = _async_to_generator(function(currentTask, index) { 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 ]; } }); }); return function(currentTask, index) { return _ref.apply(this, arguments); }; }())).catch(function(errs) { return console.error(errs); }) ]; case 1: _state.sent(); return [ 2 ]; } }); }); return function uploadAction(tasks) { return _ref.apply(this, arguments); }; }(); var handleItemClick = function(file, index) { onFileItemClick === null || onFileItemClick === void 0 ? void 0 : onFileItemClick(file, index); }; var renderImageUploader = function() { var shouldShow = Number(maxCount) > fileList.length && previewType === 'picture'; return shouldShow && /*#__PURE__*/ React.createElement("div", { className: classNames('nut-uploader-upload', previewType, { 'nut-uploader-upload-disabled': disabled }) }, /*#__PURE__*/ React.createElement("div", { className: "nut-uploader-icon" }, uploadIcon, /*#__PURE__*/ React.createElement("span", { className: "nut-uploader-icon-tip" }, uploadLabel)), /*#__PURE__*/ React.createElement("input", { className: "nut-uploader-input", type: "file", capture: capture, name: name, accept: accept, disabled: disabled, multiple: multiple, onChange: fileChange })); }; var renderListUploader = function() { if (previewType !== 'list') return null; return /*#__PURE__*/ React.createElement("div", { className: "nut-uploader-slot" }, listUploadRender || /*#__PURE__*/ React.createElement(Button, { size: "small", type: "primary" }, locale.uploader.list), Number(maxCount) > fileList.length && /*#__PURE__*/ React.createElement("input", { className: "nut-uploader-input", type: "file", capture: capture, name: name, accept: accept, disabled: disabled, multiple: multiple, onChange: fileChange })); }; return /*#__PURE__*/ React.createElement("div", _object_spread({ className: classes }, restProps), renderListUploader(), /*#__PURE__*/ React.createElement(Preview, { fileList: fileList, previewType: previewType, deletable: deletable, onDeleteItem: onDeleteItem, handleItemClick: handleItemClick, previewUrl: previewUrl, children: children, deleteIcon: deleteIcon }), renderImageUploader()); }; export var Uploader = /*#__PURE__*/ React.forwardRef(InternalUploader); Uploader.displayName = 'NutUploader';