editor: resizable rail, Esc closes panel, dev tab remembered
Rail gets a drag handle on its edge (240-640px, width persisted like the rest of the panel state). Escape now closes the panel as the last step of its chain (dialog > inline > selection > panel). The dev panel remembers its tab across reloads. Panel toggle button title notes the Esc shortcut. Harness covers resize/persist, Esc-close and dev tab. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
1 parent
bb875a0956
commit
fc0eb2c6be
8 files changed
+111
-13
No files matched your search
+31
-2
@@ -17,9 +17,13 @@ import type { Block, Controller } from '../controller'
|
||||
* - 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.
|
||||
*/
|
||||
const RAIL_W_MIN = 240
|
||||
const RAIL_W_MAX = 640
|
||||
|
||||
export function Rail() {
|
||||
const ctrl = useCtrl()
|
||||
const open = useEditorState((s) => s.rail)
|
||||
const [width, setWidth] = usePersistentState<number>('cms-onpage.railwidth', 320)
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
// Types carry every schema (titles, groups, slots): one request seeds them all.
|
||||
@@ -33,16 +37,41 @@ 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 startResize = (e: React.PointerEvent) => {
|
||||
if (e.button !== 0) return
|
||||
e.preventDefault()
|
||||
const doc = e.currentTarget.ownerDocument
|
||||
const rail = e.currentTarget.parentElement!
|
||||
const move = (m: PointerEvent) => {
|
||||
const left = rail.getBoundingClientRect().left
|
||||
setWidth(Math.round(Math.max(RAIL_W_MIN, Math.min(RAIL_W_MAX, m.clientX - left))))
|
||||
}
|
||||
const stop = () => {
|
||||
doc.removeEventListener('pointermove', move, true)
|
||||
doc.removeEventListener('pointerup', stop, true)
|
||||
}
|
||||
doc.addEventListener('pointermove', move, true)
|
||||
doc.addEventListener('pointerup', stop, true)
|
||||
}
|
||||
return (
|
||||
<aside className="cms-rail" aria-label="Page panel">
|
||||
<aside className="cms-rail" aria-label="Page panel" style={{ width: w }}>
|
||||
<header>
|
||||
<span className="cms-rail__title">
|
||||
<Icon name="outline" size={16} /> Page
|
||||
</span>
|
||||
<button className="cms-ico" onClick={() => ctrl.setRail(false)} aria-label="Close panel">
|
||||
<button className="cms-ico" onClick={() => ctrl.setRail(false)} aria-label="Close panel" title="Close panel (Esc)">
|
||||
<Icon name="close" />
|
||||
</button>
|
||||
</header>
|
||||
<div
|
||||
className="cms-rail__resize"
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-label="Resize panel"
|
||||
title="Drag to resize"
|
||||
onPointerDown={startResize}
|
||||
/>
|
||||
<div className="cms-rail__body">
|
||||
<OutlineTree />
|
||||
<Palette />
|
||||
|
||||
Reference in new issue
Block a user