diff --git a/site/content/guide/09-transitions.md b/site/content/guide/09-transitions.md
index 2a51fcaa47..e355bed7cc 100644
--- a/site/content/guide/09-transitions.md
+++ b/site/content/guide/09-transitions.md
@@ -3,14 +3,12 @@ title: Transitions
---
-### Transitions
-
Transitions allow elements to enter and leave the DOM gracefully, rather than suddenly appearing and disappearing.
```html
@@ -21,12 +19,12 @@ Transitions allow elements to enter and leave the DOM gracefully, rather than su
{/if}
```
-Transitions can have parameters — typically `delay` and `duration`, but often others, depending on the transition in question. For example, here's the `fly` transition from the [svelte-transitions](https://github.com/sveltejs/svelte-transitions) package:
+Transitions can have parameters — typically `delay` and `duration`, but often others, depending on the transition in question. For example, here's the `fly` transition:
```html
@@ -37,6 +35,9 @@ Transitions can have parameters — typically `delay` and `duration`, but often
{/if}
```
+
+### In and out
+
An element can have separate `in` and `out` transitions:
```html
@@ -53,7 +54,27 @@ An element can have separate `in` and `out` transitions:
{/if}
```
-Transitions are simple functions that take a `node` and any provided `parameters` and return an object with the following properties:
+
+### Built-in transitions
+
+Svelte comes with a handful of ready-to-use transitions:
+
+```html
+
+
+```
+
+
+### Custom transitions
+
+You can also make your own. Transitions are simple functions that take a `node` and any provided `parameters` and return an object with the following properties:
* `duration` — how long the transition takes in milliseconds
* `delay` — milliseconds before the transition starts
diff --git a/site/src/components/InlineSvg.html b/site/src/components/InlineSvg.html
index e4dc0e232f..9b4c2e3ddb 100644
--- a/site/src/components/InlineSvg.html
+++ b/site/src/components/InlineSvg.html
@@ -104,37 +104,8 @@
-
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/site/src/routes/guide/_GuideContents.html b/site/src/routes/guide/_GuideContents.html
index b19542acf0..d320ff4b93 100644
--- a/site/src/routes/guide/_GuideContents.html
+++ b/site/src/routes/guide/_GuideContents.html
@@ -1,5 +1,5 @@
-
+
diff --git a/site/src/routes/guide/_sections.js b/site/src/routes/guide/_sections.js
index f60cdee42b..fd15fb4571 100644
--- a/site/src/routes/guide/_sections.js
+++ b/site/src/routes/guide/_sections.js
@@ -4,216 +4,245 @@ import * as fleece from 'golden-fleece';
import process_markdown from '../../utils/_process_markdown.js';
import marked from 'marked';
-import prismjs from 'prismjs'; // prism-highlighter – smaller footprint [hljs: 192.5k]
+import Prism from 'prismjs'; // prism-highlighter – smaller footprint [hljs: 192.5k]
require('prismjs/components/prism-bash');
const langs = {
- 'hidden-data': 'json',
- 'html-no-repl': 'html',
+ 'hidden-data': 'json',
+ 'html-no-repl': 'html',
};
// map lang to prism-language-attr
const prismLang = {
- bash: 'bash',
- html: 'markup',
- js: 'javascript',
- css: 'css',
+ bash: 'bash',
+ html: 'markup',
+ js: 'javascript',
+ css: 'css',
};
function btoa(str) {
- return new Buffer(str).toString('base64');
+ return new Buffer(str).toString('base64');
}
const escaped = {
- '"': '"',
- "'": ''',
- '&': '&',
- '<': '<',
- '>': '>',
+ '"': '"',
+ "'": ''',
+ '&': '&',
+ '<': '<',
+ '>': '>',
};
const unescaped = Object.keys(escaped).reduce(
- (unescaped, key) => ((unescaped[escaped[key]] = key), unescaped),
- {},
+ (unescaped, key) => ((unescaped[escaped[key]] = key), unescaped),
+ {}
);
function unescape(str) {
- return String(str).replace(/&.+?;/g, match => unescaped[match] || match);
+ return String(str).replace(/&.+?;/g, match => unescaped[match] || match);
}
-const blockTypes = 'blockquote html heading hr list listitem paragraph table tablerow tablecell'.split(
- ' ',
-);
+const blockTypes = [
+ 'blockquote',
+ 'html',
+ 'heading',
+ 'hr',
+ 'list',
+ 'listitem',
+ 'paragraph',
+ 'table',
+ 'tablerow',
+ 'tablecell'
+];
function extractMeta(line, lang) {
- try {
- if (lang === 'html' && line.startsWith('')) {
- return fleece.evaluate(line.slice(4, -3).trim());
- }
-
- if (
- lang === 'js' ||
- (lang === 'json' && line.startsWith('/*') && line.endsWith('*/'))
- ) {
- return fleece.evaluate(line.slice(2, -2).trim());
- }
- } catch (err) {
- // TODO report these errors, don't just squelch them
- return null;
- }
+ try {
+ if (lang === 'html' && line.startsWith('')) {
+ return fleece.evaluate(line.slice(4, -3).trim());
+ }
+
+ if (
+ lang === 'js' ||
+ (lang === 'json' && line.startsWith('/*') && line.endsWith('*/'))
+ ) {
+ return fleece.evaluate(line.slice(2, -2).trim());
+ }
+ } catch (err) {
+ // TODO report these errors, don't just squelch them
+ return null;
+ }
}
// https://github.com/darkskyapp/string-hash/blob/master/index.js
function getHash(str) {
- let hash = 5381;
- let i = str.length;
+ let hash = 5381;
+ let i = str.length;
- while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
- return (hash >>> 0).toString(36);
+ while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
+ return (hash >>> 0).toString(36);
}
export const demos = new Map();
export default function() {
- return fs
- .readdirSync(`content/guide`)
- .filter(file => file[0] !== '.' && path.extname(file) === '.md')
- .map(file => {
- const markdown = fs.readFileSync(`content/guide/${file}`, 'utf-8');
-
- const { content, metadata } = process_markdown(markdown);
-
- const groups = [];
- let group = null;
- let uid = 1;
-
- const renderer = new marked.Renderer();
-
- renderer.code = (source, lang) => {
- source = source.replace(/^ +/gm, match =>
- match.split(' ').join('\t'),
- );
-
- const lines = source.split('\n');
-
- const meta = extractMeta(lines[0], lang);
-
- let prefix = '';
- let className = 'code-block';
-
- if (lang === 'html' && !group) {
- /* prettier-ignore
- -----------------------------------------------
- edit vedam
- don't know how to access components here
- so i hardcoded icon here
- -----------------------------------------------
- */
- if (!meta || meta.repl !== false) {
- prefix = ` `;
- }
-
- group = { id: uid++, blocks: [] };
- groups.push(group);
- }
-
- if (meta) {
- source = lines.slice(1).join('\n');
- const filename = meta.filename || (lang === 'html' && 'App.html');
- if (filename) {
- prefix = `${prefix} ${filename} `;
- className += ' named';
- }
- }
-
- if (group) group.blocks.push({ meta: meta || {}, lang, source });
-
- if (meta && meta.hidden) return '';
-
- /* prettier-ignore
- -----------------------------------------------
- design-edit vedam
- insert prism-highlighter
- -----------------------------------------------
- */
- let plang = prismLang[lang];
- const highlighted = Prism.highlight(
- source,
- Prism.languages[plang],
- lang,
- );
-
- return ``;
- };
-
- blockTypes.forEach(type => {
- const fn = renderer[type];
- renderer[type] = function() {
- group = null;
- return fn.apply(this, arguments);
- };
- });
-
- const html = marked(content, { renderer });
-
- const hashes = {};
-
- groups.forEach(group => {
- const main = group.blocks[0];
- if (main.meta.repl === false) return;
-
- const hash = getHash(group.blocks.map(block => block.source).join(''));
- hashes[group.id] = hash;
-
- const json5 = group.blocks.find(block => block.lang === 'json');
-
- const title = main.meta.title;
- if (!title) console.error(`Missing title for demo in ${file}`);
-
- demos.set(
- hash,
- JSON.stringify({
- title: title || 'Example from guide',
- components: group.blocks
- .filter(block => block.lang === 'html' || block.lang === 'js')
- .map(block => {
- const [name, type] = (block.meta.filename || '').split('.');
- return {
- name: name || 'App',
- type: type || 'html',
- source: block.source,
- };
- }),
- json5: json5 && json5.source,
- }),
- );
- });
-
- const subsections = [];
- const pattern = /(.+?)<\/h3>/g;
- let match;
-
- while ((match = pattern.exec(html))) {
- const slug = match[1];
- const title = unescape(
- match[2]
- .replace(/<\/?code>/g, '')
- .replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => {
- if ($3) return `.${$1}(...)`;
- if ($2) return `.${$1}()`;
- return `.${$1}`;
- }),
- );
-
- subsections.push({ slug, title });
- }
-
- return {
- html: html.replace(/@@(\d+)/g, (m, id) => hashes[id] || m),
- metadata,
- subsections,
- slug: file.replace(/^\d+-/, '').replace(/\.md$/, ''),
- file,
- };
- });
+ return fs
+ .readdirSync(`content/guide`)
+ .filter(file => file[0] !== '.' && path.extname(file) === '.md')
+ .map(file => {
+ const markdown = fs.readFileSync(`content/guide/${file}`, 'utf-8');
+
+ const { content, metadata } = process_markdown(markdown);
+
+ const subsections = [];
+ const groups = [];
+ let group = null;
+ let uid = 1;
+
+ const renderer = new marked.Renderer();
+
+ renderer.code = (source, lang) => {
+ source = source.replace(/^ +/gm, match =>
+ match.split(' ').join('\t')
+ );
+
+ const lines = source.split('\n');
+
+ const meta = extractMeta(lines[0], lang);
+
+ let prefix = '';
+ let className = 'code-block';
+
+ if (lang === 'html' && !group) {
+ /* prettier-ignore
+ -----------------------------------------------
+ edit vedam
+ don't know how to access components here
+ so i hardcoded icon here
+ -----------------------------------------------
+ */
+ if (!meta || meta.repl !== false) {
+ prefix = ` `;
+ }
+
+ group = { id: uid++, blocks: [] };
+ groups.push(group);
+ }
+
+ if (meta) {
+ source = lines.slice(1).join('\n');
+ const filename = meta.filename || (lang === 'html' && 'App.html');
+ if (filename) {
+ prefix = `${prefix} ${filename} `;
+ className += ' named';
+ }
+ }
+
+ if (group) group.blocks.push({ meta: meta || {}, lang, source });
+
+ if (meta && meta.hidden) return '';
+
+ /* prettier-ignore
+ -----------------------------------------------
+ design-edit vedam
+ insert prism-highlighter
+ -----------------------------------------------
+ */
+ let plang = prismLang[lang];
+ const highlighted = Prism.highlight(
+ source,
+ Prism.languages[plang],
+ lang
+ );
+
+ return ``;
+ };
+
+ const seen = new Set();
+
+ renderer.heading = (text, level, rawtext) => {
+ if (level <= 3) {
+ const slug = rawtext
+ .toLowerCase()
+ .replace(/[^a-zA-Z0-9]+/g, '-')
+ .replace(/^-/, '')
+ .replace(/-$/, '');
+
+ if (seen.has(slug)) throw new Error(`Duplicate slug ${slug}`);
+ seen.add(slug);
+
+ if (level === 3) {
+ const title = unescape(
+ text
+ .replace(/<\/?code>/g, '')
+ .replace(/\.(\w+)(\((.+)?\))?/, (m, $1, $2, $3) => {
+ if ($3) return `.${$1}(...)`;
+ if ($2) return `.${$1}()`;
+ return `.${$1}`;
+ })
+ );
+
+ subsections.push({ slug, title });
+ }
+
+ return `
+
+
+
+ ${text}
+ `;
+ }
+
+ return `${text} `;
+ };
+
+ blockTypes.forEach(type => {
+ const fn = renderer[type];
+ renderer[type] = function() {
+ group = null;
+ return fn.apply(this, arguments);
+ };
+ });
+
+ const html = marked(content, { renderer });
+
+ const hashes = {};
+
+ groups.forEach(group => {
+ const main = group.blocks[0];
+ if (main.meta.repl === false) return;
+
+ const hash = getHash(group.blocks.map(block => block.source).join(''));
+ hashes[group.id] = hash;
+
+ const json5 = group.blocks.find(block => block.lang === 'json');
+
+ const title = main.meta.title;
+ if (!title) console.error(`Missing title for demo in ${file}`);
+
+ demos.set(
+ hash,
+ JSON.stringify({
+ title: title || 'Example from guide',
+ components: group.blocks
+ .filter(block => block.lang === 'html' || block.lang === 'js')
+ .map(block => {
+ const [name, type] = (block.meta.filename || '').split('.');
+ return {
+ name: name || 'App',
+ type: type || 'html',
+ source: block.source,
+ };
+ }),
+ json5: json5 && json5.source,
+ })
+ );
+ });
+
+ return {
+ html: html.replace(/@@(\d+)/g, (m, id) => hashes[id] || m),
+ metadata,
+ subsections,
+ slug: file.replace(/^\d+-/, '').replace(/\.md$/, ''),
+ file,
+ };
+ });
}
diff --git a/site/src/routes/guide/index.html b/site/src/routes/guide/index.html
index 3c7b7c3c8f..7e3b546f06 100644
--- a/site/src/routes/guide/index.html
+++ b/site/src/routes/guide/index.html
@@ -6,7 +6,7 @@