mirror of
https://github.com/danbulant/design
synced 2026-05-19 04:08:46 +00:00
update sveltekit
This commit is contained in:
parent
14de7c0332
commit
6503b9978b
24 changed files with 552 additions and 422 deletions
|
|
@ -2,14 +2,14 @@
|
|||
"name": "design",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "svelte-kit dev",
|
||||
"dev": "vite dev",
|
||||
"build": "svelte-kit build",
|
||||
"package": "svelte-kit package",
|
||||
"preview": "svelte-kit preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-static": "1.0.0-next.28",
|
||||
"@sveltejs/kit": "1.0.0-next.291",
|
||||
"@sveltejs/kit": "1.0.0-next.431",
|
||||
"mdsvex": "0.10.5",
|
||||
"svelte": "3.46.4",
|
||||
"vite-plugin-windicss": "^1.8.6"
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
"remark-parse": "10.0.1",
|
||||
"remark-twemoji": "0.1.1",
|
||||
"twemoji": "13.1.0",
|
||||
"vite": "^3.0.9",
|
||||
"xterm": "4.18.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
769
pnpm-lock.yaml
769
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
10
src/app.html
10
src/app.html
|
|
@ -3,13 +3,13 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script data-goatcounter="https://danbulant.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>
|
||||
<link rel="icon" href="%svelte.assets%/favicon.png" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="%svelte.assets%/prism/dark.css" />
|
||||
<link rel="stylesheet" href="%svelte.assets%/global.css" />
|
||||
%svelte.head%
|
||||
<link rel="stylesheet" href="%sveltekit.assets%/prism/dark.css" />
|
||||
<link rel="stylesheet" href="%sveltekit.assets%/global.css" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body>
|
||||
<div id="svelte">%svelte.body%</div>
|
||||
<div id="svelte">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
import { DateTime } from "luxon";
|
||||
|
||||
export var value;
|
||||
var dt = DateTime.fromISO(value);
|
||||
$: dt = DateTime.fromISO(value);
|
||||
</script>
|
||||
|
||||
<code title={DateTime.fromISO(value).toRelative()}>{value}</code>
|
||||
<time datetime={dt.toISOWeekDate()} title={dt.toRelative()}>{dt.toLocaleString()}</time>
|
||||
15
src/lib/components/posts/callout.svelte
Normal file
15
src/lib/components/posts/callout.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
export var color;
|
||||
</script>
|
||||
|
||||
<!-- A simple callout with header and slot body. Header background colored according to color, and the whole callout has a left border colored as well. -->
|
||||
<div class="w-full rounded border-l border-l-4 my-2" style="border-left-color: {color}">
|
||||
<div class="rounded-tr-lg p-4" style="background-color: {color}40">
|
||||
<h1 class="text-big text-white p-0 m-0">
|
||||
<slot name="title"/>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="rounded-br-lg p-4 bg-gray-500/10">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,38 +1,28 @@
|
|||
<script context="module">
|
||||
/** @type {import('@sveltejs/kit').Load} */
|
||||
export async function load({ error, status }) {
|
||||
let response;
|
||||
try {
|
||||
response = await fetch("/api/posts.json");
|
||||
} catch(e) {}
|
||||
return {
|
||||
props: {
|
||||
status,
|
||||
error,
|
||||
posts: response && response.ok && (await response.json())
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { page } from '$app/stores';
|
||||
import { dev } from '$app/env';
|
||||
import Button from "$lib/components/button.svelte";
|
||||
import HeroPost from "$lib/components/heroPost.svelte";
|
||||
import Post from "$lib/components/post.svelte";
|
||||
|
||||
export let status;
|
||||
export let error;
|
||||
export let posts;
|
||||
let currentHover;
|
||||
|
||||
console.error(error);
|
||||
console.error($page.error);
|
||||
|
||||
function loadPosts() {
|
||||
let posts = fetch("/api/posts.json").then(t => t.json()).catch(t => []);
|
||||
return posts;
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1 class="text-center">
|
||||
{#if status == 404}
|
||||
{#if $page.status == 404}
|
||||
404 - Page Not Found
|
||||
{:else}
|
||||
{status} - {error.message}
|
||||
{$page.status} - {$page.error.message}
|
||||
{#if dev}
|
||||
<pre><code>{$page.error.stack}</code></pre>
|
||||
{/if}
|
||||
{/if}
|
||||
</h1>
|
||||
|
||||
|
|
@ -43,6 +33,8 @@
|
|||
<Button href="/">Go to my home page</Button>
|
||||
</div>
|
||||
|
||||
{#await loadPosts()}
|
||||
{:then posts}
|
||||
{#if posts && posts.length > 0}
|
||||
<div class="my-4 separator text-big">OR</div>
|
||||
|
||||
|
|
@ -59,6 +51,9 @@
|
|||
{/each}
|
||||
</main>
|
||||
{/if}
|
||||
{:catch error}
|
||||
<!-- Couldn't load -->
|
||||
{/await}
|
||||
|
||||
<style>
|
||||
.flex {
|
||||
7
src/routes/+layout.js
Normal file
7
src/routes/+layout.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
/** @type {import('./$types').PageLoad} */
|
||||
export const load = async ({ url }) => {
|
||||
return {
|
||||
url: url.pathname
|
||||
}
|
||||
};
|
||||
|
|
@ -1,20 +1,16 @@
|
|||
<script context="module">
|
||||
export const load = async ({ url }) => ({ props: { url } });
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import Navbar from "$lib/components/navbar.svelte";
|
||||
import PageTransition from "$lib/components/pageTransition.svelte";
|
||||
import "virtual:windi.css";
|
||||
import { browser } from "$app/env";
|
||||
if (browser) import("virtual:windi-devtools");
|
||||
export let url;
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<Navbar />
|
||||
|
||||
<div class="overflow-x-hidden w-100vw">
|
||||
<PageTransition {url}>
|
||||
<PageTransition url={data.url}>
|
||||
<slot />
|
||||
</PageTransition>
|
||||
</div>
|
||||
7
src/routes/+page.js
Normal file
7
src/routes/+page.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
/** @type {import('./$types').PageLoad} */
|
||||
export async function load({ fetch }) {
|
||||
return {
|
||||
posts: await fetch("/api/posts.json").then(t => t.json())
|
||||
};
|
||||
}
|
||||
|
|
@ -1,16 +1,3 @@
|
|||
<script context="module">
|
||||
/** @type {import('./index').Load} */
|
||||
export async function load({ params, fetch, session, stuff }) {
|
||||
const response = await fetch("/api/posts.json");
|
||||
|
||||
return {
|
||||
props: {
|
||||
posts: response.ok && (await response.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import Bottombar from "$lib/components/bottombar.svelte";
|
||||
import Button from "$lib/components/button.svelte";
|
||||
|
|
@ -26,7 +13,9 @@
|
|||
/** @type {null | "websites" | "applications" | "bots"} */
|
||||
var appTypeHover = null;
|
||||
|
||||
export var posts;
|
||||
export var data;
|
||||
var posts = data.posts;
|
||||
$: posts = data.posts;
|
||||
$: if(typeof window !== "undefined") console.log(posts);
|
||||
|
||||
var selectedPost = posts && posts.find(t => !t.categories.includes("experiment"));
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
/**
|
||||
* @type {import("@sveltejs/kit").RequestHandler}
|
||||
*/
|
||||
export async function get(req) {
|
||||
const allPostFiles = import.meta.glob('../posts/**/*.md');
|
||||
export async function GET(req) {
|
||||
const allPostFiles = import.meta.glob('../../posts/**/*.md');
|
||||
|
||||
const allPosts = await Promise.all(
|
||||
Object.entries(allPostFiles).map(async ([path, resolver]) => {
|
||||
const { metadata } = await resolver();
|
||||
let postPath = path.slice(2, -3);
|
||||
if(postPath.endsWith('/index')) postPath = postPath.slice(0, -6);
|
||||
if(postPath.endsWith('/+page')) postPath = postPath.slice(0, -6);
|
||||
return {
|
||||
...metadata,
|
||||
path: postPath,
|
||||
|
|
@ -20,7 +20,9 @@ export async function get(req) {
|
|||
return new Date(b.date) - new Date(a.date)
|
||||
});
|
||||
|
||||
return {
|
||||
body: allPosts.filter(t => new Date(t.date) < Date.now())
|
||||
};
|
||||
return new Response(JSON.stringify(allPosts.filter(t => new Date(t.date) < Date.now())), {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
}
|
||||
9
src/routes/posts/+page.js
Normal file
9
src/routes/posts/+page.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
/** @type {import('./$types').PageLoad} */
|
||||
export async function load({ fetch }) {
|
||||
const response = await fetch("/api/posts.json");
|
||||
|
||||
return {
|
||||
posts: response.ok && (await response.json())
|
||||
};
|
||||
}
|
||||
|
|
@ -1,16 +1,3 @@
|
|||
<script context="module">
|
||||
/** @type {import('./index').Load} */
|
||||
export async function load({ params, fetch, session, stuff }) {
|
||||
const response = await fetch("/api/posts.json");
|
||||
|
||||
return {
|
||||
props: {
|
||||
posts: response.ok && (await response.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import HeroPost from "$lib/components/heroPost.svelte";
|
||||
import Post from "$lib/components/post.svelte";
|
||||
|
|
@ -18,7 +5,9 @@
|
|||
import { flip } from 'svelte/animate';
|
||||
|
||||
var currentHover = null;
|
||||
export var posts;
|
||||
export var data;
|
||||
var posts = data.posts;
|
||||
$: posts = data.posts;
|
||||
|
||||
var tags = posts && posts.map(t => t.categories).flat().filter((t, i, a) => a.indexOf(t) == i).sort();
|
||||
|
||||
|
|
@ -15,8 +15,15 @@ description: So I added blog to my personal home page.
|
|||
import ExampleWrapper from "$lib/components/posts/exampleWrapper.svelte";
|
||||
import SimpleExample from "./_comp/simpleExample.svelte";
|
||||
import BidiExample from "./_comp/bidiExample.svelte";
|
||||
import Callout from "$lib/components/posts/callout.svelte";
|
||||
import Date from "$lib/components/Date.svelte";
|
||||
</script>
|
||||
|
||||
<Callout color="#139ab4">
|
||||
<span slot="title">Update <Date value="2022-08-24" /></span>
|
||||
Sveltekit's routing was changed, the article was updated to accomodate that.
|
||||
</Callout>
|
||||
|
||||
I'm mainly a web developer, yet for quite a while, my personal site looked like this:
|
||||
|
||||
<Image src="/posts/writing-personal-home-page/2020-website.png">
|
||||
|
|
@ -119,14 +126,15 @@ Essentially:
|
|||
|
||||
*For full description, see [Svelte Kit's documentation](https://kit.svelte.dev/docs/routing)*
|
||||
|
||||
Essentially, **each file in `src/routes` creates a new route**.
|
||||
Essentially, **each folder in `src/routes` creates a new route**.
|
||||
All special files in sveltekit start with a `+` - `+page.svelte` is the page visible to user
|
||||
|
||||
`/index.svelte` is the root page
|
||||
`/something.svelte` will be accessible as `/something`
|
||||
`/+page.svelte` is the root page
|
||||
`/something/+page.svelte` will be accessible as `/something`
|
||||
|
||||
`js` files are used to create API endpoints, which are run server side. Those can do some action (like user login/registration), or retrieve some data (like a list of blog posts, as I'll demonstrate later).
|
||||
|
||||
`md` files are compiled/transpiled into `svelte` files internally, and behave nearly identical.
|
||||
`md` files are compiled/transpiled into `svelte` files internally, and behave nearly identical. Note this only works when you set up mdsvex with sveltekit (sveltekit doesn't do it on it's own).
|
||||
|
||||
## Writing blog posts
|
||||
|
||||
|
|
@ -208,17 +216,17 @@ Hello there, **markdown**
|
|||
You can then write YAML metadata (YAML is basically simplified JSON. If you're unsure, any JSON is valid YAML, so you can write it in JSON as well). For example, this page stores it's title, description and thumbnail links there.
|
||||
|
||||
When you import the file elsewhere, you can use that metadata to for example show a preview of the post (as is the case here).
|
||||
A simple API route can be used to get a list of posts along with their metadata, for example if all the posts are in `/posts` route, you can use this as `/api/posts.json.js`:
|
||||
A simple API route can be used to get a list of posts along with their metadata, for example if all the posts are in `/posts` route, you can use this as `/api/posts.json/+server.js`:
|
||||
|
||||
```js
|
||||
export async function get() {
|
||||
const allPostFiles = import.meta.glob('../posts/**/*.md');
|
||||
export async function GET() {
|
||||
const allPostFiles = import.meta.glob('../../posts/**/*.md');
|
||||
|
||||
const allPosts = await Promise.all(
|
||||
Object.entries(allPostFiles).map(async ([path, resolver]) => {
|
||||
const { metadata } = await resolver();
|
||||
let postPath = path.slice(2, -3);
|
||||
if(postPath.endsWith('/index')) postPath = postPath.slice(0, -6);
|
||||
if(postPath.endsWith('/+page')) postPath = postPath.slice(0, -6);
|
||||
return {
|
||||
...metadata,
|
||||
path: postPath,
|
||||
|
|
@ -244,7 +252,7 @@ this will get all the metadata about posts and return it as a JSON response, ord
|
|||
[{
|
||||
"title": "An example blog post",
|
||||
"date": "2020-03-05",
|
||||
"path": "/posts/example.md"
|
||||
"path": "/posts/example"
|
||||
}]
|
||||
```
|
||||
|
||||
|
|
@ -2,6 +2,6 @@
|
|||
var name = "world";
|
||||
</script>
|
||||
|
||||
<input type=text bind:value={name}>
|
||||
<input type=text bind:value={name} class="text-black">
|
||||
|
||||
<input type=text bind:value={name}>
|
||||
<input type=text bind:value={name} class="text-black">
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<h1>Hello {funny[name] || name}</h1>
|
||||
|
||||
<input type=text bind:value={name}>
|
||||
<input type=text class="text-black" bind:value={name}>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
|
|
|
|||
|
|
@ -7,20 +7,13 @@ import remarkTwemoji from 'remark-twemoji';
|
|||
import remarkGfm from 'remark-gfm';
|
||||
import remarkExtendedTable from 'remark-extended-table';
|
||||
import rehypeKatexSvelte from "rehype-katex-svelte";
|
||||
import WindiCSS from 'vite-plugin-windicss';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
adapter: adapter({
|
||||
precompress: true
|
||||
}),
|
||||
vite: {
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
WindiCSS()
|
||||
]
|
||||
}
|
||||
})
|
||||
},
|
||||
extensions: ['.svelte', '.md'],
|
||||
|
||||
|
|
|
|||
10
vite.config.js
Normal file
10
vite.config.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import WindiCSS from 'vite-plugin-windicss';
|
||||
|
||||
export default {
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
WindiCSS(),
|
||||
sveltekit()
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue