From e2a74e333724155cf34d1cd88b9d3379c9788f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Mon, 31 Aug 2026 04:06:27 +0100 Subject: [PATCH] Add section asks what shape, and creates one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pressing the button drawn inside the page opens a dialog: a name, and a choice between one column and two, then Create section. The row lands in the database and the frame re-renders to show it. The layouts are DRAWN rather than named. "One column" is words for a shape, and a shape is faster to recognise than to read; the words stay underneath for anybody the picture does not reach. The name is asked for and not generated. It never appears on the site — it exists so a page of eight bands is navigable, and "Section 4" tells nobody anything, which is exactly the state a generated name would leave every page in. Asked at the only moment somebody knows what they are about to build. The frame is remounted after a write rather than the admin drawing the new band itself. The site renders from the database; the admin does not know how to render a page, and if it learnt it would be a second implementation of the very thing this preview exists to avoid. The canvas now finds the empty-page placeholder by its `data-page-empty` marker instead of taking `firstElementChild`. That was right for exactly as long as an empty page was the only kind — the moment a page has a section, the first child IS that section, and it would have hidden the thing being edited. Co-Authored-By: Claude Opus 5 (1M context) --- web/SitePreview.tsx | 15 ++++ web/canvas.ts | 18 +++-- web/sections/AddSectionDialog.tsx | 121 ++++++++++++++++++++++++++++++ web/sections/PageBuilderPanel.tsx | 53 ++++++++----- 4 files changed, 181 insertions(+), 26 deletions(-) create mode 100644 web/sections/AddSectionDialog.tsx diff --git a/web/SitePreview.tsx b/web/SitePreview.tsx index 0db8cbd..8acea7d 100644 --- a/web/SitePreview.tsx +++ b/web/SitePreview.tsx @@ -45,6 +45,7 @@ export const SitePreview = ({ path, theme, onDocument, + reloadToken, }: { port: number | null; /** The site path to show — `layout`, `about`, or `` for the front page. No leading slash. */ @@ -67,6 +68,17 @@ export const SitePreview = ({ * document it was injected into. */ onDocument?: (document: Document) => void | (() => void); + /** + * Change this to fetch the page again. + * + * The site renders from the database, so anything written there only appears when the document is + * requested anew. The admin cannot draw the change itself — it does not know how to render a page, + * and if it did it would be a second implementation of the one thing this preview exists to avoid. + * + * Remounts the frame rather than calling `contentWindow.location.reload()`. Both work while the frame + * is same-origin, and the remount is one mechanism that would still work if it ever were not. + */ + reloadToken?: number; }) => { const client = useClient(); /* @@ -221,6 +233,9 @@ export const SitePreview = ({ remove the attribute. This is the owner's own development server on this machine. */