Skip to content

Commit

Permalink
sveltekit: add v5 snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
codediodeio committed Oct 24, 2024
1 parent f5d8309 commit c07f7c8
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 11 deletions.
21 changes: 20 additions & 1 deletion content/courses/sveltekit/auth-animated-route.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,23 @@ video_length: 1:50
...
</main>
</AnimatedRoute>
```
```

## Svelte 5 Version

{{< file "svelte" "lib/components/AnimatedRoute.svelte" >}}
```svelte
<script>
import { fly} from "svelte/transition";
import { page } from "$app/stores";
/** @type {{children?: import('svelte').Snippet}} */
let { children } = $props();
</script>
{#key $page.url}
<div in:fly={{ x:'-100%', duration: 500 }}>
{@render children?.()}
</div>
{/key}
```

6 changes: 6 additions & 0 deletions content/courses/sveltekit/auth-basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ video_length: 2:00
<h2>Login</h2>
<button class="btn btn-primary" on:click={signInWithGoogle}>Sign in with Google</button>
```

## Svelte 5 Version

```svelte
<button class="btn btn-primary" onclick={signInWithGoogle}>Sign in with Google</button>
```
22 changes: 22 additions & 0 deletions content/courses/sveltekit/auth-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,26 @@ video_length: 0:47
<a class="btn btn-primary" href="/login">Sign in</a>
</p>
{/if}
```

## Svelte 5 Version

```svelte
<script lang="ts">
import { user } from "$lib/firebase";
interface Props {
children?: import('svelte').Snippet;
}
let { children }: Props = $props();
</script>
{#if $user}
{@render children?.()}
{:else}
<p class="text-error my-10">
You must be signed in to view this page.
<a class="btn btn-primary" href="/login">Sign in</a>
</p>
{/if}
```
16 changes: 16 additions & 0 deletions content/courses/sveltekit/auth-multistep.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,19 @@ chapter_start: User Management
</div>
</main>
```

## Svelte 5 Version

```svelte
<script lang="ts">
interface Props {
children?: import('svelte').Snippet;
}
let { children }: Props = $props();
</script>
<div class="min-h-screen flex flex-col">
{@render children?.()}
</div>
```
13 changes: 13 additions & 0 deletions content/courses/sveltekit/auth-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,16 @@ export const user = userStore();
<button class="btn btn-primary" on:click={signInWithGoogle}>Sign in with Google</button>
{/if}
```


## Svelte 5 Version

```svelte
{#if $user}
<h2 class="card-title">Welcome, {$user.displayName}</h2>
<p class="text-center text-success">You are logged in</p>
<button class="btn btn-warning" onclick={() => signOut(auth)}>Sign out</button>
{:else}
<button class="btn btn-primary" onclick={signInWithGoogle}>Sign in with Google</button>
{/if}
```
11 changes: 8 additions & 3 deletions content/courses/sveltekit/basics-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,23 @@ video_length: 2:21
free: true
---

## NEW - Svelte 5 Code

If you're following the course using **Svelte version 5 with Runes**, check out the [v5 source code](https://github.com/fireship-io/fkit-course/tree/svelte5) here. The vidoes are recorded with Svelte 4 code, but you will find the relevant code changes below each video.

## Course Resources

