From 691b228b9e1a9fd050d4fb84b502dc0466c4638c Mon Sep 17 00:00:00 2001 From: John Fawcett Date: Wed, 13 May 2026 12:07:16 -0500 Subject: [PATCH] fix(docs): hoist FitOnResize out of FlowDiagram render Defining FitOnResize inside the parent render gave it a new component identity on every parent render, forcing React to unmount/remount it and tear down the ResizeObserver each time. Hoist it to module scope and pass useReactFlow in as a prop. Also drop the unused instanceRef. --- .../components/FlowDiagram/index.tsx | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/packages/kilo-docs/components/FlowDiagram/index.tsx b/packages/kilo-docs/components/FlowDiagram/index.tsx index d8cfcc9ad31..7356cd4cf78 100644 --- a/packages/kilo-docs/components/FlowDiagram/index.tsx +++ b/packages/kilo-docs/components/FlowDiagram/index.tsx @@ -3,6 +3,33 @@ import React, { useState, useEffect, useRef } from "react" import { diagrams } from "./diagrams" +/** + * Re-fits the viewport whenever the React Flow container resizes. + * Defined at module scope so its component identity is stable across + * re-renders of FlowDiagram (otherwise React would unmount/remount it + * on every parent render and tear down the ResizeObserver each time). + */ +function FitOnResize({ + useReactFlow, +}: { + useReactFlow: typeof import("@xyflow/react").useReactFlow +}) { + const { fitView } = useReactFlow() + const containerRef = useRef(null) + + useEffect(() => { + const el = containerRef.current?.closest(".react-flow") as HTMLElement | null + if (!el) return + const observer = new ResizeObserver(() => { + fitView({ padding: 0.15 }) + }) + observer.observe(el) + return () => observer.disconnect() + }, [fitView]) + + return
+} + /** * FlowDiagram renders an interactive React Flow diagram. * Loaded lazily to avoid bundling the entire @xyflow/react library on pages that don't use it. @@ -15,7 +42,6 @@ import { diagrams } from "./diagrams" export function FlowDiagram({ name, height = "400px" }: { name: string; height?: string }) { const [mod, setMod] = useState(null) const [cssLoaded, setCssLoaded] = useState(false) - const instanceRef = useRef(null) useEffect(() => { Promise.all([ @@ -69,23 +95,6 @@ export function FlowDiagram({ name, height = "400px" }: { name: string; height?: const { ReactFlow, Background, BackgroundVariant, useReactFlow, ReactFlowProvider } = mod - const FitOnResize = () => { - const { fitView } = useReactFlow() - const containerRef = useRef(null) - - useEffect(() => { - const el = containerRef.current?.closest(".react-flow") as HTMLElement | null - if (!el) return - const observer = new ResizeObserver(() => { - fitView({ padding: 0.15 }) - }) - observer.observe(el) - return () => observer.disconnect() - }, [fitView]) - - return
- } - return (
- +