every control writes itself

The Save button is gone, and so is the SaveTarget context that announced it.
Every screen here is a preview of the thing being edited, so a change is already
visible before it is written — a button then asks somebody to confirm what they
can see.

useAutosave debounces a burst into one request. It takes the unsaved state as a
string rather than a flag, so a failed save is not retried on the next render,
and it flushes on unmount so a section change loses nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-01 07:34:34 +01:00
co-authored by Claude Opus 5
parent 6717402331
commit b5ca67e68e
8 changed files with 98 additions and 137 deletions
+3 -2
View File
@@ -4,7 +4,7 @@ import { useSearchParams } from 'react-router';
import { useClient } from 'hooks/useClient';
import { readableError } from '../errors';
import { useFlash } from '../useFlash';
import { useSaveTarget } from '../SaveTarget';
import { useAutosave } from '../useAutosave';
import { usePreviewable, useViewMode } from '../ViewMode';
import { applySpacing, paintMeasure, type SpacingDraft } from '../canvas';
import { SitePreview, useDevPort } from '../SitePreview';
@@ -203,7 +203,8 @@ export const LayoutPanel = () => {
}
};
useSaveTarget(dirty, busy, save);
// The serialised draft, or null when it matches what the server has. See useAutosave.
useAutosave(dirty ? only(draft) : null, busy, save);
// This section has a preview, so the bar offers Edit/View and the three widths.
usePreviewable();
const { device } = useViewMode();