Skip to content

Commit 7b6b368

Browse files
committedMar 7, 2025
chore(docs): Initializing the documentation project
1 parent a55f810 commit 7b6b368

39 files changed

+1369
-1
lines changed
 

‎docs/.gitignore

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Cache
16+
.vite
17+
.rasengan
18+
19+
# Editor directories and files
20+
.vscode/*
21+
!.vscode/extensions.json
22+
.idea
23+
.DS_Store
24+
*.suo
25+
*.ntvs*
26+
*.njsproj
27+
*.sln
28+
*.sw?
29+
30+
# Local Netlify folder
31+
.netlify
32+
33+
# Local Vercel folder
34+
.vercel

‎docs/package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "rasengan-docs",
3+
"private": false,
4+
"version": "1.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "rasengan dev",
8+
"build": "rasengan build",
9+
"serve": "rasengan-serve ./dist"
10+
},
11+
"dependencies": {
12+
"@rasenganjs/image": "^1.0.0",
13+
"@rasenganjs/mdx": "1.1.0-beta.0",
14+
"@rasenganjs/serve": "1.0.0-beta.54",
15+
"@rasenganjs/theme": "^1.0.1",
16+
"@tailwindcss/vite": "^4.*",
17+
"lucide-react": "^0.477.0",
18+
"motion": "^12.4.10",
19+
"rasengan": "workspace:1.0.0-beta.57",
20+
"react": "^19.0.0",
21+
"react-dom": "^19.0.0",
22+
"tailwind-merge": "^3.0.2",
23+
"tailwindcss": "^4.*"
24+
},
25+
"devDependencies": {
26+
"@types/react": "^19.0.0",
27+
"@types/react-dom": "^19.0.0",
28+
"cross-env": "^7.0.3",
29+
"typescript": "^5.1.3",
30+
"vite": "^6.0.0"
31+
}
32+
}

‎docs/public/icons/github.svg

+3
Loading

‎docs/public/rasengan.svg

+72
Loading

‎docs/public/robots.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
user-agent: *
2+
disallow: /downloads/
3+
disallow: /private/
4+
allow: /
5+
6+
user-agent: magicsearchbot
7+
disallow: /uploads/

‎docs/rasengan-env.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="rasengan/types/client" />

‎docs/rasengan.config.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { defineConfig } from 'rasengan';
2+
import tailwindcss from '@tailwindcss/vite';
3+
import mdx from '@rasenganjs/mdx/plugin';
4+
5+
export default defineConfig(async () => {
6+
return {
7+
vite: {
8+
plugins: [mdx(), tailwindcss()],
9+
},
10+
};
11+
});

‎docs/src/app/app.layout.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
import { Outlet, LayoutComponent } from 'rasengan';
3+
import { useTheme } from '@rasenganjs/theme';
4+
import { twMerge } from 'tailwind-merge';
5+
6+
const AppLayout: LayoutComponent = () => {
7+
const { isDark } = useTheme();
8+
9+
return (
10+
<section
11+
className={twMerge(
12+
'w-full h-screen overflow-y-auto bg-background font-lexend-light text-foreground',
13+
isDark ? 'dark' : ''
14+
)}
15+
>
16+
<Outlet />
17+
</section>
18+
);
19+
};
20+
21+
AppLayout.path = '/';
22+
23+
export default AppLayout;

‎docs/src/app/app.router.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { RouterComponent, defineRouter } from 'rasengan';
2+
import RootRouter from '@/app/root/root.router';
3+
import AppLayout from '@/app/app.layout';
4+
import DocsRouter from '@/app/docs/docs.router';
5+
6+
class AppRouter extends RouterComponent {}
7+
8+
export default defineRouter({
9+
imports: [RootRouter, DocsRouter],
10+
layout: AppLayout,
11+
pages: [],
12+
})(AppRouter);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { NavigationData, NavigationGroup, NavigationItem } from '@/data/docs';
2+
import { BookOpen, Box, ChevronDown, LayoutTemplate, Tag } from 'lucide-react';
3+
import { motion, AnimatePresence } from 'motion/react';
4+
import { ComponentProps, Fragment, useState } from 'react';
5+
import { twMerge } from 'tailwind-merge';
6+
7+
export default function SidebarNavigation() {
8+
const [activeTab, setActiveTab] = useState(NavigationGroup.DOCUMENTATION);
9+
10+
return (
11+
<aside className="w-[280px] border-r-[1px] border-r-border text-foreground">
12+
<section className="sticky top-8 w-full h-full max-h-[calc(100vh)] overflow-y-auto pt-16 p-6">
13+
<div className="flex flex-col gap-4 text-sm border-b-[1px] border-b-border pb-8">
14+
<div className="flex items-center mb-6 gap-2">
15+
<div className="size-10 rounded-md border-[1px] border-primary/40 bg-primary/10 flex items-center justify-center">
16+
<Tag size={20} className="text-primary" />
17+
</div>
18+
19+
<div className="flex flex-col gap-1">
20+
<span>Using stable version</span>
21+
<span className="text-[12px] text-foreground/60">v1.2.4</span>
22+
</div>
23+
</div>
24+
25+
<div className="flex items-center gap-4 text-primary hover:cursor-pointer">
26+
<BookOpen size={20} />
27+
<span>Documentation</span>
28+
</div>
29+
<div className="flex items-center gap-4 text-foreground/90 hover:cursor-pointer hover:text-primary transition-all">
30+
<Box size={20} />
31+
<span>Packages</span>
32+
</div>
33+
<div className="flex items-center gap-4 text-foreground/90 hover:cursor-pointer hover:text-primary transition-all">
34+
<LayoutTemplate size={20} />
35+
<span>Templates</span>
36+
</div>
37+
</div>
38+
39+
{NavigationData[activeTab].map((nav) => {
40+
return (
41+
<div className="mt-8">
42+
<div className="flex items-center gap-2 text-foreground/70">
43+
{nav.icon}
44+
<span className="font-mono text-[12px]">{nav.name}</span>
45+
</div>
46+
47+
<div className="flex flex-col w-full text-sm py-4">
48+
{nav.children.map((item) => {
49+
if (item.visible === false) return null;
50+
51+
return (
52+
<Fragment key={item.id}>
53+
<NavItem item={item} />
54+
</Fragment>
55+
);
56+
})}
57+
</div>
58+
</div>
59+
);
60+
})}
61+
</section>
62+
</aside>
63+
);
64+
}
65+
66+
type NavItemProps = {
67+
item: NavigationItem;
68+
className?: ComponentProps<'div'>['className'];
69+
};
70+
71+
export const NavItem = ({ item, className }: NavItemProps) => {
72+
const [isOpen, setIsOpen] = useState(false);
73+
74+
return (
75+
<div>
76+
<div
77+
className={twMerge(
78+
'flex items-center justify-between pl-4 py-1 border-l-[1px] border-l-border text-foreground/90 cursor-pointer hover:text-primary hover:border-l-primary/60 transition-all',
79+
className
80+
)}
81+
onClick={() => setIsOpen((prev) => !prev)}
82+
>
83+
<span>{item.name}</span>
84+
85+
{item.children && item.children.length > 0 && (
86+
<ChevronDown
87+
size={16}
88+
className={twMerge(
89+
'transition-all duration-300',
90+
isOpen ? '' : '-rotate-90'
91+
)}
92+
/>
93+
)}
94+
</div>
95+
96+
<AnimatePresence>
97+
{isOpen && (
98+
<motion.div
99+
key={item.id}
100+
initial="collapsed"
101+
animate="open"
102+
exit="collapsed"
103+
variants={{
104+
open: { height: 'auto' },
105+
collapsed: { height: 0 },
106+
}}
107+
transition={{ duration: 0.3, ease: 'easeInOut' }}
108+
className="overflow-hidden"
109+
>
110+
{item.children &&
111+
item.children.map((item) => {
112+
if (item.visible === false) return null;
113+
114+
return (
115+
<NavItem
116+
item={item}
117+
className={item.level === 2 ? '' : 'pl-8'}
118+
/>
119+
);
120+
})}
121+
</motion.div>
122+
)}
123+
</AnimatePresence>
124+
</div>
125+
);
126+
};

‎docs/src/app/docs/docs.layout.tsx

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Navbar from '@/components/layout/navbar';
2+
import { Outlet, LayoutComponent } from 'rasengan';
3+
import SidebarNavigation from './components/layout/sidebar';
4+
import Footer from '@/components/layout/footer';
5+
6+
const DocsLayout: LayoutComponent = () => {
7+
return (
8+
<section className="w-full h-full overflow-y-auto">
9+
<Navbar />
10+
11+
<section className="h-auto flex pt-4">
12+
<SidebarNavigation />
13+
14+
<main className="w-(--main-width) h-fulld mt-10 ">
15+
<div className="px-0 w-full">
16+
<Outlet />
17+
</div>
18+
<Footer />
19+
</main>
20+
</section>
21+
</section>
22+
);
23+
};
24+
25+
DocsLayout.path = '/docs';
26+
27+
export default DocsLayout;

‎docs/src/app/docs/docs.router.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { RouterComponent, defineRouter } from 'rasengan';
2+
import DocsLayout from '@/app/docs/docs.layout';
3+
import HomeGroup from './pages/home/home.group';
4+
5+
class DocsRouter extends RouterComponent {}
6+
7+
export default defineRouter({
8+
imports: [],
9+
layout: DocsLayout,
10+
pages: [HomeGroup],
11+
})(DocsRouter);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineRoutesGroup } from 'rasengan';
2+
import IntroductionPage from './introduction.mdx';
3+
import InstallationPage from './installation.mdx';
4+
5+
export default defineRoutesGroup({
6+
path: '/',
7+
children: [IntroductionPage, InstallationPage],
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
path: installation
3+
metadata:
4+
title: Creating your first Rasengan.js app
5+
description: Setting up your React project with the Create Rasengan CLI tool in seconds
6+
toc: true
7+
---
8+
9+
# Get started with Rasengan.js
10+
11+
Let's start
12+
13+
## Prerequisites
14+
15+
### Install Node.js
16+
17+
#### Node
18+
19+
```jsx title="Entry Client" showLineNumbers
20+
import { renderApp } from 'rasengan/client';
21+
import App from './main';
22+
23+
renderApp(App, { reactStrictMode: true });
24+
```
25+
26+
```bash title="Terminal"
27+
npx create-rasengan@latest
28+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
path: introduction
3+
metadata:
4+
title: What's Rasengan.js ?
5+
description: Discover the great React Framework for modern web applications
6+
toc: true
7+
---
8+
9+
# Introduction
10+
11+
Let's start.
12+
13+
Bonjour
14+
Bonjour
15+
Bonjour
16+
Bonjour
17+
Bonjour
18+
Bonjour
19+
Bonjour
20+
Bonjour
21+
Bonjour
22+
Bonjour
23+
Bonjour
24+
Bonjour
25+
Bonjour
26+
Bonjour
27+
Bonjour
28+
Bonjour
29+
Bonjour
30+
Bonjour
31+
Bonjour
32+
Bonjour
33+
Bonjour
34+
Bonjour
35+
Bonjour
36+
Bonjour
37+
Bonjour
38+
Bonjour
39+
Bonjour
40+
Bonjour
41+
Bonjour
42+
Bonjour
43+
Bonjour
44+
Bonjour
45+
Bonjour
46+
Bonjour
47+
Bonjour
48+
Bonjour
49+
50+
Bonjour
51+
Bonjour
52+
Bonjour
53+
Bonjour
54+
Bonjour
55+
Bonjour
56+
Bonjour
57+
Bonjour
58+
Bonjour
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineRoutesGroup } from 'rasengan';
2+
import GettingStartedGroup from './getting-started/getting-started.group';
3+
4+
export default defineRoutesGroup({
5+
path: '/',
6+
children: [GettingStartedGroup],
7+
});

‎docs/src/app/root/pages/home.page.tsx

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { PageComponent, Link } from 'rasengan';
2+
import logo from '@/assets/logo.svg';
3+
import Image from '@rasenganjs/image';
4+
import { useTheme } from '@rasenganjs/theme';
5+
6+
const Home: PageComponent = () => {
7+
const { setTheme, theme, actualTheme } = useTheme();
8+
9+
return (
10+
<section className="w-full">
11+
Home page
12+
<button
13+
onClick={() => setTheme(actualTheme === 'dark' ? 'light' : 'dark')}
14+
>
15+
Change theme
16+
</button>
17+
</section>
18+
);
19+
};
20+
21+
Home.path = '/';
22+
Home.metadata = {
23+
title: 'Home',
24+
description: 'Home page',
25+
};
26+
27+
export default Home;

‎docs/src/app/root/root.layout.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import { Outlet, LayoutComponent } from 'rasengan';
3+
4+
const AppLayout: LayoutComponent = () => {
5+
return (
6+
<React.Fragment>
7+
<Outlet />
8+
</React.Fragment>
9+
);
10+
};
11+
12+
AppLayout.path = '/';
13+
14+
export default AppLayout;

‎docs/src/app/root/root.router.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { RouterComponent, defineRouter } from 'rasengan';
2+
import Home from '@/app/root/pages/home.page';
3+
import RootLayout from '@/app/root/root.layout';
4+
5+
class RootRouter extends RouterComponent {}
6+
7+
export default defineRouter({
8+
imports: [],
9+
layout: RootLayout,
10+
pages: [Home],
11+
})(RootRouter);
76.4 KB
Binary file not shown.
76.3 KB
Binary file not shown.

‎docs/src/assets/font/Lexend-Bold.ttf

76.8 KB
Binary file not shown.

‎docs/src/assets/font/Lexend-Light.ttf

76.8 KB
Binary file not shown.
76.8 KB
Binary file not shown.
76.5 KB
Binary file not shown.

‎docs/src/assets/logo.svg

+77
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ComponentProps } from 'react';
2+
3+
type ButtonProps = {
4+
children: React.ReactNode;
5+
className?: ComponentProps<'button'>['className'];
6+
onClick?: () => void;
7+
} & ComponentProps<'button'>;
8+
9+
export default function Button({
10+
children,
11+
onClick,
12+
className,
13+
...props
14+
}: ButtonProps) {
15+
return (
16+
<button
17+
onClick={onClick}
18+
className={`${className} px-4 py-2 rounded-full hover:cursor-pointer font-lexend-regular transition-all duration-300`}
19+
{...props}
20+
>
21+
{children}
22+
</button>
23+
);
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { useTheme } from '@rasenganjs/theme';
2+
import { Moon, Sun } from 'lucide-react';
3+
import { motion, AnimatePresence } from 'motion/react';
4+
5+
export default function ThemeButton() {
6+
const { setTheme, isDark } = useTheme();
7+
8+
const handleThemeChange = () => {
9+
setTheme(isDark ? 'light' : 'dark');
10+
};
11+
12+
return (
13+
<motion.button
14+
onClick={handleThemeChange}
15+
className="relative size-8 rounded-md border-[1px] border-primary/40 bg-primary/10 flex items-center justify-center overflow-hidden hover:cursor-pointer"
16+
whileHover={{ scale: 1.05 }}
17+
>
18+
<AnimatePresence>
19+
{isDark ? (
20+
<motion.div
21+
key="moon"
22+
initial={{ scale: 0 }}
23+
animate={{ scale: 1 }}
24+
exit={{ scale: 0 }}
25+
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
26+
>
27+
<Moon size={20} className="text-primary" />
28+
</motion.div>
29+
) : (
30+
<motion.div
31+
key="sun"
32+
initial={{ scale: 0 }}
33+
animate={{ scale: 1 }}
34+
exit={{ scale: 0 }}
35+
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
36+
>
37+
<Sun size={20} className="text-primary" />
38+
</motion.div>
39+
)}
40+
</AnimatePresence>
41+
</motion.button>
42+
);
43+
}

‎docs/src/components/layout/footer.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default function Footer() {
2+
return (
3+
<footer className="border-t-[1px] border-t-border px-4 h-[400px] bg-background"></footer>
4+
);
5+
}

‎docs/src/components/layout/navbar.tsx

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import Image from '@rasenganjs/image';
2+
import ThemeButton from '../atoms/buttons/theme-button';
3+
4+
export default function Navbar() {
5+
return (
6+
<header className="fixed top-0 left-0 w-full h-[60px] bg-background border-b-[1px] border-b-border z-20 flex items-center justify-between px-4">
7+
<div className="flex items-center gap-0">
8+
<Image
9+
src={'/rasengan.svg'}
10+
alt="Rasengan Logo"
11+
width={50}
12+
height={50}
13+
/>
14+
15+
<span className="font-lexend-medium text-xl">Rasenganjs</span>
16+
</div>
17+
18+
<div className="flex items-center gap-6">
19+
<nav>
20+
<ul className="flex items-center gap-6">
21+
<li>Docs</li>
22+
<li>Blog</li>
23+
<li>Showcase</li>
24+
</ul>
25+
</nav>
26+
27+
<div className="pl-6 border-l border-l-border">
28+
<ThemeButton />
29+
</div>
30+
31+
<div className="size-8 rounded-full flex items-center justify-center">
32+
<svg
33+
width="24"
34+
height="24"
35+
viewBox="0 0 1024 1024"
36+
fill="none"
37+
xmlns="http://www.w3.org/2000/svg"
38+
className="fill-foreground"
39+
>
40+
<path
41+
fill-rule="evenodd"
42+
clip-rule="evenodd"
43+
d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z"
44+
transform="scale(64)"
45+
/>
46+
</svg>
47+
</div>
48+
</div>
49+
</header>
50+
);
51+
}

‎docs/src/data/docs/index.tsx

+279
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
import { Blocks, Handshake, Unplug } from 'lucide-react';
2+
import React from 'react';
3+
4+
export const NavigationGroup = {
5+
DOCUMENTATION: 'documentation',
6+
PACKAGES: 'packages',
7+
} as const;
8+
9+
export type NavigationType =
10+
(typeof NavigationGroup)[keyof typeof NavigationGroup];
11+
export type NavigationItem = {
12+
id: number;
13+
name: string;
14+
link?: string;
15+
level: 1 | 2 | 3;
16+
icon?: React.ReactNode;
17+
visible?: boolean;
18+
children?: Array<NavigationItem>;
19+
};
20+
21+
export const NavigationData: Record<NavigationType, Array<NavigationItem>> = {
22+
[NavigationGroup.DOCUMENTATION]: [
23+
{
24+
id: 1,
25+
name: 'GETTING STARTED',
26+
icon: <Handshake size={20} />,
27+
level: 1,
28+
children: [
29+
{
30+
id: 1,
31+
name: 'Introduction',
32+
link: '/docs/introduction',
33+
level: 2,
34+
},
35+
{
36+
id: 2,
37+
name: 'Installation',
38+
link: '/docs/installation',
39+
level: 2,
40+
},
41+
{
42+
id: 3,
43+
name: 'Project Structure',
44+
link: '/docs/project-structure',
45+
level: 2,
46+
},
47+
],
48+
},
49+
{
50+
id: 2,
51+
name: 'CORE CONCEPTS',
52+
icon: <Blocks size={20} />,
53+
level: 1,
54+
children: [
55+
{
56+
id: 1,
57+
name: 'Routing',
58+
level: 2,
59+
children: [
60+
{
61+
id: 1,
62+
name: 'Base Concepts',
63+
link: '/docs/routing/base-concepts',
64+
level: 3,
65+
},
66+
{
67+
id: 2,
68+
name: 'Routes',
69+
link: '/docs/routing/routes',
70+
level: 3,
71+
},
72+
{
73+
id: 3,
74+
name: 'Layouts',
75+
link: '/docs/routing/layouts',
76+
level: 3,
77+
},
78+
{
79+
id: 4,
80+
name: 'Linking & Navigation',
81+
link: '/docs/routing/linking-and-navigation',
82+
level: 3,
83+
},
84+
{
85+
id: 5,
86+
name: 'Dynamic Routes',
87+
link: '/docs/routing/dynamic-routes',
88+
level: 3,
89+
},
90+
{
91+
id: 6,
92+
name: 'Error Handling',
93+
link: '/docs/routing/error-handling',
94+
level: 3,
95+
},
96+
{
97+
id: 7,
98+
name: 'Redirecting',
99+
link: '/docs/routing/redirecting',
100+
level: 3,
101+
},
102+
],
103+
},
104+
{
105+
id: 2,
106+
name: 'Rendering',
107+
level: 2,
108+
children: [
109+
{
110+
id: 1,
111+
name: 'Server Side Rendering',
112+
link: '/docs/rendering/ssr',
113+
level: 3,
114+
},
115+
{
116+
id: 2,
117+
name: 'Client Side Rendering',
118+
link: '/docs/rendering/csr',
119+
level: 3,
120+
},
121+
{
122+
id: 3,
123+
name: 'Hydration',
124+
link: '/docs/deploying/hydration',
125+
level: 3,
126+
},
127+
{
128+
id: 4,
129+
name: 'Prerendering',
130+
link: '/docs/deploying/prerendering',
131+
level: 3,
132+
visible: false,
133+
},
134+
],
135+
},
136+
{
137+
id: 3,
138+
name: 'Styling',
139+
level: 2,
140+
children: [
141+
{
142+
id: 1,
143+
name: 'CSS Modules',
144+
link: '/docs/styling/css-modules',
145+
level: 3,
146+
},
147+
{
148+
id: 2,
149+
name: 'Tailwind CSS',
150+
link: '/docs/styling/tailwindcss',
151+
level: 3,
152+
},
153+
{
154+
id: 3,
155+
name: 'CSS Processeurs',
156+
link: '/docs/styling/preprocesseurs',
157+
level: 3,
158+
},
159+
],
160+
},
161+
{
162+
id: 3,
163+
name: 'Optimizing',
164+
level: 2,
165+
children: [
166+
{
167+
id: 1,
168+
name: 'Images',
169+
link: '/docs/optimizing/images',
170+
level: 3,
171+
},
172+
{
173+
id: 2,
174+
name: 'Metadata',
175+
link: '/docs/optimizing/metadata',
176+
level: 3,
177+
},
178+
{
179+
id: 3,
180+
name: 'Static Assets',
181+
link: '/docs/optimizing/static-assets',
182+
level: 3,
183+
},
184+
],
185+
},
186+
{
187+
id: 3,
188+
name: 'Configuring',
189+
level: 2,
190+
children: [
191+
{
192+
id: 1,
193+
name: 'TypeScript',
194+
link: '/docs/configuring/typescript',
195+
level: 3,
196+
},
197+
{
198+
id: 2,
199+
name: 'Environment Variables',
200+
link: '/docs/configuring/environment-variables',
201+
level: 3,
202+
},
203+
{
204+
id: 3,
205+
name: 'Modules Aliases',
206+
link: '/docs/configuring/modules-aliases',
207+
level: 3,
208+
},
209+
],
210+
},
211+
{
212+
id: 3,
213+
name: 'Deploying',
214+
level: 2,
215+
children: [
216+
{
217+
id: 1,
218+
name: 'Vercel',
219+
link: '/docs/deploying/vercel',
220+
level: 3,
221+
},
222+
{
223+
id: 2,
224+
name: 'Node Server',
225+
link: '/docs/deploying/node',
226+
level: 3,
227+
},
228+
],
229+
},
230+
],
231+
},
232+
{
233+
id: 2,
234+
name: 'API REFERENCE',
235+
icon: <Unplug size={20} />,
236+
level: 1,
237+
children: [
238+
{
239+
id: 1,
240+
name: 'Components',
241+
level: 2,
242+
children: [],
243+
},
244+
{
245+
id: 2,
246+
name: 'Functions',
247+
level: 2,
248+
children: [],
249+
},
250+
{
251+
id: 3,
252+
name: 'File Conventions',
253+
level: 2,
254+
children: [],
255+
},
256+
{
257+
id: 3,
258+
name: 'rasengan.config.js',
259+
level: 2,
260+
children: [],
261+
},
262+
{
263+
id: 3,
264+
name: 'create-rasengan CLI',
265+
level: 2,
266+
children: [],
267+
},
268+
{
269+
id: 3,
270+
name: 'Rasengan CLI',
271+
level: 2,
272+
children: [],
273+
},
274+
],
275+
},
276+
],
277+
278+
[NavigationGroup.PACKAGES]: [],
279+
};

‎docs/src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { renderApp } from 'rasengan/client';
2+
import App from './main';
3+
4+
renderApp(App, { reactStrictMode: true });

‎docs/src/main.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import '@rasenganjs/image/css';
2+
import '@rasenganjs/mdx/css';
3+
import '@/styles/index.css';
4+
import { type AppProps } from 'rasengan';
5+
import AppRouter from '@/app/app.router';
6+
import ThemeProvider from '@rasenganjs/theme';
7+
8+
export default function App({ Component, children }: AppProps) {
9+
return (
10+
<ThemeProvider>
11+
<Component router={AppRouter}>{children}</Component>
12+
</ThemeProvider>
13+
);
14+
}

‎docs/src/styles/index.css

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/* Load fonts */
2+
@font-face {
3+
font-family: 'Lexend-Bold';
4+
src: url('../assets/font/Lexend-Bold.ttf');
5+
}
6+
@font-face {
7+
font-family: 'Lexend-Medium';
8+
src: url('../assets/font/Lexend-Medium.ttf');
9+
}
10+
@font-face {
11+
font-family: 'Lexend-Regular';
12+
src: url('../assets/font/Lexend-Regular.ttf');
13+
}
14+
@font-face {
15+
font-family: 'Lexend-Light';
16+
src: url('../assets/font/Lexend-Light.ttf');
17+
}
18+
@font-face {
19+
font-family: 'GeistMono-Regular';
20+
src: url('../assets/font/GeistMono-Regular.ttf');
21+
}
22+
@font-face {
23+
font-family: 'GeistMono-Light';
24+
src: url('../assets/font/GeistMono-Light.ttf');
25+
}
26+
27+
@import 'tailwindcss';
28+
29+
@theme {
30+
--color-background: #fff;
31+
--color-foreground: #111;
32+
--color-primary: #2b63f5;
33+
--color-primary-foreground: #fff;
34+
--color-border: #e1e1e1;
35+
--color-neutral: #858585;
36+
37+
/* Fonts */
38+
--font-lexend-bold: 'Lexend-Bold', sans-serif;
39+
--font-lexend-medium: 'Lexend-Medium', sans-serif;
40+
--font-lexend-regular: 'Lexend-Regular', sans-serif;
41+
--font-lexend-light: 'Lexend-Light', sans-serif;
42+
--font-mono-regular: 'GeistMono-Regular', sans-serif;
43+
--font-mono-light: 'GeistMono-Light', sans-serif;
44+
45+
/* Size */
46+
--main-width: calc(100% - 280px);
47+
}
48+
49+
:root {
50+
--color-background: #fff;
51+
--color-foreground: #111;
52+
--color-primary: #2b63f5;
53+
--color-primary-foreground: #fff;
54+
--color-border: #e1e1e1;
55+
--color-neutral: #858585;
56+
57+
.dark {
58+
--color-primary: #2b63f5;
59+
--color-primary-foreground: #fff;
60+
--color-background: #040712;
61+
--color-foreground: #d1d5dc;
62+
--color-border: #282c35;
63+
--color-neutral: #9aa1af;
64+
}
65+
}
66+
67+
body,
68+
html {
69+
box-sizing: border-box;
70+
margin: 0;
71+
padding: 0;
72+
width: 100vw;
73+
min-height: 100vh;
74+
overflow: hidden;
75+
}
76+
77+
/* Custom styles for markdown */
78+
.rasengan-wrapper {
79+
padding-left: 2.5rem;
80+
padding-right: 2.5rem;
81+
}
82+
83+
.rasengan-markdown-body {
84+
width: 100%;
85+
}
86+
87+
.rasengan-markdown-body p {
88+
font-size: 16px;
89+
}
90+
91+
.rasengan-toc h2.title {
92+
font-family: 'GeistMono-Regular';
93+
}
94+
95+
.rasengan-markdown-body code.code-block {
96+
background-color: #1c202a;
97+
border-radius: 12px;
98+
border: 1px solid #353740;
99+
}
100+
101+
.rasengan-markdown-body figure:has(pre[data-language]) {
102+
padding: 4px;
103+
border-radius: 16px;
104+
}
105+
106+
.rasengan-markdown-body figure pre {
107+
background-color: transparent !important;
108+
}
109+
110+
.rasengan-markdown-body figure:has(pre[data-language]) figcaption,
111+
.rasengan-markdown-body figure:has(pre[data-language]) {
112+
background-color: #10141e;
113+
border: none;
114+
}
115+
116+
.rasengan-markdown-body figure:has(pre[data-language]) figcaption {
117+
font-size: 12px;
118+
height: 30px;
119+
padding-top: 0;
120+
padding-bottom: 0;
121+
padding-left: 10px;
122+
display: flex;
123+
align-items: center;
124+
}
125+
126+
.rasengan-markdown-body pre[data-language] span[data-highlighted-line] {
127+
background-color: rgba(43, 99, 245, 0.1); /* 50% opacity */
128+
}
129+
130+
.rasengan-markdown-body pre[data-language] mark[data-highlighted-chars] {
131+
background-color: rgba(43, 99, 245, 0.2);
132+
border: 1px solid rgba(43, 99, 245, 0.3);
133+
}
134+
135+
@media (min-width: 1280px) {
136+
.rasengan-markdown-body {
137+
max-width: 80rem;
138+
}
139+
}

