Add files modal and X button

This commit is contained in:
2026-01-13 23:06:14 +05:00
parent 327aff6208
commit df9fe970ab
2 changed files with 26 additions and 4 deletions

View File

@ -2,25 +2,30 @@
import type { HTMLAttributes } from "vue"; import type { HTMLAttributes } from "vue";
import { Motion } from "motion-v"; import { Motion } from "motion-v";
import { ref } from "vue"; import { ref } from "vue";
import { X } from "lucide-vue-next";
import Button from "../button/Button.vue";
interface FileUploadProps { interface FileUploadProps {
class?: HTMLAttributes["class"]; class?: HTMLAttributes["class"];
accept?: string; accept?: string;
modelValue?: File[];
} }
defineProps<FileUploadProps>(); const props = defineProps<FileUploadProps>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: "onChange", files: File[]): void; (e: "onChange", files: File[]): void;
(e: "update:modelValue", files: File[]): void;
}>(); }>();
const fileInputRef = ref<HTMLInputElement | null>(null); const fileInputRef = ref<HTMLInputElement | null>(null);
const files = ref<File[]>([]); const files = ref<File[]>(props.modelValue || []);
const isActive = ref<boolean>(false); const isActive = ref<boolean>(false);
function handleFileChange(newFiles: File[]) { function handleFileChange(newFiles: File[]) {
files.value = [...files.value, ...newFiles]; files.value = [...files.value, ...newFiles];
emit("onChange", files.value); emit("onChange", files.value);
emit("update:modelValue", files.value);
} }
function onFileChange(e: Event) { function onFileChange(e: Event) {
@ -44,6 +49,17 @@ function handleDrop(e: DragEvent) {
const droppedFiles = e.dataTransfer?.files ? Array.from(e.dataTransfer.files) : []; const droppedFiles = e.dataTransfer?.files ? Array.from(e.dataTransfer.files) : [];
if (droppedFiles.length) handleFileChange(droppedFiles); if (droppedFiles.length) handleFileChange(droppedFiles);
} }
function removeFile(event: MouseEvent, index: number) {
files.value.splice(index, 1);
event.stopPropagation();
emit("update:modelValue", files.value);
}
watch(() => props.modelValue, (newVal) => {
if (newVal) {
files.value = newVal;
}
}, { deep: true });
</script> </script>
<template> <template>
@ -81,6 +97,11 @@ function handleDrop(e: DragEvent) {
class="rounded-md bg-muted px-1.5 py-1 text-sm"> class="rounded-md bg-muted px-1.5 py-1 text-sm">
{{ file.type || "unknown type" }} {{ file.type || "unknown type" }}
</Motion> </Motion>
<Motion as="div" :initial="{ opacity: 0 }" :animate="{ opacity: 1 }">
<Button variant="ghost" @click="(e: MouseEvent) => removeFile(e, idx)">
<X />
</Button>
</Motion>
</div> </div>
</Motion> </Motion>

View File

@ -17,6 +17,8 @@ import FileUpload from '@/components/ui/file-upload/FileUpload.vue';
import FileUploadGrid from '@/components/ui/file-upload/FileUploadGrid.vue'; import FileUploadGrid from '@/components/ui/file-upload/FileUploadGrid.vue';
import Button from '@/components/ui/button/Button.vue'; import Button from '@/components/ui/button/Button.vue';
const files = ref<File[]>([]);
const currentPlaylistStore = useCurrentPlaylistStore(); const currentPlaylistStore = useCurrentPlaylistStore();
const progressEntries = ref<Map<string, StreamProgress200Item>>(new Map()); const progressEntries = ref<Map<string, StreamProgress200Item>>(new Map());
let listener: EventSourceListener<StreamProgress200Item> | null = null; let listener: EventSourceListener<StreamProgress200Item> | null = null;
@ -59,7 +61,6 @@ async function listenImports() {
} }
function onYoutubeClick(e: MouseEvent) { function onYoutubeClick(e: MouseEvent) {
console.log("hello")
e.stopPropagation(); e.stopPropagation();
} }
@ -90,7 +91,7 @@ onUnmounted(() => {
</Outline> </Outline>
</template> </template>
<div class="w-full flex flex-col p-8"> <div class="w-full flex flex-col p-8">
<FileUpload class="rounded-lg border border-dashed border-muted" @onChange=""> <FileUpload v-model="files" class="rounded-lg border border-dashed border-muted" @onChange="">
<template #default> <template #default>
<FileUploadGrid /> <FileUploadGrid />
</template> </template>