diff options
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/docs/.gitignore | 7 | ||||
| -rw-r--r-- | packages/docs/README.md | 14 | ||||
| -rw-r--r-- | packages/docs/app/app.css | 3 | ||||
| -rw-r--r-- | packages/docs/app/docs/page.tsx | 51 | ||||
| -rw-r--r-- | packages/docs/app/docs/search.ts | 12 | ||||
| -rw-r--r-- | packages/docs/app/lib/layout.shared.tsx | 9 | ||||
| -rw-r--r-- | packages/docs/app/lib/source.ts | 7 | ||||
| -rw-r--r-- | packages/docs/app/root.tsx | 73 | ||||
| -rw-r--r-- | packages/docs/app/routes.ts | 7 | ||||
| -rw-r--r-- | packages/docs/app/routes/home.tsx | 30 | ||||
| -rw-r--r-- | packages/docs/biome.json | 37 | ||||
| -rw-r--r-- | packages/docs/content/docs/index.mdx | 32 | ||||
| -rw-r--r-- | packages/docs/content/docs/meta.json | 3 | ||||
| -rw-r--r-- | packages/docs/content/docs/test.mdx | 24 | ||||
| -rw-r--r-- | packages/docs/package.json | 39 | ||||
| -rw-r--r-- | packages/docs/public/favicon.ico | bin | 0 -> 15086 bytes | |||
| -rw-r--r-- | packages/docs/react-router.config.ts | 23 | ||||
| -rw-r--r-- | packages/docs/source.config.ts | 7 | ||||
| -rw-r--r-- | packages/docs/tsconfig.json | 23 | ||||
| -rw-r--r-- | packages/docs/vite.config.ts | 17 |
20 files changed, 418 insertions, 0 deletions
diff --git a/packages/docs/.gitignore b/packages/docs/.gitignore new file mode 100644 index 0000000..8fa7200 --- /dev/null +++ b/packages/docs/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +/node_modules/ + +# React Router +/.react-router/ +/build/ +.source diff --git a/packages/docs/README.md b/packages/docs/README.md new file mode 100644 index 0000000..2b4c09a --- /dev/null +++ b/packages/docs/README.md @@ -0,0 +1,14 @@ +# docs + +This is a React Router application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). + +Run development server: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` diff --git a/packages/docs/app/app.css b/packages/docs/app/app.css new file mode 100644 index 0000000..50b3bc2 --- /dev/null +++ b/packages/docs/app/app.css @@ -0,0 +1,3 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; diff --git a/packages/docs/app/docs/page.tsx b/packages/docs/app/docs/page.tsx new file mode 100644 index 0000000..2618989 --- /dev/null +++ b/packages/docs/app/docs/page.tsx @@ -0,0 +1,51 @@ +import type { Route } from './+types/page'; +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/docs/page'; +import { source } from '@/lib/source'; +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import browserCollections from 'fumadocs-mdx:collections/browser'; +import { baseOptions } from '@/lib/layout.shared'; +import { useFumadocsLoader } from 'fumadocs-core/source/client'; + +export async function loader({ params }: Route.LoaderArgs) { + const slugs = params['*'].split('/').filter((v) => v.length > 0); + const page = source.getPage(slugs); + if (!page) throw new Response('Not found', { status: 404 }); + + return { + path: page.path, + pageTree: await source.serializePageTree(source.getPageTree()), + }; +} + +const clientLoader = browserCollections.docs.createClientLoader({ + component( + { toc, frontmatter, default: Mdx }, + // you can define props for the `<Content />` component + props?: { + className?: string; + }, + ) { + return ( + <DocsPage toc={toc} {...props}> + <title>{frontmatter.title}</title> + <meta name="description" content={frontmatter.description} /> + <DocsTitle>{frontmatter.title}</DocsTitle> + <DocsDescription>{frontmatter.description}</DocsDescription> + <DocsBody> + <Mdx components={{ ...defaultMdxComponents }} /> + </DocsBody> + </DocsPage> + ); + }, +}); + +export default function Page({ loaderData }: Route.ComponentProps) { + const { path, pageTree } = useFumadocsLoader(loaderData); + + return ( + <DocsLayout {...baseOptions()} tree={pageTree}> + {clientLoader.useContent(path)} + </DocsLayout> + ); +} diff --git a/packages/docs/app/docs/search.ts b/packages/docs/app/docs/search.ts new file mode 100644 index 0000000..9603c72 --- /dev/null +++ b/packages/docs/app/docs/search.ts @@ -0,0 +1,12 @@ +import type { Route } from './+types/search'; +import { createFromSource } from 'fumadocs-core/search/server'; +import { source } from '@/lib/source'; + +const server = createFromSource(source, { + // https://docs.orama.com/docs/orama-js/supported-languages + language: 'english', +}); + +export async function loader({ request }: Route.LoaderArgs) { + return server.GET(request); +} diff --git a/packages/docs/app/lib/layout.shared.tsx b/packages/docs/app/lib/layout.shared.tsx new file mode 100644 index 0000000..af2b6f0 --- /dev/null +++ b/packages/docs/app/lib/layout.shared.tsx @@ -0,0 +1,9 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; + +export function baseOptions(): BaseLayoutProps { + return { + nav: { + title: 'React Router', + }, + }; +} diff --git a/packages/docs/app/lib/source.ts b/packages/docs/app/lib/source.ts new file mode 100644 index 0000000..97cf767 --- /dev/null +++ b/packages/docs/app/lib/source.ts @@ -0,0 +1,7 @@ +import { loader } from 'fumadocs-core/source'; +import { docs } from 'fumadocs-mdx:collections/server'; + +export const source = loader({ + source: docs.toFumadocsSource(), + baseUrl: '/docs', +}); diff --git a/packages/docs/app/root.tsx b/packages/docs/app/root.tsx new file mode 100644 index 0000000..08b8aa8 --- /dev/null +++ b/packages/docs/app/root.tsx @@ -0,0 +1,73 @@ +import { + isRouteErrorResponse, + Links, + Meta, + Outlet, + Scripts, + ScrollRestoration, +} from 'react-router'; +import { RootProvider } from 'fumadocs-ui/provider/react-router'; +import type { Route } from './+types/root'; +import './app.css'; + +export const links: Route.LinksFunction = () => [ + { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, + { + rel: 'preconnect', + href: 'https://fonts.gstatic.com', + crossOrigin: 'anonymous', + }, + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap', + }, +]; + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + <html lang="en" suppressHydrationWarning> + <head> + <meta charSet="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <Meta /> + <Links /> + </head> + <body className="flex flex-col min-h-screen"> + <RootProvider>{children}</RootProvider> + <ScrollRestoration /> + <Scripts /> + </body> + </html> + ); +} + +export default function App() { + return <Outlet />; +} + +export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { + let message = 'Oops!'; + let details = 'An unexpected error occurred.'; + let stack: string | undefined; + + if (isRouteErrorResponse(error)) { + message = error.status === 404 ? '404' : 'Error'; + details = + error.status === 404 ? 'The requested page could not be found.' : error.statusText || details; + } else if (import.meta.env.DEV && error && error instanceof Error) { + details = error.message; + stack = error.stack; + } + + return ( + <main className="pt-16 p-4 w-full max-w-[1400px] mx-auto"> + <h1>{message}</h1> + <p>{details}</p> + {stack && ( + <pre className="w-full p-4 overflow-x-auto"> + <code>{stack}</code> + </pre> + )} + </main> + ); +} diff --git a/packages/docs/app/routes.ts b/packages/docs/app/routes.ts new file mode 100644 index 0000000..60dd630 --- /dev/null +++ b/packages/docs/app/routes.ts @@ -0,0 +1,7 @@ +import { index, route, type RouteConfig } from '@react-router/dev/routes'; + +export default [ + index('routes/home.tsx'), + route('docs/*', 'docs/page.tsx'), + route('api/search', 'docs/search.ts'), +] satisfies RouteConfig; diff --git a/packages/docs/app/routes/home.tsx b/packages/docs/app/routes/home.tsx new file mode 100644 index 0000000..7f03ba9 --- /dev/null +++ b/packages/docs/app/routes/home.tsx @@ -0,0 +1,30 @@ +import type { Route } from './+types/home'; +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { Link } from 'react-router'; +import { baseOptions } from '@/lib/layout.shared'; + +export function meta({}: Route.MetaArgs) { + return [ + { title: 'New React Router App' }, + { name: 'description', content: 'Welcome to React Router!' }, + ]; +} + +export default function Home() { + return ( + <HomeLayout {...baseOptions()}> + <div className="p-4 flex flex-col items-center justify-center text-center flex-1"> + <h1 className="text-xl font-bold mb-2">Fumadocs on React Router.</h1> + <p className="text-fd-muted-foreground mb-4"> + The truly flexible docs framework on React.js. + </p> + <Link + className="text-sm bg-fd-primary text-fd-primary-foreground rounded-full font-medium px-4 py-2.5" + to="/docs" + > + Open Docs + </Link> + </div> + </HomeLayout> + ); +} diff --git a/packages/docs/biome.json b/packages/docs/biome.json new file mode 100644 index 0000000..a637e58 --- /dev/null +++ b/packages/docs/biome.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.0/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!node_modules", + "!.source" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + }, + "domains": { + "react": "recommended" + } + }, + "assist": { + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/packages/docs/content/docs/index.mdx b/packages/docs/content/docs/index.mdx new file mode 100644 index 0000000..6c2e629 --- /dev/null +++ b/packages/docs/content/docs/index.mdx @@ -0,0 +1,32 @@ +--- +title: Hello World +description: | + Your first `document` + You'll love it! +--- + +Hey there! Fumadocs is the docs framework that also works on React Router! + +## Heading + +Hello World + +<Cards> + <Card title="Learn more about React Router" href="https://reactrouter.com" /> + <Card title="Learn more about Fumadocs" href="https://fumadocs.dev" /> +</Cards> + +```ts +console.log('I love React!'); +``` + +### Heading + +#### Heading + +| Head | Description | +| ------------------------------- | ----------------------------------- | +| `hello` | Hello World | +| very **important** | Hey | +| _Surprisingly_ | Fumadocs | +| very long text that looks weird | hello world hello world hello world | diff --git a/packages/docs/content/docs/meta.json b/packages/docs/content/docs/meta.json new file mode 100644 index 0000000..bc00362 --- /dev/null +++ b/packages/docs/content/docs/meta.json @@ -0,0 +1,3 @@ +{ + "pages": ["index", "..."] +} diff --git a/packages/docs/content/docs/test.mdx b/packages/docs/content/docs/test.mdx new file mode 100644 index 0000000..cac4d26 --- /dev/null +++ b/packages/docs/content/docs/test.mdx @@ -0,0 +1,24 @@ +--- +title: Test +description: A document to test Fumadocs +--- + +Hey there! + +## Cards + +<Cards> + <Card title="Learn more about Next.js" href="https://nextjs.org/docs" /> + <Card title="Learn more about Fumadocs" href="https://fumadocs.dev" /> +</Cards> + +### CodeBlock + +```js +console.log('Hello World'); +``` + +#### List + +- Hello +- World diff --git a/packages/docs/package.json b/packages/docs/package.json new file mode 100644 index 0000000..18a5bf3 --- /dev/null +++ b/packages/docs/package.json @@ -0,0 +1,39 @@ +{ + "name": "@dropout/docs", + "private": true, + "type": "module", + "scripts": { + "build": "react-router build", + "dev": "react-router dev", + "start": "react-router-serve ./build/server/index.js", + "types:check": "react-router typegen && fumadocs-mdx && tsc --noEmit", + "postinstall": "fumadocs-mdx", + "lint": "biome check", + "format": "biome format --write" + }, + "dependencies": { + "@react-router/node": "^7.12.0", + "@react-router/serve": "^7.12.0", + "fumadocs-core": "16.4.7", + "fumadocs-mdx": "14.2.6", + "fumadocs-ui": "16.4.7", + "isbot": "^5.1.32", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "react-router": "^7.12.0" + }, + "devDependencies": { + "@react-router/dev": "^7.12.0", + "@tailwindcss/vite": "^4.1.18", + "@types/mdx": "^2.0.13", + "@types/node": "^25.0.5", + "@types/react": "^19.2.8", + "@types/react-dom": "^19.2.3", + "react-router-devtools": "^6.1.0", + "tailwindcss": "^4.1.18", + "typescript": "^5.9.3", + "vite": "^7.3.1", + "vite-tsconfig-paths": "^6.0.4", + "@biomejs/biome": "^2.3.11" + } +} diff --git a/packages/docs/public/favicon.ico b/packages/docs/public/favicon.ico Binary files differnew file mode 100644 index 0000000..5dbdfcd --- /dev/null +++ b/packages/docs/public/favicon.ico diff --git a/packages/docs/react-router.config.ts b/packages/docs/react-router.config.ts new file mode 100644 index 0000000..cfcfbe4 --- /dev/null +++ b/packages/docs/react-router.config.ts @@ -0,0 +1,23 @@ +import type { Config } from '@react-router/dev/config'; +import { glob } from 'node:fs/promises'; +import { createGetUrl, getSlugs } from 'fumadocs-core/source'; + +const getUrl = createGetUrl('/docs'); + +export default { + ssr: true, + async prerender({ getStaticPaths }) { + const paths: string[] = []; + const excluded: string[] = ['/api/search']; + + for (const path of getStaticPaths()) { + if (!excluded.includes(path)) paths.push(path); + } + + for await (const entry of glob('**/*.mdx', { cwd: 'content/docs' })) { + paths.push(getUrl(getSlugs(entry))); + } + + return paths; + }, +} satisfies Config; diff --git a/packages/docs/source.config.ts b/packages/docs/source.config.ts new file mode 100644 index 0000000..0564068 --- /dev/null +++ b/packages/docs/source.config.ts @@ -0,0 +1,7 @@ +import { defineConfig, defineDocs } from 'fumadocs-mdx/config'; + +export const docs = defineDocs({ + dir: 'content/docs', +}); + +export default defineConfig(); diff --git a/packages/docs/tsconfig.json b/packages/docs/tsconfig.json new file mode 100644 index 0000000..717253d --- /dev/null +++ b/packages/docs/tsconfig.json @@ -0,0 +1,23 @@ +{ + "include": ["**/*", "**/.server/**/*", "**/.client/**/*", ".react-router/types/**/*"], + "compilerOptions": { + "lib": ["DOM", "DOM.Iterable", "ES2022"], + "types": ["node", "vite/client"], + "target": "esnext", + "module": "esnext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "rootDirs": [".", "./.react-router/types"], + "baseUrl": ".", + "paths": { + "@/*": ["./app/*"], + "fumadocs-mdx:collections/*": [".source/*"] + }, + "esModuleInterop": true, + "verbatimModuleSyntax": true, + "noEmit": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true + } +} diff --git a/packages/docs/vite.config.ts b/packages/docs/vite.config.ts new file mode 100644 index 0000000..f408dc5 --- /dev/null +++ b/packages/docs/vite.config.ts @@ -0,0 +1,17 @@ +import { reactRouter } from '@react-router/dev/vite'; +import tailwindcss from '@tailwindcss/vite'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import mdx from 'fumadocs-mdx/vite'; +import * as MdxConfig from './source.config'; + +export default defineConfig({ + plugins: [ + mdx(MdxConfig), + tailwindcss(), + reactRouter(), + tsconfigPaths({ + root: __dirname, + }), + ], +}); |