Make left and right panels resizable with reka-ui Splitter

Uses SplitterGroup/SplitterPanel/SplitterResizeHandle. Panels
default to 15% width, min 10%, max 30%. Layout persists across
reloads via auto-save-id. Resize handle highlights blue on hover.
This commit is contained in:
Danila Poyarkov 2026-02-28 22:22:39 +03:00
parent ffc1b7f56b
commit a89e886981
3 changed files with 20 additions and 6 deletions

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import { useEventListener, useUrlSearchParams } from '@vueuse/core'
import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'reka-ui'
import { useKeyboard } from './composables/use-keyboard'
import { useMenu } from './composables/use-menu'
@ -30,13 +31,26 @@ if (!('test' in params)) {
<template>
<div class="flex h-screen w-screen flex-col">
<div class="flex flex-1 overflow-hidden">
<LayersPanel v-if="showChrome" />
<SplitterGroup v-if="showChrome" direction="horizontal" class="flex-1 overflow-hidden" auto-save-id="editor-layout">
<SplitterPanel :default-size="15" :min-size="10" :max-size="30" class="flex">
<LayersPanel />
</SplitterPanel>
<SplitterResizeHandle class="w-0 cursor-col-resize after:absolute after:inset-y-0 after:-left-0.5 after:w-1 after:hover:bg-accent after:hover:opacity-50" />
<SplitterPanel :default-size="70" :min-size="30" class="flex">
<div class="relative flex min-w-0 flex-1">
<EditorCanvas />
<Toolbar />
</div>
</SplitterPanel>
<SplitterResizeHandle class="w-0 cursor-col-resize after:absolute after:inset-y-0 after:-left-0.5 after:w-1 after:hover:bg-accent after:hover:opacity-50" />
<SplitterPanel :default-size="15" :min-size="10" :max-size="30" class="flex">
<PropertiesPanel />
</SplitterPanel>
</SplitterGroup>
<div v-else class="flex flex-1 overflow-hidden">
<div class="relative flex min-w-0 flex-1">
<EditorCanvas />
<Toolbar v-if="showChrome" />
</div>
<PropertiesPanel v-if="showChrome" />
</div>
</div>
</template>

View file

@ -211,7 +211,7 @@ function updateDropTarget(ev: PointerEvent) {
</script>
<template>
<aside class="flex w-60 flex-col overflow-y-auto border-r border-border bg-panel">
<aside class="flex min-w-0 flex-1 flex-col overflow-y-auto border-r border-border bg-panel">
<PagesPanel />
<header class="shrink-0 px-3 py-2 text-[11px] uppercase tracking-wider text-muted">Layers</header>
<div ref="listRef" class="relative flex-1 overflow-y-auto px-1">

View file

@ -23,7 +23,7 @@ const isComponentType = computed(() => {
</script>
<template>
<aside class="flex w-[241px] flex-col overflow-hidden border-l border-border bg-panel">
<aside class="flex min-w-0 flex-1 flex-col overflow-hidden border-l border-border bg-panel">
<!-- Tabs -->
<div class="flex h-10 shrink-0 items-center gap-1 border-b border-border px-2">
<button class="rounded px-2.5 py-1 text-xs font-semibold text-surface">Design</button>