> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lightspark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Build your flow

> Design your flow and get the API calls for your exact use case

export const FlowBuilderEmbed = () => {
  const [src, setSrc] = React.useState(null);
  React.useEffect(() => {
    const prefButtons = () => {
      const g = document.querySelector('#sidebar-content [role="group"][aria-label="Theme preference"]');
      if (!g) return null;
      return {
        group: g,
        system: g.querySelector('button[aria-label="Switch to system theme"]'),
        light: g.querySelector('button[aria-label="Switch to light theme"]'),
        dark: g.querySelector('button[aria-label="Switch to dark theme"]')
      };
    };
    const currentPref = () => {
      const b = prefButtons();
      const pressed = b && b.group.querySelector('button[aria-pressed="true"]');
      const label = pressed ? pressed.getAttribute('aria-label') || '' : '';
      if (label.indexOf('system') !== -1) return 'system';
      if (label.indexOf('light') !== -1) return 'light';
      if (label.indexOf('dark') !== -1) return 'dark';
      return null;
    };
    const isDark = document.documentElement.classList.contains('dark');
    const initialPref = currentPref();
    setSrc('https://grid-flow-builder.vercel.app/?embed=true&theme=' + (initialPref || (isDark ? 'dark' : 'light')));
    let ignoreNextMutation = false;
    const sendTheme = () => {
      const t = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
      const iframe = document.getElementById('flow-builder-iframe');
      if (iframe && iframe.contentWindow) {
        iframe.contentWindow.postMessage({
          type: 'theme-sync',
          theme: t,
          pref: currentPref() || undefined
        }, '*');
      }
    };
    const handleMessage = e => {
      if (e.data && e.data.type === 'theme-request') {
        sendTheme();
        return;
      }
      if (e.data && e.data.type === 'theme-sync') {
        const isDarkNow = document.documentElement.classList.contains('dark');
        const wantsDark = e.data.theme === 'dark';
        const want = e.data.pref;
        const btns = want ? prefButtons() : null;
        if (btns && btns[want]) {
          if (currentPref() !== want) {
            if (isDarkNow !== wantsDark) ignoreNextMutation = true;
            btns[want].click();
          }
          return;
        }
        if (isDarkNow !== wantsDark) {
          ignoreNextMutation = true;
          document.documentElement.classList.toggle('dark');
        }
      }
    };
    window.addEventListener('message', handleMessage);
    const obs = new MutationObserver(() => {
      if (ignoreNextMutation) {
        ignoreNextMutation = false;
        return;
      }
      sendTheme();
    });
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => {
      window.removeEventListener('message', handleMessage);
      obs.disconnect();
    };
  }, []);
  if (!src) return null;
  return <iframe id="flow-builder-iframe" src={src} title="Grid Flow Builder" allow="clipboard-write" />;
};

<div id="flow-builder-container">
  <FlowBuilderEmbed />
</div>
