site: add FAQs page (#4823)

pull/4835/head
Antony Jones 5 years ago committed by GitHub
parent ee130793ca
commit 9be3310431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,7 @@
---
question: I'm new to Svelte. Where should I start?
---
We think the best way to get started is playing through the interactive [Tutorial](https://svelte.dev/tutorial). Each step there is mainly focused on one specific aspect and is easy to follow. You'll be editing and running real Svelte components right in your browser.
Five to ten minutes should be enough to get you up and running. An hour and a half should get you through the entire tutorial.

@ -0,0 +1,5 @@
---
question: How can I update my components written in Svelte v2?
---
svelte-upgrade isn't fully working for v2->v3 yet, [but it's close](https://github.com/sveltejs/svelte-upgrade/pull/12).

@ -0,0 +1,7 @@
---
question: Is Svelte v2 still available?
---
New features aren't being added to it, and bugs will probably only be fixed if they are extremely nasty or present some sort of security vulnerability.
The documentation is still available [here](https://v2.svelte.dev/guide).

@ -0,0 +1,5 @@
---
question: How do I do hot module reloading?
---
Use the community plugins for [rollup](https://github.com/rixo/rollup-plugin-svelte-hot) and [webpack](https://github.com/rixo/svelte-loader-hot).

@ -0,0 +1,10 @@
---
question: Are there any video courses?
---
There are no official ones, but here are a couple of third-part ones that we know of.
- [Egghead](https://egghead.io/playlists/getting-started-with-svelte-3-05a8541a)
- [Udemy](https://www.udemy.com/sveltejs-the-complete-guide/)
Note that Udemy very frequently has discounts over 90%.

@ -0,0 +1,5 @@
---
question: Is svelte.dev down?
---
Probably not, but it's possible. If you can't seem to access any `.dev` sites, check out [this SuperUser question and answer](https://superuser.com/q/1413402).

@ -0,0 +1,5 @@
---
question: How can I get VSCode to syntax-highlight my .svelte files?
---
There is an [official VSCode extension for Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), however it is still in the **beta** testing stage, and not all issues have been ironed out.

@ -0,0 +1,5 @@
---
question: What about Typescript support?
---
You need to install a [community supported preprocessor](https://github.com/sveltejs/integrations#preprocessors) such as [svelte-preprocess](https://github.com/kaisermann/svelte-preprocess). Work is ongoing to improve [IDE support](https://github.com/sveltejs/language-tools/issues/83) and build [additional CLI tooling](https://github.com/sveltejs/language-tools/issues/68)

@ -0,0 +1,5 @@
---
question: Does Svelte scale?
---
There will be a blog post about this eventually, but in the meantime, check out [this issue](https://github.com/sveltejs/svelte/issues/2546).

@ -0,0 +1,5 @@
---
question: Is there a UI component library?
---
There are several UI component libraries. Find them under the [code section](https://svelte-community.netlify.com/code) of the Svelte Community website.

@ -0,0 +1,6 @@
---
question: How do I test Svelte apps?
---
We don't have a good answer to this yet, but it is a priority. There are a few approaches that people take when testing, but it generally involves compiling the component and mounting it to something and then performing the tests.
You essentially need to create a bundle for each component you're testing (since svelte is a compiler and not a normal library) and then mount them. You can mount to a JSDOM instance, or you can use Puppeteer if you need a real browser, or you can use a tool like Cypress. There is an example of this in the Sapper starter template.

@ -0,0 +1,13 @@
---
question: Is there a router?
---
You can use any router lib you want. A lot of people use [page.js](https://github.com/visionmedia/page.js). There's also [navaid](https://github.com/lukeed/navaid), which is very similar.
If you prefer a declarative HTML approach, there's [svelte-routing](https://github.com/EmilTholin/svelte-routing).
If you need hash-based routing on the client side, check out [svelte-spa-router](https://github.com/ItalyPaleAle/svelte-spa-router), or [abstract-state-router](https://github.com/TehShrike/abstract-state-router/), a mature router for business software.
For filesystem-based routing, you can take a look at [Routify](https://routify.dev).
For an official solution, there's nothing that's simply a routing library. There is, however, the official [Sapper](https://sapper.svelte.dev/) framework, a Next.js-style application framework built on Svelte, which includes its own filesystem-based routing.

@ -133,44 +133,14 @@
border: 0.8rem solid var(--second); border: 0.8rem solid var(--second);
} }
/* headers anchors */
.post :global(.offset-anchor) {
position: relative;
display: block;
top: calc(-1 * (var(--nav-h) + var(--top-offset) - 1rem));
width: 0;
height: 0;
}
.post :global(.anchor) { .post :global(.anchor) {
position: absolute;
display: block;
background: url(/icons/link.svg) 0 50% no-repeat;
background-size: 1em 1em;
width: 1.4em;
height: 1em;
top: calc((var(--h3) - 24px) / 2); top: calc((var(--h3) - 24px) / 2);
left: -1.4em;
opacity: 0;
transition: opacity 0.2s;
border: none !important; /* TODO get rid of linkify */
} }
.post :global(h2):hover :global(.anchor),
.post :global(h3):hover :global(.anchor),
.post :global(h4):hover :global(.anchor),
.post :global(h5):hover :global(.anchor),
.post :global(h6):hover :global(.anchor) {
opacity: 1;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.post :global(.anchor) { .post :global(.anchor) {
transform: scale(0.6); transform: scale(0.6);
opacity: 1; opacity: 1;
top: calc((1em - 0.6 * 24px) / 2);
left: -1.0em; left: -1.0em;
} }
} }

@ -1,4 +0,0 @@
export function get(req, res) {
res.writeHead(302, { Location: 'https://github.com/sveltejs/svelte/wiki/FAQ' });
res.end();
}

@ -0,0 +1,58 @@
import fs from 'fs';
import path from 'path';
import { extract_frontmatter, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import marked from 'marked';
import { makeSlugProcessor } from '../../utils/slug';
import { highlight } from '../../utils/highlight';
import { SLUG_PRESERVE_UNICODE } from '../../../config';
const makeSlug = makeSlugProcessor(SLUG_PRESERVE_UNICODE);
export default function get_faqs() {
return fs
.readdirSync('content/faq')
.map(file => {
if (path.extname(file) !== '.md') return;
const match = /^([0-9]+)-(.+)\.md$/.exec(file);
if (!match) throw new Error(`Invalid filename '${file}'`);
const [, order, slug] = match;
const markdown = fs.readFileSync(`content/faq/${file}`, 'utf-8');
const { content, metadata } = extract_frontmatter(markdown);
const renderer = new marked.Renderer();
renderer.link = link_renderer;
renderer.code = highlight;
renderer.heading = (text, level, rawtext) => {
const fragment = makeSlug(rawtext);
return `
<h${level}>
<span id="${fragment}" class="offset-anchor"></span>
<a href="faq#${fragment}" class="anchor" aria-hidden="true"></a>
${text}
</h${level}>`;
};
const answer = marked(
content.replace(/^\t+/gm, match => match.split('\t').join(' ')),
{ renderer }
);
const fragment = makeSlug(slug);
return {
fragment,
order,
answer,
metadata
};
})
.sort((a, b) => a.order - b.order);
}

@ -0,0 +1,24 @@
import send from '@polka/send';
import get_faqs from './_faqs.js';
let json;
export function get(req, res) {
if (!json || process.env.NODE_ENV !== 'production') {
const faqs = get_faqs()
.map(faq => {
return {
fragment: faq.fragment,
answer: faq.answer,
metadata: faq.metadata
};
});
json = JSON.stringify(faqs);
}
send(res, 200, json, {
'Content-Type': 'application/json',
'Cache-Control': `max-age=${5 * 60 * 1e3}` // 5 minutes
});
}

@ -0,0 +1,89 @@
<script context="module">
export async function preload() {
const faqs = await this.fetch(`faq.json`).then(r => r.json());
return { faqs };
}
</script>
<script>
const description = "Frequently Asked Questions about Svelte"
export let faqs;
</script>
<svelte:head>
<title>Frequently Asked Questions • Svelte</title>
<meta name="twitter:title" content="Svelte FAQ">
<meta name="twitter:description" content={description}>
<meta name="Description" content={description}>
</svelte:head>
<div class='faqs stretch'>
<h1>Frequently Asked Questions</h1>
{#each faqs as faq}
<article class='faq'>
<h2>
<span id={faq.fragment} class="offset-anchor"></span>
<a class="anchor" rel='prefetch' href='faq#{faq.fragment}' title='{faq.question}'>&nbsp;</a>
{faq.metadata.question}
</h2>
<p>{@html faq.answer}</p>
</article>
{/each}
</div>
<style>
.faqs {
grid-template-columns: 1fr 1fr;
grid-gap: 1em;
min-height: calc(100vh - var(--nav-h));
padding: var(--top-offset) var(--side-nav) 6rem var(--side-nav);
max-width: var(--main-width);
margin: 0 auto;
}
h2 {
display: inline-block;
margin: 3.2rem 0 1rem 0;
color: var(--text);
max-width: 18em;
font-size: var(--h3);
font-weight: 400;
}
.faq:first-child {
margin: 0 0 2rem 0;
padding: 0 0 4rem 0;
border-bottom: var(--border-w) solid #6767785b; /* based on --second */
}
.faq:first-child h2 {
font-size: 4rem;
font-weight: 400;
color: var(--second);
}
.faq p {
font-size: var(--h5);
max-width: 30em;
color: var(--second);
}
:global(.faqs .faq ul) {
margin-left: 3.2rem;
}
.faqs :global(.anchor) {
top: calc((var(--h3) - 24px) / 2);
}
@media (max-width: 768px) {
.faqs :global(.anchor) {
transform: scale(0.6);
opacity: 1;
left: -1.0em;
}
}
</style>

@ -7,6 +7,7 @@
%sapper.base% %sapper.base%
<link href=global.css rel=stylesheet>
<link href=prism.css rel=stylesheet> <link href=prism.css rel=stylesheet>
<link rel='manifest' href='manifest.json'> <link rel='manifest' href='manifest.json'>
<link rel='icon' type='image/png' href='favicon.png'> <link rel='icon' type='image/png' href='favicon.png'>

@ -1,500 +1,31 @@
/* /* headers anchors */
-----------------------------------------------
vars css custom-properties
NOTE .offset-anchor {
- some vars change inside media-queries!
- under normal conditions, there's no need to touch these
-----------------------------------------------
*/
:root {
--nav-h: 6rem;
--top-offset: 6rem;
--sidebar-w: 30rem;
--sidebar-mid-w: 36rem;
--sidebar-large-w: 48rem;
--main-width: 80rem;
--code-w: 72em;
--side-nav: 3.2rem;
--side-page: var(--side-nav);
/* easings */
--in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
--out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
--inout-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
--in-back: cubic-bezier(0.6, -0.28, 0.735, 0.045);
--out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--inout-back: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@media screen and (min-width: 768px) {
:root {
--side-page: 14vw;
--top-offset: 10rem;
--side-nav: 4.8rem;
}
}
/* theme vars */
.theme-default {
--back: #ffffff;
--back-light: #f6fafd;
--back-api: #eff8ff;
--prime: #ff3e00;
--second: #676778;
--flash: #40b3ff;
--heading: var(--second);
--text: #444;
--sidebar-text: rgba(255, 255, 255, .75);
--border-w: .3rem; /* border-width */
--border-r: .4rem; /* border-radius */
}
/* typo vars */
.typo-default {
--unit: .8rem;
--code-fs: 1.3rem;
--h6: 1.4rem;
--h5: 1.6rem;
--h4: 1.8rem; /* default font-size */
--h3: 2.6rem;
--h2: 3rem;
--h1: 3.2rem;
--linemax: 42em; /* max line-length */
--lh: 1.5; /* base line-height */
}
body {
--font: 'Overpass', sans-serif;
--font-mono: 'Fira Mono', monospace;
--font-ui: var(--font-mono);
--font-system: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}
/* fonts ---------------------------------- */
/* overpass-300normal - latin */
@font-face {
font-family: 'Overpass';
font-style: normal;
font-weight: 300;
font-display: fallback;
src:
local('Overpass Light '),
local('Overpass-Light'),
url('fonts/overpass/overpass-latin-300.woff2') format('woff2');
}
/* overpass-600normal - latin */
@font-face {
font-family: 'Overpass';
font-style: normal;
font-weight: 600;
font-display: fallback;
src:
local('Overpass Bold '),
local('Overpass-Bold'),
url('fonts/overpass/overpass-latin-600.woff2') format('woff2');
}
/* fira-mono-400normal - latin */
@font-face {
font-family: 'Fira Mono';
font-style: normal;
font-weight: 400;
font-display: fallback;
src:
local('Fira Mono Regular '),
local('Fira Mono-Regular'),
url('fonts/fira-mono/fira-mono-latin-400.woff2') format('woff2');
}
/* base reset ----------------------------- */
html {
font-size: 62.5%;
-ms-text-size-adjust: 62.5%;
-webkit-text-size-adjust: 62.5%;
-ms-overflow-style: -ms-autohiding-scrollbar;
box-sizing: border-box;
border-collapse: collapse;
}
html,
body,
#sapper {
width: 100%;
height: 100%;
}
* {
box-sizing: inherit;
margin: 0;
padding: 0;
}
/* link reset ----------------------------- */
a {
text-decoration: none;
cursor: pointer;
color: inherit;
}
a:hover, a:active { color: var(--flash) }
a:focus { outline: none }
/*
-----------------------------------------------
global styles
-----------------------------------------------
*/
/* typography ----------------------------- */
body {
font: 300 var(--h4)/var(--lh) var(--font);
background-color: var(--back);
color: var(--text);
/* default spacing of Overpass is a bit too airy */
/* letter-spacing: -.013em; */
}
h1, h2, h3, h4, h5, h6, blockquote {
position: relative; position: relative;
margin: 0;
color: var(--heading);
}
/* h1, h2, h3, h4, h5, h6 { font-weight: 600 } */
h6 { font-size: var(--h6) }
h5 { font-size: var(--h5) }
h4 { font-size: var(--h4) }
h3 { font-size: var(--h3) }
h2 { font-size: var(--h2) }
h1 { font-size: var(--h1) }
h1, h2 {
font-family: var(--font);
line-height: 1.25;
}
h3 { font-weight: 300 }
p, ol, ul {
margin: 0 0 1em 0;
}
.b, b, strong { font-weight: 600 }
tt, code, kbd, samp {
font: 400 var(--code-fs)/1.7 var(--font-mono);
}
code {
position: relative;
border-radius: .3em;
white-space: nowrap;
color: #444;
-webkit-font-smoothing: initial;
}
pre code {
top: 0;
white-space: inherit;
background-color: none;
}
/* sync CodeMirror with prism */
.CodeMirror {
font-size: var(--code-fs) !important;
}
::selection {
background: var(--flash);
color: white;
}
/* opinionated styles --------------------- */
li:not(.white) > h2 {
color: var(--second)
}
blockquote {
position: relative;
margin: 1.6rem 0 2.4rem;
padding: 2rem 2.4rem 1.8rem 2.4rem;
border-radius: var(--border-r);
font-family: var(--font);
max-width: var(--linemax);
}
blockquote p {
font-size: var(--h5);
}
blockquote :last-child {
margin: 0;
}
/* buttons -------------------------------- */
button {
font-family: inherit;
font-size: inherit;
background-color: transparent;
border: none;
color: currentColor;
cursor: pointer;
}
button:focus,
.btn:focus { outline: 0 }
button[disabled],
.btn[disabled],
.btn:hover[disabled] {
opacity: .55;
pointer-events: none;
}
button > svg,
.btn > svg {
position: relative;
top: -.1rem;
width: 2rem !important;
height: 2rem !important;
stroke: currentColor !important;
}
/* reset ------- */
.btn {
--btn-h: 4rem;
--btn-outline: .2rem;
--btn-font: var(--font);
--btn-calc-h: calc(var(--btn-h) - var(--btn-outline) * 2);
--btn-hover: linear-gradient(to top, rgba(0,0,0,.07), rgba(0,0,0,.07));
position: relative;
margin: 0 .8rem .8rem 0;
vertical-align: middle;
white-space: nowrap;
display: inline-block;
zoom: 1;
border: none transparent;
font: var(--h4) var(--btn-font);
border-radius: var(--border-r);
color: currentColor;
cursor: pointer;
}
/* default */
.btn {
line-height: var(--btn-h);
height: var(--btn-h);
padding: 0 1.6rem;
transition: all .1s;
}
.btn:hover {
transform: scale(.98);
mix-blend-mode: multiply;
background-image: var(--btn-hover);
}
/* optional */
.btn[outline] {
line-height: var(--btn-calc-h);
height: var(--btn-calc-h);
border: var(--btn-outline) solid currentColor;
background-color: white;
color: currentColor;
}
/* links ------------------------------------- */
a {
position: relative;
padding: 0 0 1px 0;
border-bottom: 1px solid currentColor;
user-select: none;
color: var(--prime);
transition: color .2s, border .2s, padding .2s;
}
a:hover {
color: var(--flash);
}
a:hover {
padding: 0;
border-bottom: 2px solid currentColor;
}
a.no-underline {
border-bottom: none;
padding: 0;
}
/* a:hover:not(.disabled) > .icon { stroke: var(--flash) } */
/* lists ---------------------------------- */
.listify ol,
.listify ul {
--list-padding: 2.9rem;
list-style: none;
color: currentColor;
margin-left: var(--list-padding);
}
.listify ol > li,
.listify ul > li {
max-width: calc(var(--linemax) - var(--list-padding));
line-height: 1.5;
margin: 0 0 0.4rem 0;
}
.listify ul > li:before {
content: '';
position: absolute;
margin-top: 1.1rem;
margin-left: -1.8rem;
background-color: var(--second);
width: .6rem;
height: .6rem;
border-radius: 2px;
opacity: 0.7;
}
.listify ol { list-style: decimal }
/* tables --------------------------------- */
table {
width: 100%;
font-size: var(--h5);
}
td, th {
text-align: left;
border-bottom: 1px solid #eee;
padding: 0.4rem 0.8rem 0.4rem 0;
}
table code, table span {
white-space: pre;
}
/* grid ----------------------------------- */
.grid, .grid.half {
display: grid;
grid-gap: 2.4rem;
grid-template-columns: 1fr;
align-items: center;
}
.grid.stretch { align-items: stretch }
.grid > .cols-2,
.grid > .cols-3 { grid-column: span 1 }
@media screen and (min-width: 840px) {
.grid.half,
.grid { grid-template-columns: repeat(2, 1fr) }
.grid > .cols-2,
.grid > .cols-3 { grid-column: span 2 }
}
@media screen and (min-width: 1100px) {
.grid { grid-template-columns: repeat(3, 1fr) }
.grid > .cols-2 { grid-column: span 2 }
.grid > .cols-3 { grid-column: span 3 }
}
/* helper styles -------------------------- */
.flex-auto { flex: 1 0 auto }
.py0 {
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.legend, figcaption, .post aside {
max-width: none;
margin: 0 auto;
padding: 1.6rem 0 0 .8rem;
font: 1.2rem/1.6 var(--font-ui);
}
.filename {
display: inline-block;
padding: 1.6rem 0 0 1rem;
font: var(--h6) var(--font-ui);
}
.box {
padding: 2.4rem 3.2rem;
border-radius: var(--border-r);
}
/* theme colors --------------------------- */
.prime { color: var(--prime) !important }
.second { color: var(--second) !important }
.flash { color: var(--flash) !important }
.black { color: black !important }
.white { color: white !important }
.back { background-color: var(--back) !important }
.back-light { background-color: var(--back-light) !important }
.bg-prime { background-color: var(--prime) !important }
.bg-second { background-color: var(--second) !important }
.bg-flash { background-color: var(--flash) !important }
/* inputs --------------------------------- */
input[type="checkbox"] {
/* display: block; */
position: relative;
height: 1em;
width: calc(100% - 0.6em);
max-width: 2em;
top: -2px;
border-radius: 0.5em;
-webkit-appearance: none;
outline: none;
margin: 0 0.6em 0 0;
}
input[type="checkbox"]::before {
content: "";
position: absolute;
display: block; display: block;
height: 100%; top: calc(-1 * (var(--nav-h) + var(--top-offset)) + 11rem);
width: 100%; width: 0;
padding: 2px; height: 0;
border-radius: 1em;
top: 0;
left: 0;
background: var(--second);
/* box-sizing: border-box; */
box-sizing: content-box;
} }
input[type="checkbox"]:checked::before { .anchor {
background: var(--prime);
}
input[type="checkbox"]::after {
content: "";
position: absolute; position: absolute;
display: block; display: block;
background: url(/icons/link.svg) 0 50% no-repeat;
background-size: 1em 1em;
width: 1.4em;
height: 1em; height: 1em;
width: 1em; top: calc(((var(--h3) - 24px) / 2) + 0.6em);
top: 2px; left: -1.4em;
left: 2px; opacity: 0;
border-radius: 1em; transition: opacity 0.2s;
background: white; border: none !important; /* TODO get rid of linkify */
box-shadow: 0 0px 1px rgba(0,0,0,.4), 0 4px 2px rgba(0,0,0,.1); }
-webkit-transition: background .2s ease-out, left .2s ease-out;
} h2:hover .anchor,
h3:hover .anchor,
input[type="checkbox"]:checked::after { h4:hover .anchor,
left: calc(100% - 9px); h5:hover .anchor,
h6:hover .anchor {
opacity: 1;
} }

Loading…
Cancel
Save