Skip to content

Commit 6b90d44

Browse files
committed
Merge #113: add melt-ui toc in (pages)
b72f1c3 add melt-ui toc in (pages) (Graeme Byrne) Pull request description: * To improve Table of Contents as mentioned [here](#87) and [here](#92), I installed [Melt UI](https://www.melt-ui.com/) to handle the Table of Contents. I implemented it according to the [Melt UI's docs](https://www.melt-ui.com/docs/builders/table-of-contents) for the appropriate parts of each page in `routes/(pages)`. * Fixed any changes this installation had on other parts of the website. * Refactored repeated styles used in `routes/(pages)` by extracting into `PagesWrapper.svelte`. * Extracted table headings and table data from `routes/(pages)/about/+page.svelte` into `constants/constants` to maintain consistency with data used in other tables on the website. ACKs for top commit: josecelano: ACK b72f1c3 Tree-SHA512: a8a8b9eb72484b8a88786579f3d1fc86dcfd839b3004f472bc4f52ca8c50e1eeeb311f52cda31e57ae5d21b7c58344e6ba302807eac973acf38c72fb16e2a6b1
2 parents 3b3aa7e + b72f1c3 commit 6b90d44

29 files changed

+2177
-1323
lines changed

package-lock.json

Lines changed: 1084 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
"devDependencies": {
2121
"@histoire/plugin-svelte": "^0.17.17",
2222
"@iconify/svelte": "^4.0.2",
23+
"@melt-ui/pp": "^0.3.2",
24+
"@melt-ui/svelte": "^0.86.0",
2325
"@sveltejs/adapter-static": "^3.0.1",
2426
"@sveltejs/kit": "^2.5.25",
2527
"@types/swiper": "^5.4.3",
@@ -44,15 +46,19 @@
4446
"svelte": "^4.2.19",
4547
"svelte-check": "^3.8.0",
4648
"svelte-sitemap": "^2.6.0",
49+
"tailwindcss": "^3.4.14",
4750
"typescript": "^5.5.4",
4851
"vite": "^5.2.12"
4952
},
5053
"type": "module",
5154
"dependencies": {
5255
"@fontsource-variable/roboto-mono": "^5.0.19",
5356
"@fontsource-variable/roboto-slab": "^5.0.20",
57+
"@tailwindcss/typography": "^0.5.15",
58+
"autoprefixer": "^10.4.20",
5459
"feather-icons": "^4.29.2",
5560
"flexsearch": "^0.7.43",
61+
"postcss": "^8.4.49",
5662
"shiki": "^1.6.1",
5763
"shiki-es": "^0.14.0",
5864
"svelte-toc": "^0.5.9",

postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {}
5+
}
6+
};

src/app.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@import 'tailwindcss/base';
2+
@import 'tailwindcss/components';
3+
@import 'tailwindcss/utilities';
4+
/* src/app.css */
5+
@tailwind base;
6+
@tailwind components;
7+
@tailwind utilities;

src/lib/components/atoms/Banner.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@
2929
display: flex;
3030
text-align: center;
3131
}
32+
33+
h1 {
34+
font-size: 2.5rem;
35+
font-weight: bolder;
36+
}
3237
</style>

