docs: svelte 5 structure wip

svelte-5-docs-proposal-wip
Simon Holthausen 7 months ago
parent c9c4b9d50b
commit 2dc2085d0d

@ -0,0 +1,108 @@
export async function load({ url }) {
if (url.pathname === '/docs') {
return {
sections: []
};
}
const { get_docs_data, get_docs_list } = await import('../docs/render.js');
const sections = get_docs_list(await get_docs_data('./src/routes/docs-new/content', 'docs-new'));
sections.push(
{
title: 'Reference - Runes',
pages: [
{ title: '$state' },
{ title: '$derived' },
{ title: '$effect' },
{ title: '$props' },
{ title: '$inspect' },
{ title: '$host' }
]
},
{
title: 'Reference - Imports',
pages: [
{ title: 'svelte' },
{ title: 'svelte/reactivity' },
{ title: 'svelte/server' },
{ title: `svelte/elements` },
{ title: `svelte/store` },
{ title: `svelte/actions` },
{ title: `svelte/transition` },
{ title: `svelte/animate` },
{ title: `svelte/motion` },
{ title: `svelte/easing` },
{ title: `svelte/compiler` }
]
},
{
title: 'Reference - Other',
pages: [{ title: 'Warnings' }, { title: 'Errors' }]
}
);
return {
sections
// sections: /** @type {Array<{title: string; pages: Array<{title: string }>}>} */ ([
// { title: 'Introduction', pages: [{ title: 'Overview' }, { title: 'Getting started' }] },
// {
// title: 'Template syntax',
// pages: [
// { title: 'Component fundamentals' },
// { title: 'Basic markup' },
// { title: 'Control flow' },
// { title: 'Snippets' },
// { title: 'Styles & Classes' },
// { title: 'Transitions & Animations' },
// { title: 'Bindings' },
// { title: 'Actions' },
// { title: 'Special elements' }
// ]
// },
// {
// title: 'Runes',
// pages: [{ title: 'State' }, { title: 'Side effects' }]
// },
// {
// title: 'Runtime',
// pages: [
// { title: 'Stores' },
// { title: 'Context' },
// { title: 'Lifecycle hooks' },
// { title: 'Imperative component API' }
// ]
// },
// {
// title: 'Misc',
// pages: [
// { title: 'Debugging' },
// { title: 'Testing' },
// { title: 'TypeScript' },
// { title: 'Custom elements API' },
// { title: 'Legacy syntax' },
// { title: 'Reactivity indepth' },
// { title: 'Svelte 5 migration guide' }
// ]
// },
// // {
// // title: 'Reference',
// // pages: [
// // { title: 'Runes' },
// // { title: 'svelte' },
// // { title: 'svelte/reactivity' },
// // { title: 'svelte/server' },
// // { title: `svelte/elements` },
// // { title: `svelte/store` },
// // { title: `svelte/actions` },
// // { title: `svelte/transition` },
// // { title: `svelte/animate` },
// // { title: `svelte/motion` },
// // { title: `svelte/easing` },
// // { title: `svelte/compiler` },
// // { title: 'Warnings' }
// // ]
// // },
// ])
};
}

