214 lines
8.6 KiB
Vue
214 lines
8.6 KiB
Vue
<script setup>
|
|
import Icon from '@/Components/Icon.vue';
|
|
import { toRef, ref, onMounted } from 'vue';
|
|
import { initFlowbite } from 'flowbite';
|
|
|
|
onMounted(() => {
|
|
initFlowbite();
|
|
});
|
|
|
|
|
|
const props = defineProps({
|
|
block: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(['update:block']);
|
|
const local = toRef(props, 'block');
|
|
|
|
// Drag state first column
|
|
const firstDraggedIndex = ref(null);
|
|
|
|
function handleDragStartPFirst(event, index) {
|
|
firstDraggedIndex.value = index;
|
|
event.dataTransfer.effectAllowed = 'move';
|
|
event.dataTransfer.setData('text/plain', index);
|
|
};
|
|
|
|
function handleDragOverPFirst(event) {
|
|
event.preventDefault();
|
|
event.dataTransfer.dropEffect = 'move';
|
|
};
|
|
|
|
function handleDropPFirst(event, index) {
|
|
event.preventDefault();
|
|
const fromIndex = firstDraggedIndex.value;
|
|
if (fromIndex === null || fromIndex === index) return;
|
|
|
|
const item = local.value.firstcolumn.splice(fromIndex, 1)[0];
|
|
local.value.firstcolumn.splice(index, 0, item);
|
|
firstDraggedIndex.value = null;
|
|
};
|
|
|
|
function addPFirst() {
|
|
local.value.firstcolumn.push({
|
|
text: '',
|
|
style: 'regular',
|
|
});
|
|
}
|
|
|
|
function removePFirst(index) {
|
|
local.value.firstcolumn.splice(index, 1);
|
|
};
|
|
|
|
// Drag state second column
|
|
const secondDraggedIndex = ref(null);
|
|
|
|
function handleDragStartPSecond(event, index) {
|
|
secondDraggedIndex.value = index;
|
|
event.dataTransfer.effectAllowed = 'move';
|
|
event.dataTransfer.setData('text/plain', index);
|
|
};
|
|
|
|
function handleDragOverPSecond(event) {
|
|
event.preventDefault();
|
|
event.dataTransfer.dropEffect = 'move';
|
|
};
|
|
|
|
function handleDropPSecond(event, index) {
|
|
event.preventDefault();
|
|
const fromIndex = secondDraggedIndex.value;
|
|
if (fromIndex === null || fromIndex === index) return;
|
|
|
|
const item = local.value.secondcolumn.splice(fromIndex, 1)[0];
|
|
local.value.secondcolumn.splice(index, 0, item);
|
|
secondDraggedIndex.value = null;
|
|
};
|
|
|
|
function addPSecond() {
|
|
local.value.secondcolumn.push({
|
|
text: '',
|
|
style: 'regular',
|
|
});
|
|
}
|
|
|
|
function removePSecond(index) {
|
|
local.value.secondcolumn.splice(index, 1);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-4">
|
|
<div class="mb-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Anker navn (DOM ID)</label>
|
|
<input
|
|
type="text"
|
|
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white"
|
|
v-model="local.anchorName"
|
|
/>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<h3 class="font-bold text-sm text-gray-800 dark:text-white">
|
|
Venstre kolonne
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div
|
|
v-for="(paragraph, index) in local.firstcolumn"
|
|
:key="index"
|
|
class="flex items-start gap-2 p-4 rounded border dark:border-gray-600 bg-gray-50 dark:bg-gray-800"
|
|
draggable="true"
|
|
@dragstart="handleDragStartPFirst($event, index)"
|
|
@dragover="handleDragOverPFirst"
|
|
@drop="handleDropPFirst($event, index)"
|
|
>
|
|
<div class="cursor-move mt-1 text-gray-500 dark:text-gray-400">
|
|
<Icon name="move" class="w-4 h-4" />
|
|
</div>
|
|
|
|
<div class="flex-1 space-y-2">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-sm font-semibold text-gray-700 dark:text-gray-300">Paragraf {{ index + 1 }}</span>
|
|
<button @click="removePFirst(index)" class="text-red-500 hover:underline text-xs">Fjern</button>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<label :for="`style-l-${index}`" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Velg en tekststil</label>
|
|
<select
|
|
:id="`style-l-${index}`"
|
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
v-model="paragraph.style"
|
|
>
|
|
<option value="headinglarge">Stor overskrift</option>
|
|
<option value="heading">Overskrift</option>
|
|
<option value="headingbold">Fet overskrift</option>
|
|
<option value="regular">Vanlig</option>
|
|
<option value="video">Video</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400">Tekst/Innhold</label>
|
|
<textarea rows="2" class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white" v-model="paragraph.text"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button @click="addPFirst" class="mt-2 px-4 py-2 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
|
|
Legg til ny paragraf
|
|
</button>
|
|
|
|
<div class="space-y-4">
|
|
<h3 class="font-bold text-sm text-gray-800 dark:text-white">
|
|
Høyre kolonne
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
<div
|
|
v-for="(paragraph, index) in local.secondcolumn"
|
|
:key="index"
|
|
class="flex items-start gap-2 p-4 rounded border dark:border-gray-600 bg-gray-50 dark:bg-gray-800"
|
|
draggable="true"
|
|
@dragstart="handleDragStartPSecond($event, index)"
|
|
@dragover="handleDragOverPSecond"
|
|
@drop="handleDropPSecond($event, index)"
|
|
>
|
|
<div class="cursor-move mt-1 text-gray-500 dark:text-gray-400">
|
|
<Icon name="move" class="w-4 h-4" />
|
|
</div>
|
|
|
|
<div class="flex-1 space-y-2">
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-sm font-semibold text-gray-700 dark:text-gray-300">Paragraf {{ index + 1 }}</span>
|
|
<button @click="removePSecond(index)" class="text-red-500 hover:underline text-xs">Fjern</button>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<label :for="`style-r-${index}`" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Velg en tekststil</label>
|
|
<select
|
|
:id="`style-r-${index}`"
|
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
v-model="paragraph.style"
|
|
>
|
|
<option value="headinglarge">Stor overskrift</option>
|
|
<option value="heading">Overskrift</option>
|
|
<option value="headingbold">Fet overskrift</option>
|
|
<option value="regular">Vanlig</option>
|
|
<option value="video">Video</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs font-medium text-gray-600 dark:text-gray-400">Tekst/Innhold</label>
|
|
<textarea rows="2" class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white" v-model="paragraph.text"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button @click="addPSecond" class="mt-2 px-4 py-2 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
|
|
Legg til ny paragraf
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style>
|