src/lib/components/atoms/Card.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{@html title.icon}
99
</span>
1010
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
11-
<h2>{@html title.title}</h2>
11+
<h3>{@html title.title}</h3>
1212
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
1313
<p>{@html title.para}</p>
1414
</div>
@@ -26,9 +26,10 @@
2626
display: inline-block;
2727
}
2828
29-
h2 {
29+
h3 {
3030
font-size: 20px;
3131
color: rgba(245, 245, 245, 0.96);
32+
font-weight: bold;
3233
}
3334
3435
p {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script lang="ts">
2+
export let heading: string;
3+
</script>
4+
5+
<div class="para">
6+
{#if heading}
7+
<h1>{heading}</h1>
8+
{/if}
9+
<div class="layout">
10+
<slot />
11+
</div>
12+
</div>
13+
14+
<style lang="scss">
15+
@import '$lib/scss/breakpoints.scss';
16+
17+
.para {
18+
display: flex;
19+
flex-direction: column;
20+
max-width: 1100px;
21+
margin: 0 auto;
22+
}
23+
24+
h1 {
25+
padding-inline: 2.5rem;
26+
font-size: 2rem;
27+
padding-top: 6rem;
28+
}
29+
30+
.layout {
31+
display: flex;
32+
flex-direction: column;
33+
padding-top: 4rem;
34+
padding-inline: 2.5rem;
35+
}
36+
37+
@include for-desktop-up {
38+
.layout {
39+
height: 100vh;
40+
flex-direction: row;
41+
gap: 4rem;
42+
}
43+
}
44+
</style>

src/lib/components/atoms/TableOfContents.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
}
2424
});
2525
},
26-
{ threshold: 0.9 }
26+
{ threshold: 0.1 }
2727
);
2828
2929
sections.forEach((section) => {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte'; // ✨ Import Svelte onMount
3+
import Tree from './Tree.svelte';
4+
import { createTableOfContents } from '@melt-ui/svelte';
5+
import { pushState } from '$app/navigation';
6+
7+
let isMobileScreen = false;
8+
9+
onMount(() => {
10+
isMobileScreen = window.innerWidth <= 1200;
11+
12+
const handleResize = () => {
13+
isMobileScreen = window.innerWidth <= 1024;
14+
};
15+
window.addEventListener('resize', handleResize);
16+
return () => window.removeEventListener('resize', handleResize); // ✨ Clean up
17+
});
18+
19+
const {
20+
elements: { item },
21+
states: { activeHeadingIdxs, headingsTree }
22+
} = createTableOfContents({
23+
selector: '#toc-builder-preview',
24+
exclude: [],
25+
activeType: 'highest',
26+
pushStateFn: pushState,
27+
headingFilterFn: (heading) => !heading.hasAttribute('data-toc-ignore'),
28+
29+
scrollFn: (id) => {
30+
const container = document.getElementById('toc-builder-preview');
31+
const element = document.getElementById(id);
32+
33+
if (container && element) {
34+
const containerTopOffset = container.offsetTop;
35+
const elementTopOffset = element.offsetTop;
36+
37+
if (isMobileScreen) {
38+
element.scrollIntoView({
39+
behavior: 'smooth',
40+
block: 'start'
41+
});
42+
} else {
43+
container.scrollTo({
44+
top: elementTopOffset - containerTopOffset,
45+
behavior: 'smooth'
46+
});
47+
}
48+
}
49+
}
50+
});
51+
</script>
52+
53+
<div class="lg:overflow-y-auto rounded-lg text-white">
54+
<nav>
55+
{#key $headingsTree}
56+
<Tree tree={$headingsTree} activeHeadingIdxs={$activeHeadingIdxs} {item} />
57+
{/key}
58+
</nav>
59+
</div>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script lang="ts">
2+
import { type TableOfContentsItem, type TableOfContentsElements, melt } from '@melt-ui/svelte';
3+
4+
export let tree: TableOfContentsItem[] = [];
5+
export let activeHeadingIdxs: number[];
6+
export let item: TableOfContentsElements['item'];
7+
export let level = 1;
8+
</script>
9+
10+
<ul class="mt-0 list-none {level !== 1 ? 'pl-4' : ''}">
11+
{#if tree && tree.length}
12+
{#each tree as heading, i (i)}
13+
<li class="mt-0 pt-2">
14+
<a
15+
href="#{heading.id}"
16+
use:melt={$item(heading.id)}
17+
class="inline-flex items-center justify-center gap-1 text-white no-underline transition-colors
18+
hover:text-[rgba(255,_49,_0,_1)] data-[active]:text-[rgba(255,_49,_0,_1)]"
19+
>
20+
<!--
21+
Along with the heading title, the original heading node
22+
is also passed down, so you can display headings
23+
however you want.
24+
-->
25+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
26+
{@html heading.node.innerHTML}
27+
</a>
28+
{#if heading.children && heading.children.length}
29+
<svelte:self tree={heading.children} level={level + 1} {activeHeadingIdxs} {item} />
30+
{/if}
31+
</li>
32+
{/each}
33+
{/if}
34+
</ul>
35+
36+
<style>
37+
a {
38+
word-break: keep-all;
39+
}
40+
</style>

0 commit comments

Comments
 (0)