diff --git a/web/sections/PageBuilderPanel.tsx b/web/sections/PageBuilderPanel.tsx index a90b8b6..d4601aa 100644 --- a/web/sections/PageBuilderPanel.tsx +++ b/web/sections/PageBuilderPanel.tsx @@ -3,6 +3,7 @@ import { useSearchParams } from 'react-router'; import { useClient } from 'hooks/useClient'; import { readableError } from '../errors'; import { SitePreview, useDevPort } from '../SitePreview'; +import { usePreviewable, useViewMode } from '../ViewMode'; import { paintCanvas, type CanvasSection } from '../canvas'; import { AddSectionDialog, type SectionLayout } from './AddSectionDialog'; import { usePages, type Page } from '../usePages'; @@ -33,6 +34,11 @@ export const PageBuilderPanel = () => { const devPort = useDevPort(); const { pages, announce } = usePages(); + // This section has a preview, so the bar offers Edit/View and the three widths — the same opt-in + // Layout makes. Pages, the list, does not: there is nothing there to view at tablet width. + usePreviewable(); + const { mode } = useViewMode(); + const [error, setError] = useState(null); const [sections, setSections] = useState([]); @@ -62,14 +68,29 @@ export const PageBuilderPanel = () => { Stable, because SitePreview holds it and re-runs it on every load. A new function each render would be a new injection each render. */ + /* + In VIEW, nothing is painted at all. + + Not the chrome dimmed or the buttons hidden — no injection, so the frame holds exactly the document + the site served. That is what View has to mean here: outlines, labels and a drop zone are the + editor's, and a preview that keeps any of them is not showing you the page. + + The check is INSIDE the callback and `mode` is a dependency, so switching to View hands SitePreview + a new function: its effect runs the previous paint's cleanup and then paints nothing. That is what + takes the chrome away, with no reload and no second code path. + */ const onDocument = useCallback( - (frameDocument: Document) => - paintCanvas(frameDocument, { + (frameDocument: Document) => { + if (mode === 'view') return; + return paintCanvas(frameDocument, { sections, onAddSection: () => handlersRef.current.add(), onDeleteSection: (section) => handlersRef.current.remove(section.id), - }), - [sections], + }); + }, + // `mode` is in here so switching to View gives SitePreview a NEW function, which runs the previous + // paint's cleanup and then paints nothing. That is what removes the chrome without a reload. + [sections, mode], ); /*