"}]," component that shows the current position and zoom level\\nof the viewport."]}],"\\n",["$","li",null,{"className":"x:my-[.5em]","children":["A ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," component that reveals the state of each node."]}],"\\n",["$","li",null,{"className":"x:my-[.5em]","children":["A ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," that wraps your flow’s ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"onNodesChange"}]," handler and logs\\neach change as it is dised."]}],"\\n"]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":"While we find these tools useful for making sure React Flow is working properly,\\nyou might also find them useful for debugging your applications as your flows and\\ntheir interactions become more complex."}],"\\n",["$","div",null,{"className":"nestedSandpack","children":"$L1c"}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":"We encourage you to copy any or all of the components from this example into your\\nown projects and modify them to suit your needs: each component works independently!"}],"\\n",["$","h2",null,{"id":"node-inspector","className":"x:tracking-tight x:text-slate-900 x:dark:text-slate-100 x:font-semibold x:target:animate-[fade-in_1.5s] x:mt-10 x:border-b x:pb-1 x:text-3xl nextra-border","children":["Node Inspector",["$","$L1d",null,{"id":"node-inspector"}]]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["The ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," component makes use of our ",["$","$L1b",null,{"href":"/api-reference/hooks/use-nodes","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":"useNodes"}]}],"\\nhook to access all the nodes in the flow. Typically we discourage using this hook\\nbecause it will trigger a re-render any time ",["$","em",null,{"children":"any"}]," of your nodes change, but that’s\\nexactly what makes it so useful for debugging!"]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["The ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"width"}]," and ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"height"}]," properties are added to each node by React Flow after it has measured\\nthe node’s dimensions. We pass those dimensions, as well as other information like\\nthe node’s id and type, to a custom ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," component."]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["We make use of the ",["$","$L1b",null,{"href":"/api-reference/components/viewport-portal","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]}],"\\ncomponent to let us render the inspector into React Flow’s viewport. That means\\nit’s content will be positioned and transformed along with the rest of the flow\\nas the user pans and zooms."]}],"\\n",["$","h2",null,{"id":"change-logger","className":"x:tracking-tight x:text-slate-900 x:dark:text-slate-100 x:font-semibold x:target:animate-[fade-in_1.5s] x:mt-10 x:border-b x:pb-1 x:text-3xl nextra-border","children":["Change Logger",["$","$L1d",null,{"id":"change-logger"}]]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["Any change to your nodes and edges that originates from React Flow itself is\\ncommunicated to you through the ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"onNodesChange"}]," and ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"onEdgesChange"}]," callbacks.\\nIf you are working with a controlled flow (that means you’re managing the nodes\\nand edges yourself), you need to apply those changes to your state in order to\\nkeep everything in sync."]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["The ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," component wraps your user-provided ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"onNodesChange"}]," handler\\nwith a custom function that intercepts and logs each change as it is dised.\\nWe can do this by using the ",["$","$L1b",null,{"href":"/api-reference/hooks/use-store","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":"useStore"}]}]," and\\n",["$","$L1b",null,{"href":"/api-reference/hooks/use-store-api","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":"useStoreApi"}]}]," hooks to access the store and\\nand then update React Flow’s internal state accordingly. These two hooks give you\\npowerful access to React Flow’s internal state and methods."]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["Beyond debugging, using the ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," can be a great way to learn more\\nabout how React Flow works and get you thinking about the different functionality\\nyou can build on top of each change."]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["You can find documentation on the ",["$","$L1b",null,{"href":"/api-reference/types/node-change","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":"NodeChange"}]}],"\\nand ",["$","$L1b",null,{"href":"/api-reference/types/edge-change","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":"EdgeChange"}]}]," types in the API reference."]}],"\\n",["$","h2",null,{"id":"viewport-logger","className":"x:tracking-tight x:text-slate-900 x:dark:text-slate-100 x:font-semibold x:target:animate-[fade-in_1.5s] x:mt-10 x:border-b x:pb-1 x:text-3xl nextra-border","children":["Viewport Logger",["$","$L1d",null,{"id":"viewport-logger"}]]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["The ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]," is the simplest example of what state you can pull out\\nof React Flow’s store if you know what to look for. The state of the viewport is\\nstored internally under the ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"transform"}]," key (a name we inherited from\\n",["$","a",null,{"href":"https://d3js.org/d3-zoom#zoomTransform","target":"_blank","rel":"noreferrer","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["d3-zoom",[" ",["$","svg",null,{"fill":"none","stroke":"currentColor","strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":1.7,"viewBox":"0 0 24 24","height":"1em","className":"x:inline x:align-baseline x:shrink-0","children":[["$","path",null,{"d":"M7 17L17 7"}],["$","path",null,{"d":"M7 7h10v10"}]]}]]]}],"). This component extracts the\\n",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"x"}],", ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"y"}],", and ",["$","code",null,{"className":"nextra-code","dir":"ltr","children":"zoom"}]," components of the transform and renders them into a\\n",["$","$L1b",null,{"href":"/api-reference/components/panel","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["$","code",null,{"className":"nextra-code","dir":"ltr","children":""}]}]," component."]}],"\\n",["$","h2",null,{"id":"let-us-know-what-you-think","className":"x:tracking-tight x:text-slate-900 x:dark:text-slate-100 x:font-semibold x:target:animate-[fade-in_1.5s] x:mt-10 x:border-b x:pb-1 x:text-3xl nextra-border","children":["Let us know what you think",["$","$L1d",null,{"id":"let-us-know-what-you-think"}]]}],"\\n",["$","p",null,{"className":"x:not-first:mt-[1.25em] x:leading-7","children":["As mentioned above, if you have any feedback or ideas on how to improve the devtools,\\nplease let us know on ",["$","a",null,{"href":"https://discord.gg/Bqt6xrs","target":"_blank","rel":"noreferrer","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":["Discord",[" ",["$","svg",null,{"fill":"none","stroke":"currentColor","strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":1.7,"viewBox":"0 0 24 24","height":"1em","className":"x:inline x:align-baseline x:shrink-0","children":[["$","path",null,{"d":"M7 17L17 7"}],["$","path",null,{"d":"M7 7h10v10"}]]}]]]}]," or via mail at\\n",["$","$L1b",null,{"href":"mailto:info@xyflow.com","prefetch":"$undefined","className":"x:focus-visible:nextra-focus x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]","children":"info@xyflow.com"}],". If you build your own devtools using these ideas, we’d love to\\nhear about it!"]}]]\n'])