64 lines
1.8 KiB
Vue
64 lines
1.8 KiB
Vue
<script setup>
|
|
import { ref } from 'vue';
|
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|
|
|
/** Propiedades */
|
|
const props = defineProps({
|
|
type: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
icon: String,
|
|
title: String,
|
|
description: String,
|
|
});
|
|
|
|
/** Eventos */
|
|
const emit = defineEmits(['dragstart']);
|
|
|
|
/** Referencias */
|
|
const isDragging = ref(false);
|
|
|
|
/** Métodos */
|
|
const handleDragStart = (event) => {
|
|
isDragging.value = true;
|
|
event.dataTransfer.setData('text/plain', JSON.stringify({
|
|
type: props.type,
|
|
title: props.title
|
|
}));
|
|
emit('dragstart', props.type);
|
|
};
|
|
|
|
const handleDragEnd = () => {
|
|
isDragging.value = false;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
draggable="true"
|
|
@dragstart="handleDragStart"
|
|
@dragend="handleDragEnd"
|
|
class="flex items-center gap-3 p-3 rounded-lg border border-gray-200 bg-white cursor-grab hover:bg-gray-50 hover:border-blue-300 transition-colors dark:bg-primary-d dark:border-primary/20 dark:hover:bg-primary/10"
|
|
:class="{
|
|
'opacity-50 cursor-grabbing': isDragging,
|
|
'shadow-sm hover:shadow-md': !isDragging
|
|
}"
|
|
>
|
|
<div class="flex-shrink-0 w-8 h-8 rounded-md bg-blue-100 flex items-center justify-center dark:bg-blue-900/30">
|
|
<GoogleIcon
|
|
:name="icon"
|
|
class="text-blue-600 dark:text-blue-400 text-lg"
|
|
/>
|
|
</div>
|
|
|
|
<div class="flex-1 min-w-0">
|
|
<div class="text-sm font-medium text-gray-900 dark:text-primary-dt">
|
|
{{ title }}
|
|
</div>
|
|
<div class="text-xs text-gray-500 dark:text-primary-dt/70 truncate">
|
|
{{ description }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template> |