pull/3913/head
mertsincan 2023-04-28 17:19:34 +01:00
commit 6e9a844032
6 changed files with 489 additions and 35 deletions

View File

@ -142,6 +142,12 @@ const FileUploadProps = [
type: 'string',
default: 'null',
description: 'Style class of the component.'
},
{
name: 'pt',
type: 'any',
default: 'null',
description: 'Uses to pass attributes to DOM elements inside the component.'
}
];

View File

@ -1,16 +1,16 @@
<template>
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="p-fileupload-file">
<img role="presentation" class="p-fileupload-file-thumbnail" :alt="file.name" :src="file.objectURL" :width="previewWidth" />
<div class="p-fileupload-file-details">
<div class="p-fileupload-file-name">{{ file.name }}</div>
<span class="p-fileupload-file-size">{{ formatSize(file.size) }}</span>
<FileUploadBadge :value="badgeValue" class="p-fileupload-file-badge" :severity="badgeSeverity" />
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="p-fileupload-file" v-bind="ptm('file')">
<img role="presentation" class="p-fileupload-file-thumbnail" :alt="file.name" :src="file.objectURL" :width="previewWidth" v-bind="ptm('thumbnail')" />
<div class="p-fileupload-file-details" v-bind="ptm('details')">
<div class="p-fileupload-file-name" v-bind="ptm('fileName')">{{ file.name }}</div>
<span class="p-fileupload-file-size" v-bind="ptm('fileSize')">{{ formatSize(file.size) }}</span>
<FileUploadBadge :value="badgeValue" class="p-fileupload-file-badge" :severity="badgeSeverity" :pt="ptm('badge')" />
</div>
<div class="p-fileupload-file-actions">
<FileUploadButton @click="$emit('remove', index)" text rounded severity="danger" class="p-fileupload-file-remove">
<div class="p-fileupload-file-actions" v-bind="ptm('actions')">
<FileUploadButton @click="$emit('remove', index)" text rounded severity="danger" class="p-fileupload-file-remove" :pt="ptm('removeButton')">
<template #icon="iconProps">
<component v-if="templates.fileremoveicon" :is="templates.fileremoveicon" :class="iconProps.class" :file="file" :index="index" />
<TimesIcon v-else :class="iconProps.class" aria-hidden="true" />
<TimesIcon v-else :class="iconProps.class" aria-hidden="true" v-bind="ptm('removeButton')['icon']" />
</template>
</FileUploadButton>
</div>
@ -19,10 +19,12 @@
<script>
import Badge from 'primevue/badge';
import BaseComponent from 'primevue/basecomponent';
import Button from 'primevue/button';
import TimesIcon from 'primevue/icons/times';
export default {
extends: BaseComponent,
emits: ['remove'],
props: {
files: {

View File

@ -8,8 +8,20 @@
*
*/
import { VNode } from 'vue';
import { ButtonPassThroughOptions } from '../button';
import { MessagePassThroughOptions } from '../message';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
export declare type FileUploadPassThroughOptionType = FileUploadPassThroughAttributes | ((options: FileUploadPassThroughMethodOptions) => FileUploadPassThroughAttributes) | null | undefined;
/**
* Custom passthrough(pt) option method.
*/
export interface FileUploadPassThroughMethodOptions {
props: FileUploadProps;
state: FileUploadState;
}
/**
* Custom select event.
* @see {@link FileUploadEmits.select}
@ -138,6 +150,143 @@ export interface FileUploadRemoveUploadedFile {
files: File[];
}
/**
* Custom passthrough(pt) options.
* @see {@link FileUploadProps.pt}
*/
export interface FileUploadPassThroughOptions {
/**
* Uses to pass attributes to the root's DOM element.
*/
root?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the input's DOM element.
*/
input?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the buttonbar's DOM element.
*/
buttonbar?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the header' DOM element.
*/
header?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the button's DOM element.
*/
button?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the choose icon's DOM element.
*/
chooseIcon?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the upload button's DOM element.
* @see {@link ButtonPassThroughOptions}
*/
uploadButton?: ButtonPassThroughOptions;
/**
* Uses to pass attributes to the cancel button's DOM element.
* @see {@link ButtonPassThroughOptions}
*/
cancelButton?: ButtonPassThroughOptions;
/**
* Uses to pass attributes to the content's DOM element.
*/
content?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the progressbar's DOM element.
*/
progressbar?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the messages' DOM element.
* @see {@link MessagePassThroughOptions}
*/
messages?: MessagePassThroughOptions;
/**
* Uses to pass attributes to the empty's DOM element.
*/
empty?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the basic button's DOM element.
*/
basicButton?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the upload icon's DOM element.
*/
uploadIcon?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the label's DOM element.
*/
label?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the file's DOM element.
*/
file?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the thumbnail's DOM element.
*/
thumbnail?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the details's DOM element.
*/
details?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the fileName's DOM element.
*/
fileName?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the fileSize's DOM element.
*/
fileSize?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the badge's DOM element.
*/
badge?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the actions's DOM element.
*/
actions?: FileUploadPassThroughOptionType;
/**
* Uses to pass attributes to the remove button's DOM element.
* @see {@link ButtonPassThroughOptions}
*/
removeButton?: ButtonPassThroughOptions;
}
/**
* Custom passthrough attributes for each DOM elements
*/
export interface FileUploadPassThroughAttributes {
[key: string]: any;
}
/**
* Defines current inline state in FileUpload component.
*/
export interface FileUploadState {
/**
* Current uploaded file count state as a number.
* @defaultValue 0
*/
uploadedFileCount: number;
/**
* Current files.
*/
files: any[];
/**
* Current messages.
*/
messages: any[];
/**
* Current progress state as a number.
*/
progress: number;
/**
* Current uploaded files.
*/
uploadedFiles: any[];
}
/**
* Defines valid properties in FileUpload component.
*/
@ -257,6 +406,11 @@ export interface FileUploadProps {
* Style class of the component.
*/
class?: any;
/**
* Uses to pass attributes to DOM elements inside the component.
* @type {FileUploadPassThroughOptions}
*/
pt?: FileUploadPassThroughOptions;
}
/**

View File

@ -1,58 +1,59 @@
<template>
<div v-if="isAdvanced" class="p-fileupload p-fileupload-advanced p-component">
<input ref="fileInput" type="file" @change="onFileSelect" :multiple="multiple" :accept="accept" :disabled="chooseDisabled" />
<div class="p-fileupload-buttonbar">
<slot name="header" :files="files" :uploadedFiles="uploadedFiles" :chooseCallback="choose" :uploadCallback="upload" :clearCallback="clear">
<span v-ripple :class="advancedChooseButtonClass" :style="style" @click="choose" @keydown.enter="choose" @focus="onFocus" @blur="onBlur" tabindex="0">
<div v-if="isAdvanced" class="p-fileupload p-fileupload-advanced p-component" v-bind="ptm('root')">
<input ref="fileInput" type="file" @change="onFileSelect" :multiple="multiple" :accept="accept" :disabled="chooseDisabled" v-bind="ptm('input')" />
<div class="p-fileupload-buttonbar" v-bind="ptm('buttonbar')">
<slot name="header" :files="files" :uploadedFiles="uploadedFiles" :chooseCallback="choose" :uploadCallback="upload" :clearCallback="clear" v-bind="ptm('header')">
<span v-ripple :class="advancedChooseButtonClass" :style="style" @click="choose" @keydown.enter="choose" @focus="onFocus" @blur="onBlur" tabindex="0" v-bind="ptm('button')">
<slot name="chooseicon">
<component :is="chooseIcon ? 'span' : 'PlusIcon'" :class="['p-button-icon p-button-icon-left', chooseIcon]" aria-hidden="true" />
<component :is="chooseIcon ? 'span' : 'PlusIcon'" :class="['p-button-icon p-button-icon-left', chooseIcon]" aria-hidden="true" v-bind="ptm('chooseIcon')" />
</slot>
<span class="p-button-label">{{ chooseButtonLabel }}</span>
<span class="p-button-label" v-bind="ptm('chooseButtonLabel')">{{ chooseButtonLabel }}</span>
</span>
<FileUploadButton v-if="showUploadButton" :label="uploadButtonLabel" @click="upload" :disabled="uploadDisabled">
<FileUploadButton v-if="showUploadButton" :label="uploadButtonLabel" @click="upload" :disabled="uploadDisabled" :pt="ptm('uploadButton')">
<template #icon="iconProps">
<slot name="uploadicon">
<component :is="uploadIcon ? 'span' : 'UploadIcon'" :class="[iconProps.class, uploadIcon]" aria-hidden="true" />
<component :is="uploadIcon ? 'span' : 'UploadIcon'" :class="[iconProps.class, uploadIcon]" aria-hidden="true" v-bind="ptm('uploadButton')['icon']" />
</slot>
</template>
</FileUploadButton>
<FileUploadButton v-if="showCancelButton" :label="cancelButtonLabel" @click="clear" :disabled="cancelDisabled">
<FileUploadButton v-if="showCancelButton" :label="cancelButtonLabel" @click="clear" :disabled="cancelDisabled" :pt="ptm('cancelButton')">
<template #icon="iconProps">
<slot name="cancelicon">
<component :is="cancelIcon ? 'span' : 'TimesIcon'" :class="[iconProps.class, cancelIcon]" aria-hidden="true" />
<component :is="cancelIcon ? 'span' : 'TimesIcon'" :class="[iconProps.class, cancelIcon]" aria-hidden="true" v-bind="ptm('cancelButton')['icon']" />
</slot>
</template>
</FileUploadButton>
</slot>
</div>
<div ref="content" class="p-fileupload-content" @dragenter="onDragEnter" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop">
<div ref="content" class="p-fileupload-content" @dragenter="onDragEnter" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop" v-bind="ptm('content')">
<slot name="content" :files="files" :uploadedFiles="uploadedFiles" :removeUploadedFileCallback="removeUploadedFile" :removeFileCallback="remove" :progress="progress" :messages="messages">
<FileUploadProgressBar v-if="hasFiles" :value="progress" :showValue="false" />
<FileUploadMessage v-for="msg of messages" :key="msg" severity="error" @close="onMessageClose">{{ msg }}</FileUploadMessage>
<FileContent v-if="hasFiles" :files="files" @remove="remove" :badgeValue="pendingLabel" :previewWidth="previewWidth" :templates="$slots" />
<FileContent :files="uploadedFiles" @remove="removeUploadedFile" :badgeValue="completedLabel" badgeSeverity="success" :previewWidth="previewWidth" :templates="$slots" />
<FileUploadProgressBar v-if="hasFiles" :value="progress" :showValue="false" :pt="ptm('progressbar')" />
<FileUploadMessage v-for="msg of messages" :key="msg" severity="error" @close="onMessageClose" :pt="ptm('messages')">{{ msg }}</FileUploadMessage>
<FileContent v-if="hasFiles" :files="files" @remove="remove" :badgeValue="pendingLabel" :previewWidth="previewWidth" :templates="$slots" :pt="pt" />
<FileContent :files="uploadedFiles" @remove="removeUploadedFile" :badgeValue="completedLabel" badgeSeverity="success" :previewWidth="previewWidth" :templates="$slots" :pt="pt" />
</slot>
<div v-if="$slots.empty && !hasFiles && !hasUploadedFiles" class="p-fileupload-empty">
<div v-if="$slots.empty && !hasFiles && !hasUploadedFiles" class="p-fileupload-empty" v-bind="ptm('empty')">
<slot name="empty"></slot>
</div>
</div>
</div>
<div v-else-if="isBasic" class="p-fileupload p-fileupload-basic p-component">
<FileUploadMessage v-for="msg of messages" :key="msg" severity="error" @close="onMessageClose">{{ msg }}</FileUploadMessage>
<span v-ripple :class="basicChooseButtonClass" :style="style" @mouseup="onBasicUploaderClick" @keydown.enter="choose" @focus="onFocus" @blur="onBlur" tabindex="0">
<div v-else-if="isBasic" class="p-fileupload p-fileupload-basic p-component" v-bind="ptm('root')">
<FileUploadMessage v-for="msg of messages" :key="msg" severity="error" @close="onMessageClose" :pt="ptm('messages')">{{ msg }}</FileUploadMessage>
<span v-ripple :class="basicChooseButtonClass" :style="style" @mouseup="onBasicUploaderClick" @keydown.enter="choose" @focus="onFocus" @blur="onBlur" tabindex="0" v-bind="ptm('basicButton')">
<slot v-if="!hasFiles || auto" name="uploadicon">
<component :is="uploadIcon ? 'span' : 'UploadIcon'" :class="['p-button-icon p-button-icon-left', uploadIcon]" aria-hidden="true" />
<component :is="uploadIcon ? 'span' : 'UploadIcon'" :class="['p-button-icon p-button-icon-left', uploadIcon]" aria-hidden="true" v-bind="ptm('uploadIcon')" />
</slot>
<slot v-else name="chooseicon">
<component :is="chooseIcon ? 'span' : 'PlusIcon'" :class="['p-button-icon p-button-icon-left', chooseIcon]" aria-hidden="true" />
<component :is="chooseIcon ? 'span' : 'PlusIcon'" :class="['p-button-icon p-button-icon-left', chooseIcon]" aria-hidden="true" v-bind="ptm('chooseIcon')" />
</slot>
<span class="p-button-label">{{ basicChooseButtonLabel }}</span>
<input v-if="!hasFiles" ref="fileInput" type="file" :accept="accept" :disabled="disabled" :multiple="multiple" @change="onFileSelect" @focus="onFocus" @blur="onBlur" />
<span class="p-button-label" v-bind="ptm('label')">{{ basicChooseButtonLabel }}</span>
<input v-if="!hasFiles" ref="fileInput" type="file" :accept="accept" :disabled="disabled" :multiple="multiple" @change="onFileSelect" @focus="onFocus" @blur="onBlur" v-bind="ptm('input')" />
</span>
</div>
</template>
<script>
import BaseComponent from 'primevue/basecomponent';
import Button from 'primevue/button';
import PlusIcon from 'primevue/icons/plus';
import TimesIcon from 'primevue/icons/times';
@ -65,6 +66,7 @@ import FileContent from './FileContent.vue';
export default {
name: 'FileUpload',
extends: BaseComponent,
emits: ['select', 'uploader', 'before-upload', 'progress', 'upload', 'error', 'before-send', 'clear', 'remove', 'remove-uploaded-file'],
props: {
name: {

View File

@ -9,6 +9,7 @@
*/
import { ButtonHTMLAttributes, VNode } from 'vue';
import { MenuItem } from '../menuitem';
import { TieredMenuPassThroughOptions } from '../tieredmenu';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
export declare type SplitButtonPassThroughOptionType = SplitButtonPassThroughAttributes | ((options: SplitButtonPassThroughMethodOptions) => SplitButtonPassThroughAttributes) | null | undefined;
@ -48,8 +49,9 @@ export interface SplitButtonPassThroughOptions {
menuButtonIcon?: SplitButtonPassThroughOptionType;
/**
* Uses to pass attributes to the menu's DOM element.
* @see {@link TieredMenuPassThroughOptions}
*/
menu?: SplitButtonPassThroughOptionType;
menu?: TieredMenuPassThroughOptions;
}
/**

View File

@ -14742,6 +14742,27 @@
"methodDescription": "Defines methods that can be accessed by the component's reference.",
"typeDescription": "Defines the custom types used by the module.",
"values": {
"FileUploadPassThroughMethodOptions": {
"description": "Custom passthrough(pt) option method.",
"relatedProp": "",
"props": [
{
"name": "props",
"optional": false,
"readonly": false,
"type": "FileUploadProps",
"default": ""
},
{
"name": "state",
"optional": false,
"readonly": false,
"type": "FileUploadState",
"default": ""
}
],
"methods": []
},
"FileUploadSelectEvent": {
"description": "Custom select event.",
"relatedProp": "FileUploadEmits.select",
@ -14941,6 +14962,257 @@
],
"methods": []
},
"FileUploadPassThroughOptions": {
"description": "Custom passthrough(pt) options.",
"relatedProp": "FileUploadProps.pt",
"props": [
{
"name": "root",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the root's DOM element."
},
{
"name": "input",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the input's DOM element."
},
{
"name": "buttonbar",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the buttonbar's DOM element."
},
{
"name": "header",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the header' DOM element."
},
{
"name": "button",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the button's DOM element."
},
{
"name": "chooseIcon",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the choose icon's DOM element."
},
{
"name": "uploadButton",
"optional": true,
"readonly": false,
"type": "ButtonPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to the upload button's DOM element."
},
{
"name": "cancelButton",
"optional": true,
"readonly": false,
"type": "ButtonPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to the cancel button's DOM element."
},
{
"name": "content",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the content's DOM element."
},
{
"name": "progressbar",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the progressbar's DOM element."
},
{
"name": "messages",
"optional": true,
"readonly": false,
"type": "MessagePassThroughOptions",
"default": "",
"description": "Uses to pass attributes to the messages' DOM element."
},
{
"name": "empty",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the empty's DOM element."
},
{
"name": "basicButton",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the basic button's DOM element."
},
{
"name": "uploadIcon",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the upload icon's DOM element."
},
{
"name": "label",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the label's DOM element."
},
{
"name": "file",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the file's DOM element."
},
{
"name": "thumbnail",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the thumbnail's DOM element."
},
{
"name": "details",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the details's DOM element."
},
{
"name": "fileName",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the fileName's DOM element."
},
{
"name": "fileSize",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the fileSize's DOM element."
},
{
"name": "badge",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the badge's DOM element."
},
{
"name": "actions",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptionType",
"default": "",
"description": "Uses to pass attributes to the actions's DOM element."
},
{
"name": "removeButton",
"optional": true,
"readonly": false,
"type": "ButtonPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to the remove button's DOM element."
}
],
"methods": []
},
"FileUploadPassThroughAttributes": {
"description": "Custom passthrough attributes for each DOM elements",
"relatedProp": "",
"props": [
{
"name": "[key: string]",
"optional": false,
"readonly": false,
"type": "any"
}
],
"methods": []
},
"FileUploadState": {
"description": "Defines current inline state in FileUpload component.",
"relatedProp": "",
"props": [
{
"name": "uploadedFileCount",
"optional": false,
"readonly": false,
"type": "number",
"default": "0",
"description": "Current uploaded file count state as a number."
},
{
"name": "files",
"optional": false,
"readonly": false,
"type": "any[]",
"default": "",
"description": "Current files."
},
{
"name": "messages",
"optional": false,
"readonly": false,
"type": "any[]",
"default": "",
"description": "Current messages."
},
{
"name": "progress",
"optional": false,
"readonly": false,
"type": "number",
"default": "",
"description": "Current progress state as a number."
},
{
"name": "uploadedFiles",
"optional": false,
"readonly": false,
"type": "any[]",
"default": "",
"description": "Current uploaded files."
}
],
"methods": []
},
"FileUploadProps": {
"description": "Defines valid properties in FileUpload component.",
"relatedProp": "",
@ -15147,6 +15419,14 @@
"type": "any",
"default": "",
"description": "Style class of the component."
},
{
"name": "pt",
"optional": true,
"readonly": false,
"type": "FileUploadPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to DOM elements inside the component."
}
],
"methods": []
@ -15348,6 +15628,14 @@
]
}
}
},
"types": {
"description": "Defines the custom types used by the module.",
"values": {
"FileUploadPassThroughOptionType": {
"values": "FileUploadPassThroughAttributes | (options: FileUploadPassThroughMethodOptions) => FileUploadPassThroughAttributes | null | undefined"
}
}
}
},
"focustrap": {
@ -25824,7 +26112,7 @@
"name": "menu",
"optional": true,
"readonly": false,
"type": "SplitButtonPassThroughOptionType",
"type": "TieredMenuPassThroughOptions",
"default": "",
"description": "Uses to pass attributes to the menu's DOM element."
}