diff --git a/src/app/components/Onboarding.tsx b/src/app/components/Onboarding.tsx index a15722b..2079b20 100644 --- a/src/app/components/Onboarding.tsx +++ b/src/app/components/Onboarding.tsx @@ -41,10 +41,6 @@ function ExampleThumbnail({ spec }: { spec: Record }) { useEffect(() => { const node = hostRef.current; if (!node) return; - // TODO: thumbnails render once at mount width and don't call handle.resize(), - // so a `width: 'container'` chart won't re-fit when the window resizes and the - // grid reflows the card. Cosmetic only (the card clips/letterboxes via overflow - // hidden) on a brief first-run surface; wire a resize observer if it ever shows. let handle: RenderHandle | null = null; let cancelled = false; // `container` width fits the card; a fixed height keeps every card uniform. @@ -60,8 +56,18 @@ function ExampleThumbnail({ spec }: { spec: Record }) { // somehow fails to render must never break onboarding — leave the card // image blank and let the name + description carry it. }); + // A `container`-width chart only re-reads its size on a window resize, so the + // grid reflowing a card (window resize → new column width) needs the same + // synthesized re-fit LivePreview uses. The observer reads `handle` lazily, so + // it no-ops until the async render resolves. + let ro: ResizeObserver | undefined; + if (typeof ResizeObserver !== 'undefined') { + ro = new ResizeObserver(() => handle?.resize()); + ro.observe(node); + } return () => { cancelled = true; + ro?.disconnect(); handle?.destroy(); }; }, [spec, uiTheme]);