Menu item, address and page title — what the retired /fofos-admin/pages panel held, moved to the column where everything else about that page is edited. Above the device toggle, because the toggle scopes what is under it to one width and none of these three have widths. Read from the URL rather than announced: they belong to the page whatever is selected inside it, so picking a block must not replace them. A changed slug changes the page's own address, so the panel follows it — left alone the URL would name a page the list no longer holds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
82 lines
3.7 KiB
TypeScript
82 lines
3.7 KiB
TypeScript
import { DeviceToggle } from './DeviceToggle';
|
|
import { PageSettings } from './sections/PageSettings';
|
|
import { useNav } from './routes';
|
|
import { pageFromParam, usePages } from './usePages';
|
|
import { useEditorSlot } from './useEditorSlot';
|
|
|
|
/**
|
|
* Where an editor opens — a column beside the preview rather than a drawer beneath it.
|
|
*
|
|
* It was rendered under the frame, which took the height from the thing being edited: choosing a
|
|
* spacing shrank the page you were choosing it for, and on a laptop the preview lost a third of itself
|
|
* to a row of two dropdowns. A panel keeps the page whole and puts the controls where a workspace puts
|
|
* controls.
|
|
*
|
|
* It holds nothing of its own except the width. The panel that owns a selection builds the editor and
|
|
* announces it — see useEditorSlot for why it carries the element rather than a description of one.
|
|
*
|
|
* ── The device toggle is here, above everything ──
|
|
*
|
|
* It was in a bar across the top of the detail panel, which put it beside Sync and Publish — three
|
|
* things that act on the SITE next to one that decides how you are looking at it. It belongs with the
|
|
* settings it scopes: a spacing is chosen per width, and the control saying which width should be the
|
|
* first thing in the column those choices are made in.
|
|
*
|
|
* Always drawn, including when nothing is selected. It is not part of the editor — it decides what the
|
|
* PREVIEW shows, so hiding it until a block is picked would mean selecting something to change the
|
|
* width and then deselecting it.
|
|
*
|
|
* It reads `?device=` rather than a context, which is what lets it live in a panel that is a sibling of
|
|
* the one holding the preview. See DeviceToggle.
|
|
*/
|
|
export const EditorPanel = () => {
|
|
const [editor] = useEditorSlot();
|
|
|
|
/*
|
|
The selected page's own settings, above everything.
|
|
|
|
Read here rather than announced like the editor below it, because they are not the editor: they
|
|
belong to the page whatever is selected inside it, and a block being picked must not replace them.
|
|
Above the device toggle, because the toggle scopes what is under it to one width and none of these
|
|
three have widths.
|
|
*/
|
|
const { section, item } = useNav();
|
|
const { pages } = usePages();
|
|
const page = section === 'pages' ? pageFromParam(pages, item) : null;
|
|
|
|
return (
|
|
<div className="flex size-full flex-col overflow-hidden">
|
|
{page && (
|
|
<div className="shrink-0 border-b border-border px-3 py-3">
|
|
<PageSettings page={page} />
|
|
</div>
|
|
)}
|
|
|
|
{/* Outside the scroll area, so a long editor cannot carry it off the screen. */}
|
|
<div className="shrink-0 border-b border-border px-3 py-2">
|
|
<DeviceToggle />
|
|
</div>
|
|
|
|
{editor ? (
|
|
/*
|
|
`@container`, once, for every section inside it.
|
|
|
|
The sections lay out in two columns and have to fall back to one when the panel is dragged
|
|
narrow — and the window's width says nothing about that, because the width here is a divider
|
|
somebody moves. Declared on the scroller rather than per section, so a new section is
|
|
responsive by being in the column rather than by remembering to say so.
|
|
*/
|
|
<div className="@container min-h-0 flex-1 overflow-auto p-3">{editor}</div>
|
|
) : (
|
|
<div className="flex min-h-0 flex-1 items-center justify-center p-6 text-center">
|
|
{/* Names what the panel is FOR rather than saying it is empty. "Nothing selected" describes
|
|
this component's state; this describes the reader's next move. */}
|
|
<p className="text-xs text-muted-foreground">
|
|
Pick a block in the page to edit it, or press Spacing on a band.
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|