Add files modal and X button
This commit is contained in:
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user