Skip to content
Open
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
53 changes: 53 additions & 0 deletions docs/src/lib/navigation-neighbors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { Navigation, NavigationNeighbor, NavigationNeighbors } from "@svecodocs/kit";

export type NavigationNeighborMap = Map<string, NavigationNeighbors>;

function flatNavigationAnchors(navigationAnchors: Navigation["anchors"]): NavigationNeighbor[] {
if (!navigationAnchors) {
return [];
}
return navigationAnchors.filter((anchor) => !anchor.disabled);
}

function flatNavigationSections(navigationSections: Navigation["sections"]): NavigationNeighbor[] {
const sections: NavigationNeighbor[] = [];

if (!navigationSections) {
return sections;
}

for (const section of navigationSections) {
if (section?.items) {
for (const navigation of section.items) {
if (!navigation.disabled && navigation.href) {
sections.push({
title: navigation.title,
description: navigation.description || "",
href: navigation.href,
});
}
}
}
}
return sections;
}

export function getFlattenedNavigableItems(navigationConfig: Navigation): NavigationNeighbor[] {
const anchors = flatNavigationAnchors(navigationConfig.anchors);
const sections = flatNavigationSections(navigationConfig.sections);
return [...anchors, ...sections];
}

export function preCalculateNavigationNeighbors(navigation: Navigation): NavigationNeighborMap {
const navigableItems = getFlattenedNavigableItems(navigation);
const lookupMap: NavigationNeighborMap = new Map();

const { length } = navigableItems;
for (let i = 0; i < length; i++) {
const previous = i > 0 ? navigableItems[i - 1] : undefined;
const next = i < length - 1 ? navigableItems[i + 1] : undefined;
lookupMap.set(navigableItems[i].href, { previous, next });
}

return lookupMap;
}
35 changes: 23 additions & 12 deletions docs/src/lib/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,42 @@ import ChalkboardTeacher from "phosphor-svelte/lib/ChalkboardTeacher";
import RocketLaunch from "phosphor-svelte/lib/RocketLaunch";
import Tag from "phosphor-svelte/lib/Tag";
import { getAllDocs } from "./utils.js";
import type { Doc } from "$content/index";
import { preCalculateNavigationNeighbors } from "$lib/navigation-neighbors";

const allDocs = getAllDocs();

const components = allDocs
.filter((doc) => doc.section === "Components")
.map((doc) => ({
title: doc.title,
href: `/docs/${doc.slug}`,
}));
export function getSectionDocs(section: Doc["section"], pathPrefix = "/docs/") {
return allDocs
.filter((doc) => doc.section === section)
.map((doc) => ({
title: doc.title,
href: `${pathPrefix}${doc.slug}`,
description: doc.description,
}));
}

const configuration = allDocs
.filter((doc) => doc.section === "Configuration")
.map((doc) => ({
title: doc.title,
href: `/docs/${doc.slug}`,
}));
const components = getSectionDocs("Components");

const configuration = getSectionDocs("Configuration");

