Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions apps/svelte.dev/src/lib/components/SecondaryNav.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
import type { Snippet } from 'svelte';

let { children }: { children: Snippet } = $props();
</script>

<div class="secondary-nav">
{@render children()}
</div>

<style>
.secondary-nav {
width: 100%;
height: var(--sk-secondary-nav-height);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.6rem var(--sk-page-padding-side);
background-color: var(--sk-back-2);
color: var(--sk-text-1);
white-space: nowrap;
flex: 0;
gap: 1rem;

@media (min-width: 800px) {
padding-top: 1rem;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import { browser } from '$app/environment';
import SelectIcon from '$lib/components/SelectIcon.svelte';
import { untrack } from 'svelte';
import SecondaryNav from '$lib/components/SecondaryNav.svelte';

interface Props {
examples: Array<{ title: string; examples: any[] }>;
Expand Down Expand Up @@ -228,7 +229,7 @@ export default app;`

<svelte:window on:keydown={handleKeydown} />

<div class="app-controls">
<SecondaryNav>
<SelectIcon
bind:this={select}
title="examples"
Expand Down Expand Up @@ -302,27 +303,9 @@ export default app;`
</button>
{/if}
</div>
</div>
</SecondaryNav>

<style>
.app-controls {
width: 100%;
height: var(--sk-secondary-nav-height);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.6rem var(--sk-page-padding-side);
background-color: var(--sk-back-2);
color: var(--sk-text-1);
white-space: nowrap;
flex: 0;
gap: 1rem;

@media (min-width: 800px) {
padding-top: 1rem;
}
}

.buttons {
display: flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
display: flex;
align-items: center;
padding: 0em 0 0 0.4rem;
height: calc(var(--sk-secondary-nav-height) - 1.5rem);
/* height: calc(var(--sk-secondary-nav-height) - 1.5rem); */
z-index: 99;
}

Expand Down
27 changes: 11 additions & 16 deletions apps/svelte.dev/src/routes/tutorial/[...slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import { needs_webcontainers, text_files } from './shared';
import OutputRollup from './OutputRollup.svelte';
import { page } from '$app/stores';
import Controls from './Controls.svelte';

export let data;

Expand Down Expand Up @@ -241,12 +242,20 @@
<ContextMenu />

<div class="container" class:mobile>
<Controls
index={data.index}
exercise={data.exercise}
{completed}
toggle={() => {
reset_files(Object.values(completed ? a : b));
}}
/>

<div class="top" class:offset={show_editor}>
<SplitPane id="main" type="horizontal" min="360px" max="50%" pos="33%">
<section slot="a" class="content">
<Sidebar
bind:sidebar
index={data.index}
exercise={data.exercise}
on:select={(e) => {
navigate_to_file(e.detail.file);
Expand Down Expand Up @@ -280,21 +289,6 @@
}}
/>
{/if}

<button
class="solve"
class:completed
disabled={!data.exercise.has_solution}
on:click={() => {
reset_files(Object.values(completed ? a : b));
}}
>
{#if completed && data.exercise.has_solution}
reset
{:else}
solve <Icon name="arrow-right" />
{/if}
</button>
</section>

<section class="editor-container" slot="b">
Expand Down Expand Up @@ -365,6 +359,7 @@
/* we transform the default state, rather than the editor state, because otherwise
the positioning of tooltips is wrong (doesn't take into account transforms) */
transform: translate(50%, 0);
border-top: 1px solid var(--sk-back-5);
}

.top.offset {
Expand Down
40 changes: 20 additions & 20 deletions apps/svelte.dev/src/routes/tutorial/[...slug]/Chrome.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
</script>

<div class="chrome">
<button disabled={loading || !refresh} class="reload icon" onclick={refresh} aria-label="reload"
<button
disabled={loading || !refresh}
class="reload icon raised"
onclick={refresh}
aria-label="reload"
></button>

<input
Expand All @@ -37,17 +41,18 @@
}}
/>

<a
<!-- TODO maybe reinstate in future, if we can make it work with non-webcontainer exercises -->
<!-- <a
{href}
class="new-tab icon"
target="_blank"
aria-label={href ? 'open in new tab' : undefined}
tabindex="0"
></a>
></a> -->

<button
disabled={loading || !toggle_terminal}
class="terminal icon"
class="terminal icon raised"
onclick={() => toggle_terminal?.()}
aria-label="toggle terminal"
></button>
Expand All @@ -59,6 +64,8 @@
height: 4rem;
display: flex;
border-top: 1px solid var(--sk-back-4);
padding: 0.2rem;
gap: 0.2rem;
}

button {
Expand All @@ -67,14 +74,15 @@

input {
flex: 1;
padding: 0.5rem 1rem 0.4rem 1rem;
border: none;
background-color: var(--sk-back-3);
padding: 0.2rem 0.6rem;
border: 1px solid var(--sk-back-4);
/* TODO this should apply to all buttons/inputs? */
border-radius: var(--sk-border-radius);
color: var(--sk-text-1);
font: var(--sk-font-ui-medium);
height: 3.2rem;
}

a:focus-visible,
button:focus-visible,
input:focus-visible {
outline-offset: -2px;
Expand All @@ -83,18 +91,9 @@
.icon,
.icon::after {
position: relative;
height: 100%;
width: 3.2rem;
aspect-ratio: 1;
background: var(--sk-back-4) no-repeat 50% 50%;
background-size: 2rem;
}

a:not([href]) {
opacity: 0.5;
}

.new-tab {
background-image: url($lib/icons/external.svg);
background-size: 1.8rem;
}

.terminal {
Expand All @@ -106,7 +105,8 @@
position: absolute;
left: 0;
top: 0;
background-image: url($lib/icons/refresh.svg);
background: url($lib/icons/refresh.svg) no-repeat 50% 50%;
background-size: 1.8rem;
transition: 0.2s ease-out;
}

Expand Down
100 changes: 100 additions & 0 deletions apps/svelte.dev/src/routes/tutorial/[...slug]/Controls.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<script lang="ts">
import { goto } from '$app/navigation';
import SecondaryNav from '$lib/components/SecondaryNav.svelte';
import SelectIcon from '$lib/components/SelectIcon.svelte';
import type { Exercise, PartStub } from '$lib/tutorial';
import { Icon } from '@sveltejs/site-kit/components';

interface Props {
index: PartStub[];
exercise: Exercise;
completed: boolean;
toggle: () => void;
}

let { index, exercise, completed, toggle }: Props = $props();

// TODO this really sucks, why is `exercise.slug` not the slug?
let actual_slug = $derived.by(() => {
const parts = exercise.slug.split('/');
return `${parts[1]}/${parts[3]}`;
});
</script>

<SecondaryNav>
<SelectIcon
value={actual_slug}
onchange={(e) => {
goto(`/tutorial/${e.currentTarget.value}`);
}}
>
{#each index as part}
<optgroup label={part.title}>
{#each part.chapters as chapter}
<option disabled>{chapter.title}</option>

{#each chapter.exercises as exercise}
<option value={exercise.slug}>{exercise.title}</option>
{/each}
{/each}
</optgroup>
{/each}
</SelectIcon>

<a
href={exercise.prev ? `/tutorial/${exercise.prev?.slug}` : undefined}
aria-label={exercise.prev && 'Previous exercise'}
>
<Icon name="arrow-left" size={18} />
</a>
<a
href={exercise.next ? `/tutorial/${exercise.next?.slug}` : undefined}
aria-label={exercise.next && 'Next exercise'}
>
<Icon name="arrow-right" size={18} />
</a>

<div class="breadcrumbs">
<span>{exercise.part.title}</span>
<span>{exercise.chapter.title}</span>
<span>{exercise.title}</span>
</div>

<button class="raised" class:completed disabled={!exercise.has_solution} onclick={toggle}>
{#if completed && exercise.has_solution}
reset
{:else}
solve
{/if}
</button>
</SecondaryNav>

<style>
a {
color: inherit;

&:not([href]) {
opacity: 0.1;
cursor: default;
}
}

.breadcrumbs {
flex: 1;
font: var(--sk-font-ui-medium);
overflow: hidden;
text-overflow: ellipsis;

span:not(:last-child)::after {
content: ' / ';
color: var(--sk-text-4);
font: var(--sk-font-ui-small);
}
}

button {
height: 3.2rem;
padding: 0 1rem;
font: var(--sk-font-ui-small);
}
</style>
Loading
Loading