Files
wehub-resource-sync 719032b19f
Update Schema / Update configuration json schema (push) Has been cancelled
Memory Benchmark / Memory Test (Full Analysis) (push) Has been cancelled
CI Quality / Lint GitHub Actions (actionlint) (push) Has been cancelled
CI Quality / Lint GitHub Actions (zizmor) (push) Has been cancelled
CI Quality / Check typos (push) Has been cancelled
CI / Test coverage (push) Has been cancelled
CI / Test (22.x, windows-latest) (push) Has been cancelled
CI / Test (24.x, macos-latest) (push) Has been cancelled
CI / Test (24.x, ubuntu-latest) (push) Has been cancelled
CI / Test (24.x, windows-latest) (push) Has been cancelled
CI / Test (26.x, macos-latest) (push) Has been cancelled
CI / Test (26.x, ubuntu-latest) (push) Has been cancelled
CI / Test (26.x, windows-latest) (push) Has been cancelled
CI / Test with Bun (latest, macos-latest) (push) Has been cancelled
CI / Test with Bun (latest, ubuntu-latest) (push) Has been cancelled
CI / Test with Bun (latest, windows-latest) (push) Has been cancelled
CI / Build and run (22.x, macos-latest) (push) Has been cancelled
CI / Build and run (22.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (22.x, windows-latest) (push) Has been cancelled
autofix.ci / autofix (push) Has been cancelled
CI Browser Extension / Lint Browser Extension (push) Has been cancelled
CI Browser Extension / Test Browser Extension (push) Has been cancelled
Memory Benchmark / Memory Test (push) Has been cancelled
CI Website / Lint Website Client (push) Has been cancelled
CI Website / Lint Website Server (push) Has been cancelled
CI Website / Test Website Server (push) Has been cancelled
CI Website / Bundle Website Server (push) Has been cancelled
CI / Lint Biome (push) Has been cancelled
CI / Lint oxlint (push) Has been cancelled
CI / Lint TypeScript (push) Has been cancelled
CI / Lint Secretlint (push) Has been cancelled
CI / Test (22.x, macos-latest) (push) Has been cancelled
CI / Test (22.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (24.x, macos-latest) (push) Has been cancelled
CI / Build and run (24.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (24.x, windows-latest) (push) Has been cancelled
CI / Build and run (26.x, macos-latest) (push) Has been cancelled
CI / Build and run (26.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (26.x, windows-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, macos-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, ubuntu-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Docker / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Docker / build (linux/arm/v7, ubuntu-24.04-arm) (push) Has been cancelled
Docker / build (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Docker / merge (push) Has been cancelled
Pack repository with Repomix / pack-repo (push) Has been cancelled
Performance Benchmark History / Benchmark (macos-latest) (push) Has been cancelled
Performance Benchmark History / Benchmark (ubuntu-latest) (push) Has been cancelled
Performance Benchmark History / Benchmark (windows-latest) (push) Has been cancelled
Performance Benchmark History / Store Results (push) Has been cancelled
Test Repomix Action / Test Node.js 22 (push) Has been cancelled
Test Repomix Action / Test Node.js 24 (push) Has been cancelled
Test Repomix Action / Test Node.js 26 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:37 +08:00

236 lines
4.8 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { AlertTriangle, FolderArchive } from 'lucide-vue-next';
import { useFileUpload } from '../../composables/useFileUpload';
import { useZipProcessor } from '../../composables/useZipProcessor';
import PackButton from './PackButton.vue';
const props = defineProps<{
loading: boolean;
showButton?: boolean;
}>();
const emit = defineEmits<{
upload: [file: File];
cancel: [];
}>();
const { validateZipFile } = useZipProcessor();
const {
fileInput,
dragActive,
selectedItem: selectedFile,
errorMessage,
hasError,
isValid,
inputAttributes,
handleFileSelect,
handleDragOver,
handleDragLeave,
handleDrop,
triggerFileInput,
clearSelection,
} = useFileUpload({
mode: 'file',
placeholder: 'Drop your ZIP file here or click to browse (max 10MB)',
icon: 'file',
options: {
maxFileSize: 10 * 1024 * 1024, // 10MB
acceptedTypes: ['.zip'],
accept: '.zip',
validateFile: validateZipFile,
},
});
async function onFileSelect(files: FileList | null) {
const result = await handleFileSelect(files);
if (result.success && result.result) {
emit('upload', result.result);
}
}
async function onDrop(event: DragEvent) {
const result = await handleDrop(event);
if (result.success && result.result) {
emit('upload', result.result);
}
}
function clearFile() {
clearSelection();
}
</script>
<template>
<div class="upload-wrapper">
<div
class="upload-container"
:class="{ 'drag-active': dragActive, 'has-error': hasError }"
role="button"
tabindex="0"
aria-label="Upload ZIP file"
@dragover.prevent="handleDragOver"
@dragleave="handleDragLeave"
@drop.prevent="onDrop"
@click="triggerFileInput"
@keydown.enter.self.prevent="triggerFileInput"
@keydown.space.self.prevent="triggerFileInput"
>
<input
ref="fileInput"
v-bind="inputAttributes"
class="hidden-input"
@change="(e) => onFileSelect((e.target as HTMLInputElement).files)"
/>
<div class="upload-content">
<div class="upload-icon">
<AlertTriangle v-if="hasError" class="icon-error" size="20" />
<FolderArchive v-else class="icon-folder" size="20" />
</div>
<div class="upload-text">
<p v-if="errorMessage" class="error-message">
{{ errorMessage }}
</p>
<p v-else-if="selectedFile" class="selected-file">
Selected: {{ selectedFile }}
<button
type="button"
class="clear-button"
aria-label="Clear selected file"
@click.stop="clearFile"
>×</button>
</p>
<template v-else>
<p>Drop your ZIP file here or click to browse (max 10MB)</p>
</template>
</div>
</div>
</div>
</div>
<div v-if="showButton" class="pack-button-container">
<PackButton
:loading="loading"
:isValid="isValid"
@cancel="$emit('cancel')"
/>
</div>
</template>
<style scoped>
.upload-wrapper {
width: 100%;
}
.upload-container {
border: 2px dashed var(--vp-c-border);
border-radius: 8px;
padding: 0 16px;
cursor: pointer;
transition: all 0.2s ease;
height: 50px;
display: flex;
align-items: center;
background: var(--vp-c-bg);
user-select: none;
}
.upload-container:hover {
border-color: var(--vp-c-brand-1);
background-color: var(--vp-c-bg-soft);
}
.upload-container:focus-visible {
outline: 2px solid var(--vp-c-brand-1);
outline-offset: 2px;
}
.drag-active {
border-color: var(--vp-c-brand-1);
background-color: var(--vp-c-bg-soft);
}
.has-error {
border-color: var(--vp-c-danger-1);
}
.hidden-input {
display: none;
}
.upload-content {
display: flex;
flex-direction: row;
align-items: center;
gap: 12px;
width: 100%;
pointer-events: none; /* Allow clicks to pass through to container */
}
.upload-icon {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.icon-folder {
color: var(--vp-c-text-1);
}
.icon-error {
color: var(--vp-c-danger-1);
}
.upload-text {
flex: 1;
font-size: 14px;
}
.upload-text p {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.error-message {
color: var(--vp-c-danger-1);
}
.selected-file {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
}
.clear-button {
background: none;
border: none;
color: var(--vp-c-text-2);
cursor: pointer;
font-size: 1.2em;
padding: 0 4px;
line-height: 1;
flex-shrink: 0;
pointer-events: auto; /* Re-enable pointer events for button */
}
.clear-button:hover {
color: var(--vp-c-text-1);
}
.pack-button-container {
width: 100%;
display: flex;
justify-content: center;
margin-top: 16px;
}
@media (max-width: 640px) {
.upload-text p {
font-size: 13px;
}
}
</style>