export const navigation = defineNavigation({
anchors: [
{
title: "Introduction",
href: "/docs",
description: "What exactly is Svecodocs?",
icon: ChalkboardTeacher,
},
{
title: "Getting Started",
href: "/docs/getting-started",
description: "A quick guide to get started using Svecodocs",
icon: RocketLaunch,
},
{
title: "Releases",
description: "See the latest changes and updates",
href: "https://github.com/svecosystem/svecodocs/releases",
icon: Tag,
},
Expand All @@ -49,3 +54,9 @@ export const navigation = defineNavigation({
},
],
});

export const neighborLookup = preCalculateNavigationNeighbors(navigation);

export function getNavigationNeighbors(pathname: string) {
return neighborLookup.get(pathname);
}
8 changes: 7 additions & 1 deletion docs/src/routes/(docs)/docs/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<script lang="ts">
import { DocPage } from "@svecodocs/kit";
import { getNavigationNeighbors } from "$lib/navigation";
import { page } from "$app/state";
let { data } = $props();
</script>

<DocPage component={data.component} {...data.metadata} />
<DocPage
component={data.component}
{...data.metadata}
navigationNeighbors={getNavigationNeighbors(page.url.pathname)}
/>
8 changes: 7 additions & 1 deletion docs/src/routes/(docs)/docs/[...slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<script lang="ts">
import { DocPage } from "@svecodocs/kit";
import { getNavigationNeighbors } from "$lib/navigation";
import { page } from "$app/state";
let { data } = $props();
</script>

<DocPage component={data.component} {...data.metadata} />
<DocPage
component={data.component}
{...data.metadata}
navigationNeighbors={getNavigationNeighbors(page.url.pathname)}
/>
2 changes: 1 addition & 1 deletion docs/src/routes/api/search.json/search.json

Large diffs are not rendered by default.

19 changes: 14 additions & 5 deletions packages/kit/src/lib/components/layout/doc-page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import PageHeader from "$lib/components/layout/page-header/page-header.svelte";
import Toc from "$lib/components/toc/toc.svelte";
import type { Component, ComponentProps } from "svelte";
import type { Contributor, TOCEntry } from "$lib/types.js";
import type { Contributor, TOCEntry, NavigationNeighbors } from "$lib/types.js";
import Metadata from "../metadata.svelte";
import ContributorSection from "../contributors-section.svelte";
import NavigationNeighborButtons from "./navigation-neighbors.svelte";

let {
component,
Expand All @@ -14,6 +15,7 @@
toc,
metadata = {},
contributors = [],
navigationNeighbors,
}: {
component: Component;
componentProps?: Record<string, unknown>;
Expand All @@ -22,6 +24,7 @@
toc: TOCEntry[];
metadata?: ComponentProps<typeof Metadata>;
contributors?: Contributor[];
navigationNeighbors?: NavigationNeighbors;
} = $props();

const PageComponent = $derived(component);
Expand All @@ -40,9 +43,15 @@
<aside>
<Toc toc={{ items: tocItems }} type="mobile" />
</aside>
<main class="mx-auto w-full min-w-0 max-w-[640px] pb-12 2xl:max-w-[760px]" id="main-content">
<PageHeader {title} {description} />
<PageComponent {...componentProps} />
<ContributorSection {contributors} />
<main
class="mx-auto flex h-full w-full min-w-0 max-w-[640px] flex-col pb-12 2xl:max-w-[760px]"
id="main-content"
>
<div class="flex-1">
<PageHeader {title} {description} />
<PageComponent {...componentProps} />
<ContributorSection {contributors} />
</div>
<NavigationNeighborButtons {...navigationNeighbors} />
</main>
</div>
71 changes: 71 additions & 0 deletions packages/kit/src/lib/components/layout/navigation-neighbors.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<script lang="ts">
import type { NavigationNeighbors } from "$lib/types.js";
import { Button } from "$lib/components/ui/button/index.js";

type Props = NavigationNeighbors;

let { previous, next }: Props = $props();
</script>

{#if previous || next}
<div class="mt-6 flex w-full flex-col gap-2 lg:flex-row">
{#if previous}
{@const isExternalLink = !previous.href.startsWith("/")}
<Button
variant="subtle"
href={previous.href}
target={isExternalLink ? "_blank" : undefined}
class="flex h-fit w-full flex-col items-start gap-2 rounded-lg p-4 text-sm"
>
<div class="inline-flex items-center gap-1.5 font-medium">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="-mx-1 size-4 shrink-0 rtl:rotate-180"
><path d="m15 18-6-6 6-6"></path></svg
>
<p>{previous.title}</p>
</div>
<p class="text-muted-foreground w-[90%] truncate font-normal">
{previous.description}
</p>
</Button>
{/if}
{#if next}
{@const isExternalLink = !next.href.startsWith("/")}
<Button
variant="subtle"
href={next.href}
target={isExternalLink ? "_blank" : undefined}
class="flex h-fit w-full flex-col items-end gap-2 rounded-lg p-4 text-end text-sm"
>
<div class="inline-flex flex-row-reverse items-center gap-1.5 font-medium">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="-mx-1 size-4 shrink-0 rtl:rotate-180"
><path d="m9 18 6-6-6-6"></path></svg
>
<p>{next.title}</p>
</div>
<p class="text-muted-foreground w-[90%] truncate font-normal">
{next.description}
</p>
</Button>
{/if}
</div>
{/if}
13 changes: 13 additions & 0 deletions packages/kit/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type AnchorNavItem = {
title: string;
href: string;
icon: Component;
description: string;
disabled?: boolean;
};

Expand All @@ -36,6 +37,7 @@ export type SidebarNavSection = {

export type SidebarNavItem = {
title: string;
description: string;
href?: string;
disabled?: boolean;
external?: boolean;
Expand All @@ -49,6 +51,17 @@ export type Navigation = {
items?: SidebarNavItem[];
};

export type NavigationNeighbor = {
title: string;
description: string;
href: string;
};

export type NavigationNeighbors = {
previous?: NavigationNeighbor;
next?: NavigationNeighbor;
};

export type TOCEntry = {
title: string;
url: string;
Expand Down
Loading