‎docs/src/template.tsx

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { type TemplateProps } from 'rasengan';
2+
3+
export default function Template({ Head, Body, Script }: TemplateProps) {
4+
return (
5+
<html lang="en">
6+
<Head>
7+
<meta charSet="UTF-8" />
8+
<link rel="icon" type="image/svg+xml" href="/rasengan.svg" />
9+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
10+
</Head>
11+
12+
<Body>
13+
<Script />
14+
</Body>
15+
</html>
16+
);
17+
}

‎docs/tsconfig.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"target": "ES2020",
5+
6+
/* Bundler mode */
7+
"moduleResolution": "bundler",
8+
"module": "ESNext",
9+
"jsx": "react-jsx",
10+
11+
/* Aliases for intellisence */
12+
"paths": {
13+
"@/*": ["src/*"]
14+
}
15+
},
16+
"include": ["src", "rasengan-env.d.ts"],
17+
18+
"extends": "./node_modules/rasengan/tsconfig.base.json"
19+
}

‎packages/rasengan/src/routing/utils/define-routes-group.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const generateRoutesGroup = (
3636

3737
pages.push(...childrenPages);
3838
} else {
39-
const routePath = path[0] === '/' ? path : `/${path}`;
39+
const routePath = path === '/' ? '' : path[0] === '/' ? path : `/${path}`;
4040

4141
// Check if the page is a PageComponent
4242
if (page['path']) {

‎pnpm-lock.yaml

+183
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pnpm-workspace.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
packages:
22
- 'packages/**'
33
- 'playground/**'
4+
- 'docs/**'

0 commit comments

Comments
 (0)
Please sign in to comment.