diff --git a/CHANGELOG.md b/CHANGELOG.md index 37639a3ac..18ea195b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Changed +- Add Figma-style page management in the Pages panel with a context menu for renaming/deleting pages and drag-and-drop page reordering. - Add JSX authoring support for components, component sets, and instances. - Add design JSX variable helpers so color props can use `designVar()` / `defineVars()` references and emit graph variable bindings. - Add structured design JSX paint helpers for solid fills, multiple fills, and gradients. diff --git a/packages/core/src/editor/pages.ts b/packages/core/src/editor/pages.ts index f7c3b5534..98704b918 100644 --- a/packages/core/src/editor/pages.ts +++ b/packages/core/src/editor/pages.ts @@ -60,6 +60,17 @@ export function createPageActions(ctx: EditorContext) { } } + function movePage(pageId: string, index: number) { + const pages = ctx.graph.getPages() + const currentIndex = pages.findIndex((page) => page.id === pageId) + if (currentIndex === -1) return + + const nextIndex = Math.max(0, Math.min(index, pages.length - 1)) + if (nextIndex === currentIndex) return + + ctx.graph.insertChildAt(pageId, ctx.graph.rootId, nextIndex) + } + function renamePage(pageId: string, name: string) { ctx.graph.updateNode(pageId, { name }) } @@ -73,6 +84,7 @@ export function createPageActions(ctx: EditorContext) { switchPage, addPage, deletePage, + movePage, renamePage, setPageColor, clearPageViewports: pageViewportStore.clearPageViewports diff --git a/packages/vue/src/primitives/PageList/PageListRoot.vue b/packages/vue/src/primitives/PageList/PageListRoot.vue index 94bcb8baa..16be94124 100644 --- a/packages/vue/src/primitives/PageList/PageListRoot.vue +++ b/packages/vue/src/primitives/PageList/PageListRoot.vue @@ -12,9 +12,11 @@ const emit = defineEmits<{ switch: [pageId: string] rename: [pageId: string, name: string] delete: [pageId: string] + move: [pageId: string, index: number] }>() -const { pages, currentPageId, switchPage, addPage, renamePage, deletePage } = usePageList() +const { pages, currentPageId, switchPage, addPage, renamePage, deletePage, movePage } = + usePageList() const dividerPattern = computed(() => customDividerPattern ?? /^[-–—*\s]+$/) @@ -42,11 +44,17 @@ function handleDelete(pageId: string) { emit('delete', pageId) } +function handleMove(pageId: string, index: number) { + movePage(pageId, index) + emit('move', pageId, index) +} + const actions = { add: handleAdd, switch: handleSwitch, rename: handleRename, - delete: handleDelete + delete: handleDelete, + move: handleMove } diff --git a/packages/vue/src/primitives/PageList/usePageList.ts b/packages/vue/src/primitives/PageList/usePageList.ts index 2ec94f6d5..12e527552 100644 --- a/packages/vue/src/primitives/PageList/usePageList.ts +++ b/packages/vue/src/primitives/PageList/usePageList.ts @@ -22,6 +22,7 @@ export function usePageList() { switchPage: editor.switchPage, addPage: editor.addPage, deletePage: editor.deletePage, + movePage: editor.movePage, renamePage: editor.renamePage } } diff --git a/src/components/PagesPanel.vue b/src/components/PagesPanel.vue index a9e0469c0..c3a547872 100644 --- a/src/components/PagesPanel.vue +++ b/src/components/PagesPanel.vue @@ -1,18 +1,37 @@ @@ -57,44 +114,90 @@ function handlePageDblClick( data-test-id="pages-scroll" class="scrollbar-thin h-full overflow-x-hidden overflow-y-auto px-1 pb-1" > -