openpencil/src/components/PagesPanel.vue
Danila Poyarkov 8eff364dcd Use sceneVersion instead of renderVersion for UI panels
renderVersion bumps on every pan/zoom/hover — it's the canvas redraw signal.
sceneVersion only bumps when the scene graph actually changes.

Panels (properties, layers, context menu, pages, export preview) now
depend on sceneVersion, so they don't re-render during navigation.
2026-03-01 00:33:14 +03:00

80 lines
2.4 KiB
Vue

<script setup lang="ts">
import { computed, ref, nextTick } from 'vue'
import { useEditorStore } from '@/stores/editor'
const store = useEditorStore()
const pages = computed(() => {
void store.state.sceneVersion
return store.graph.getPages()
})
const editingPageId = ref<string | null>(null)
function startRename(pageId: string) {
editingPageId.value = pageId
nextTick(() => {
const input = document.querySelector<HTMLInputElement>('[data-page-edit]')
input?.focus()
input?.select()
})
}
function commitRename(pageId: string, input: HTMLInputElement) {
if (editingPageId.value !== pageId) return
const value = input.value.trim()
if (value && value !== store.graph.getNode(pageId)?.name) {
store.renamePage(pageId, value)
}
editingPageId.value = null
}
function onKeydown(e: KeyboardEvent, pageId: string) {
if (e.key === 'Enter' || e.key === 'Escape') {
;(e.target as HTMLInputElement).blur()
}
}
</script>
<template>
<div class="shrink-0 border-b border-border">
<div class="flex items-center justify-between px-3 py-1.5">
<span class="text-[11px] uppercase tracking-wider text-muted">Pages</span>
<button
class="cursor-pointer rounded border-none bg-transparent px-1 text-base leading-none text-muted hover:bg-hover hover:text-surface"
title="Add page"
@click="store.addPage()"
>
+
</button>
</div>
<div class="px-1 pb-1">
<div v-for="pg in pages" :key="pg.id">
<input
v-if="editingPageId === pg.id"
data-page-edit
class="w-full rounded border border-accent bg-input px-2 py-1 text-xs text-surface outline-none"
:value="pg.name"
@blur="commitRename(pg.id, $event.target as HTMLInputElement)"
@keydown="onKeydown($event, pg.id)"
/>
<button
v-else
class="flex w-full cursor-pointer items-center gap-1.5 rounded border-none px-2 py-1 text-left text-xs"
:class="
pg.id === store.state.currentPageId
? 'bg-hover text-surface'
: 'bg-transparent text-muted hover:bg-hover hover:text-surface'
"
@click="store.switchPage(pg.id)"
@dblclick="startRename(pg.id)"
>
<icon-lucide-file class="size-3 shrink-0" />
{{ pg.name }}
</button>
</div>
</div>
</div>
</template>