diff --git a/package-lock.json b/package-lock.json index 8fa5f7d..068ff7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "spark-template", "version": "0.0.0", "dependencies": { + "@babel/standalone": "^7.28.6", "@github/spark": ">=0.43.1 <1", "@heroicons/react": "^2.2.0", "@hookform/resolvers": "^4.1.3", @@ -163,6 +164,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/standalone": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.28.6.tgz", + "integrity": "sha512-l/vUUfIKWdKHbHLqISTekuOaMuxNrnk7qlxFmhAKCayRXhkbBMB6zaJW+9oo0eLFgZLQEpG43LH4sxcEuy1M5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", diff --git a/package.json b/package.json index 45ea44f..12be3c3 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "preview": "vite preview" }, "dependencies": { + "@babel/standalone": "^7.28.6", "@github/spark": ">=0.43.1 <1", "@heroicons/react": "^2.2.0", "@hookform/resolvers": "^4.1.3", diff --git a/src/components/ReactPreview.tsx b/src/components/ReactPreview.tsx index 2a24a4e..2539b65 100644 --- a/src/components/ReactPreview.tsx +++ b/src/components/ReactPreview.tsx @@ -5,6 +5,7 @@ import { Alert, AlertDescription } from '@/components/ui/alert' import { AIErrorHelper } from '@/components/AIErrorHelper' import { WarningCircle } from '@phosphor-icons/react' import { InputParameter } from '@/lib/types' +import * as Babel from '@babel/standalone' interface ReactPreviewProps { code: string @@ -29,7 +30,7 @@ export function ReactPreview({ code, language, functionName, inputParameters }: } try { - const transformedCode = code + const cleanedCode = code .replace(/^import\s+.*from\s+['"]react['"];?\s*/gm, '') .replace(/^import\s+.*from\s+['"].*['"];?\s*/gm, '') .replace(/export\s+default\s+/g, '') @@ -38,20 +39,23 @@ export function ReactPreview({ code, language, functionName, inputParameters }: let componentToReturn = functionName if (!componentToReturn) { - const functionMatch = transformedCode.match(/(?:function|const|let|var)\s+([A-Z]\w*)/); + const functionMatch = cleanedCode.match(/(?:function|const|let|var)\s+([A-Z]\w*)/); if (functionMatch) { componentToReturn = functionMatch[1] } } + const transformedResult = Babel.transform(cleanedCode, { + presets: ['react', 'typescript'], + filename: 'component.tsx', + }) + + const transformedCode = transformedResult.code || '' + const wrappedCode = ` (function() { const React = arguments[0]; - const useState = React.useState; - const useEffect = React.useEffect; - const useRef = React.useRef; - const useMemo = React.useMemo; - const useCallback = React.useCallback; + const { useState, useEffect, useRef, useMemo, useCallback, useReducer, useContext } = React; ${transformedCode}