mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 17:30:59 +01:00
merge conflict
This commit is contained in:
commit
20e5fe9da7
1
site/content/examples/homepage-demo-hello-world/App.html
Normal file
1
site/content/examples/homepage-demo-hello-world/App.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>Hello {name}!</h1>
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "world"
|
||||
}
|
11
site/content/examples/homepage-demo-reactivity/App.html
Normal file
11
site/content/examples/homepage-demo-reactivity/App.html
Normal file
@ -0,0 +1,11 @@
|
||||
<script>
|
||||
let count = 0;
|
||||
|
||||
function increment() {
|
||||
count += 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<button on:click={increment}>
|
||||
clicks: {count}
|
||||
</button>
|
@ -0,0 +1 @@
|
||||
{}
|
12
site/content/examples/homepage-demo-scoped-styles/App.html
Normal file
12
site/content/examples/homepage-demo-scoped-styles/App.html
Normal file
@ -0,0 +1,12 @@
|
||||
<script>
|
||||
import Foo from './Foo.html';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
p {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>this <p> is bold but not red</p>
|
||||
<Foo/>
|
@ -0,0 +1,7 @@
|
||||
<style>
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>this <p> is red but not bold</p>
|
@ -0,0 +1 @@
|
||||
{}
|
74
site/content/examples/homepage-demo-transitions/App.html
Normal file
74
site/content/examples/homepage-demo-transitions/App.html
Normal file
@ -0,0 +1,74 @@
|
||||
<script>
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fade, draw, fly } from 'svelte/transition';
|
||||
import { expand, blur } from './custom-transitions.js';
|
||||
import { inner, outer } from './shape.js';
|
||||
|
||||
let visible = true;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
path {
|
||||
fill: white;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
label {
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
left: 1em;
|
||||
}
|
||||
|
||||
.centered {
|
||||
font-size: 20vw;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
font-family: 'Overpass';
|
||||
letter-spacing: 0.12em;
|
||||
color: #676778;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.centered span {
|
||||
will-change: filter;
|
||||
}
|
||||
</style>
|
||||
|
||||
{#if visible}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
|
||||
<g out:fade="{{duration: 200}}" opacity=0.2>
|
||||
<path
|
||||
in:expand="{{duration: 400, delay: 1000, easing: quintOut}}"
|
||||
style="stroke: #ff3e00; fill: #ff3e00; stroke-width: 50;"
|
||||
d={outer}
|
||||
/>
|
||||
<path
|
||||
in:draw="{{duration: 1000}}"
|
||||
style="stroke:#ff3e00; stroke-width: 1.5"
|
||||
d={inner}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div class="centered" out:fly="{{y: -20, duration: 800}}">
|
||||
{#each 'SVELTE' as char, i}
|
||||
<span
|
||||
in:blur="{{delay: 1000 + i * 150, duration: 800}}"
|
||||
>{char}</span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<label>
|
||||
<input type="checkbox" bind:checked={visible}>
|
||||
toggle me
|
||||
</label>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Overpass:100" rel="stylesheet">
|
@ -0,0 +1,34 @@
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
|
||||
export function expand(node, params) {
|
||||
const {
|
||||
delay = 0,
|
||||
duration = 400,
|
||||
easing = cubicOut
|
||||
} = params;
|
||||
|
||||
const w = parseFloat(getComputedStyle(node).strokeWidth);
|
||||
|
||||
return {
|
||||
delay,
|
||||
duration,
|
||||
easing,
|
||||
css: t => `opacity: ${t}; stroke-width: ${t * w}`
|
||||
};
|
||||
}
|
||||
|
||||
export function blur(node, params) {
|
||||
const {
|
||||
b = 10,
|
||||
delay = 0,
|
||||
duration = 400,
|
||||
easing = cubicOut
|
||||
} = params;
|
||||
|
||||
return {
|
||||
delay,
|
||||
duration,
|
||||
easing,
|
||||
css: (t, u) => `opacity: ${t}; filter: blur(${u * b}px);`
|
||||
};
|
||||
}
|
@ -0,0 +1 @@
|
||||
{}
|
5
site/content/examples/homepage-demo-transitions/shape.js
Normal file
5
site/content/examples/homepage-demo-transitions/shape.js
Normal file
@ -0,0 +1,5 @@
|
||||
export const inner = `M45.41,108.86A21.81,21.81,0,0,1,22,100.18,20.2,20.2,0,0,1,18.53,84.9a19,19,0,0,1,.65-2.57l.52-1.58,1.41,1a35.32,35.32,0,0,0,10.75,5.37l1,.31-.1,1a6.2,6.2,0,0,0,1.11,4.08A6.57,6.57,0,0,0,41,95.19a6,6,0,0,0,1.68-.74L70.11,76.94a5.76,5.76,0,0,0,2.59-3.83,6.09,6.09,0,0,0-1-4.6,6.58,6.58,0,0,0-7.06-2.62,6.21,6.21,0,0,0-1.69.74L52.43,73.31a19.88,19.88,0,0,1-5.58,2.45,21.82,21.82,0,0,1-23.43-8.68A20.2,20.2,0,0,1,20,51.8a19,19,0,0,1,8.56-12.7L56,21.59a19.88,19.88,0,0,1,5.58-2.45A21.81,21.81,0,0,1,85,27.82,20.2,20.2,0,0,1,88.47,43.1a19,19,0,0,1-.65,2.57l-.52,1.58-1.41-1a35.32,35.32,0,0,0-10.75-5.37l-1-.31.1-1a6.2,6.2,0,0,0-1.11-4.08,6.57,6.57,0,0,0-7.06-2.62,6,6,0,0,0-1.68.74L36.89,51.06a5.71,5.71,0,0,0-2.58,3.83,6,6,0,0,0,1,4.6,6.58,6.58,0,0,0,7.06,2.62,6.21,6.21,0,0,0,1.69-.74l10.48-6.68a19.88,19.88,0,0,1,5.58-2.45,21.82,21.82,0,0,1,23.43,8.68A20.2,20.2,0,0,1,87,76.2a19,19,0,0,1-8.56,12.7L51,106.41a19.88,19.88,0,0,1-5.58,2.45`;
|
||||
|
||||
export const outer = `
|
||||
M65,34 L37,52 A1 1 0 0 0 44 60 L70.5,44.5 A1 1 0 0 0 65,34Z
|
||||
M64,67 L36,85 A1 1 0 0 0 42 94 L68,77.5 A1 1 0 0 0 64,67Z`;
|
@ -57,7 +57,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
width: 100vw;
|
||||
height: var(--nav-h);
|
||||
padding: 0 var(--side-nav);
|
||||
margin: 0 auto;
|
||||
@ -162,7 +162,7 @@
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
width: 100vw;
|
||||
height: var(--nav-h);
|
||||
padding: 0 var(--side-nav) 0 var(--side-nav);
|
||||
display: flex;
|
||||
|
@ -3,10 +3,14 @@
|
||||
import Nav from '../components/TopNav.html';
|
||||
|
||||
export let child;
|
||||
export let path;
|
||||
</script>
|
||||
|
||||
<InlineSvg />
|
||||
<Nav segment={child.segment} />
|
||||
{#if path !== '/repl/embed'}
|
||||
<Nav segment={child.segment} />
|
||||
{/if}
|
||||
|
||||
<main>
|
||||
<svelte:component this={child.component} {...child.props} />
|
||||
</main>
|
||||
@ -15,7 +19,7 @@
|
||||
main {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding: var(--nav-h) 0 0 0;
|
||||
padding: var(--nav-h) var(--side-nav) 0 var(--side-nav);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
@ -53,22 +53,21 @@ function createExample(slug) {
|
||||
export function get(req, res) {
|
||||
const { slug } = req.params;
|
||||
|
||||
if (!slugs.has(slug)) {
|
||||
try {
|
||||
if (!lookup.has(slug) || process.env.NODE_ENV !== 'production') {
|
||||
lookup.set(slug, createExample(slug));
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(lookup.get(slug));
|
||||
} catch (err) {
|
||||
res.writeHead(404, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(JSON.stringify({ error: 'not found' }));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lookup.has(slug) || process.env.NODE_ENV !== 'production') {
|
||||
lookup.set(slug, createExample(slug));
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
res.end(lookup.get(slug));
|
||||
}
|
@ -77,15 +77,6 @@
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* .post:first-child .byline::after {
|
||||
content: 'Latest post';
|
||||
font-weight: 700;
|
||||
color: var(--second);
|
||||
text-transform: uppercase;
|
||||
margin-left: 1em;
|
||||
} */
|
||||
|
||||
|
||||
.post p {
|
||||
font-size: var(--h5);
|
||||
max-width: 30em;
|
||||
@ -103,21 +94,4 @@
|
||||
.posts a:hover > h2 {
|
||||
color: var(--flash)
|
||||
}
|
||||
|
||||
.byline {
|
||||
/* width: 100%; */
|
||||
padding: 1.6rem 0 0 0;
|
||||
/* border-bottom: 1px solid var(--second); */
|
||||
font: 300 var(--code-fs)/1.7 var(--font-mono);
|
||||
}
|
||||
|
||||
time {
|
||||
/* border-bottom: 1px solid var(--second); */
|
||||
}
|
||||
|
||||
.byline a {
|
||||
color: var(--second);
|
||||
}
|
||||
|
||||
.byline a:hover { color: var(--flash) }
|
||||
</style>
|
@ -8,7 +8,8 @@
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
margin: 10rem var(--side-page);
|
||||
margin: 10rem auto;
|
||||
max-width: 120rem;
|
||||
}
|
||||
|
||||
.container ul {
|
||||
@ -57,15 +58,6 @@
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.learn-btn {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.legend { padding-top: 4rem }
|
||||
|
||||
.box {
|
||||
padding: 2em;
|
||||
display: flex;
|
||||
@ -129,8 +121,6 @@
|
||||
height: 420px;
|
||||
border: none;
|
||||
border-radius: var(--border-r);
|
||||
font: 300 1rem/1.4 var(--font-mono);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 920px) {
|
||||
@ -168,7 +158,7 @@
|
||||
<ul class='grid stretch'>
|
||||
<li class='box bg-prime white'>
|
||||
<h2 style='padding:2.4rem 0 0 0'>Write less code</h2>
|
||||
<p>Write boilerplate-free components using languages you already know — HTML, CSS and JavaScript</p>
|
||||
<p>Build boilerplate-free components using languages you already know — HTML, CSS and JavaScript</p>
|
||||
|
||||
<a href="TODO-blog-post-on-loc">learn more</a>
|
||||
</li>
|
||||
@ -189,11 +179,13 @@
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="container grid half">
|
||||
<section class="container grid half linkify">
|
||||
<div>
|
||||
<p>Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the <em>browser</em>, Svelte shifts that work into a <em>compile step</em> that happens when you build your app.</p>
|
||||
|
||||
<p>Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.</p>
|
||||
|
||||
<p><a href="TODO-svelte-3-blog-post">Read the introductory blog post</a> to learn more.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -22,7 +22,8 @@
|
||||
.user {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0em 3.2rem 0 1.6rem;
|
||||
padding: 0em 1.2rem 0 1.6rem;
|
||||
height: 0.8em;
|
||||
line-height: 1;
|
||||
z-index: 99;
|
||||
}
|
||||
@ -40,7 +41,7 @@
|
||||
span {
|
||||
/* position: relative; padding: 0 2em 0 0; */
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
display: none;
|
||||
font-family: var(--font-ui);
|
||||
font-size: 1.3rem;
|
||||
opacity: 0.7;
|
||||
@ -54,17 +55,18 @@
|
||||
position: absolute;
|
||||
top: -0.05em;
|
||||
right: 0;
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
width: 2.1rem;
|
||||
height: 2.1rem;
|
||||
border: 1px solid rgba(255,255,255,0.3);
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
width: calc(100% - 0rem);
|
||||
width: calc(100% + 1.6rem);
|
||||
min-width: 6em;
|
||||
top: 3rem;
|
||||
left: 0rem;
|
||||
right: -1.6rem;
|
||||
background-color: var(--second);
|
||||
padding: 0.8rem 1.6rem;
|
||||
z-index: 99;
|
||||
@ -82,4 +84,19 @@
|
||||
.menu button:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.user {
|
||||
padding: 0em 3.2rem 0 1.6rem;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -276,7 +276,7 @@ export default app;` });
|
||||
{:else}
|
||||
<button class="icon" on:click={login}>
|
||||
<Icon name="log-in" />
|
||||
Log in to save
|
||||
<span> Log in to save</span>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@ -307,6 +307,8 @@ export default app;` });
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: relative;
|
||||
top: -0.1rem;
|
||||
display: inline-block;
|
||||
padding: 0.2em;
|
||||
opacity: .7;
|
||||
@ -338,8 +340,15 @@ export default app;` });
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.icon[title^='fullscreen'] { display: inline }
|
||||
button span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.icon[title^='fullscreen'] { display: inline }
|
||||
|
||||
button span {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
export let mode;
|
||||
export let code;
|
||||
export let readonly;
|
||||
export let error;
|
||||
export let errorLoc;
|
||||
export let readonly = false;
|
||||
export let error = null;
|
||||
export let errorLoc = null;
|
||||
export let warningCount = 0;
|
||||
export let flex = false;
|
||||
export let lineNumbers = true;
|
||||
@ -146,7 +146,10 @@
|
||||
|
||||
<style>
|
||||
.codemirror-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.codemirror-container :global(.CodeMirror) {
|
||||
@ -165,17 +168,6 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.codemirror-container {
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.codemirror-container :global(.CodeMirror) {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.codemirror-container :global(.CodeMirror-gutters) {
|
||||
padding: 0 1.6rem 0 .8rem;
|
||||
border: none;
|
||||
|
@ -168,7 +168,7 @@
|
||||
</style>
|
||||
|
||||
<div class="component-selector">
|
||||
<div class="file-tabs" on:dblclick="{() => dispatch('create')}">
|
||||
<div class="file-tabs" on:dblclick="{addNew}">
|
||||
{#each $component_store as component}
|
||||
<button
|
||||
id={component.name}
|
||||
|
@ -13,7 +13,7 @@
|
||||
background: var(--back-light);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 600px) {
|
||||
.editor-wrapper {
|
||||
/* make it easier to interact with scrollbar */
|
||||
padding-right: 8px;
|
||||
|
77
site/src/routes/repl/_components/InputOutputToggle.html
Normal file
77
site/src/routes/repl/_components/InputOutputToggle.html
Normal file
@ -0,0 +1,77 @@
|
||||
<style>
|
||||
.input-output-toggle {
|
||||
display: grid;
|
||||
position: absolute;
|
||||
user-select: none;
|
||||
grid-template-columns: 1fr 40px 1fr;
|
||||
grid-gap: 0.5em;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 4.2rem;
|
||||
border-top: 1px solid var(--second);
|
||||
}
|
||||
|
||||
input {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 1em;
|
||||
width: calc(100% - 0.6em);
|
||||
top: -2px;
|
||||
border-radius: 0.5em;
|
||||
-webkit-appearance: none;
|
||||
outline: none;
|
||||
margin: 0 0.6em 0 0;
|
||||
}
|
||||
|
||||
input::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 1em;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
background: var(--second);
|
||||
box-sizing: border-box;
|
||||
-webkit-transition: .25s ease-out;
|
||||
padding: 2px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
input:checked::before {
|
||||
background: var(--prime);
|
||||
}
|
||||
|
||||
input::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
border-radius: 1em;
|
||||
background: white;
|
||||
box-shadow: 0 0px 1px rgba(0,0,0,.4), 0 4px 2px rgba(0,0,0,.1);
|
||||
-webkit-transition: .2s ease-out;
|
||||
}
|
||||
|
||||
input:checked::after {
|
||||
left: calc(100% - 9px);
|
||||
}
|
||||
|
||||
span {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #555;
|
||||
}
|
||||
</style>
|
||||
|
||||
<label class="input-output-toggle">
|
||||
<span class:active={!checked} style="text-align: right">input</span>
|
||||
<input type="checkbox" bind:checked>
|
||||
<span class:active={checked}>output</span>
|
||||
</label>
|
@ -297,29 +297,19 @@
|
||||
|
||||
<style>
|
||||
.iframe-container {
|
||||
border-top: 1px solid #ccc;
|
||||
background-color: white;
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: calc(100vh -3em);
|
||||
height: 100%;
|
||||
/* height: calc(100vh - var(--nav-h)); */
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.iframe-container {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
iframe {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.greyed-out {
|
||||
filter: grayscale(50%) blur(1px);
|
||||
opacity: .25;
|
||||
|
@ -13,6 +13,7 @@
|
||||
export let values_store;
|
||||
export let json5;
|
||||
export let sourceError;
|
||||
export let sourceErrorLoc;
|
||||
export let runtimeError;
|
||||
|
||||
// refs
|
||||
@ -37,12 +38,17 @@
|
||||
viewer.setProp(prop, value);
|
||||
updateValues(prop, value);
|
||||
}
|
||||
|
||||
function navigate(event) {
|
||||
// TODO handle navigation from error messages
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.view-toggle {
|
||||
height: var(--pane-controls-h);
|
||||
border-bottom: 1px solid #eee;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
button {
|
||||
@ -108,9 +114,8 @@
|
||||
>CSS output</button>
|
||||
</div>
|
||||
|
||||
|
||||
{#if view === 'result'}
|
||||
<SplitPane type="vertical">
|
||||
<SplitPane type="vertical" pos={67}>
|
||||
<div slot="a">
|
||||
{#if bundle}
|
||||
<Viewer
|
||||
@ -122,7 +127,6 @@
|
||||
{props}
|
||||
{sourceError}
|
||||
bind:error={runtimeError}
|
||||
on:data="{e => updateData(e.detail.current)}"
|
||||
on:navigate={navigate}
|
||||
on:binding="{e => setPropFromViewer(e.detail.prop, e.detail.value)}"
|
||||
/>
|
||||
@ -159,7 +163,7 @@
|
||||
</section>
|
||||
</SplitPane>
|
||||
{:else}
|
||||
<SplitPane type="vertical">
|
||||
<SplitPane type="vertical" pos={67}>
|
||||
<div slot="a">
|
||||
<CodeMirror
|
||||
mode="javascript"
|
||||
|
@ -6,6 +6,7 @@
|
||||
import CodeMirror from './CodeMirror.html';
|
||||
import Input from './Input/index.html';
|
||||
import Output from './Output/index.html';
|
||||
import InputOutputToggle from './InputOutputToggle.html';
|
||||
|
||||
export let version = 'alpha'; // TODO change this to latest when the time comes
|
||||
export let app;
|
||||
@ -55,6 +56,9 @@
|
||||
let sourceErrorLoc;
|
||||
let runtimeErrorLoc;
|
||||
|
||||
let width = typeof window !== 'undefined' ? window.innerWidth : 300;
|
||||
let show_output = false;
|
||||
|
||||
onMount(async () => {
|
||||
workers = {
|
||||
compiler: new Worker('/workers/compiler.js'),
|
||||
@ -64,7 +68,7 @@
|
||||
workers.compiler.postMessage({ type: 'init', version });
|
||||
workers.compiler.onmessage = event => {
|
||||
js = event.data.js;
|
||||
css = event.data.css;
|
||||
css = event.data.css || `/* Add a <style> tag to see compiled CSS */`;
|
||||
if (event.data.props) props = event.data.props;
|
||||
};
|
||||
|
||||
@ -169,7 +173,17 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.repl-inner { height: 100% }
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 4.2rem);
|
||||
}
|
||||
|
||||
.repl-inner {
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.repl-inner :global(section) {
|
||||
position: relative;
|
||||
@ -232,51 +246,63 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.show-if-mobile { display: none }
|
||||
.offset {
|
||||
transform: translate(-50%,0);
|
||||
}
|
||||
|
||||
.repl-outer.zen-mode {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
@media (min-width: 600px) {
|
||||
.container {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
section { height: 100% }
|
||||
.repl-inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-output-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.offset {
|
||||
transition: none;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="repl-inner">
|
||||
<SplitPane type="horizontal">
|
||||
<section slot=a>
|
||||
<Input
|
||||
{component_store}
|
||||
{selected_store}
|
||||
{values_store}
|
||||
error={sourceError}
|
||||
errorLoc="{sourceErrorLoc || runtimeErrorLoc}"
|
||||
{warningCount}
|
||||
on:remove={removeComponent}
|
||||
on:change="{handleChange}"
|
||||
/>
|
||||
</section>
|
||||
<div class="container" bind:clientWidth={width}>
|
||||
<div class="repl-inner" class:offset="{show_output}">
|
||||
<SplitPane type="horizontal" fixed="{600 > width}" pos={60} fixed_pos={50}>
|
||||
<section slot=a>
|
||||
<Input
|
||||
{component_store}
|
||||
{selected_store}
|
||||
{values_store}
|
||||
error={sourceError}
|
||||
errorLoc="{sourceErrorLoc || runtimeErrorLoc}"
|
||||
{warningCount}
|
||||
on:remove={removeComponent}
|
||||
on:change="{handleChange}"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section slot=b style='height: 100%;'>
|
||||
<Output
|
||||
{version}
|
||||
{selected_store}
|
||||
{js}
|
||||
{css}
|
||||
{bundle}
|
||||
{ssr}
|
||||
{dom}
|
||||
{props}
|
||||
{values_store}
|
||||
{sourceError}
|
||||
{runtimeError}
|
||||
/>
|
||||
</section>
|
||||
</SplitPane>
|
||||
</div>
|
||||
<section slot=b style='height: 100%;'>
|
||||
<Output
|
||||
{version}
|
||||
{selected_store}
|
||||
{js}
|
||||
{css}
|
||||
{bundle}
|
||||
{ssr}
|
||||
{dom}
|
||||
{props}
|
||||
{values_store}
|
||||
{sourceError}
|
||||
{runtimeError}
|
||||
/>
|
||||
</section>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<InputOutputToggle bind:checked={show_output}/>
|
@ -5,13 +5,17 @@
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let type;
|
||||
export let pos = 50;
|
||||
export let fixed = false;
|
||||
export let fixed_pos = pos;
|
||||
export let min = 50;
|
||||
// export let min1 = min;
|
||||
// export let min2 = min;
|
||||
|
||||
const refs = {};
|
||||
const side = type === 'horizontal' ? 'left' : 'top';
|
||||
const dimension = type === 'horizontal' ? 'width' : 'height';
|
||||
|
||||
let pos = 50;
|
||||
let dragging = false;
|
||||
|
||||
function setPos(event) {
|
||||
@ -122,45 +126,36 @@
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.pane {
|
||||
/* override divider-set dimensions */
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
.left, .right, .divider {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.left, .right, .divider {
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
.left, .right {
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.top, .bottom {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top { top: 0; }
|
||||
.bottom { bottom: 0; }
|
||||
.left, .right {
|
||||
height: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.top, .bottom {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.top { top: 0; }
|
||||
.bottom { bottom: 0; }
|
||||
</style>
|
||||
|
||||
<div class="container" bind:this={refs.container}>
|
||||
<div class="pane" style="{dimension}: {pos}%;">
|
||||
<div class="pane" style="{dimension}: {fixed ? fixed_pos : pos}%;">
|
||||
<slot name="a"></slot>
|
||||
</div>
|
||||
|
||||
<div class="pane" style="{dimension}: {100 - pos}%;">
|
||||
<div class="pane" style="{dimension}: {100 - (fixed ? fixed_pos : pos)}%;">
|
||||
<slot name="b"></slot>
|
||||
</div>
|
||||
|
||||
<div class="{type} divider" style="{side}: calc({pos}% - 8px)" use:drag={setPos}></div>
|
||||
{#if !fixed}
|
||||
<div class="{type} divider" style="{side}: calc({pos}% - 8px)" use:drag={setPos}></div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if dragging}
|
||||
|
108
site/src/routes/repl/embed.html
Normal file
108
site/src/routes/repl/embed.html
Normal file
@ -0,0 +1,108 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import * as fleece from 'golden-fleece';
|
||||
import Repl from './_components/Repl.html';
|
||||
|
||||
export let query;
|
||||
let version = query.version || 'alpha';
|
||||
|
||||
let app = {
|
||||
components: [],
|
||||
values: {}
|
||||
};
|
||||
|
||||
let name = 'loading...';
|
||||
|
||||
onMount(() => {
|
||||
fetch(`https://unpkg.com/svelte@${version}/package.json`)
|
||||
.then(r => r.json())
|
||||
.then(pkg => {
|
||||
version = pkg.version;
|
||||
});
|
||||
|
||||
if (query.gist) {
|
||||
fetch(`gist/${query.gist}`).then(r => r.json()).then(data => {
|
||||
const { id, description, files } = data;
|
||||
|
||||
name = description;
|
||||
|
||||
let values = {};
|
||||
|
||||
const components = Object.keys(files)
|
||||
.map(file => {
|
||||
const dot = file.lastIndexOf('.');
|
||||
if (!~dot) return;
|
||||
|
||||
const source = files[file].content;
|
||||
|
||||
// while we're here...
|
||||
if (file === 'data.json' || file === 'data.json5') {
|
||||
values = tryParseData(source) || {};
|
||||
}
|
||||
|
||||
return {
|
||||
name: file.slice(0, dot),
|
||||
type: file.slice(dot + 1),
|
||||
source
|
||||
};
|
||||
})
|
||||
.filter(x => x.type === 'html' || x.type === 'js')
|
||||
.sort((a, b) => {
|
||||
if (a.name === 'App' && a.type === 'html') return -1;
|
||||
if (b.name === 'App' && b.type === 'html') return 1;
|
||||
|
||||
if (a.type !== b.type) return a.type === 'html' ? -1 : 1;
|
||||
|
||||
return a.name < b.name ? -1 : 1;
|
||||
});
|
||||
|
||||
app = { components, values };
|
||||
});
|
||||
} else if (query.demo) {
|
||||
const url = `api/examples/${query.demo}`;
|
||||
|
||||
fetch(url).then(async response => {
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
|
||||
app = {
|
||||
values: tryParseData(data.json5) || {}, // TODO make this more error-resistant
|
||||
components: data.components
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function tryParseData(json5) {
|
||||
try {
|
||||
return fleece.evaluate(json5);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.repl-outer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--back);
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
--pane-controls-h: 4.2rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<svelte:head>
|
||||
<title>{name} • Svelte REPL</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="repl-outer">
|
||||
{#if process.browser}
|
||||
<Repl {version} {app}/>
|
||||
{/if}
|
||||
</div>
|
@ -137,35 +137,29 @@
|
||||
<style>
|
||||
.repl-outer {
|
||||
position: relative;
|
||||
min-height: calc(100vh - var(--nav-h));
|
||||
height: calc(100vh - var(--nav-h));
|
||||
--app-controls-h: 5.6rem;
|
||||
--pane-controls-h: 4.2rem;
|
||||
overflow: hidden;
|
||||
background-color: var(--back);
|
||||
padding: var(--app-controls-h) 0 0 0;
|
||||
margin: 0 -0.8rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pane { width: 100%; height: 100% }
|
||||
|
||||
h3 {
|
||||
margin: 4rem 0 0 0;
|
||||
padding: 0 2.4rem .8rem;
|
||||
font-size: 1.3rem;
|
||||
.zen-mode {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.pane { width: 100%; height: 100% }
|
||||
|
||||
@media (min-width: 600px) {
|
||||
.repl-outer {
|
||||
height: calc(100vh - var(--nav-h));
|
||||
background-color: var(--back);
|
||||
overflow: hidden;
|
||||
--app-controls-h: 5.6rem;
|
||||
padding: var(--app-controls-h) 0 0 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.repl-outer.zen-mode {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
margin: 0 -4.8rem; /* can't do calc(0 - var(--side-nav)) */
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -11,7 +11,6 @@ html {
|
||||
-ms-text-size-adjust: 62.5%;
|
||||
-webkit-text-size-adjust: 62.5%;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
overflow-y: scroll;
|
||||
box-sizing: border-box;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
@ -61,7 +60,7 @@ a:focus {
|
||||
--sidebar-w: 24rem;
|
||||
--main-width: 80rem;
|
||||
--code-w: 72em;
|
||||
--side-nav: 4.8rem;
|
||||
--side-nav: .8rem;
|
||||
--side-page: var(--side-nav);
|
||||
|
||||
/* easings */
|
||||
@ -230,16 +229,21 @@ button[outline] {
|
||||
padding: 0 .4rem .1rem;
|
||||
border-bottom: .1rem solid hsla(15, 100%, 50%, 0.5); /* muted --prime */
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
/* white-space: nowrap; */
|
||||
color: inherit;
|
||||
transition: color .2s;
|
||||
transition: color .2s, border .2s, padding .2s;
|
||||
}
|
||||
|
||||
.linkify a:not(.open-in-repl):hover {
|
||||
color: var(--flash);
|
||||
}
|
||||
|
||||
.linkify a:not(.open-in-repl):before {
|
||||
.linkify a:not(.open-in-repl):hover {
|
||||
padding: 0 .4rem 0;
|
||||
border-bottom: .2rem solid hsla(15, 100%, 50%, 1);
|
||||
}
|
||||
|
||||
/* .linkify a:not(.open-in-repl):before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@ -259,7 +263,7 @@ button[outline] {
|
||||
.linkify a:not(.open-in-repl):hover:before {
|
||||
visibility: visible;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
} */
|
||||
|
||||
a:hover > .icon { stroke: var(--flash) }
|
||||
|
||||
@ -386,6 +390,7 @@ table span {
|
||||
:root {
|
||||
--side-page: 14vw;
|
||||
--top-offset: 10rem;
|
||||
--side-nav: 4.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 80 KiB |
1
site/static/svelte-app.json
Normal file
1
site/static/svelte-app.json
Normal file
@ -0,0 +1 @@
|
||||
[]
|
Binary file not shown.
Before Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in New Issue
Block a user