Skip to content
Merged
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
30 changes: 10 additions & 20 deletions scripts/verify-static-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,26 @@ const apiSymbolsByRoute = new Map(
apiSymbolSets[entrypoint.symbolSet as keyof typeof apiSymbolSets],
])
);
const docsHome = docsCatalog.find((page) => page.route === '/docs');
if (!docsHome) throw new Error('Missing /docs catalog entry');

const marketing = [
{ route: '/', ...marketingRouteMetadata['/'] },
...marketingPages.map((page) => ({
route: page.path,
title: page.title,
description: page.description,
})),
{
route: '/docs',
title: `${docsHome.title} | Askr`,
description: docsHome.description,
},
{ route: '/404', ...marketingRouteMetadata['/404'] },
].map((page) => ({ ...page, layout: 'marketing' }));

const docs = docsCatalog
.filter((page) => page.route !== '/docs')
.map((page) => ({
route: page.route,
title: `${page.title} | Askr`,
description: page.description,
headings: page.headings.map(({ id }) => ({ id })),
apiSymbols: apiSymbolsByRoute
.get(page.route)
?.map(({ anchor }) => ({ anchor })),
layout: 'docs',
}));
const docs = docsCatalog.map((page) => ({
route: page.route,
title: `${page.title} | Askr`,
description: page.description,
headings: page.headings.map(({ id }) => ({ id })),
apiSymbols: apiSymbolsByRoute
.get(page.route)
?.map(({ anchor }) => ({ anchor })),
layout: 'docs',
}));

const expectations = [...marketing, ...docs];
const expectedRoutes = new Set(expectations.map(({ route }) => route));
Expand Down
20 changes: 0 additions & 20 deletions src/pages/_routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from './marketing/_routes';
import { DocsLayout } from './docs/_layout';
import { docsCatalog } from './docs/catalog';
import { MarketingLayout } from './marketing/_layout';

export type { RouteMetadata } from './marketing/_routes';

Expand All @@ -23,15 +22,8 @@ export const routeMetadata: Readonly<Record<string, RouteMetadata>> = {
export const routeRegistry = createRouteRegistry(() => {
registerMarketingRoutes();

const docsHome = docsCatalog.find((page) => page.route === '/docs');
if (!docsHome) throw new Error('Missing /docs catalog entry');
group({ layout: MarketingLayout }, () => {
route('/docs', lazy(docsHome.loader), { meta: routeMetadata['/docs'] });
});

group({ layout: DocsLayout }, () => {
for (const page of docsCatalog) {
if (page.route === '/docs') continue;
route(page.route, lazy(page.loader), {
meta: routeMetadata[page.route],
});
Expand All @@ -49,20 +41,8 @@ export async function createStaticRouteRegistry() {
const registry = createRouteRegistry(() => {
registerMarketingRoutes();

const docsHome = docsCatalog.find((page) => page.route === '/docs');
if (!docsHome) throw new Error('Missing /docs catalog entry');
group({ layout: MarketingLayout }, () => {
let component = components.get(docsHome.loader);
if (!component) {
component = lazy(docsHome.loader);
components.set(docsHome.loader, component);
}
route('/docs', component, { meta: routeMetadata['/docs'] });
});

group({ layout: DocsLayout }, () => {
for (const page of docsCatalog) {
if (page.route === '/docs') continue;
let component = components.get(page.loader);
if (!component) {
component = lazy(page.loader);
Expand Down
118 changes: 33 additions & 85 deletions src/pages/docs/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@ import {
SidebarScope,
SidebarTrigger,
} from '@askrjs/themes/components';
import {
BookOpenIcon,
CompassIcon,
Layers3Icon,
LibraryIcon,
MonitorIcon,
PanelsTopLeftIcon,
RocketIcon,
RouteIcon,
ServerIcon,
WrenchIcon,
} from '@askrjs/lucide';
import { SiteLayout } from '../site-layout';
import {
docsByRoute,
Expand All @@ -35,84 +23,44 @@ import {

function DocsNavigation({ close }: { close?: () => void }) {
const activePath = resolveDocsRoute(currentRoute());
const sectionIcons = [
BookOpenIcon,
RocketIcon,
Layers3Icon,
RouteIcon,
MonitorIcon,
ServerIcon,
PanelsTopLeftIcon,
WrenchIcon,
CompassIcon,
LibraryIcon,
] as const;

return (
<SidebarContent as="nav" aria-label="Documentation navigation">
{docsSections.map((section, sectionIndex) => {
const active = section.pages.some((page) => page.route === activePath);
const SectionIcon = sectionIcons[sectionIndex] ?? BookOpenIcon;
const subsections = section.pages.reduce((groups, page) => {
const label = page.navSection ?? section.label;
const pages = groups.get(label) ?? [];
pages.push(page);
groups.set(label, pages);
return groups;
}, new Map<string, (typeof section.pages)[number][]>());

{docsSections.map((section) => {
return (
<SidebarGroup data-nav-section={section.id}>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton asChild active={active}>
<Link href={section.landingRoute} onClick={close}>
<SectionIcon size={18} aria-hidden="true" />
<span>{section.label}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
{active && (
<SidebarGroupContent>
{Array.from(subsections).map(([label, pages]) => (
<div>
{label !== section.label && (
<SidebarGroupLabel>{label}</SidebarGroupLabel>
)}
<SidebarMenu>
{pages.map((page) => (
<SidebarMenuItem>
<SidebarMenuButton
asChild
active={page.route === activePath}
size="sm"
<SidebarGroup key={section.id} data-nav-section={section.id}>
<SidebarGroupLabel>{section.label}</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{section.pages.map((page) => (
<SidebarMenuItem key={page.route}>
<SidebarMenuButton
asChild
active={page.route === activePath}
size="sm"
>
<Link
href={page.route}
aria-current={
page.route === activePath ? 'page' : undefined
}
onClick={close}
>
<span>{page.title}</span>
{page.status !== 'stable' && (
<span
class="docs-sidebar-nav__status"
title={page.status}
>
<Link
href={page.route}
aria-current={
page.route === activePath ? 'page' : undefined
}
onClick={close}
>
<span>{page.title}</span>
{page.status !== 'stable' && (
<span
class="docs-sidebar-nav__status"
title={page.status}
>
</span>
)}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</div>
</span>
)}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarGroupContent>
)}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
);
})}
Expand All @@ -130,7 +78,7 @@ function TableOfContents() {
<p>On this page</p>
<ul>
{headings.map((heading) => (
<li>
<li key={heading.id}>
<a href={`#${heading.id}`}>{heading.title}</a>
</li>
))}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/docs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function HeadingContent({
}: {
item: DocsHeadingDefinition;
page: DocsPageDefinition;
[prop: string]: unknown;
}) {
return (
<section aria-labelledby={item.id}>
Expand Down Expand Up @@ -186,7 +187,7 @@ export default function DocsPage() {
<UsageGuide page={page} />
<ComponentDemo page={page} />
{page.headings.map((item) => (
<HeadingContent item={item} page={page} />
<HeadingContent key={item.id} item={item} page={page} />
))}
{page.route === '/docs' && (
<>
Expand Down