Inline context menu into EditorCanvas, delete CanvasContextMenu.vue

The wrapper component existed only to do hit-test + select on right-click,
which is now editor.selectAtPoint(). The 5-line Reka UI ContextMenu
composition belongs directly in EditorCanvas where the canvas ref lives.
This commit is contained in:
Danila Poyarkov 2026-03-17 08:31:12 +03:00
parent b2ed748608
commit f084212ce8
2 changed files with 56 additions and 67 deletions

View file

@ -1,21 +0,0 @@
<script setup lang="ts">
import { ContextMenuRoot, ContextMenuTrigger, ContextMenuPortal } from 'reka-ui'
import NodeContextMenuContent from './NodeContextMenuContent.vue'
const { onContextMenu } = defineProps<{
onContextMenu?: (e: MouseEvent) => void
}>()
</script>
<template>
<ContextMenuRoot :modal="false">
<ContextMenuTrigger as-child @contextmenu="onContextMenu">
<slot />
</ContextMenuTrigger>
<ContextMenuPortal>
<NodeContextMenuContent />
</ContextMenuPortal>
</ContextMenuRoot>
</template>

View file

@ -1,10 +1,11 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ContextMenuRoot, ContextMenuTrigger, ContextMenuPortal } from 'reka-ui'
import { toolCursor, useCanvas, useCanvasDrop, useCanvasInput, useTextEdit } from '@open-pencil/vue'
import { useCollabInjected } from '@/composables/use-collab'
import { useEditorStore } from '@/stores/editor'
import CanvasContextMenu from './CanvasContextMenu.vue'
import NodeContextMenuContent from './NodeContextMenuContent.vue'
const store = useEditorStore()
const collab = useCollabInjected()
@ -47,56 +48,65 @@ function onContextMenu(e: MouseEvent) {
</script>
<template>
<CanvasContextMenu :on-context-menu="onContextMenu">
<div
data-test-id="canvas-area"
class="canvas-area relative min-h-0 min-w-0 flex-1 overflow-hidden"
>
<canvas
ref="canvasRef"
data-test-id="canvas-element"
:style="{ cursor }"
class="block size-full touch-none"
/>
<Transition
enter-active-class="transition-opacity duration-150"
enter-from-class="opacity-0"
leave-active-class="transition-opacity duration-150"
leave-to-class="opacity-0"
<ContextMenuRoot :modal="false">
<ContextMenuTrigger as-child @contextmenu="onContextMenu">
<div
data-test-id="canvas-area"
class="canvas-area relative min-h-0 min-w-0 flex-1 overflow-hidden"
>
<div
v-if="isDraggingOver"
class="pointer-events-none absolute inset-0 z-40 border-2 border-dashed border-accent/60 bg-accent/5"
<canvas
ref="canvasRef"
data-test-id="canvas-element"
:style="{ cursor }"
class="block size-full touch-none"
/>
</Transition>
<Transition leave-active-class="transition-opacity duration-300" leave-to-class="opacity-0">
<div
v-if="store.state.loading"
data-test-id="canvas-loading"
class="absolute inset-0 z-50 flex items-center justify-center bg-canvas"
<Transition
enter-active-class="transition-opacity duration-150"
enter-from-class="opacity-0"
leave-active-class="transition-opacity duration-150"
leave-to-class="opacity-0"
>
<svg
class="size-8 text-white opacity-40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="m15.232 5.232 3.536 3.536m-2.036-5.036a2.5 2.5 0 0 1 3.536 3.536L6.5 21.036H3v-3.572L16.732 3.732Z"
/>
</svg>
<div
class="absolute bottom-1/2 left-1/2 h-0.5 w-25 -translate-x-1/2 translate-y-10 overflow-hidden rounded-full bg-white/8"
v-if="isDraggingOver"
class="pointer-events-none absolute inset-0 z-40 border-2 border-dashed border-accent/60 bg-accent/5"
/>
</Transition>
<Transition
leave-active-class="transition-opacity duration-300"
leave-to-class="opacity-0"
>
<div
v-if="store.state.loading"
data-test-id="canvas-loading"
class="absolute inset-0 z-50 flex items-center justify-center bg-canvas"
>
<svg
class="size-8 text-white opacity-40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="m15.232 5.232 3.536 3.536m-2.036-5.036a2.5 2.5 0 0 1 3.536 3.536L6.5 21.036H3v-3.572L16.732 3.732Z"
/>
</svg>
<div
class="h-full w-2/5 animate-[slide_1s_ease-in-out_infinite] rounded-full bg-white/25"
/>
class="absolute bottom-1/2 left-1/2 h-0.5 w-25 -translate-x-1/2 translate-y-10 overflow-hidden rounded-full bg-white/8"
>
<div
class="h-full w-2/5 animate-[slide_1s_ease-in-out_infinite] rounded-full bg-white/25"
/>
</div>
</div>
</div>
</Transition>
</div>
</CanvasContextMenu>
</Transition>
</div>
</ContextMenuTrigger>
<ContextMenuPortal>
<NodeContextMenuContent />
</ContextMenuPortal>
</ContextMenuRoot>
</template>