JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
<script src="https://unpkg.com/[email protected]/lib/jailed.js"></script>
JavaScript
import { html, render, useState, useEffect, useMemo } from "https://unpkg.com/[email protected]/preact/standalone.module.js";
const code = `
const { count, setCount } = props;
return html\`
<button onClick=$\{() => { setCount(count + 1) }}>
$\{count} clicks
</button>
\`;
`;
function App() {
const [count, setCount] = useState(0);
return html`<${StringComponent} code=${code} props=${{ count }} />`;
}
function StringComponent({ code, props }) {
const plugin = useMemo(() => {
let fullCode = `
application.setInterface({ Component });
function Component(props, cb) {
for (const [key, value] of Object.entries(application.remote)) {
self[key] = value;
}
function html(...args) {
return args;
}
const result = (() => {
${code}
})();
console.log(props);
console.log("Result:", result);
cb(result);
}
`;
const plugin = new jailed.DynamicPlugin(fullCode, {});
return plugin;
}, [code]);
const [result, setResult] = useState(html`Loading...`);
useEffect(() => {
if (plugin) {
let cancelled = false;
plugin.whenConnected(() => {
console.log(plugin.remote.Component);
plugin.remote.Component(props, newResult => {
console.log(newResult, cancelled);
if (!cancelled) setResult(html(...newResult));
});
});
return () => {
cancelled = true;
}
}
}, [props, plugin]);
return result;
}
render(html`<${App} />`, document.body);