@treeui/vue 0.13.0 → 0.15.0
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/dist/components/TAppShell.cjs.map +1 -1
- package/dist/components/TAppShell.js.map +1 -1
- package/dist/components/TAppShell.vue.d.ts +25 -0
- package/dist/components/TAppShell.vue.d.ts.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js +166 -104
- package/dist/components/TAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TButton.cjs.map +1 -1
- package/dist/components/TButton.js.map +1 -1
- package/dist/components/TButton.vue.d.ts +8 -2
- package/dist/components/TButton.vue.d.ts.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js +12 -3
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TChart.cjs.map +1 -1
- package/dist/components/TChart.js.map +1 -1
- package/dist/components/TChart.vue.d.ts.map +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.js +58 -58
- package/dist/components/TChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TColorSwatch.cjs +2 -0
- package/dist/components/TColorSwatch.cjs.map +1 -0
- package/dist/components/TColorSwatch.js +7 -0
- package/dist/components/TColorSwatch.js.map +1 -0
- package/dist/components/TColorSwatch.vue.d.ts +33 -0
- package/dist/components/TColorSwatch.vue.d.ts.map +1 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/components/TColorSwatch.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TDropdown.vue.d.ts +1 -1
- package/dist/components/TDropdown.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.cjs.map +1 -1
- package/dist/components/TFileUpload.js.map +1 -1
- package/dist/components/TFileUpload.vue.d.ts +77 -10
- package/dist/components/TFileUpload.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js +393 -144
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TInput.cjs.map +1 -1
- package/dist/components/TInput.js.map +1 -1
- package/dist/components/TInput.vue.d.ts +4 -1
- package/dist/components/TInput.vue.d.ts.map +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TKbd.cjs +2 -0
- package/dist/components/TKbd.cjs.map +1 -0
- package/dist/components/TKbd.js +7 -0
- package/dist/components/TKbd.js.map +1 -0
- package/dist/components/TKbd.vue.d.ts +18 -0
- package/dist/components/TKbd.vue.d.ts.map +1 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.js +12 -0
- package/dist/components/TKbd.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TNavMenu.cjs.map +1 -1
- package/dist/components/TNavMenu.js.map +1 -1
- package/dist/components/TNavMenu.vue.d.ts +9 -0
- package/dist/components/TNavMenu.vue.d.ts.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +67 -55
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TPage.cjs +2 -0
- package/dist/components/TPage.cjs.map +1 -0
- package/dist/components/TPage.js +7 -0
- package/dist/components/TPage.js.map +1 -0
- package/dist/components/TPage.vue.d.ts +35 -0
- package/dist/components/TPage.vue.d.ts.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPageHeader.cjs +2 -0
- package/dist/components/TPageHeader.cjs.map +1 -0
- package/dist/components/TPageHeader.js +7 -0
- package/dist/components/TPageHeader.js.map +1 -0
- package/dist/components/TPageHeader.vue.d.ts +40 -0
- package/dist/components/TPageHeader.vue.d.ts.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPopover.vue.d.ts +1 -1
- package/dist/components/TPopover.vue.d.ts.map +1 -1
- package/dist/components/TSelect.cjs.map +1 -1
- package/dist/components/TSelect.js.map +1 -1
- package/dist/components/TSelect.vue.d.ts +4 -1
- package/dist/components/TSelect.vue.d.ts.map +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +1 -4
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TSpacer.cjs +2 -0
- package/dist/components/TSpacer.cjs.map +1 -0
- package/dist/components/TSpacer.js +7 -0
- package/dist/components/TSpacer.js.map +1 -0
- package/dist/components/TSpacer.vue.d.ts +8 -0
- package/dist/components/TSpacer.vue.d.ts.map +1 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.js +16 -0
- package/dist/components/TSpacer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSplit.cjs +2 -0
- package/dist/components/TSplit.cjs.map +1 -0
- package/dist/components/TSplit.js +7 -0
- package/dist/components/TSplit.js.map +1 -0
- package/dist/components/TSplit.vue.d.ts +38 -0
- package/dist/components/TSplit.vue.d.ts.map +1 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/TSplit.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TStack.cjs.map +1 -1
- package/dist/components/TStack.js.map +1 -1
- package/dist/components/TStack.vue.d.ts +3 -0
- package/dist/components/TStack.vue.d.ts.map +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js +6 -1
- package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TStackItem.cjs +2 -0
- package/dist/components/TStackItem.cjs.map +1 -0
- package/dist/components/TStackItem.js +7 -0
- package/dist/components/TStackItem.js.map +1 -0
- package/dist/components/TStackItem.vue.d.ts +38 -0
- package/dist/components/TStackItem.vue.d.ts.map +1 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/TStackItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TText.cjs +2 -0
- package/dist/components/TText.cjs.map +1 -0
- package/dist/components/TText.js +7 -0
- package/dist/components/TText.js.map +1 -0
- package/dist/components/TText.vue.d.ts +39 -0
- package/dist/components/TText.vue.d.ts.map +1 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js +32 -0
- package/dist/components/TText.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TTextarea.cjs.map +1 -1
- package/dist/components/TTextarea.js.map +1 -1
- package/dist/components/TTextarea.vue.d.ts +4 -1
- package/dist/components/TTextarea.vue.d.ts.map +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js +2 -0
- package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +12 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/composables/useTheme.cjs +2 -0
- package/dist/composables/useTheme.cjs.map +1 -0
- package/dist/composables/useTheme.d.ts +38 -0
- package/dist/composables/useTheme.d.ts.map +1 -0
- package/dist/composables/useTheme.js +54 -0
- package/dist/composables/useTheme.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -55
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +113 -97
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/contracts.cjs +1 -1
- package/dist/types/contracts.cjs.map +1 -1
- package/dist/types/contracts.d.ts +8 -1
- package/dist/types/contracts.d.ts.map +1 -1
- package/dist/types/contracts.js +8 -2
- package/dist/types/contracts.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TFileUpload.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: {\n file: File;\n index: number;\n removeFile: () => void;\n }) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isUnavailable = computed(() => props.disabled || props.loading);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isUnavailable.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst fileKey = (file: File, index: number) =>\n `${file.name}-${file.size}-${file.lastModified}-${index}`;\n\nconst matchesAccept = (file: File) => {\n if (!props.accept.trim()) {\n return true;\n }\n\n const tokens = props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean);\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isUnavailable.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isUnavailable.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst removeFile = (index: number) => {\n if (isUnavailable.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isUnavailable.value || !hasFiles.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isUnavailable.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isUnavailable.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isUnavailable\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isUnavailable || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isUnavailable ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ label }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"(file, index) in modelValue\"\n :key=\"fileKey(file, index)\"\n class=\"t-file-upload__file\"\n >\n <slot\n name=\"file\"\n :file=\"file\"\n :index=\"index\"\n :remove-file=\"() => removeFile(index)\"\n >\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ formatFileSize(file.size) }}\n </p>\n </div>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n :aria-label=\"`Remove ${file.name}`\"\n @click=\"removeFile(index)\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TFileUpload.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TProgress from './TProgress.vue';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nexport type TFileUploadStatus =\n | 'pending'\n | 'uploading'\n | 'paused'\n | 'error'\n | 'success';\n\nexport interface TFileUploadState {\n status: TFileUploadStatus;\n progress?: number;\n uploadedBytes?: number;\n remainingMs?: number;\n remainingLabel?: string;\n error?: string;\n resumable?: boolean;\n retryable?: boolean;\n thumbnailUrl?: string;\n meta?: string;\n}\n\nexport type TFileUploadStateSource =\n | ReadonlyMap<File, TFileUploadState>\n | ((file: File, index: number) => TFileUploadState | undefined);\n\nexport interface TFileUploadRetryPayload {\n file: File;\n index: number;\n fileKey: string;\n mode: 'resume' | 'restart';\n state: TFileUploadState;\n}\n\nexport interface TFileUploadCancelPayload {\n file: File;\n index: number;\n fileKey: string;\n state: TFileUploadState;\n reason: 'remove' | 'clear';\n}\n\nexport interface TFileUploadFileSlotProps {\n file: File;\n index: number;\n fileKey: string;\n state: TFileUploadState | undefined;\n thumbnailUrl: string | undefined;\n sizeLabel: string;\n typeLabel: string;\n dimensionsLabel: string | undefined;\n progressLabel: string | undefined;\n remainingLabel: string | undefined;\n uploadedLabel: string | undefined;\n statusLabel: string | undefined;\n actionLabel: string | undefined;\n canRetry: boolean;\n retryMode: 'resume' | 'restart';\n isDragActive: boolean;\n isDragReject: boolean;\n removeFile: () => void;\n retryFile: () => void;\n}\n\ninterface ThumbEntry {\n url: string;\n width: number | null;\n height: number | null;\n}\n\ninterface FileRow {\n slotProps: TFileUploadFileSlotProps;\n rowClass: string | undefined;\n metaText: string;\n statusText: string;\n errorText: string | undefined;\n errorId: string | undefined;\n showProgress: boolean;\n progressValue: number | undefined;\n progressAriaLabel: string;\n isBusy: boolean;\n isSuccess: boolean;\n}\n\nconst DEFAULT_STATUS_LABELS: Record<TFileUploadStatus, string> = {\n pending: 'Waiting',\n uploading: 'Uploading',\n paused: 'Paused',\n error: 'Upload failed',\n success: 'Uploaded',\n};\n\n// The status log keeps a bounded history of announcements. Old entries are\n// trimmed rather than replaced in place so that each terminal transition\n// inserts a brand new node: `aria-relevant` defaults to \"additions text\", so\n// assistive tech announces the insertion and ignores the trim.\nconst STATUS_LOG_LIMIT = 5;\n\ntype StatusLogEntry = {\n id: number;\n text: string;\n};\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n isDragReject: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: TFileUploadFileSlotProps) => unknown;\n 'file-status'?: (props: TFileUploadFileSlotProps) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n uploadState?: TFileUploadStateSource;\n dragLabel?: string;\n dragRejectLabel?: string;\n thumbnails?: boolean;\n maxThumbnailSize?: number | null;\n retryLabel?: string;\n resumeLabel?: (percent: number) => string;\n remainingTimeFormat?: (remainingMs: number) => string;\n statusLabels?: Partial<Record<TFileUploadStatus, string>>;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n uploadState: undefined,\n dragLabel: 'Release to upload',\n dragRejectLabel: 'This file type is not accepted',\n thumbnails: true,\n maxThumbnailSize: 10 * 1024 * 1024,\n retryLabel: 'Retry',\n resumeLabel: (percent: number) => `Resume from ${percent}%`,\n remainingTimeFormat: (remainingMs: number) => {\n if (remainingMs < 5000) {\n return 'Less than 5s left';\n }\n\n const seconds = Math.round(remainingMs / 1000);\n\n if (seconds < 60) {\n return `About ${seconds}s left`;\n }\n\n const minutes = Math.round(seconds / 60);\n\n if (minutes < 60) {\n return `About ${minutes} min left`;\n }\n\n return `About ${Math.round(minutes / 60)}h left`;\n },\n statusLabels: () => ({}),\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n retry: [payload: TFileUploadRetryPayload];\n cancel: [payload: TFileUploadCancelPayload];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isDragReject = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\nconst statusLog = ref<StatusLogEntry[]>([]);\nlet statusLogId = 0;\nconst retryFocusKey = ref<string | null>(null);\nconst thumbs = ref(new Map<File, ThumbEntry>());\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isDisabled = computed(() => props.disabled);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst resolvedStatusLabels = computed(() => ({\n ...DEFAULT_STATUS_LABELS,\n ...props.statusLabels,\n}));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isDisabled.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'is-drag-reject': isDragReject.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst dropzoneLabel = computed(() => {\n if (isDragReject.value) {\n return props.dragRejectLabel;\n }\n\n return isDragActive.value ? props.dragLabel : props.label;\n});\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst formatFileType = (file: File) => {\n const dotIndex = file.name.lastIndexOf('.');\n const extension = dotIndex > 0 && dotIndex < file.name.length - 1\n ? file.name.slice(dotIndex + 1).toUpperCase()\n : '';\n\n if (extension && extension.length <= 5) {\n return extension;\n }\n\n const subtype = file.type.includes('/') ? file.type.split('/')[1] : '';\n\n return subtype ? subtype.toUpperCase() : 'FILE';\n};\n\nlet keySeq = 0;\nconst keyCache = new WeakMap<File, string>();\n\nconst fileKeyFor = (file: File) => {\n let key = keyCache.get(file);\n\n if (!key) {\n keySeq += 1;\n key = `${uploadId}-f${keySeq}`;\n keyCache.set(file, key);\n }\n\n return key;\n};\n\nconst acceptTokens = computed(() =>\n props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean),\n);\n\nconst matchesAccept = (file: File) => {\n if (acceptTokens.value.length === 0) {\n return true;\n }\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return acceptTokens.value.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst canDetectDragReject = computed(() =>\n acceptTokens.value.length > 0 && acceptTokens.value.every((token) => token.includes('/')),\n);\n\nconst matchesAcceptType = (type: string) => {\n const fileType = type.toLowerCase();\n\n if (!fileType) {\n return true;\n }\n\n return acceptTokens.value.some((token) =>\n token.endsWith('/*') ? fileType.startsWith(token.slice(0, -1)) : fileType === token,\n );\n};\n\nconst detectDragReject = (dataTransfer?: DataTransfer | null) => {\n if (!canDetectDragReject.value || !dataTransfer) {\n return false;\n }\n\n const items = dataTransfer.items;\n\n if (!items || items.length === 0) {\n return false;\n }\n\n const fileItems = Array.from(items).filter((item) => item.kind === 'file');\n\n if (fileItems.length === 0) {\n return false;\n }\n\n return fileItems.every((item) => !matchesAcceptType(item.type));\n};\n\nconst resolveState = (file: File, index: number) => {\n const source = props.uploadState;\n\n if (!source) {\n return undefined;\n }\n\n return typeof source === 'function' ? source(file, index) : source.get(file);\n};\n\nconst resolvedStates = computed(() => props.modelValue.map(resolveState));\n\nconst canUseObjectUrl = () =>\n typeof window !== 'undefined' &&\n typeof URL !== 'undefined' &&\n typeof URL.createObjectURL === 'function' &&\n typeof URL.revokeObjectURL === 'function';\n\nconst isThumbnailable = (file: File) =>\n file.type.startsWith('image/') &&\n (props.maxThumbnailSize === null || file.size <= props.maxThumbnailSize);\n\nconst releaseAllThumbnails = () => {\n if (canUseObjectUrl()) {\n for (const entry of thumbs.value.values()) {\n URL.revokeObjectURL(entry.url);\n }\n }\n\n thumbs.value.clear();\n};\n\nconst syncThumbnails = () => {\n if (!props.thumbnails || !canUseObjectUrl()) {\n releaseAllThumbnails();\n return;\n }\n\n const live = new Set(props.modelValue);\n\n for (const [file, entry] of [...thumbs.value]) {\n if (!live.has(file)) {\n URL.revokeObjectURL(entry.url);\n thumbs.value.delete(file);\n }\n }\n\n for (const file of props.modelValue) {\n if (thumbs.value.has(file) || !isThumbnailable(file)) {\n continue;\n }\n\n const url = URL.createObjectURL(file);\n thumbs.value.set(file, { url, width: null, height: null });\n\n const image = new Image();\n\n image.onload = () => {\n const current = thumbs.value.get(file);\n\n if (!current || current.url !== url) {\n return;\n }\n\n thumbs.value.set(file, { url, width: image.naturalWidth, height: image.naturalHeight });\n };\n\n image.src = url;\n }\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isDisabled.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isDisabled.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst emitCancel = (file: File, index: number, reason: 'remove' | 'clear') => {\n const state = resolvedStates.value[index];\n\n if (!state || (state.status !== 'uploading' && state.status !== 'paused')) {\n return;\n }\n\n emit('cancel', { file, index, fileKey: fileKeyFor(file), state, reason });\n};\n\nconst removeFile = (index: number) => {\n if (isDisabled.value) {\n return;\n }\n\n const file = props.modelValue[index];\n\n if (file) {\n emitCancel(file, index, 'remove');\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isDisabled.value || !hasFiles.value) {\n return;\n }\n\n props.modelValue.forEach((file, index) => {\n emitCancel(file, index, 'clear');\n });\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst rows = computed<FileRow[]>(() =>\n props.modelValue.map((file, index) => {\n const state = resolvedStates.value[index];\n const status = state?.status;\n const thumb = thumbs.value.get(file);\n const key = fileKeyFor(file);\n\n const progress = state?.progress;\n const percent = typeof progress === 'number' ? Math.round(progress) : undefined;\n const isResumable = state?.resumable === true;\n\n const canRetry = Boolean(\n state && (status === 'error' || status === 'paused') && state.retryable !== false,\n );\n const retryMode: 'resume' | 'restart' = isResumable ? 'resume' : 'restart';\n\n const sizeLabel = formatFileSize(file.size);\n const typeLabel = formatFileType(file);\n const dimensionsLabel = thumb && thumb.width !== null && thumb.height !== null\n ? `${thumb.width} × ${thumb.height}`\n : undefined;\n\n const progressLabel = status === 'uploading' && percent !== undefined\n ? `${percent}%`\n : undefined;\n\n let remainingLabel: string | undefined;\n\n if (status === 'uploading') {\n if (state?.remainingLabel) {\n remainingLabel = state.remainingLabel;\n } else if (\n typeof state?.remainingMs === 'number' &&\n Number.isFinite(state.remainingMs) &&\n state.remainingMs >= 0\n ) {\n remainingLabel = props.remainingTimeFormat(state.remainingMs);\n }\n }\n\n const uploadedLabel = (status === 'error' || status === 'paused') &&\n typeof state?.uploadedBytes === 'number'\n ? `${formatFileSize(state.uploadedBytes)} of ${sizeLabel} uploaded`\n : undefined;\n\n const statusLabel = status ? resolvedStatusLabels.value[status] : undefined;\n\n let actionLabel: string | undefined;\n\n if (canRetry) {\n actionLabel = isResumable && percent !== undefined\n ? props.resumeLabel(percent)\n : props.retryLabel;\n }\n\n const errorText = status === 'error' ? state?.error : undefined;\n\n const slotProps: TFileUploadFileSlotProps = {\n file,\n index,\n fileKey: key,\n state,\n thumbnailUrl: state?.thumbnailUrl ?? thumb?.url,\n sizeLabel,\n typeLabel,\n dimensionsLabel,\n progressLabel,\n remainingLabel,\n uploadedLabel,\n statusLabel,\n actionLabel,\n canRetry,\n retryMode,\n isDragActive: isDragActive.value,\n isDragReject: isDragReject.value,\n removeFile: () => removeFile(index),\n retryFile: () => {\n if (!canRetry || isDisabled.value || !state) {\n return;\n }\n\n emit('retry', { file, index, fileKey: key, mode: retryMode, state });\n },\n };\n\n return {\n slotProps,\n rowClass: status ? `is-${status}` : undefined,\n metaText: [typeLabel, sizeLabel, dimensionsLabel, state?.meta].filter(Boolean).join(' · '),\n statusText: [statusLabel, progressLabel, remainingLabel, uploadedLabel]\n .filter(Boolean)\n .join(' · '),\n errorText,\n errorId: errorText ? `${key}-error` : undefined,\n showProgress: Boolean(\n state &&\n (status === 'uploading' ||\n status === 'paused' ||\n status === 'error' ||\n (status === 'success' && percent !== undefined)),\n ),\n progressValue: status === 'uploading' ? progress : (progress ?? 0),\n progressAriaLabel: `${statusLabel ?? ''} ${file.name}`.trim(),\n isBusy: status === 'uploading',\n isSuccess: status === 'success',\n };\n }),\n);\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isDisabled.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onRetryFocus = (key: string) => {\n retryFocusKey.value = key;\n};\n\nconst onRetryBlur = (key: string) => {\n if (retryFocusKey.value === key) {\n retryFocusKey.value = null;\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isDisabled.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n isDragReject.value = detectDragReject(event.dataTransfer);\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n isDragReject.value = detectDragReject(event.dataTransfer);\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n isDragReject.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n isDragReject.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nconst previousStatuses = new Map<File, TFileUploadStatus>();\n\nwatch(\n resolvedStates,\n (states) => {\n const messages: string[] = [];\n const live = new Set<File>();\n\n props.modelValue.forEach((file, index) => {\n live.add(file);\n\n const status = states[index]?.status;\n\n if (!status) {\n return;\n }\n\n const previous = previousStatuses.get(file);\n\n if (previous === status) {\n return;\n }\n\n previousStatuses.set(file, status);\n\n if (previous === undefined) {\n return;\n }\n\n if (status === 'success') {\n messages.push(`${file.name} uploaded.`);\n } else if (status === 'error') {\n messages.push(`${file.name} failed. ${states[index]?.error ?? ''}`.trim());\n }\n });\n\n for (const file of [...previousStatuses.keys()]) {\n if (!live.has(file)) {\n previousStatuses.delete(file);\n }\n }\n\n if (messages.length > 0) {\n // Append instead of overwriting a single string: two identical messages\n // in a row (a retry that fails with the same error) would otherwise write\n // a byte-identical value, which `Object.is` suppresses — no DOM mutation,\n // so `aria-live` never fires and the repeat failure is announced as silence.\n statusLogId += 1;\n statusLog.value = [\n ...statusLog.value,\n { id: statusLogId, text: messages.join(' ') },\n ].slice(-STATUS_LOG_LIMIT);\n }\n },\n { flush: 'post', immediate: true },\n);\n\nwatch(\n resolvedStates,\n () => {\n const key = retryFocusKey.value;\n const root = rootRef.value;\n\n if (!key || !root) {\n return;\n }\n\n if (document.activeElement && document.activeElement !== document.body) {\n return;\n }\n\n if (root.querySelector(`[data-t-retry=\"${key}\"]`)) {\n return;\n }\n\n retryFocusKey.value = null;\n\n const fallback = root.querySelector<HTMLElement>(`[data-t-remove=\"${key}\"]`) ??\n root.querySelector<HTMLElement>('.t-file-upload__dropzone');\n\n fallback?.focus();\n },\n { flush: 'post' },\n);\n\nwatch(() => props.modelValue, syncThumbnails);\nwatch(() => props.thumbnails, syncThumbnails);\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n syncThumbnails();\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n releaseAllThumbnails();\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isDisabled\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isDisabled || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isDisabled ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :is-drag-reject=\"isDragReject\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ dropzoneLabel }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n class=\"t-file-upload__status-log t-visually-hidden\"\n role=\"log\"\n aria-live=\"polite\"\n >\n <p\n v-for=\"entry in statusLog\"\n :key=\"entry.id\"\n class=\"t-file-upload__status-log-entry\"\n >\n {{ entry.text }}\n </p>\n </div>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isDisabled\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"row in rows\"\n :key=\"row.slotProps.fileKey\"\n class=\"t-file-upload__file\"\n :class=\"row.rowClass\"\n :aria-busy=\"row.isBusy || undefined\"\n >\n <slot\n name=\"file\"\n v-bind=\"row.slotProps\"\n >\n <span\n class=\"t-file-upload__thumb\"\n aria-hidden=\"true\"\n >\n <img\n v-if=\"row.slotProps.thumbnailUrl\"\n class=\"t-file-upload__thumb-image\"\n :src=\"row.slotProps.thumbnailUrl\"\n alt=\"\"\n >\n <span\n v-else\n class=\"t-file-upload__thumb-fallback\"\n >\n {{ row.slotProps.typeLabel }}\n </span>\n </span>\n\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ row.slotProps.file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ row.metaText }}\n </p>\n\n <slot\n name=\"file-status\"\n v-bind=\"row.slotProps\"\n >\n <div\n v-if=\"row.showProgress\"\n class=\"t-file-upload__file-progress\"\n >\n <TProgress\n size=\"sm\"\n :value=\"row.progressValue\"\n :label=\"row.progressAriaLabel\"\n />\n </div>\n\n <p\n v-if=\"row.statusText\"\n class=\"t-file-upload__file-status\"\n >\n <span\n v-if=\"row.isSuccess\"\n class=\"t-file-upload__proof\"\n aria-hidden=\"true\"\n >✓</span>{{ row.statusText }}\n </p>\n\n <p\n v-if=\"row.errorText\"\n :id=\"row.errorId\"\n class=\"t-file-upload__file-error\"\n >\n {{ row.errorText }}\n </p>\n </slot>\n </div>\n\n <button\n v-if=\"row.slotProps.canRetry\"\n class=\"t-file-upload__retry\"\n type=\"button\"\n :data-t-retry=\"row.slotProps.fileKey\"\n :disabled=\"isDisabled\"\n :aria-describedby=\"row.errorId\"\n @focus=\"onRetryFocus(row.slotProps.fileKey)\"\n @blur=\"onRetryBlur(row.slotProps.fileKey)\"\n @click=\"row.slotProps.retryFile()\"\n >\n {{ row.slotProps.actionLabel }}\n </button>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :data-t-remove=\"row.slotProps.fileKey\"\n :disabled=\"isDisabled\"\n :aria-label=\"`Remove ${row.slotProps.file.name}`\"\n @click=\"row.slotProps.removeFile()\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|