2024-12-29 00:31:52 +00:00
|
|
|
<template>
|
2025-08-14 21:48:38 +01:00
|
|
|
<div
|
|
|
|
|
@dragenter.prevent="handleDragEnter"
|
|
|
|
|
@dragover.prevent="handleDragOver"
|
|
|
|
|
@dragleave.prevent="handleDragLeave"
|
|
|
|
|
@drop.prevent="handleDrop"
|
|
|
|
|
>
|
|
|
|
|
<slot />
|
|
|
|
|
<div
|
|
|
|
|
v-if="isDragging"
|
|
|
|
|
:class="[
|
2026-01-06 00:35:51 +00:00
|
|
|
'absolute inset-0 flex items-center justify-center rounded-2xl bg-black/60 text-contrast shadow',
|
2025-08-14 21:48:38 +01:00
|
|
|
overlayClass,
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
<div class="text-center">
|
2026-01-06 00:35:51 +00:00
|
|
|
<UploadIcon class="mx-auto h-16 w-16 shadow-2xl" />
|
2025-08-14 21:48:38 +01:00
|
|
|
<p class="mt-2 text-xl">
|
|
|
|
|
Drop {{ type ? type.toLocaleLowerCase() : 'file' }}s here to upload
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-29 00:31:52 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-08-14 21:48:38 +01:00
|
|
|
import { UploadIcon } from '@modrinth/assets'
|
|
|
|
|
import { ref } from 'vue'
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
2025-08-14 21:48:38 +01:00
|
|
|
(event: 'filesDropped', files: File[]): void
|
|
|
|
|
}>()
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
defineProps<{
|
2025-08-14 21:48:38 +01:00
|
|
|
overlayClass?: string
|
|
|
|
|
type?: string
|
|
|
|
|
}>()
|
2024-12-29 00:31:52 +00:00
|
|
|
|
2025-08-14 21:48:38 +01:00
|
|
|
const isDragging = ref(false)
|
|
|
|
|
const dragCounter = ref(0)
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
const handleDragEnter = (event: DragEvent) => {
|
2025-08-14 21:48:38 +01:00
|
|
|
event.preventDefault()
|
2026-01-06 00:35:51 +00:00
|
|
|
if (!event.dataTransfer?.types.includes('application/modrinth-file-move')) {
|
2025-08-14 21:48:38 +01:00
|
|
|
dragCounter.value++
|
|
|
|
|
isDragging.value = true
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
const handleDragOver = (event: DragEvent) => {
|
2025-08-14 21:48:38 +01:00
|
|
|
event.preventDefault()
|
|
|
|
|
}
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
const handleDragLeave = (event: DragEvent) => {
|
2025-08-14 21:48:38 +01:00
|
|
|
event.preventDefault()
|
|
|
|
|
dragCounter.value--
|
|
|
|
|
if (dragCounter.value === 0) {
|
|
|
|
|
isDragging.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-29 00:31:52 +00:00
|
|
|
|
|
|
|
|
const handleDrop = (event: DragEvent) => {
|
2025-08-14 21:48:38 +01:00
|
|
|
event.preventDefault()
|
|
|
|
|
isDragging.value = false
|
|
|
|
|
dragCounter.value = 0
|
2024-12-29 00:31:52 +00:00
|
|
|
|
2026-01-06 00:35:51 +00:00
|
|
|
const isInternalMove = event.dataTransfer?.types.includes('application/modrinth-file-move')
|
2025-08-14 21:48:38 +01:00
|
|
|
if (isInternalMove) return
|
2024-12-29 00:31:52 +00:00
|
|
|
|
2025-08-14 21:48:38 +01:00
|
|
|
const files = event.dataTransfer?.files
|
|
|
|
|
if (files) {
|
|
|
|
|
emit('filesDropped', Array.from(files))
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-29 00:31:52 +00:00
|
|
|
</script>
|