- [Full Project Source Code](https://github.com/fireship-io/fkit-course)
- [Full Project Source Code v4](https://github.com/fireship-io/fkit-course)
- [Full Project Source Code v5](https://github.com/fireship-io/fkit-course/tree/svelte5)
- [Official Svelte Tutorial](https://svelte.dev/tutorial/basics)
- [SvelteKit Docs](https://kit.svelte.dev/)

## Create a SvelteKit Project

{{< file "terminal" "command line" >}}
```bash
npm create svelte@latest my-app
npx sv create my-app
cd my-app
npm install
npm run dev -- --open
npm run dev
```
13 changes: 12 additions & 1 deletion content/courses/sveltekit/project-link-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,15 @@ video_length: 2:29
{/if}
</main>
```
```


## Svelte 5 Version

```ts
let showForm = $state(false);

let urlIsValid = $derived($formData.url.match(/^(ftp|http|https):\/\/[^ "]+$/));
let titleIsValid = $derived($formData.title.length < 20 && $formData.title.length > 0);
let formIsValid = $derived(urlIsValid && titleIsValid);
```
18 changes: 16 additions & 2 deletions content/courses/sveltekit/project-seo.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ export const load = (async ({ params }) => {
const data = snapshot.docs[0]?.data();

if (!exists) {
throw error(404, "that user does not exist!");
error(404, "that user does not exist!");
}

if (!data.published) {
throw error(403, `The profile of @${data.username} is not public!`);
error(403, `The profile of @${data.username} is not public!`);
}

return {
Expand Down Expand Up @@ -89,4 +89,18 @@ export const load = (async ({ params }) => {
</main>
```

## Svelte 5 Changes

```svelte
<script lang="ts">
import type { PageData } from "./$types";
interface Props {
data: PageData;
}
let { data }: Props = $props();
</script>
```
94 changes: 94 additions & 0 deletions content/courses/sveltekit/project-sortable-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,98 @@ Add the sortable list to the edit page
@apply border-gray-400 scale-105;
}
</style>
```

## Svelte 5 Version

```svelte
<script lang="ts">
import { flip } from "svelte/animate";
import { createEventDispatcher } from "svelte";
interface Item {
id: string;
index: number;
[key: string]: any;
}
interface Props {
list: any[];
children?: import('svelte').Snippet<[any]>;
}
let { list, children }: Props = $props();
let isOver: string | boolean = $state(false);
const dispatch = createEventDispatcher();
function getDraggedParent(node: any): Item {
if (!node.dataset.index) {
return getDraggedParent(node.parentNode);
} else {
return { ...node.dataset } as Item;
}
}
function onDragStart(e: DragEvent) {
// @ts-ignore
const dragged = getDraggedParent(e.target);
e.dataTransfer?.setData("source", dragged?.index.toString());
}
function onDragOver(e: DragEvent) {
e.preventDefault();
// @ts-ignore
const id = e.target.dataset?.id;
const dragged = getDraggedParent(e.target);
isOver = dragged?.id ?? false;
}
function onDragLeave(e: DragEvent) {
const dragged = getDraggedParent(e.target);
isOver === dragged.id && (isOver = false);
}
function onDrop(e: DragEvent) {
e.preventDefault();
isOver = false;
const dragged = getDraggedParent(e.target);
reorder({
from: e.dataTransfer?.getData("source"),
to: dragged.index,
});
}
const reorder = ({ from, to }: any) => {
const newList = [...list];
newList[from] = [newList[to], (newList[to] = newList[from])][0];
dispatch("sort", newList);
};
</script>
{#if list?.length}
<ul class="list-none p-0 flex flex-col items-center">
{#each list as item, index (item.id)}
<li
class="border-2 border-dashed border-transparent p-2 transition-all max-w-md w-full"
class:over={item.id === isOver}
data-index={index}
data-id={item.id}
draggable="true"
ondragstart={onDragStart}
ondragover={onDragOver}
ondragleave={onDragLeave}
ondrop={onDrop}
animate:flip={{ duration: 300 }}
>
{@render children?.({ item, index, })}
</li>
{/each}
</ul>
{:else}
<p class="text-center my-12 text-lg font-bold">No items</p>
{/if}
```
60 changes: 59 additions & 1 deletion content/courses/sveltekit/project-upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,62 @@ video_length: 3:27
<a {href} class="btn btn-primary"> Finish </a>
</AuthCheck>
```
```

## Svelte 5 Version

```svelte
<script lang="ts">
import AuthCheck from "$lib/components/AuthCheck.svelte";
import { user, userData, storage, db } from "$lib/firebase";
import { doc, updateDoc } from "firebase/firestore";
import { getDownloadURL, ref, uploadBytes } from "firebase/storage";
let previewURL: string = $state();
let uploading = $state(false);
let href = $derived(`/${$userData?.username}/edit`);
async function upload(e: any) {
uploading = true;
const file = e.target.files[0];
previewURL = URL.createObjectURL(file);
const storageRef = ref(storage, `users/${$user!.uid}/profile.png`);
const result = await uploadBytes(storageRef, file);
const url = await getDownloadURL(result.ref);
await updateDoc(doc(db, "users", $user!.uid), { photoURL: url });
uploading = false;
}
</script>
<AuthCheck>
<h2 class="card-title">Upload a Profile Photo</h2>
<form class="max-w-screen-md w-full">
<div class="form-control w-full max-w-xs my-10 mx-auto text-center">
<img
src={previewURL ?? $userData?.photoURL ?? "/user.png"}
alt="photoURL"
width="256"
height="256"
class="mx-auto"
/>
<label for="photoURL" class="label">
<span class="label-text">Pick a file</span>
</label>
<input
onchange={upload}
name="photoURL"
type="file"
class="file-input file-input-bordered w-full max-w-xs"
accept="image/png, image/jpeg, image/gif, image/webp"
/>
{#if uploading}
<p>Uploading...</p>
<progress class="progress progress-info w-56 mt-6"></progress>
{/if}
</div>
</form>
<a {href} class="btn btn-primary"> Finish </a>
</AuthCheck>
Loading

0 comments on commit c07f7c8

Please sign in to comment.