54 lines
1.1 KiB
Vue
54 lines
1.1 KiB
Vue
<template>
|
|
<div @dragover.prevent="onDragOver" @dragenter.prevent="onDragEnter" @dragleave="onDragLeave" @drop.prevent="onDrop"
|
|
:class="['droppable', { 'is-drag-over': isDragOver }]">
|
|
<slot :is-dragging-over="isDragOver" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
accept?: string
|
|
onDrop: (data: any) => void
|
|
}>()
|
|
|
|
const isDragOver = ref(false)
|
|
|
|
const onDragOver = (e: DragEvent) => {
|
|
if (!isDragOver.value) isDragOver.value = true
|
|
}
|
|
|
|
const onDragEnter = (e: DragEvent) => {
|
|
isDragOver.value = true
|
|
}
|
|
|
|
const onDragLeave = () => {
|
|
isDragOver.value = false
|
|
}
|
|
|
|
const onDrop = (e: DragEvent) => {
|
|
isDragOver.value = false
|
|
const data = e.dataTransfer?.getData('application/json')
|
|
if (data) {
|
|
try {
|
|
props.onDrop(JSON.parse(data))
|
|
} catch (e) {
|
|
console.error('Erreur lors du drop', e)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.droppable {
|
|
min-height: 100px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.droppable.is-drag-over {
|
|
background-color: rgba(0, 0, 0, 0.1);
|
|
border: 2px dashed #4CAF50;
|
|
}
|
|
</style>
|