improve: tutorial pages.

This commit is contained in:
ItzNotABug
2024-08-05 15:19:43 +05:30
parent a1f2337752
commit 0a20a89c14
2 changed files with 88 additions and 73 deletions

View File

@@ -3,80 +3,96 @@
import { Feedback } from '$lib/components'; import { Feedback } from '$lib/components';
import type { Tutorial } from '$markdoc/layouts/Tutorial.svelte'; import type { Tutorial } from '$markdoc/layouts/Tutorial.svelte';
import type { TocItem } from './DocsArticle.svelte'; import type { TocItem } from './DocsArticle.svelte';
import Section from '$markdoc/tags/Section.svelte';
export let title: string;
export let toc: Array<TocItem>; export let toc: Array<TocItem>;
export let currentStep: number; export let currentStep: number;
export let back: string;
export let date: string; export let date: string;
export let tutorials: Array<Tutorial>; export let tutorials: Array<Tutorial>;
const firstStepItem = tutorials[0];
// currentStep starts from 1, the arrays start from 0.
const currentStepItem = (tutorials[currentStep - 1] ?? firstStepItem);
$: nextStep = tutorials.find((tutorial) => tutorial.step === currentStep + 1); $: nextStep = tutorials.find((tutorial) => tutorial.step === currentStep + 1);
$: prevStep = tutorials.find((tutorial) => tutorial.step === currentStep - 1); $: prevStep = tutorials.find((tutorial) => tutorial.step === currentStep - 1);
function getDecrementedStep(stepOrTutorial: number | Tutorial): number {
if (typeof stepOrTutorial === 'number') {
return stepOrTutorial - 1;
} else {
return stepOrTutorial.step - 1;
}
}
// `any` for compatibility with reactive variables.
function getCorrectTitle(tutorial: any | Tutorial, checkAt: number): string {
if (tutorial.step === checkAt) {
return 'Introduction';
} else {
return tutorial.title;
}
}
</script> </script>
<main class="u-contents" id="main"> <main class="u-contents" id="main">
<article class="web-article u-contents"> <article class="web-article u-contents">
<header class="web-article-header"> <header class="web-article-header">
<div class="web-article-header-start u-flex-vertical web-u-cross-start"> <div class="web-article-header-start u-flex-vertical web-u-cross-start">
<button
class="web-icon-button web-is-only-mobile"
aria-label="previous page"
>
<span class="icon-cheveron-left" aria-hidden="true" />
</button>
<ul class="web-metadata web-caption-400"> <ul class="web-metadata web-caption-400">
<slot name="metadata" /> {#if currentStepItem.difficulty}
<li>{currentStepItem.difficulty}</li>
{/if}
{#if currentStepItem.readtime}
<li>{currentStepItem.readtime} min</li>
{/if}
</ul> </ul>
<div class="u-position-relative u-flex u-cross-center"> <div class="u-position-relative u-flex u-cross-center">
{#if back} <h1 class="web-title">{firstStepItem.title}</h1>
<a
href={back}
class="
web-button is-text is-only-icon web-u-cross-center web-u-size-40
u-position-absolute u-inset-inline-start-0 web-u-translate-x-negative"
aria-label="previous page"
>
<span
class="icon-cheveron-left web-u-font-size-24 web-u-color-text-primary web-is-not-mobile"
aria-hidden="true"
/>
</a>
{/if}
<h1 class="web-title">{title}</h1>
</div> </div>
</div> </div>
<div class="web-article-header-end" /> <div class="web-article-header-end" />
</header> </header>
<div class="web-article-content"> <div class="web-article-content">
<slot /> <Section
<div class="u-flex u-main-space-between"> id={currentStepItem.href}
{#if prevStep} step={getDecrementedStep(currentStep)}
<a href={prevStep.href} class="web-button is-text"> title={getCorrectTitle(currentStepItem, 1)}
<span class="icon-cheveron-left" aria-hidden="true" /> isWithLine={false}
<span class="web-sub-body-500"> >
Step {prevStep.step}<span class="web-is-not-mobile"
>: {prevStep.title}</span <div class="u-padding-block-start-32">
> <slot />
</span> </div>
</a>
{/if} <div class="u-flex u-main-space-between">
{#if nextStep} {#if prevStep}
<a <a href={prevStep.href} class="web-button is-text previous-step-anchor">
href={nextStep.href} <span class="icon-cheveron-left" aria-hidden="true" />
class="web-button is-secondary" <span class="web-sub-body-500">
style:margin-left={prevStep ? undefined : 'auto'} Step {getDecrementedStep(prevStep)}<span class="web-is-not-mobile"
> >: {getCorrectTitle(prevStep, 1)}</span
<span class="web-sub-body-500"> >
Step {nextStep.step}<span class="web-is-not-mobile" </span>
>: {nextStep.title}</span </a>
> {/if}
</span> {#if nextStep}
<span class="icon-cheveron-right" aria-hidden="true" /> <a
</a> href={nextStep.href}
{/if} class="web-button is-secondary"
</div> style:margin-left={prevStep ? undefined : 'auto'}
>
<span class="web-sub-body-500">
Step {getDecrementedStep(nextStep)}<span class="web-is-not-mobile"
>: {nextStep.title}</span
>
</span>
<span class="icon-cheveron-right" aria-hidden="true" />
</a>
{/if}
</div>
</Section>
<Feedback {date} /> <Feedback {date} />
</div> </div>
@@ -86,7 +102,7 @@
<h5 class="web-references-menu-title web-eyebrow">Tutorial Steps</h5> <h5 class="web-references-menu-title web-eyebrow">Tutorial Steps</h5>
</div> </div>
<ol class="web-references-menu-list"> <ol class="web-references-menu-list">
{#each tutorials as tutorial} {#each tutorials as tutorial, index}
{@const isCurrentStep = currentStep === tutorial.step} {@const isCurrentStep = currentStep === tutorial.step}
<li class="web-references-menu-item"> <li class="web-references-menu-item">
<a <a
@@ -95,14 +111,15 @@
class:tutorial-scroll-indicator={isCurrentStep && !toc.length} class:tutorial-scroll-indicator={isCurrentStep && !toc.length}
class:is-selected={isCurrentStep} class:is-selected={isCurrentStep}
> >
<span class="web-numeric-badge">{tutorial.step}</span> <span class="web-numeric-badge">{tutorial.step - 1}</span>
<span class="web-caption-400">{tutorial.title}</span> <!-- first item will always be introduction -->
<span class="web-caption-400">{index === 0 ? 'Introduction' : tutorial.title}</span>
</a> </a>
{#if isCurrentStep} {#if isCurrentStep && toc.slice(1).length}
<ol <ol
class="web-references-menu-list u-margin-block-start-16 u-margin-inline-start-32" class="web-references-menu-list u-margin-block-start-16 u-margin-inline-start-32"
> >
{#each toc as parent} {#each toc.slice(1) as parent}
<li class="web-references-menu-item"> <li class="web-references-menu-item">
<a <a
href={parent.href} href={parent.href}
@@ -110,11 +127,6 @@
class:tutorial-scroll-indicator={parent.selected} class:tutorial-scroll-indicator={parent.selected}
class:is-selected={parent.selected} class:is-selected={parent.selected}
> >
{#if parent?.step}
<span class="web-numeric-badge"
>{parent.step}</span
>
{/if}
<span class="web-caption-400">{parent.title}</span> <span class="web-caption-400">{parent.title}</span>
</a> </a>
{#if parent.children} {#if parent.children}
@@ -154,3 +166,15 @@
</main> </main>
<style>
.web-article-header {
padding-inline-start: unset !important;
}
.previous-step-anchor {
border: unset !important;
outline: unset !important;
background: unset !important;
padding-inline-start: unset !important;
}
</style>

View File

@@ -6,6 +6,8 @@
step: number; step: number;
href: string; href: string;
draft?: boolean; draft?: boolean;
difficulty?: string;
readtime?: string;
}; };
</script> </script>
@@ -21,10 +23,7 @@
export let title: string; export let title: string;
export let description: string; export let description: string;
export let difficulty: string;
export let readtime: string;
export let step: number; export let step: number;
export let back: string;
export let date: string; export let date: string;
setContext<LayoutContext>('headings', writable({})); setContext<LayoutContext>('headings', writable({}));
@@ -77,15 +76,7 @@
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
</svelte:head> </svelte:head>
<DocsTutorial {title} {back} {toc} {tutorials} {date} currentStep={step}> <DocsTutorial {toc} {tutorials} {date} currentStep={step}>
<svelte:fragment slot="metadata">
{#if difficulty}
<li>{difficulty}</li>
{/if}
{#if readtime}
<li>{readtime} min</li>
{/if}
</svelte:fragment>
<slot /> <slot />
</DocsTutorial> </DocsTutorial>
<MainFooter variant="docs" /> <MainFooter variant="docs" />