Reuben_OS / app /components /DartPadEmbed.tsx
Reubencf's picture
open close
ad31128
'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>
)
}