Spaces:
Running
Running
| 'use client' | |
| import React, { useEffect, useRef, useState } from 'react' | |
| interface DartPadEmbedProps { | |
| code: string | |
| theme?: 'light' | 'dark' | |
| } | |
| export function DartPadEmbed({ code, theme = 'light' }: DartPadEmbedProps) { | |
| const containerRef = useRef<HTMLDivElement>(null) | |
| const [isLoaded, setIsLoaded] = useState(false) | |
| useEffect(() => { | |
| if (!containerRef.current) return | |
| // Create a unique ID for this instance | |
| const embedId = `dartpad-${Date.now()}` | |
| // Create the container for DartPad with the code | |
| const embedContainer = document.createElement('div') | |
| embedContainer.id = embedId | |
| embedContainer.style.width = '100%' | |
| embedContainer.style.height = '100%' | |
| // Clear the container and add the new element | |
| containerRef.current.innerHTML = '' | |
| containerRef.current.appendChild(embedContainer) | |
| // Use iframe with postMessage to inject code and run it | |
| const iframe = document.createElement('iframe') | |
| iframe.src = `https://dartpad.dev/embed-flutter.html?theme=${theme}&run=true` | |
| iframe.style.width = '100%' | |
| iframe.style.height = '100%' | |
| iframe.style.border = 'none' | |
| // Listen for iframe load and inject the code | |
| iframe.onload = () => { | |
| setIsLoaded(true) | |
| // Wait a bit for DartPad to fully initialize | |
| setTimeout(() => { | |
| // Try to inject the code using postMessage | |
| try { | |
| // DartPad listens for messages to update code | |
| iframe.contentWindow?.postMessage({ | |
| type: 'sourceCode', | |
| sourceCode: { | |
| main: code | |
| } | |
| }, '*') | |
| // Auto-run the code after a short delay | |
| setTimeout(() => { | |
| iframe.contentWindow?.postMessage({ | |
| type: 'execute' | |
| }, '*') | |
| }, 500) | |
| } catch (error) { | |
| console.error('Failed to inject code:', error) | |
| } | |
| }, 1000) | |
| } | |
| embedContainer.appendChild(iframe) | |
| return () => { | |
| // Cleanup | |
| if (containerRef.current) { | |
| containerRef.current.innerHTML = '' | |
| } | |
| } | |
| }, [code, theme]) | |
| return ( | |
| <div className="w-full h-full relative"> | |
| {!isLoaded && ( | |
| <div className="absolute inset-0 flex items-center justify-center bg-gray-900"> | |
| <div className="text-white">Loading DartPad...</div> | |
| </div> | |
| )} | |
| <div ref={containerRef} className="w-full h-full" /> | |
| </div> | |
| ) | |
| } | |