Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 5x 5x 5x 2x 2x 1x 5x | <script setup lang="ts">
import type { Conflict } from '../../crdt/ConflictDetector'
const props = defineProps<{ conflicts: Conflict[] }>()
const emit = defineEmits<{ dismiss: [] }>()
</script>
<template>
<Transition name="banner">
<div
v-if="conflicts.length > 0"
class="mx-4 mt-2 flex items-start gap-3 bg-ctp-yellow/10 border border-ctp-yellow/25 rounded-xl px-4 py-3"
>
<span class="text-ctp-yellow text-base shrink-0 mt-0.5">⚡</span>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-ctp-yellow">
{{ conflicts.length }} gleichzeitige {{ conflicts.length === 1 ? 'Änderung' : 'Änderungen' }} erkannt
</p>
<p class="text-xs text-ctp-yellow/70 mt-0.5">
Automatisch zusammengeführt — neueste Änderung hat Vorrang.
</p>
</div>
<button
@click="emit('dismiss')"
class="text-ctp-yellow/60 hover:text-ctp-yellow transition-colors shrink-0"
aria-label="Schließen"
>
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</Transition>
</template>
<style scoped>
.banner-enter-active,
.banner-leave-active {
transition: all 0.25s ease;
}
.banner-enter-from,
.banner-leave-to {
opacity: 0;
transform: translateY(-8px);
}
</style>
|