mirror of
https://github.com/youwen5/site.git
synced 2024-11-24 17:33:51 -08:00
feat: add toc header on mobile instead of card
This commit is contained in:
parent
e604f0f6af
commit
0c8370ee8a
5 changed files with 67 additions and 35 deletions
|
@ -8,7 +8,7 @@
|
|||
import ThemePicker from '../ThemePicker.svelte';
|
||||
</script>
|
||||
|
||||
<Drawer.Root shouldScaleBackground direction="top">
|
||||
<Drawer.Root direction="top">
|
||||
<Drawer.Trigger asChild let:builder>
|
||||
<Button variant="outline" size="icon" builders={[builder]} class="px-2 md:hidden">
|
||||
<HamburgerMenu class="icon border-1 border-primary" />
|
||||
|
|
56
src/lib/components/Toc/TocHeader.svelte
Normal file
56
src/lib/components/Toc/TocHeader.svelte
Normal file
|
@ -0,0 +1,56 @@
|
|||
<script lang="ts">
|
||||
import type { TocStore } from '@svelte-put/toc';
|
||||
import Separator from '../ui/separator/separator.svelte';
|
||||
import { Accordion } from 'bits-ui';
|
||||
import { toclink } from '@svelte-put/toc';
|
||||
import { CaretDown } from 'svelte-radix';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
export let tocStore: TocStore;
|
||||
export let placeholder: string;
|
||||
|
||||
const calcTextClasses = (el: HTMLElement) => {
|
||||
if (el.tagName === 'H2') return 'text-xl';
|
||||
return 'text-md text-muted-foreground';
|
||||
};
|
||||
|
||||
$: currentDisplayed = $tocStore.activeItem ? $tocStore.activeItem.text : placeholder;
|
||||
</script>
|
||||
|
||||
<nav class="fixed top-24 left-0 w-full bg-background bg-opacity-50 backdrop-blur-lg z-30 lg:hidden">
|
||||
<Accordion.Root class="px-8">
|
||||
<Accordion.Item value="toc">
|
||||
<Accordion.Trigger
|
||||
class="text-xl flex w-full flex-1 items-center justify-between py-1 font-medium transition-all [&[data-state=open]>span>svg]:rotate-180"
|
||||
>{currentDisplayed}
|
||||
<span
|
||||
class="inline-flex size-8 items-center justify-center rounded-[7px] bg-transparent transition-all hover:bg-dark-10"
|
||||
><CaretDown class="size-[18px] transition-all duration-200" /></span
|
||||
>
|
||||
</Accordion.Trigger>
|
||||
<Accordion.Content transition={slide} transitionConfig={{ duration: 200 }} class="pb-[25px]">
|
||||
{#if $tocStore.items.size}
|
||||
<ol>
|
||||
{#each $tocStore.items.values() as tocItem}
|
||||
{@const selected = $tocStore.activeItem === tocItem}
|
||||
<li class="border-l-secondary border-l-4 py-1" class:highlighted={selected}>
|
||||
<!-- svelte-ignore a11y-missing-attribute a11y-missing-content -->
|
||||
<a
|
||||
use:toclink={{ store: tocStore, tocItem, observe: true }}
|
||||
class={`hover:bg-muted px-2 py-1 rounded-r-sm transition-all ${calcTextClasses(tocItem.element)}`}
|
||||
/>
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
{/if}
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
</Accordion.Root>
|
||||
<Separator />
|
||||
</nav>
|
||||
|
||||
<style lang="postcss">
|
||||
.highlighted {
|
||||
@apply bg-blue-200 dark:bg-blue-900 border-l-blue-500;
|
||||
}
|
||||
</style>
|
|
@ -1,27 +1 @@
|
|||
import type { PageLoad } from './$types.js';
|
||||
import { marked } from 'marked';
|
||||
import markedKatex from 'marked-katex-extension';
|
||||
import markedAlert from 'marked-alert';
|
||||
|
||||
export const prerender = true;
|
||||
|
||||
const options = {
|
||||
throwOnError: false
|
||||
};
|
||||
marked.use(markedKatex(options));
|
||||
marked.use(markedAlert());
|
||||
|
||||
export const load: PageLoad = async ({ fetch }) => {
|
||||
try {
|
||||
const data = await fetch('/test.md');
|
||||
const markdown = await marked.parse(await data.text());
|
||||
|
||||
return {
|
||||
markdown
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
markdown: `Error: ${e}`
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<script lang="ts">
|
||||
import MobileToc from '$lib/components/Toc/MobileToc.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import Article from '$lib/components/Blog/Article.svelte';
|
||||
import { toc, createTocStore } from '@svelte-put/toc';
|
||||
import StickyToc from '$lib/components/Toc/StickyToc.svelte';
|
||||
import TocHeader from '$lib/components/toc/TocHeader.svelte';
|
||||
|
||||
const tocStore = createTocStore();
|
||||
|
||||
export let data: PageData;
|
||||
|
@ -28,7 +29,9 @@
|
|||
<meta name="author" content="Youwen Wu" />
|
||||
</svelte:head>
|
||||
|
||||
<div class="lg:flex mx-auto mt-14 px-4">
|
||||
<TocHeader {tocStore} placeholder="On this page" />
|
||||
|
||||
<div class="lg:flex mx-auto mt-24 lg:mt-14 px-4">
|
||||
<div class="flex-shrink xl:basis-1/4" />
|
||||
<main
|
||||
class="flex-grow basis-3/4 xl:basis-2/4 flex-shrink"
|
||||
|
@ -39,14 +42,11 @@
|
|||
properties: { 'aria-hidden': 'true', class: 'hidden' },
|
||||
position: 'before'
|
||||
},
|
||||
scrollMarginTop: 120
|
||||
scrollMarginTop: 120,
|
||||
selector: ':where(h2, h3, h4, h5, h6)'
|
||||
}}
|
||||
>
|
||||
<Article {doc}>
|
||||
<svelte:fragment slot="mobile-toc">
|
||||
<MobileToc {tocStore} />
|
||||
</svelte:fragment>
|
||||
</Article>
|
||||
<Article {doc} />
|
||||
</main>
|
||||
|
||||
<aside class="basis-1/4 relative hidden lg:block">
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
## Introduction
|
||||
|
||||
The following content is a test post for the blog's markdown and $\KaTeX$ rendering capabilities. There's a few errors, and wikilinks aren't supported. This file was copy pasted directly out of my `obsidian.md` notebook, so it contains some weird formatting.
|
||||
|
||||
<br />
|
||||
|
|
Loading…
Reference in a new issue