{"version":3,"sources":["../../modules/react/themes/index.ts","../../modules/react/themes/theme-provider/index.tsx","../../modules/react/hooks/useBroadcastChannel/index.tsx"],"sourcesContent":["export {\r\n    ThemeProvider,\r\n    useTheme\r\n} from './theme-provider';","import React, { createContext, useContext, useState, useEffect, useRef } from \"react\";\r\nimport { useBroadcastChannel } from \"../../hooks/useBroadcastChannel\";\r\n\r\nconst ThemeContext = createContext<{\r\n  theme: string;\r\n  handleThemeChange: (theme: string) => void;\r\n}>({ theme: \"light\", handleThemeChange: () => {} });\r\n\r\n// Helper function to get cookie value\r\nfunction getCookie(name: string): string | null {\r\n  if (typeof document === \"undefined\") return null;\r\n  const value = `; ${document.cookie}`;\r\n  const parts = value.split(`; ${name}=`);\r\n  if (parts.length === 2) {\r\n    return parts.pop()?.split(\";\").shift() || null;\r\n  }\r\n  return null;\r\n}\r\n\r\nexport const ThemeProvider = ({ \r\n  children,\r\n  initialTheme \r\n}: { \r\n  children: React.ReactNode;\r\n  initialTheme?: string;\r\n}) => {\r\n  const { message: themeMessage, sendMessage } = useBroadcastChannel('theme_channel');\r\n  \r\n  // Track what we last sent to avoid loops\r\n  const lastSentRef = useRef<string | null>(null);\r\n\r\n  // Initialize theme consistently between server and client\r\n  const [theme, setTheme] = useState<string>(() => {\r\n    if (initialTheme) return initialTheme;\r\n    \r\n    if (typeof window !== \"undefined\") {\r\n      const windowData = (window as any).__FW_DATA__;\r\n      if (windowData?.theme) return windowData.theme;\r\n    }\r\n    \r\n    if (typeof window !== \"undefined\") {\r\n      const cookieTheme = getCookie(\"theme\");\r\n      if (cookieTheme) return cookieTheme;\r\n    }\r\n    \r\n    return \"light\";\r\n  });\r\n\r\n  // Handle messages from broadcast channel (other tabs)\r\n  // This effect ONLY responds to themeMessage changes, not theme changes\r\n  useEffect(() => {\r\n    if (!themeMessage) return;\r\n    \r\n    // Ignore if this is a message we just sent\r\n    if (themeMessage === lastSentRef.current) {\r\n      lastSentRef.current = null;\r\n      return;\r\n    }\r\n    \r\n    // Only update if different from current theme\r\n    setTheme((currentTheme) => {\r\n      if (themeMessage !== currentTheme) {\r\n        // Update cookie\r\n        if (typeof document !== \"undefined\") {\r\n          document.cookie = `theme=${themeMessage}; path=/; max-age=31536000`;\r\n        }\r\n        \r\n        // Update window data\r\n        if (typeof window !== \"undefined\") {\r\n          if (!(window as any).__FW_DATA__) {\r\n            (window as any).__FW_DATA__ = {};\r\n          }\r\n          (window as any).__FW_DATA__ = {\r\n            ...(window as any).__FW_DATA__,\r\n            theme: themeMessage,\r\n          };\r\n        }\r\n        \r\n        return themeMessage;\r\n      }\r\n      return currentTheme;\r\n    });\r\n  }, [themeMessage]); // Only depend on themeMessage, NOT theme!\r\n\r\n  // Handle window.__FW_DATA__ changes during SPA navigation\r\n  useEffect(() => {\r\n    const handleDataRefresh = () => {\r\n      if (typeof window !== \"undefined\") {\r\n        const windowData = (window as any).__FW_DATA__;\r\n        if (windowData?.theme) {\r\n          setTheme((currentTheme) => {\r\n            if (windowData.theme !== currentTheme) {\r\n              return windowData.theme;\r\n            }\r\n            return currentTheme;\r\n          });\r\n        }\r\n      }\r\n    };\r\n\r\n    if (typeof window !== \"undefined\") {\r\n      window.addEventListener(\"fw-data-refresh\", handleDataRefresh);\r\n      return () => {\r\n        window.removeEventListener(\"fw-data-refresh\", handleDataRefresh);\r\n      };\r\n    }\r\n  }, []); // No dependencies - event listener doesn't need theme\r\n\r\n  // Handle initialTheme prop changes\r\n  useEffect(() => {\r\n    if (initialTheme && initialTheme !== theme) {\r\n      setTheme(initialTheme);\r\n    }\r\n  }, [initialTheme]); // Only depend on initialTheme, not theme\r\n\r\n  // Update body class when theme changes\r\n  useEffect(() => {\r\n    if (typeof document === \"undefined\") return;\r\n\r\n    const body = document.body;\r\n    const currentClasses = body.className.split(\" \").filter(Boolean);\r\n    const themeClasses = [\"light\", \"dark\"];\r\n    const filteredClasses = currentClasses.filter(\r\n      (cls) => !themeClasses.includes(cls)\r\n    );\r\n    const newClassName = [...filteredClasses, theme].filter(Boolean).join(\" \");\r\n    \r\n    if (body.className !== newClassName) {\r\n      body.className = newClassName;\r\n    }\r\n  }, [theme]);\r\n\r\n  const handleThemeChange = (newTheme: string) => {\r\n    // Update state immediately\r\n    setTheme(newTheme);\r\n\r\n    // Update cookie\r\n    if (typeof document !== \"undefined\") {\r\n      document.cookie = `theme=${newTheme}; path=/; max-age=31536000`;\r\n    }\r\n\r\n    // Update window data\r\n    if (typeof window !== \"undefined\") {\r\n      if (!(window as any).__FW_DATA__) {\r\n        (window as any).__FW_DATA__ = {};\r\n      }\r\n      (window as any).__FW_DATA__ = {\r\n        ...(window as any).__FW_DATA__,\r\n        theme: newTheme,\r\n      };\r\n    }\r\n    \r\n    // Mark this as the last value we sent\r\n    lastSentRef.current = newTheme;\r\n    \r\n    // Broadcast to other tabs\r\n    sendMessage(newTheme);\r\n    \r\n    // Clear the ref after a delay\r\n    setTimeout(() => {\r\n      if (lastSentRef.current === newTheme) {\r\n        lastSentRef.current = null;\r\n      }\r\n    }, 500);\r\n  };\r\n\r\n  return (\r\n    <ThemeContext.Provider value={{ theme, handleThemeChange }}>\r\n      {children}\r\n    </ThemeContext.Provider>\r\n  );\r\n};\r\n\r\nexport const useTheme = () => {\r\n  return useContext(ThemeContext);\r\n};\r\n","import React, { useEffect, useState, useRef, useCallback } from \"react\";\r\n\r\nexport const useBroadcastChannel = (channelName: string) => {\r\n  const [message, setMessage] = useState(null);\r\n  const channelRef = useRef<BroadcastChannel | null>(null);\r\n\r\n  useEffect(() => {\r\n    // Create channel only once, inside useEffect\r\n    if (!channelRef.current && typeof window !== \"undefined\") {\r\n      channelRef.current = new BroadcastChannel(channelName);\r\n    }\r\n\r\n    const channel = channelRef.current;\r\n    if (!channel) return;\r\n\r\n    const handleMessage = (event: MessageEvent) => {\r\n      setMessage(event.data);\r\n    };\r\n\r\n    channel.onmessage = handleMessage;\r\n\r\n    // Clean up the channel when the component unmounts\r\n    return () => {\r\n      if (channelRef.current) {\r\n        channelRef.current.close();\r\n        channelRef.current = null;\r\n      }\r\n    };\r\n  }, [channelName]);\r\n\r\n  const sendMessage = useCallback((msg: unknown) => {\r\n    if (channelRef.current) {\r\n      channelRef.current.postMessage(msg);\r\n    }\r\n  }, []);\r\n\r\n  return { message, sendMessage };\r\n};\r\n"],"mappings":"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","names":["import_react"]}