the page builder gets Edit/View and the three widths
The same bar Layout has, from the same opt-in: the section says it has a preview and the controls appear. Pages — the list — still says nothing, because there is nothing there to view at tablet width. VIEW paints nothing at all. Not dimmed chrome or hidden buttons: no injection, so the frame holds exactly the document the site served. That is what View has to mean here — the outlines, the labels and the drop zone are the editor's, and a preview that keeps any of them is not showing you the page. Done by putting `mode` in the callback's dependencies rather than by branching on it somewhere else. Switching hands SitePreview a new function; its effect runs the previous paint's cleanup and then does nothing. The chrome goes without a reload and without a second code path that could disagree with the first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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<string | null>(null);
|
||||
const [sections, setSections] = useState<CanvasSection[]>([]);
|
||||
|
||||
@@ -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],
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user