naive-ui
Version:
A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast
275 lines (274 loc) • 14.2 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vooks_1 = require("vooks");
const vue_1 = require("vue");
const _internal_1 = require("../../_internal");
const icons_1 = require("../../_internal/icons");
const _utils_1 = require("../../_utils");
const button_1 = require("../../button");
const image_1 = require("../../image");
const icons_2 = require("./icons");
const interface_1 = require("./interface");
const UploadProgress_1 = __importDefault(require("./UploadProgress"));
const utils_1 = require("./utils");
const buttonThemeOverrides = {
paddingMedium: '0 3px',
heightMedium: '24px',
iconSizeMedium: '18px'
};
exports.default = (0, vue_1.defineComponent)({
name: 'UploadFile',
props: {
clsPrefix: {
type: String,
required: true
},
file: {
type: Object,
required: true
},
listType: {
type: String,
required: true
},
index: {
type: Number,
required: true
}
},
setup(props) {
const NUpload = (0, vue_1.inject)(interface_1.uploadInjectionKey);
const imageRef = (0, vue_1.ref)(null);
const thumbnailUrlRef = (0, vue_1.ref)('');
const progressStatusRef = (0, vue_1.computed)(() => {
const { file } = props;
if (file.status === 'finished')
return 'success';
if (file.status === 'error')
return 'error';
return 'info';
});
const buttonTypeRef = (0, vue_1.computed)(() => {
const { file } = props;
if (file.status === 'error')
return 'error';
return undefined;
});
const showProgressRef = (0, vue_1.computed)(() => {
const { file } = props;
return file.status === 'uploading';
});
const showCancelButtonRef = (0, vue_1.computed)(() => {
if (!NUpload.showCancelButtonRef.value)
return false;
const { file } = props;
return ['uploading', 'pending', 'error'].includes(file.status);
});
const showRemoveButtonRef = (0, vue_1.computed)(() => {
if (!NUpload.showRemoveButtonRef.value)
return false;
const { file } = props;
return ['finished'].includes(file.status);
});
const showDownloadButtonRef = (0, vue_1.computed)(() => {
if (!NUpload.showDownloadButtonRef.value)
return false;
const { file } = props;
return ['finished'].includes(file.status);
});
const showRetryButtonRef = (0, vue_1.computed)(() => {
if (!NUpload.showRetryButtonRef.value)
return false;
const { file } = props;
return ['error'].includes(file.status);
});
const mergedThumbnailUrlRef = (0, vooks_1.useMemo)(() => {
return thumbnailUrlRef.value || props.file.thumbnailUrl || props.file.url;
});
const showPreviewButtonRef = (0, vue_1.computed)(() => {
if (!NUpload.showPreviewButtonRef.value)
return false;
const { file: { status }, listType } = props;
return (['finished'].includes(status)
&& mergedThumbnailUrlRef.value
&& listType === 'image-card');
});
function handleRetryClick() {
return __awaiter(this, void 0, void 0, function* () {
const onRetry = NUpload.onRetryRef.value;
if (onRetry) {
const onRetryReturn = yield onRetry({ file: props.file });
if (onRetryReturn === false) {
return;
}
}
NUpload.submit(props.file.id);
});
}
function handleRemoveOrCancelClick(e) {
e.preventDefault();
const { file } = props;
if (['finished', 'pending', 'error'].includes(file.status)) {
handleRemove(file);
}
else if (['uploading'].includes(file.status)) {
handleAbort(file);
}
else {
(0, _utils_1.warn)('upload', 'The button clicked type is unknown.');
}
}
function handleDownloadClick(e) {
e.preventDefault();
handleDownload(props.file);
}
function handleRemove(file) {
const { xhrMap, doChange, onRemoveRef: { value: onRemove }, mergedFileListRef: { value: mergedFileList } } = NUpload;
void Promise.resolve(onRemove
? onRemove({
file: Object.assign({}, file),
fileList: mergedFileList,
index: props.index
})
: true).then((result) => {
if (result === false)
return;
const fileAfterChange = Object.assign({}, file, {
status: 'removed'
});
xhrMap.delete(file.id);
doChange(fileAfterChange, undefined, {
remove: true
});
});
}
function handleDownload(file) {
const { onDownloadRef: { value: onDownload }, customDownloadRef: { value: customDownload } } = NUpload;
void Promise.resolve(onDownload ? onDownload(Object.assign({}, file)) : true).then((res) => {
if (res !== false) {
if (customDownload) {
customDownload(Object.assign({}, file));
}
else {
(0, _utils_1.download)(file.url, file.name);
}
}
});
}
function handleAbort(file) {
const { xhrMap } = NUpload;
const xhr = xhrMap.get(file.id);
xhr === null || xhr === void 0 ? void 0 : xhr.abort();
handleRemove(Object.assign({}, file));
}
function handlePreviewClick(e) {
const { onPreviewRef: { value: onPreview } } = NUpload;
if (onPreview) {
onPreview(props.file, {
event: e
});
}
else if (props.listType === 'image-card') {
const { value } = imageRef;
if (!value)
return;
value.click();
}
}
const deriveFileThumbnailUrl = () => __awaiter(this, void 0, void 0, function* () {
const { listType } = props;
if (listType !== 'image' && listType !== 'image-card') {
return;
}
if (NUpload.shouldUseThumbnailUrlRef.value(props.file)) {
thumbnailUrlRef.value = yield NUpload.getFileThumbnailUrlResolver(props.file);
}
});
(0, vue_1.watchEffect)(() => {
void deriveFileThumbnailUrl();
});
return {
mergedTheme: NUpload.mergedThemeRef,
progressStatus: progressStatusRef,
buttonType: buttonTypeRef,
showProgress: showProgressRef,
disabled: NUpload.mergedDisabledRef,
showCancelButton: showCancelButtonRef,
showRemoveButton: showRemoveButtonRef,
showDownloadButton: showDownloadButtonRef,
showRetryButton: showRetryButtonRef,
showPreviewButton: showPreviewButtonRef,
mergedThumbnailUrl: mergedThumbnailUrlRef,
shouldUseThumbnailUrl: NUpload.shouldUseThumbnailUrlRef,
renderIcon: NUpload.renderIconRef,
imageRef,
handleRemoveOrCancelClick,
handleDownloadClick,
handleRetryClick,
handlePreviewClick
};
},
render() {
const { clsPrefix, mergedTheme, listType, file, renderIcon } = this;
// if there is text list type, show file icon
let icon;
const isImageType = listType === 'image';
const isImageCardType = listType === 'image-card';
if (isImageType || isImageCardType) {
icon
= !this.shouldUseThumbnailUrl(file) || !this.mergedThumbnailUrl ? ((0, vue_1.h)("span", { class: `${clsPrefix}-upload-file-info__thumbnail` }, renderIcon ? (renderIcon(file)) : (0, utils_1.isImageFile)(file) ? ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: icons_2.renderImageIcon })) : ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: icons_2.renderDocumentIcon })))) : ((0, vue_1.h)("a", { rel: "noopener noreferer", target: "_blank", href: file.url || undefined, class: `${clsPrefix}-upload-file-info__thumbnail`, onClick: this.handlePreviewClick }, listType === 'image-card' ? ((0, vue_1.h)(image_1.NImage, { src: this.mergedThumbnailUrl || undefined, previewSrc: file.url || undefined, alt: file.name, ref: "imageRef" })) : ((0, vue_1.h)("img", { src: this.mergedThumbnailUrl || undefined, alt: file.name }))));
}
else {
icon = ((0, vue_1.h)("span", { class: `${clsPrefix}-upload-file-info__thumbnail` }, renderIcon ? (renderIcon(file)) : ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: () => (0, vue_1.h)(icons_1.AttachIcon, null) }))));
}
const progress = ((0, vue_1.h)(UploadProgress_1.default, { show: this.showProgress, percentage: file.percentage || 0, status: this.progressStatus }));
const showName = listType === 'text' || listType === 'image';
return ((0, vue_1.h)("div", { class: [
`${clsPrefix}-upload-file`,
`${clsPrefix}-upload-file--${this.progressStatus}-status`,
file.url
&& file.status !== 'error'
&& listType !== 'image-card'
&& `${clsPrefix}-upload-file--with-url`,
`${clsPrefix}-upload-file--${listType}-type`
] },
(0, vue_1.h)("div", { class: `${clsPrefix}-upload-file-info` },
icon,
(0, vue_1.h)("div", { class: `${clsPrefix}-upload-file-info__name` },
showName
&& (file.url && file.status !== 'error' ? ((0, vue_1.h)("a", { rel: "noopener noreferer", target: "_blank", href: file.url || undefined, onClick: this.handlePreviewClick }, file.name)) : ((0, vue_1.h)("span", { onClick: this.handlePreviewClick }, file.name))),
isImageType && progress),
(0, vue_1.h)("div", { class: [
`${clsPrefix}-upload-file-info__action`,
`${clsPrefix}-upload-file-info__action--${listType}-type`
] },
this.showPreviewButton ? ((0, vue_1.h)(button_1.NButton, { key: "preview", quaternary: true, type: this.buttonType, onClick: this.handlePreviewClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button, builtinThemeOverrides: buttonThemeOverrides }, {
icon: () => ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: () => (0, vue_1.h)(icons_1.EyeIcon, null) }))
})) : null,
(this.showRemoveButton || this.showCancelButton)
&& !this.disabled && ((0, vue_1.h)(button_1.NButton, { key: "cancelOrTrash", theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button, quaternary: true, builtinThemeOverrides: buttonThemeOverrides, type: this.buttonType, onClick: this.handleRemoveOrCancelClick }, {
icon: () => ((0, vue_1.h)(_internal_1.NIconSwitchTransition, null, {
default: () => this.showRemoveButton ? ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix, key: "trash" }, { default: () => (0, vue_1.h)(icons_1.TrashIcon, null) })) : ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix, key: "cancel" }, { default: () => (0, vue_1.h)(icons_1.CancelIcon, null) }))
}))
})),
this.showRetryButton && !this.disabled && ((0, vue_1.h)(button_1.NButton, { key: "retry", quaternary: true, type: this.buttonType, onClick: this.handleRetryClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button, builtinThemeOverrides: buttonThemeOverrides }, {
icon: () => ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: () => (0, vue_1.h)(icons_1.RetryIcon, null) }))
})),
this.showDownloadButton ? ((0, vue_1.h)(button_1.NButton, { key: "download", quaternary: true, type: this.buttonType, onClick: this.handleDownloadClick, theme: mergedTheme.peers.Button, themeOverrides: mergedTheme.peerOverrides.Button, builtinThemeOverrides: buttonThemeOverrides }, {
icon: () => ((0, vue_1.h)(_internal_1.NBaseIcon, { clsPrefix: clsPrefix }, { default: () => (0, vue_1.h)(icons_1.DownloadIcon, null) }))
})) : null)),
!isImageType && progress));
}
});
;