diff --git a/site/src/routes/repl/_components/ExampleSelector.html b/site/src/routes/repl/_components/AppControls/ExampleSelector.html similarity index 96% rename from site/src/routes/repl/_components/ExampleSelector.html rename to site/src/routes/repl/_components/AppControls/ExampleSelector.html index b41ff40231..8e937e5bc3 100644 --- a/site/src/routes/repl/_components/ExampleSelector.html +++ b/site/src/routes/repl/_components/AppControls/ExampleSelector.html @@ -1,6 +1,6 @@ + @@ -169,8 +193,8 @@ App.html {:else} - {#if component.edit} - {component.name + (/\./.test(component.name) ? '' : '.html')} + {#if component === editing} + {component.name + (/\./.test(component.name) ? '' : `.${component.type}`)} - + diff --git a/site/src/routes/repl/_components/Input/ModuleEditor.html b/site/src/routes/repl/_components/Input/ModuleEditor.html index 7dc74bdf05..ce38ae6bc6 100644 --- a/site/src/routes/repl/_components/Input/ModuleEditor.html +++ b/site/src/routes/repl/_components/Input/ModuleEditor.html @@ -1,7 +1,7 @@ + \ No newline at end of file diff --git a/site/src/routes/repl/_components/Output/PropEditor.html b/site/src/routes/repl/_components/Output/PropEditor.html new file mode 100644 index 0000000000..0486cf1f34 --- /dev/null +++ b/site/src/routes/repl/_components/Output/PropEditor.html @@ -0,0 +1,55 @@ + + + + + + + + + \ No newline at end of file diff --git a/site/src/routes/repl/_components/Output/Viewer.html b/site/src/routes/repl/_components/Output/Viewer.html index b160277952..83c58a701b 100644 --- a/site/src/routes/repl/_components/Output/Viewer.html +++ b/site/src/routes/repl/_components/Output/Viewer.html @@ -8,10 +8,19 @@ export let bundle; export let dom; export let ssr; - export let data; + export let values; + export let props; export let sourceError; export let error; + export function setProp(prop, value) { + if (component) { + component[prop] = value; + } + } + + let component; + const refs = {}; const importCache = {}; let pendingImports = 0; @@ -70,8 +79,6 @@ let init; onMount(() => { - let component; - refs.child.addEventListener('load', () => { const iframe = refs.child; const body = iframe.contentDocument.body; @@ -150,7 +157,7 @@ const createHtml = () => { try { evalInIframe(`${ssr.code} - var rendered = SvelteComponent.render(${JSON.stringify(data)}); + var rendered = SvelteComponent.render(${JSON.stringify(values)}); if (rendered.css.code) { var style = document.createElement('style'); @@ -183,7 +190,7 @@ var component = new SvelteComponent({ target: document.body, - data: ${JSON.stringify(data)} + props: ${JSON.stringify(values)} });`); component = window.app = window.component = iframe.contentWindow.component; @@ -249,17 +256,18 @@ toDestroy = component; component = null; - if (data !== undefined) init(); + if (values !== undefined) init(); }; - data_handler = data => { + values_handler = values => { + console.log({ values }); if (updating) return; try { if (component) { error = null; updating = true; - component.$set(data); + component.$set(values); updating = false; } else { init(); @@ -274,16 +282,35 @@ error = e; } }; + + props_handler = props => { + if (!component) { + // TODO can this happen? + console.error(`no component to bind to`); + return; + } + + props.forEach(prop => { + // TODO should there be a public API for binding? + // e.g. `component.$watch(prop, handler)`? + // (answer: probably) + component.$$.bound[prop] = value => { + dispatch('binding', { prop, value }); + }; + }); + }; }); }); function noop(){} let run = noop; let bundle_handler = noop; - let data_handler = noop; + let values_handler = noop; + let props_handler = noop; $: bundle_handler(bundle); - $: data_handler(data); + $: values_handler(values); + $: props_handler(props); @@ -66,31 +103,39 @@ {#if bundle} {:else} - loading Svelte compiler... + + loading Svelte compiler... {/if} - - Props editor - + Props editor - + + {#each props.sort() as prop (prop)} + {prop} + + + + {/each} + {:else} @@ -106,11 +151,9 @@ - - Compiler options - + Compiler options - TODO + TODO {/if} \ No newline at end of file diff --git a/site/src/routes/repl/_components/Repl.html b/site/src/routes/repl/_components/Repl.html index 449f5f1e2e..c69dfd17c9 100644 --- a/site/src/routes/repl/_components/Repl.html +++ b/site/src/routes/repl/_components/Repl.html @@ -9,8 +9,7 @@ export let version; export let components; export let selectedComponent; - export let data; - export let json5; + export let values; let bundle = null; let dom; @@ -20,10 +19,11 @@ let dataError = null; let dataErrorLoc = null; let warningCount = 0; - let compiled = ''; + let code = ''; let uid = 0; - - let sourceErrorLoc, runtimeErrorLoc; + let props = []; + let sourceErrorLoc; + let runtimeErrorLoc; let worker; @@ -38,11 +38,13 @@ case 'bundled': ({ bundle, dom, ssr, warningCount, error: sourceError } = event.data.result); + console.log(dom, sourceError); runtimeError = null; break; case 'compiled': - compiled = event.data.result; + code = event.data.result.code; + if (event.data.result.props) props = event.data.result.props; break; } } @@ -57,22 +59,6 @@ }; }); - function createComponent() { - const newComponent = { - name: uid++ ? `Component${uid}` : 'Component1', - type: 'html', - source: '', - edit: true - }; - - components = components.concat(newComponent); - - setTimeout(() => { - document.getElementById(newComponent.name).scrollIntoView(false); - selectedComponent = newComponent; - }); - } - function removeComponent() { const component = selectedComponent; @@ -92,6 +78,35 @@ } } + function compile(component) { + if (component.type === 'html') { + worker.postMessage({ + type: 'compile', + component, + entry: component === components[0] + }); + } else { + code = component.source; + } + } + + function handleSelect(event) { + console.log(`handleSelect`); + + selectedComponent = event.detail.component; + // compile(selectedComponent); + } + + function handleChange() { + console.log(`handleChange`); + + // recompile selected component + compile(selectedComponent); + + // regenerate bundle (TODO do this in a separate worker?) + worker.postMessage({ type: 'bundle', components }); + } + function updateData(current) { const data = fleece.evaluate(json5); @@ -121,6 +136,15 @@ : null; } + $: if (worker && components) { + console.log(`posting`, worker, components); + worker.postMessage({ type: 'bundle', components }); + } + + $: if (worker && selectedComponent) { + compile(selectedComponent); + } + $: try { data= fleece.evaluate(json5); dataError = null; @@ -129,34 +153,6 @@ dataError = err; dataErrorLoc = err && err.loc; } - - $: if (worker && components.length > 0) { - worker.postMessage({ type: 'bundle', components }); - } - - let last_selected_component; - $: { - // slightly counterintuitively, we only want to rebundle if - // this is the *same* component — not if we've just selected - // a different one - // if (selectedComponent === last_selected_component) { - // if (worker && components.length > 0) { - // console.log(`2`, components); - // worker.postMessage({ type: 'bundle', components }); - // } - // } - - // recompile the currently selected component - if (selectedComponent) { - if (selectedComponent.type === 'html') { - worker.postMessage({ type: 'compile', component: selectedComponent }); - } else { - compiled = selectedComponent.source; - } - } - - last_selected_component = selectedComponent; - }
loading Svelte compiler...
{prop}