Skip to content

Commit ed266df

Browse files
committed
docs: add copy mdx
1 parent 507dd15 commit ed266df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+611
-247
lines changed

pnpm-lock.yaml

Lines changed: 26 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { components, guides, overviews, snippets, utilities } from ".velite"
2+
import { expandComponentContent } from "lib/mdx-expansion"
3+
import { NextRequest, NextResponse } from "next/server"
4+
5+
// Default finder function for most collections
6+
const defaultFindBy = (d: any, slug: string) => d.slug === slug
7+
8+
// Define collection mappings for cleaner lookups
9+
const collections: Record<
10+
string,
11+
{
12+
data: any[]
13+
findBy?: (d: any, slug: string) => boolean
14+
}
15+
> = {
16+
overview: { data: overviews },
17+
components: { data: components },
18+
guides: { data: guides },
19+
utilities: { data: utilities },
20+
snippets: {
21+
data: snippets,
22+
findBy: (d, slug) => d.frontmatter?.slug === `/snippets/${slug}`,
23+
},
24+
}
25+
26+
type CollectionType = keyof typeof collections
27+
28+
function findDocument(category: string, slug: string) {
29+
// First, try to find in the specified category
30+
const collection = collections[category as CollectionType]
31+
if (collection) {
32+
const findBy = collection.findBy || defaultFindBy
33+
const doc = collection.data.find((d) => findBy(d, slug))
34+
if (doc) {
35+
return {
36+
doc,
37+
contentType:
38+
category === "components" ? "component" : (category as string),
39+
}
40+
}
41+
}
42+
43+
// If not found or invalid category, search all collections using the category as the slug
44+
for (const [type, collection] of Object.entries(collections)) {
45+
if (type === "snippets") continue // Skip snippets for direct slug search
46+
47+
const findBy = collection.findBy || defaultFindBy
48+
const doc = collection.data.find((d) => findBy(d, category))
49+
if (doc) {
50+
return { doc, contentType: type === "components" ? "component" : type }
51+
}
52+
}
53+
54+
return { doc: null, contentType: null }
55+
}
56+
57+
export async function GET(
58+
_request: NextRequest,
59+
context: { params: Promise<{ slug: string[] }> },
60+
) {
61+
const { slug } = await context.params
62+
63+
if (!slug || slug.length === 0) {
64+
return NextResponse.json({ error: "No slug provided" }, { status: 400 })
65+
}
66+
67+
let category = slug[0]
68+
let rest = slug.slice(1)
69+
let framework: string | undefined
70+
71+
// Check if the path is like /components/react/avatar
72+
// If second segment is a framework, extract it
73+
if (category === "components" && rest.length >= 2) {
74+
const possibleFramework = rest[0]
75+
if (["react", "vue", "solid", "svelte"].includes(possibleFramework)) {
76+
framework = possibleFramework
77+
rest = rest.slice(1) // Remove framework from the path
78+
}
79+
}
80+
81+
const searchSlug = rest.join("/")
82+
const { doc, contentType } = findDocument(category, searchSlug)
83+
84+
if (!doc) {
85+
return NextResponse.json({ error: "Content not found" }, { status: 404 })
86+
}
87+
88+
// Get the raw content
89+
let rawContent = doc.body?.raw || doc.raw || doc.content || ""
90+
91+
// Expand component content (CodeSnippets, ApiTable, ContextTable, etc.) if content type is component
92+
if (contentType === "component" && rawContent) {
93+
const componentId = doc.slug // The slug is the component ID (e.g., "accordion", "dialog", etc.)
94+
rawContent = expandComponentContent(rawContent, componentId, doc, framework)
95+
}
96+
97+
// Return all available data from velite
98+
const response = {
99+
// Core fields
100+
slug: doc.slug,
101+
title: doc.title || doc.frontmatter?.title,
102+
description: doc.description || doc.frontmatter?.description,
103+
contentType,
104+
framework, // Include the framework if specified
105+
106+
// Content with expanded snippets
107+
content: rawContent,
108+
html: doc.body?.html || doc.html,
109+
110+
// Package info
111+
package: doc.package || doc.frontmatter?.package,
112+
113+
// URLs
114+
editUrl: doc.editUrl,
115+
permalink: doc.permalink,
116+
}
117+
118+
return NextResponse.json(response)
119+
}

website/app/docs-layout.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client"
22

3+
import { CopyPageWidget } from "components/copy-page-widget"
34
import { FrameworkSelect } from "components/framework-select"
45
import { MdxFooter } from "components/mdx-footer"
56
import { EditPageLink } from "components/mdx/edit-page-link"
@@ -8,7 +9,8 @@ import { Sidebar } from "components/sidebar"
89
import { SkipNavContent, SkipNavLink } from "components/skip-nav"
910
import { TableOfContents } from "components/toc"
1011
import { TopNavigation } from "components/top-navigation"
11-
import { Box, Spacer, styled } from "styled-system/jsx"
12+
import { usePathname } from "next/navigation"
13+
import { Box, Flex, Spacer, styled } from "styled-system/jsx"
1214

1315
type DocsLayoutProps = {
1416
children: React.ReactNode
@@ -24,6 +26,7 @@ export default function DocsLayout(props: DocsLayoutProps) {
2426
const { children, doc, toc } = props
2527
const tableOfContent = toc?.data ?? doc.frontmatter?.toc ?? []
2628
const hideToc = tableOfContent.length < 2
29+
const pathname = usePathname()
2730

2831
return (
2932
<Box>
@@ -65,6 +68,20 @@ export default function DocsLayout(props: DocsLayoutProps) {
6568
pr={{ xl: "16" }}
6669
>
6770
<Box mr={{ xl: "15.5rem" }}>
71+
{doc?.title && (
72+
<Flex alignItems="center" gap="4" mb="6">
73+
<styled.h1 textStyle="display.lg" maxW="85ch" flex="1">
74+
{doc.title}
75+
</styled.h1>
76+
{doc?.body?.raw && (
77+
<CopyPageWidget
78+
slug={pathname}
79+
content={doc.body.raw}
80+
title={doc.title}
81+
/>
82+
)}
83+
</Flex>
84+
)}
6885
{children}
6986
{doc?.editUrl && (
7087
<EditPageLink href={doc.editUrl}>

0 commit comments

Comments
 (0)