Skip to content

Commit

Permalink
docs: change Toc style
Browse files Browse the repository at this point in the history
  • Loading branch information
gioboa committed Dec 23, 2024
1 parent 11cd8eb commit 67577dc
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 25 deletions.
2 changes: 1 addition & 1 deletion docs/src/components/Aside/Aside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const Aside = component$(() => {
{title}
</a>
) : (
<span class="mb-2 block rounded bg-blue-700 px-4 py-1 text-base font-bold uppercase text-white no-underline">
<span class="mb-2 block rounded bg-blue-700 dark:bg-blue-600 px-4 py-1 text-base font-bold uppercase text-white no-underline">
{text}
</span>
)}
Expand Down
61 changes: 37 additions & 24 deletions docs/src/components/Toc/Toc.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { cn } from "~/utils/cn";
import { component$, useSignal, $, useOnWindow } from '@qwik.dev/core';
import type { ContentHeading } from '@qwik.dev/router';
import { component$, useSignal, $, useOnWindow } from "@qwik.dev/core";
import type { ContentHeading } from "@qwik.dev/router";

export const Toc = component$(
({ headings }: { headings: ContentHeading[] }) => {
if (headings.length === 0) {
return null;
}
return (
<div class="space-y-2 sticky top-24 max-h-[calc(80vh)] p-1 dark:text-white text-black hidden xl:block">
<div class="font-medium">On This Page</div>
<div class="sticky top-24 hidden max-h-[calc(80vh)] space-y-2 p-1 text-black dark:text-white xl:block">
<div class="mb-2 block rounded bg-blue-700 px-4 py-1 text-base font-bold uppercase text-white no-underline dark:bg-blue-600">
On this page
</div>
<TableOfContents headings={headings} />
</div>
);
Expand All @@ -25,30 +27,39 @@ interface Node extends ContentHeading {
type Tree = Array<Node>;

const TableOfContents = component$<TableOfContentsProps>(({ headings }) => {
const sanitizedHeadings = headings.map(({ text, id, level }) => ({ text, id, level }));
const sanitizedHeadings = headings.map(({ text, id, level }) => ({
text,
id,
level,
}));
const itemIds = headings.map(({ id }) => id);
const activeHeading = useActiveItem(itemIds);
const tree = buildTree(sanitizedHeadings);
const fixStartingBug: Node = { ...tree, children: [tree] };
return <RecursiveList tree={fixStartingBug} activeItem={activeHeading.value ?? ''} />;
return (
<RecursiveList
tree={fixStartingBug}
activeItem={activeHeading.value ?? ""}
/>
);
});

function deltaToStrg(
currNode: Node,
nextNode: Node,
): 'same level' | 'down one level' | 'up one level' | 'upwards discontinuous' {
): "same level" | "down one level" | "up one level" | "upwards discontinuous" {
const delta = currNode.level - nextNode.level;
if (delta > 1) {
return 'upwards discontinuous';
return "upwards discontinuous";
}
if (delta === 1) {
return 'up one level';
return "up one level";
}
if (delta === 0) {
return 'same level';
return "same level";
}
if (delta === -1) {
return 'down one level';
return "down one level";
}

throw new Error(
Expand All @@ -68,25 +79,25 @@ function buildTree(nodes: ContentHeading[]) {
childrenMap.set(nextNode.level, nextNode.children);
const deltaStrg = deltaToStrg(currNode, nextNode);
switch (deltaStrg) {
case 'upwards discontinuous': {
case "upwards discontinuous": {
const delta = currNode.level - nextNode.level;
if (childrenMap.has(delta - 1)) {
const nthParent = childrenMap.get(delta - 1);
nthParent?.push(nextNode);
}
break;
}
case 'up one level': {
case "up one level": {
const grandParent = childrenMap.get(currNode.level - 2);
grandParent?.push(nextNode);
break;
}
case 'same level': {
case "same level": {
const parent = childrenMap.get(currNode.level - 1);
parent?.push(nextNode);
break;
}
case 'down one level': {
case "down one level": {
currNode.children.push(nextNode);
break;
}
Expand All @@ -107,7 +118,7 @@ type RecursiveListProps = {
const RecursiveList = component$<RecursiveListProps>(
({ tree, activeItem, limit = 3 }) => {
return tree.children.length && tree.level < limit ? (
<ul class={cn('m-0 list-none', { 'pl-4': tree.level !== 1 })}>
<ul class={cn("m-0 list-none", { "pl-4": tree.level !== 1 })}>
{tree.children.map((childNode) => (
<li key={childNode.id} class="mt-0 list-none pt-2">
<Anchor node={childNode} activeItem={activeItem} />
Expand All @@ -125,7 +136,7 @@ const useActiveItem = (itemIds: string[]) => {
const activeId = useSignal<string>();

useOnWindow(
'scroll',
"scroll",
$(() => {
const observer = new IntersectionObserver(
(entries) => {
Expand All @@ -135,7 +146,7 @@ const useActiveItem = (itemIds: string[]) => {
}
});
},
{ rootMargin: '0% 0% -85% 0%' },
{ rootMargin: "0% 0% -85% 0%" },
);

itemIds.forEach((id) => {
Expand Down Expand Up @@ -175,18 +186,20 @@ const Anchor = component$<AnchorProps>(({ node, activeItem }) => {
if (element) {
const navbarHeight = 90;
const position =
element.getBoundingClientRect().top + window.scrollY - navbarHeight;
window.scrollTo({ top: position, behavior: 'auto' });
element.getBoundingClientRect().top +
window.scrollY -
navbarHeight;
window.scrollTo({ top: position, behavior: "auto" });
}
}),
]}
class={cn(
node.level > 2 && 'ml-2',
'inline-block no-underline transition-colors',
isActive ? 'text-blue-500 dark:text-blue-300' : 'text-muted-foreground',
node.level > 2 && "ml-2",
"inline-block no-underline transition-colors",
isActive ? "text-blue-500 dark:text-blue-300" : "text-muted-foreground",
)}
>
{node.text}
</a>
);
});
});

0 comments on commit 67577dc

Please sign in to comment.