From b7849c035922405059e656d12660a027de498a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mats=20T=C3=B6rnberg?= Date: Sat, 7 Nov 2026 13:37:45 +0100 Subject: [PATCH] Repair outline rows and add split panels for drag & drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Outline chevron buttons were matched by a generic `.cms-outline li button { width: 100% }` rule, so each expand/collapse arrow took a full row and the tree looked stacked and broken. Scope row styling to `.cms-orow__main`, fix the chevron to 22px, add rotating chevrons to the section headers, and turn the blocks palette from centered narrow cards into left-aligned rows. Add a split toggle to the panel header: outline stays visible in a left column while Blocks/Nodes switch as tabs in a right column, so a drag source and its outline drop gaps are on screen together. Choice and library tab persist per profile; stacked mode is unchanged. 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- src/ui/Rail.tsx | 93 ++++++++++++++++++++++++++++--------- src/ui/styles.css | 58 ++++++++++++++--------- test/rail-sections.test.tsx | 33 +++++++++++++ 3 files changed, 140 insertions(+), 44 deletions(-) diff --git a/src/ui/Rail.tsx b/src/ui/Rail.tsx index 4f4f26f..228c4a8 100644 --- a/src/ui/Rail.tsx +++ b/src/ui/Rail.tsx @@ -9,21 +9,29 @@ import { useCtrl, useEditorState, usePersistentState } from './hooks' import type { Block, Controller } from '../controller' /** - * Left panel: outline + blocks + nodes in one place (no tabs). + * Left panel: outline + blocks + nodes. * * - Outline is a tree with its slots (e.g. a pdp's `info-section` / * `3d-accessories` connections): drag any row by its grip to reorder, drop * palette blocks and searched nodes onto the gaps between rows or into slots. * - Blocks are the new types that fit this page (drag onto the page or the outline). * - Nodes finds *existing* nodes (type filter + text) to link into the page. + * + * Stacked (default) all sections share one scroll. Split mode puts the outline + * in a left column and Blocks/Nodes as switchable tabs in a right column, so a + * drag source and its outline drop gaps are visible at the same time. */ const RAIL_W_MIN = 240 const RAIL_W_MAX = 640 +type LibTab = 'blocks' | 'nodes' + export function Rail() { const ctrl = useCtrl() const open = useEditorState((s) => s.rail) const [width, setWidth] = usePersistentState('cms-onpage.railwidth', 320) + const [split, setSplit] = usePersistentState('cms-onpage.railsplit', false) + const [lib, setLib] = usePersistentState('cms-onpage.raillib', 'blocks') useEffect(() => { if (!open) return // Types carry every schema (titles, groups, slots): one request seeds them all. @@ -37,7 +45,8 @@ export function Rail() { void ctrl.fillHandles() }, [open, ctrl]) if (!open) return null - const w = Math.max(RAIL_W_MIN, Math.min(width, window.innerWidth - 24)) + const single = Math.max(RAIL_W_MIN, Math.min(width, window.innerWidth - 24)) + const w = split ? Math.min(single * 2 + 12, window.innerWidth - 24) : single const startResize = (e: React.PointerEvent) => { if (e.button !== 0) return e.preventDefault() @@ -55,14 +64,25 @@ export function Rail() { doc.addEventListener('pointerup', stop, true) } return ( -