switch REPL orientation in tutorial, hide props editor

pull/2143/head
Rich Harris 7 years ago
parent f4748e23b0
commit 816f83f4b6

@ -19,6 +19,7 @@
export let runtimeError; export let runtimeError;
export let compileOptions; export let compileOptions;
export let embedded; export let embedded;
export let show_props;
// refs // refs
let viewer; let viewer;
@ -121,7 +122,7 @@
</div> </div>
{#if view === 'result'} {#if view === 'result'}
<SplitPane type="vertical" pos={67}> <SplitPane type="vertical" pos={67} fixed={!show_props} fixed_pos={100}>
<div slot="a"> <div slot="a">
{#if bundle} {#if bundle}
<Viewer <Viewer
@ -143,27 +144,29 @@
</div> </div>
<section slot="b"> <section slot="b">
<h3>Props editor</h3> {#if show_props}
<h3>Props editor</h3>
{#if props}
{#if props.length > 0} {#if props}
<div class="props"> {#if props.length > 0}
{#each props.sort() as prop (prop)} <div class="props">
<code style="display: block; whitespace: pre;">{prop}</code> {#each props.sort() as prop (prop)}
<code style="display: block; whitespace: pre;">{prop}</code>
<!-- TODO `bind:this={propEditors[prop]}` — currently fails -->
<PropEditor <!-- TODO `bind:this={propEditors[prop]}` — currently fails -->
value={$values_store[prop]} <PropEditor
on:change="{e => setPropFromEditor(prop, e.detail.value)}" value={$values_store[prop]}
/> on:change="{e => setPropFromEditor(prop, e.detail.value)}"
{/each} />
</div> {/each}
{:else} </div>
<div style="padding: 0.5em" class="linkify"> {:else}
<!-- TODO explain distincion between logic-less and logic-ful components? --> <div style="padding: 0.5em" class="linkify">
<!-- TODO style the <a> so it looks like a link --> <!-- TODO explain distincion between logic-less and logic-ful components? -->
<p style="font-size: 1.3rem; color: var(--second)">This component has no props — <a href="guide#external-properties">declare props with the export keyword</a></p> <!-- TODO style the <a> so it looks like a link -->
</div> <p style="font-size: 1.3rem; color: var(--second)">This component has no props — <a href="guide#external-properties">declare props with the export keyword</a></p>
</div>
{/if}
{/if} {/if}
{/if} {/if}
</section> </section>

@ -1,90 +1,89 @@
export default class ReplProxy { export default class ReplProxy {
constructor(iframe) { constructor(iframe) {
this.iframe = iframe; this.iframe = iframe;
this.cmdId = 1; this.cmdId = 1;
this.pendingCmds = new Map(); this.pendingCmds = new Map();
this.onPropUpdate = null; this.onPropUpdate = null;
this.onFetchProgress = null; this.onFetchProgress = null;
this.handle_event = (ev) => this.handleReplMessage(ev); this.handle_event = (ev) => this.handleReplMessage(ev);
window.addEventListener("message", this.handle_event, false); window.addEventListener("message", this.handle_event, false);
} }
destroy() { destroy() {
window.removeEventListener("message", this.handle_event); window.removeEventListener("message", this.handle_event);
} }
iframeCommand(command, args) { iframeCommand(command, args) {
return new Promise( (resolve, reject) => { return new Promise( (resolve, reject) => {
this.cmdId = this.cmdId + 1; this.cmdId = this.cmdId + 1;
this.pendingCmds.set(this.cmdId, { resolve: resolve, reject: reject }); this.pendingCmds.set(this.cmdId, { resolve: resolve, reject: reject });
this.iframe.contentWindow.postMessage({ this.iframe.contentWindow.postMessage({
action: command, action: command,
cmdId: this.cmdId, cmdId: this.cmdId,
args: args args: args
}, '*') }, '*')
}); });
} }
handleCommandMessage(cmdData) { handleCommandMessage(cmdData) {
let action = cmdData.action; let action = cmdData.action;
let id = cmdData.cmdId; let id = cmdData.cmdId;
let handler = this.pendingCmds.get(id); let handler = this.pendingCmds.get(id);
if (handler) { if (handler) {
this.pendingCmds.delete(id); this.pendingCmds.delete(id);
if (action == "cmdError") { if (action == "cmdError") {
let { message, stack } = cmdData; let { message, stack } = cmdData;
let e = new Error(message); let e = new Error(message);
e.stack = stack; e.stack = stack;
console.log("repl cmd fail"); console.log("repl cmd fail");
handler.reject(e) handler.reject(e)
} }
if (action == "cmdOk") { if (action == "cmdOk") {
handler.resolve(cmdData.args) handler.resolve(cmdData.args)
} }
} else { } else {
console.error("command not found", id, cmdData, [...this.pendingCmds.keys()]); console.error("command not found", id, cmdData, [...this.pendingCmds.keys()]);
} }
} }
handleReplMessage(ev) { handleReplMessage(ev) {
let action = ev.data.action; let action = ev.data.action;
if ( action == "cmdError" || action == "cmdOk" ) { if ( action == "cmdError" || action == "cmdOk" ) {
this.handleCommandMessage(ev.data); this.handleCommandMessage(ev.data);
} }
if (action == "prop_update") { if (action == "prop_update") {
let { prop, value } = ev.data.args; let { prop, value } = ev.data.args;
if (this.onPropUpdate) if (this.onPropUpdate)
this.onPropUpdate(prop, value) this.onPropUpdate(prop, value)
} }
if (action == "fetch_progress") { if (action == "fetch_progress") {
if (this.onFetchProgress) if (this.onFetchProgress)
this.onFetchProgress(ev.data.args.remaining) this.onFetchProgress(ev.data.args.remaining)
} }
} }
eval(script) { eval(script) {
return this.iframeCommand("eval", { script: script }); return this.iframeCommand("eval", { script: script });
} }
setProp(prop, value) { setProp(prop, value) {
return this.iframeCommand("set_prop", {prop, value}) return this.iframeCommand("set_prop", {prop, value})
} }
bindProps(props) { bindProps(props) {
return this.iframeCommand("bind_props", { props: props }) return this.iframeCommand("bind_props", { props: props })
} }
handleLinks() { handleLinks() {
return this.iframeCommand("catch_clicks", {}); return this.iframeCommand("catch_clicks", {});
} }
fetchImports(bundle) {
return this.iframeCommand("fetch_imports", { bundle })
}
fetchImports(bundle) {
return this.iframeCommand("fetch_imports", { bundle })
}
} }

@ -11,6 +11,8 @@
export let version = 'beta'; // TODO change this to latest when the time comes export let version = 'beta'; // TODO change this to latest when the time comes
export let app; export let app;
export let embedded = false; export let embedded = false;
export let orientation = 'auto';
export let show_props = true;
export function toJSON() { export function toJSON() {
// TODO there's a bug here — Svelte hoists this function because // TODO there's a bug here — Svelte hoists this function because
@ -277,7 +279,12 @@
<div class="container" bind:clientWidth={width}> <div class="container" bind:clientWidth={width}>
<div class="repl-inner" class:offset="{show_output}"> <div class="repl-inner" class:offset="{show_output}">
<SplitPane type="horizontal" fixed="{600 > width}" pos={60} fixed_pos={50}> <SplitPane
type="{orientation === 'rows' ? 'vertical' : 'horizontal'}"
fixed="{600 > width}"
pos="{orientation === 'rows' ? 50 : 60}"
fixed_pos={50}
>
<section slot=a> <section slot=a>
<Input <Input
{component_store} {component_store}
@ -306,6 +313,7 @@
{sourceError} {sourceError}
{runtimeError} {runtimeError}
{embedded} {embedded}
{show_props}
/> />
</section> </section>
</SplitPane> </SplitPane>

@ -146,7 +146,7 @@
</div> </div>
<div class="tutorial-repl"> <div class="tutorial-repl">
<Repl {app}/> <Repl {app} orientation="rows" show_props={false}/>
</div> </div>
</div> </div>

Loading…
Cancel
Save