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.
80 lines
2.4 KiB
Vue
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>
|