make tutorial mobile-friendly

pull/2383/head
Richard Harris 6 years ago
parent 648bd176c5
commit b96715f812

@ -0,0 +1,37 @@
<script>
export let offset = 0;
</script>
<style>
.toggle {
width: 100%;
height: 42px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid var(--second);
}
button {
padding: 0.3em 0.6em;
border-radius: 1em;
line-height: 1;
height: 1em;
box-sizing: content-box;
color: #999;
border: 1px solid #f4f4f4;
width: 4em;
margin: 0 0.15em;
}
.selected {
background-color: var(--prime);
color: white;
}
</style>
<div class="toggle">
<button class:selected={offset === 0} on:click={() => offset = 0}>tutorial</button>
<button class:selected={offset === 1} on:click={() => offset = 1}>input</button>
<button class:selected={offset === 2} on:click={() => offset = 2}>output</button>
</div>

@ -15,6 +15,7 @@
<script> <script>
import TableOfContents from './_components/TableOfContents.svelte'; import TableOfContents from './_components/TableOfContents.svelte';
import ScreenToggle from './_components/ScreenToggle.svelte';
import Icon from '../../../components/Icon.svelte'; import Icon from '../../../components/Icon.svelte';
import Repl from '@sveltejs/svelte-repl'; import Repl from '@sveltejs/svelte-repl';
import { getContext } from 'svelte'; import { getContext } from 'svelte';
@ -29,6 +30,9 @@
let scrollable; let scrollable;
const lookup = new Map(); const lookup = new Map();
let width = process.browser ? window.innerWidth : 1000;
let offset = 0;
sections.forEach(section => { sections.forEach(section => {
section.chapters.forEach(chapter => { section.chapters.forEach(chapter => {
const obj = { const obj = {
@ -70,6 +74,8 @@
}); });
} }
$: mobile = width < 768;
function reset() { function reset() {
repl.update({ repl.update({
components: chapter.app_a.map(clone) components: chapter.app_a.map(clone)
@ -110,11 +116,27 @@
padding: 0; padding: 0;
/* margin: 0 calc(var(--side-nav) * -1); */ /* margin: 0 calc(var(--side-nav) * -1); */
box-sizing: border-box; box-sizing: border-box;
}
.viewport {
width: 100%;
height: 100%;
display: grid; display: grid;
grid-template-columns: minmax(33.333%, 480px) auto; grid-template-columns: minmax(33.333%, 480px) auto;
grid-auto-rows: 100%; grid-auto-rows: 100%;
} }
.mobile .viewport {
width: 300%;
height: calc(100% - 42px);
grid-template-columns: 33.333% 66.666%;
transition: transform 0.3s;
}
.mobile .offset-1 { transform: translate(-33.333%, 0); }
.mobile .offset-2 { transform: translate(-66.666%, 0); }
.tutorial-text { .tutorial-text {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -215,44 +237,53 @@
<title>{selected.section.title} / {selected.chapter.title} • Svelte Tutorial</title> <title>{selected.section.title} / {selected.chapter.title} • Svelte Tutorial</title>
</svelte:head> </svelte:head>
<div class="tutorial-outer"> <svelte:window bind:innerWidth={width}/>
<div class="tutorial-text">
<div class="table-of-contents">
<TableOfContents {sections} {slug} {selected}/>
</div>
<div class="chapter-markup" bind:this={scrollable}> <div class="tutorial-outer" class:mobile>
{@html chapter.html} <div class="viewport offset-{offset}">
<div class="tutorial-text">
<div class="controls"> <div class="table-of-contents">
{#if chapter.app_b} <TableOfContents {sections} {slug} {selected}/>
<!-- TODO disable this button when the contents of the REPL
matches the expected end result -->
<button class="show" on:click="{() => completed ? reset() : complete()}">
{completed ? 'Reset' : 'Show me'}
</button>
{/if}
{#if selected.next}
<a class="next" href="tutorial/{selected.next.slug}">Next <Icon name="arrow-right" /></a>
{/if}
</div> </div>
<div class="improve-chapter"> <div class="chapter-markup" bind:this={scrollable}>
<a href={improve_link}><Icon name="edit" size={14}/> Edit this chapter</a> {@html chapter.html}
<div class="controls">
{#if chapter.app_b}
<!-- TODO disable this button when the contents of the REPL
matches the expected end result -->
<button class="show" on:click="{() => completed ? reset() : complete()}">
{completed ? 'Reset' : 'Show me'}
</button>
{/if}
{#if selected.next}
<a class="next" href="tutorial/{selected.next.slug}">Next <Icon name="arrow-right" /></a>
{/if}
</div>
<div class="improve-chapter">
<a href={improve_link}><Icon name="edit" size={14}/> Edit this chapter</a>
</div>
</div> </div>
</div> </div>
</div>
<div class="tutorial-repl"> <div class="tutorial-repl">
<Repl <Repl
bind:this={repl} bind:this={repl}
{svelteUrl} {svelteUrl}
{rollupUrl} {rollupUrl}
orientation="rows" orientation={mobile ? 'columns' : 'rows'}
on:change={handle_change} fixed={mobile}
setup={mapbox_setup} on:change={handle_change}
relaxed setup={mapbox_setup}
/> relaxed
/>
</div>
</div> </div>
{#if mobile}
<ScreenToggle bind:offset/>
{/if}
</div> </div>

Loading…
Cancel
Save