@ -0,0 +1,111 @@
<script>
import { page } from '$app/stores';
import { DocsContents } from '@sveltejs/site-kit/docs';
export let data;
$: pageData = $page.data.page;
$: title = pageData?.title;
$: category = pageData?.category;
console.log(data.sections);
</script>
<div class="container">
<div class="toc-container" style="order: 1">
<DocsContents contents={data.sections} />
</div>
<div class="page content">
{#if category}
<p class="category">{category}</p>
{/if}
{#if title}
<h1>{title}</h1>
{/if}
<slot />
</div>
</div>
<style>
.container {
--sidebar-menu-width: 28rem;
--sidebar-width: var(--sidebar-menu-width);
--ts-toggle-height: 4.2rem;
display: flex;
flex-direction: column;
}
.page {
padding: var(--sk-page-padding-top) var(--sk-page-padding-side);
min-width: 0 !important;
}
.page :global(:where(h2, h3) code) {
all: unset;
}
.category {
font: 700 var(--sk-text-s) var(--sk-font);
text-transform: uppercase;
letter-spacing: 0.12em;
margin: 0 0 0.5em;
color: var(--sk-text-3);
}
@media (min-width: 832px) {
.content {
padding-left: calc(var(--sidebar-width) + var(--sk-page-padding-side));
}
}
.toc-container {
background: var(--sk-back-3);
display: none;
}
@media (min-width: 832px) {
.toc-container {
display: block;
width: var(--sidebar-width);
height: calc(100vh - var(--sk-nav-height));
position: fixed;
left: 0;
top: var(--sk-nav-height);
overflow-x: hidden;
overflow-y: auto;
}
.toc-container::before {
content: '';
position: fixed;
width: 0;
height: 100%;
top: 0;
left: calc(var(--sidebar-width) - 1px);
border-right: 1px solid var(--sk-back-5);
}
.page {
padding-left: calc(var(--sidebar-width) + var(--sk-page-padding-side));
}
}
@media (min-width: 1200px) {
.container {
--sidebar-width: max(28rem, 23vw);
flex-direction: row;
}
.page {
--on-this-page-display: block;
padding: var(--sk-page-padding-top) calc(var(--sidebar-width) + var(--sk-page-padding-side));
margin: 0 auto;
max-width: var(--sk-line-max-width);
box-sizing: content-box;
}
}
</style>

@ -0,0 +1,5 @@
import { redirect } from '@sveltejs/kit';
export function load() {
redirect(307, '/docs-new/overview');
}

@ -0,0 +1,19 @@
import { error } from '@sveltejs/kit';
export async function entries() {
const { get_docs_data } = await import('../../docs/render.js');
const data = await get_docs_data('./src/routes/docs-new/content', 'docs-new');
return data[0].pages.map((page) => ({ slug: page.slug }));
}
export async function load({ params }) {
const { get_docs_data, get_parsed_docs } = await import('../../docs/render.js');
const data = await get_docs_data('./src/routes/docs-new/content', 'docs-new');
const processed_page = await get_parsed_docs(data, params.slug);
if (!processed_page) error(404);
return { page: processed_page };
}

@ -0,0 +1,76 @@
<script>
import { page } from '$app/stores';
import { copy_code_descendants } from '@sveltejs/site-kit/actions';
import { DocsOnThisPage, setupDocsHovers } from '@sveltejs/site-kit/docs';
export let data;
$: pages = data.sections.flatMap((section) => section.pages);
$: index = pages.findIndex(({ path }) => path === $page.url.pathname);
$: prev = pages[index - 1];
$: next = pages[index + 1];
setupDocsHovers();
</script>
<svelte:head>
<title>{data.page?.title} • Docs • Svelte 5 preview</title>
<meta name="twitter:title" content="{data.page.title} • Docs • Svelte 5 preview" />
<meta name="twitter:description" content="{data.page.title} • Svelte 5 preview documentation" />
<meta name="Description" content="{data.page.title} • Svelte 5 preview documentation" />
</svelte:head>
<div class="text" id="docs-content" use:copy_code_descendants>
<DocsOnThisPage details={data.page} />
{@html data.page.content}
</div>
<div class="controls">
<div>
<span class:faded={!prev}>previous</span>
{#if prev}
<a href={prev.path}>{prev.title}</a>
{/if}
</div>
<div>
<span class:faded={!next}>next</span>
{#if next}
<a href={next.path}>{next.title}</a>
{/if}
</div>
</div>
<style>
.controls {
max-width: calc(var(--sk-line-max-width) + 1rem);
border-top: 1px solid var(--sk-back-4);
padding: 1rem 0 0 0;
display: grid;
grid-template-columns: 1fr 1fr;
margin: 6rem 0 0 0;
}
.controls > :first-child {
text-align: left;
}
.controls > :last-child {
text-align: right;
}
.controls span {
display: block;
font-size: 1.2rem;
text-transform: uppercase;
font-weight: 600;
color: var(--sk-text-3);
}
.controls span.faded {
opacity: 0.4;
}
</style>

@ -0,0 +1,7 @@
---
title: Overview
---
- Short intro to what Svelte is and why it's the best ever
- A few code examples to have a very rough understanding of how Svelte code looks like
- Jump off points to tutorial, SvelteKit etc

@ -0,0 +1,8 @@
---
title: Getting started
---
- `npm create svelte@latest`, describe that it scaffolds SvelteKit project
- `npm create vite@latest`, describe that it scaffolds Svelte SPA powered by Vite
- mention `svelte-add`
- Jump off points to tutorial, SvelteKit etc

@ -0,0 +1,6 @@
---
title: Component fundamentals
---
- script (module) / template / style (rough overview)
- `$props` / `$state` (in the context of components)

@ -0,0 +1,5 @@
---
title: Basic markup
---
- [basically what we have in the Svelte docs today](https://svelte.dev/docs/basic-markup)

@ -0,0 +1,8 @@
---
title: Control flow
---
- if
- each
- await (or move that into some kind of data loading section?)
- NOT: key (move into transition section, because that's the common use case)

@ -0,0 +1,10 @@
---
title: Snippets
---
Better title needed?
- `#snippet`
- `@render`
- how they can be used to reuse markup
- how they can be used to pass UI content to components

@ -0,0 +1,9 @@
---
title: Styles & Classes
---
- style scoping
- `:global`
- `style:`
- `class:`
- `--css` props

@ -0,0 +1,10 @@
---
title: Transitions & Animations
---
- how to use (template syntax)
- when to use
- global vs local
- easing & motion
- mention imports
- key block

@ -0,0 +1,7 @@
---
title: Actions
---
- template syntax
- how to write
- typings

@ -0,0 +1,7 @@
---
title: Bindings
---
- how for dom elements
- list of all bindings
- how for components

@ -0,0 +1,5 @@
---
title: Special elements
---
- [basically what we have in the docs today](https://svelte.dev/docs/special-elements)

@ -0,0 +1,9 @@
---
title: State
---
- `$state` (.frozen)
- `$derived` (.by)
- using classes
- getters/setters (what to do to keep reactivity "alive")
- universal reactivity

@ -0,0 +1,6 @@
---
title: Side effects
---
- `$effect` (.pre)
- when not to use it, better patterns for what to do instead

@ -0,0 +1,6 @@
---
title: Stores
---
- how to use
- how to write

@ -0,0 +1,6 @@
---
title: Context
---
- get/set/hasContext
- how to use, best practises (like encapsulating them)

@ -0,0 +1,8 @@
---
title: Lifecycle hooks
---
- onMount/onDestroy
- mention that `$effect` might be better for your use case
- beforeUpdate/afterUpdate with deprecation notice?
- or skip this entirely and only have it in the reference docs?

@ -0,0 +1,11 @@
---
title: Imperative component API
---
better title needed?
- mount
- unmount
- render
- hydrate
- how they interact with each other

@ -0,0 +1,6 @@
---
title: Debugging
---
- `@debug`
- `$inspect`

@ -0,0 +1,8 @@
---
title: Testing
---
- component testing basics
- rune testing basics
- vitest setup
- e2e

@ -0,0 +1,9 @@
---
title: TypeScript
---
- [basically what we have today](https://svelte.dev/docs/typescript)
- built-in support, but only for type-only features
- generics
- using `Component` and the other helper types
- using `svelte-check`

@ -0,0 +1,5 @@
---
title: Custom elements API
---
- [basically what we have today](https://svelte.dev/docs/custom-elements-api)

@ -0,0 +1,6 @@
---
title: Reactivity indepth
---
- how to think about Runes ("just JavaScript" with added reactivity, what this means for keeping reactivity alive across boundaries)
- signals

@ -0,0 +1,5 @@
---
title: Svelte 5 migration guide
---
- the stuff from the preview docs and possibly more

@ -28,7 +28,7 @@ export async function get_parsed_docs(docs_data, slug) {
}
/** @return {Promise<import('./types').DocsData>} */
export async function get_docs_data(base = './src/routes/docs/content') {
export async function get_docs_data(base = './src/routes/docs/content', path = '/docs') {
const { readdir, readFile } = await import('node:fs/promises');
/** @type {import('./types').DocsData} */
@ -76,7 +76,7 @@ export async function get_docs_data(base = './src/routes/docs/content') {
content: page_content,
category: category_title,
sections: await get_sections(page_content),
path: `${app_base}/docs/${page_slug}`,
path: `${app_base}/${path}/${page_slug}`,
file: `${category_dir}/${filename}`
});
}

Loading…
Cancel
Save