the preview is 1:1, and the measure is visible
TWO CHANGES, and the first is an argument I got wrong. The frame was scaled to fit the panel with a transform. That made the preview change apparent size as the panel was dragged, so the same page looked different at every panel width and nothing could be judged against anything. A preview is 1:1 or it is not a preview. So it stays at the device's real width and OVERFLOWS when there is not room — a scrollbar rather than a lie. The width was never negotiable anyway: the site's media queries answer it, so a frame given the panel's width renders the tablet layout and calls it desktop. What changes is only what happens when it does not fit, and scrolling is the honest answer. THE MEASURE, as two fixed lines and a width in pixels. The page is held to max-w-7xl and centred, so on a wide screen the content stops well short of the window and nothing says where. That is invisible until something is placed against the edge and turns out to be in the wrong place — which is the moment it becomes expensive. Fixed rather than absolute, so they stay while the page scrolls; a guide that scrolls away is a guide for the top of the page only. Not drawn at all when the column IS the full width, because two lines against the window edges are noise claiming to be information. One more site marker: data-content-column. Four attributes now, still no behaviour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-22
@@ -108,14 +108,17 @@ export const SitePreview = ({
|
||||
const [failed, setFailed] = useState<string | null>(null);
|
||||
|
||||
/*
|
||||
How much room there is, so the frame can be SCALED rather than squeezed.
|
||||
How much room there is. The frame is always the real device width and is NEVER scaled to fit.
|
||||
|
||||
The iframe is always the real device width — 390, 834, 1440 — and shrunk to fit with a transform.
|
||||
Giving it the panel's width instead would mean the site's own media queries answered the panel's
|
||||
size, so "Desktop" in a narrow panel would render the tablet layout and label it desktop. That is
|
||||
the one thing a preview must not do.
|
||||
It used to shrink with a transform, and that was worse than it sounds: the preview changed apparent
|
||||
size as the panel was dragged, so the same page looked different at every panel width and nothing
|
||||
could be judged against anything. A preview that is 1:1 or nothing is a preview you can trust.
|
||||
|
||||
Measured rather than assumed because the panel is resizable and the workspace splits it.
|
||||
So it stays 390, 834 or 1440 and OVERFLOWS when there is not room, which is a scrollbar rather than
|
||||
a lie. The width was never negotiable anyway: the site's media queries answer it, so a frame given
|
||||
the panel's width would render the tablet layout and call it desktop.
|
||||
|
||||
Still measured, because the height is whatever the panel has.
|
||||
*/
|
||||
const box = useRef<HTMLDivElement | null>(null);
|
||||
const [available, setAvailable] = useState({ width: 0, height: 0 });
|
||||
@@ -218,12 +221,6 @@ export const SitePreview = ({
|
||||
: !ready ? 'Connecting…'
|
||||
: null;
|
||||
|
||||
/*
|
||||
Never scaled UP. A 390px phone blown up to fill a wide panel is a phone nobody has, and every
|
||||
judgement made against it — how big that headline is, how much fits above the fold — would be wrong
|
||||
in the direction of "looks fine".
|
||||
*/
|
||||
const scale = available.width ? Math.min(1, available.width / width) : 1;
|
||||
|
||||
/*
|
||||
All the room there is. WIDTH is the device; height is just how much of the page you can see.
|
||||
@@ -242,10 +239,10 @@ export const SitePreview = ({
|
||||
<section className="flex min-h-0 flex-1 flex-col gap-2">
|
||||
<div ref={box} className="min-h-0 flex-1">
|
||||
<div
|
||||
className="mx-auto overflow-hidden rounded-lg border border-border bg-white"
|
||||
// The scaled footprint, so the border hugs the frame and the page below does not jump when
|
||||
// the device changes.
|
||||
style={{ width: Math.min(width * scale, available.width || width), height: shownHeight }}
|
||||
// `overflow-auto`, not hidden: at Desktop in a narrow panel the frame is wider than the room,
|
||||
// and scrolling to the rest of it is the honest answer where scaling was not.
|
||||
className="mx-auto overflow-auto rounded-lg border border-border bg-white"
|
||||
style={{ width: Math.min(width, available.width || width), height: shownHeight }}
|
||||
>
|
||||
{message ? (
|
||||
<p className="p-6 text-center text-xs text-muted-foreground">{message}</p>
|
||||
@@ -270,12 +267,8 @@ export const SitePreview = ({
|
||||
src={`/api/dev-proxy/${port}/${path}`}
|
||||
title={`The site at /${path}`}
|
||||
className="border-0"
|
||||
style={{
|
||||
width,
|
||||
height: shownHeight / scale,
|
||||
transform: `scale(${scale})`,
|
||||
transformOrigin: 'top left',
|
||||
}}
|
||||
// The device's real width, and the room's real height. No transform: see the note above.
|
||||
style={{ width, height: shownHeight }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user