v.1.13.0 add: context menu
This commit is contained in:
@@ -15,7 +15,7 @@ export default function Home() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center px-2 py-8 text-center sm:py-36">
|
<div className="flex flex-col items-center justify-center px-2 py-8 text-center sm:py-36">
|
||||||
<Link
|
<Link
|
||||||
href="/docs/getting-started/changelog"
|
href="/docs/changelog/version-1"
|
||||||
className="mb-5 sm:text-lg flex items-center gap-2 underline underline-offset-4 sm:-mt-12"
|
className="mb-5 sm:text-lg flex items-center gap-2 underline underline-offset-4 sm:-mt-12"
|
||||||
>
|
>
|
||||||
<div className="z-10 flex min-h-10 items-center justify-center max-[800px]:mt-10">
|
<div className="z-10 flex min-h-10 items-center justify-center max-[800px]:mt-10">
|
||||||
@@ -25,7 +25,7 @@ export default function Home() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
|
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
|
||||||
<span>🚀 New Version - Release v1.12.0</span>
|
<span>🚀 New Version - Release v1.13.0</span>
|
||||||
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
||||||
</AnimatedShinyText>
|
</AnimatedShinyText>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
133
components/context-popover.tsx
Normal file
133
components/context-popover.tsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { ROUTES, EachRoute } from "@/lib/routes-config";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import * as LucideIcons from "lucide-react";
|
||||||
|
import { ChevronsUpDown, Check, type LucideIcon } from "lucide-react";
|
||||||
|
|
||||||
|
interface ContextPopoverProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all root-level routes with context
|
||||||
|
function getContextRoutes(): EachRoute[] {
|
||||||
|
return ROUTES.filter(route => route.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the first item's href from a route
|
||||||
|
function getFirstItemHref(route: EachRoute): string {
|
||||||
|
return route.items?.[0]?.href ? `${route.href}${route.items[0].href}` : route.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the active context route from the current path
|
||||||
|
function getActiveContextRoute(path: string): EachRoute | undefined {
|
||||||
|
if (!path.startsWith('/docs')) return undefined;
|
||||||
|
const docPath = path.replace(/^\/docs/, '');
|
||||||
|
return getContextRoutes().find(route => docPath.startsWith(route.href));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get icon component by name
|
||||||
|
function getIcon(name: string) {
|
||||||
|
const Icon = LucideIcons[name as keyof typeof LucideIcons] as LucideIcon | undefined;
|
||||||
|
if (!Icon) return <LucideIcons.FileQuestion className="h-4 w-4" />;
|
||||||
|
return <Icon className="h-4 w-4" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ContextPopover({ className }: ContextPopoverProps) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const router = useRouter();
|
||||||
|
const [activeRoute, setActiveRoute] = useState<EachRoute>();
|
||||||
|
const contextRoutes = getContextRoutes();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (pathname.startsWith("/docs")) {
|
||||||
|
setActiveRoute(getActiveContextRoute(pathname));
|
||||||
|
} else {
|
||||||
|
setActiveRoute(undefined);
|
||||||
|
}
|
||||||
|
}, [pathname]);
|
||||||
|
|
||||||
|
if (!pathname.startsWith("/docs") || contextRoutes.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className={cn(
|
||||||
|
"w-full max-w-[240px] flex items-center justify-between font-semibold text-foreground px-0 pt-8",
|
||||||
|
"hover:bg-transparent hover:text-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{activeRoute?.context?.icon && (
|
||||||
|
<span className="text-primary bg-primary/10 border border-primary rounded p-0.5">
|
||||||
|
{getIcon(activeRoute.context.icon)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span className="truncate text-sm">
|
||||||
|
{activeRoute?.context?.title || activeRoute?.title || 'Select context'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<ChevronsUpDown className="h-4 w-4 text-foreground/50" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent
|
||||||
|
className="w-64 p-2"
|
||||||
|
align="start"
|
||||||
|
sideOffset={6}
|
||||||
|
>
|
||||||
|
<div className="space-y-1">
|
||||||
|
{contextRoutes.map((route) => {
|
||||||
|
const isActive = activeRoute?.href === route.href;
|
||||||
|
const firstItemPath = getFirstItemHref(route);
|
||||||
|
const contextPath = `/docs${firstItemPath}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={route.href}
|
||||||
|
onClick={() => router.push(contextPath)}
|
||||||
|
className={cn(
|
||||||
|
"relative flex w-full items-center gap-2 rounded px-2 py-1.5 text-sm",
|
||||||
|
"text-left outline-none transition-colors",
|
||||||
|
isActive
|
||||||
|
? "bg-primary/20 text-primary"
|
||||||
|
: "text-foreground/80 hover:bg-primary/20"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{route.context?.icon && (
|
||||||
|
<span className={cn(
|
||||||
|
"flex h-4 w-4 items-center justify-center",
|
||||||
|
isActive ? "text-primary" : "text-foreground/60"
|
||||||
|
)}>
|
||||||
|
{getIcon(route.context.icon)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<div className="flex-1 min-w-0 overflow-hidden">
|
||||||
|
<div className="truncate font-medium">
|
||||||
|
{route.context?.title || route.title}
|
||||||
|
</div>
|
||||||
|
{route.context?.description && (
|
||||||
|
<div className="text-xs text-muted-foreground truncate text-ellipsis overflow-hidden max-w-full">
|
||||||
|
{route.context.description}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{isActive && (
|
||||||
|
<Check className="h-3.5 w-3.5" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,44 +1,62 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { ROUTES } from "@/lib/routes-config";
|
import { ROUTES, EachRoute } from "@/lib/routes-config";
|
||||||
import SubLink from "./sublink";
|
import SubLink from "./sublink";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface DocsMenuProps {
|
interface DocsMenuProps {
|
||||||
isSheet?: boolean;
|
isSheet?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the current context from the path
|
||||||
|
function getCurrentContext(path: string): string | undefined {
|
||||||
|
if (!path.startsWith('/docs')) return undefined;
|
||||||
|
|
||||||
|
// Extract the first segment after /docs/
|
||||||
|
const match = path.match(/^\/docs\/([^\/]+)/);
|
||||||
|
return match ? match[1] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the route that matches the current context
|
||||||
|
function getContextRoute(contextPath: string): EachRoute | undefined {
|
||||||
|
return ROUTES.find(route => {
|
||||||
|
const normalizedHref = route.href.replace(/^\/+|\/+$/g, '');
|
||||||
|
return normalizedHref === contextPath;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export default function DocsMenu({ isSheet = false, className = "" }: DocsMenuProps) {
|
export default function DocsMenu({ isSheet = false, className = "" }: DocsMenuProps) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
// Skip rendering if not on a docs page
|
// Skip rendering if not on a docs page
|
||||||
if (!pathname.startsWith("/docs")) return null;
|
if (!pathname.startsWith("/docs")) return null;
|
||||||
|
|
||||||
|
// Get the current context
|
||||||
|
const currentContext = getCurrentContext(pathname);
|
||||||
|
|
||||||
|
// Get the route for the current context
|
||||||
|
const contextRoute = currentContext ? getContextRoute(currentContext) : undefined;
|
||||||
|
|
||||||
|
// If no context route is found, don't render anything
|
||||||
|
if (!contextRoute) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
aria-label="Documentation navigation"
|
aria-label="Documentation navigation"
|
||||||
className={className}
|
className={cn("transition-all duration-200", className)}
|
||||||
>
|
>
|
||||||
<ul className="flex flex-col gap-3.5 mt-5 pr-2 pb-6">
|
<ul className="flex flex-col gap-1.5 py-4">
|
||||||
{ROUTES.map((item, index) => {
|
{/* Display only the items from the current context */}
|
||||||
// Normalize href - hapus leading/trailing slashes
|
<li key={contextRoute.title}>
|
||||||
const normalizedHref = `/${item.href.replace(/^\/+|\/+$/g, '')}`;
|
<SubLink
|
||||||
const itemHref = `/docs${normalizedHref}`;
|
{...contextRoute}
|
||||||
|
href={`/docs${contextRoute.href}`}
|
||||||
const modifiedItems = {
|
level={0}
|
||||||
...item,
|
isSheet={isSheet}
|
||||||
href: itemHref,
|
/>
|
||||||
level: 0,
|
|
||||||
isSheet,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li key={`${item.title}-${index}`}>
|
|
||||||
<SubLink {...modifiedItems} />
|
|
||||||
</li>
|
</li>
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { DialogTitle, DialogDescription } from "@/components/ui/dialog";
|
|||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import DocsMenu from "@/components/docs-menu";
|
import DocsMenu from "@/components/docs-menu";
|
||||||
import { ModeToggle } from "@/components/theme-toggle";
|
import { ModeToggle } from "@/components/theme-toggle";
|
||||||
|
import ContextPopover from "@/components/context-popover";
|
||||||
|
|
||||||
// Toggle Button Component
|
// Toggle Button Component
|
||||||
export function ToggleButton({
|
export function ToggleButton({
|
||||||
@@ -51,9 +52,14 @@ export function Leftbar() {
|
|||||||
${collapsed ? "w-[24px]" : "w-[280px]"} flex flex-col pr-2`}
|
${collapsed ? "w-[24px]" : "w-[280px]"} flex flex-col pr-2`}
|
||||||
>
|
>
|
||||||
<ToggleButton collapsed={collapsed} onToggle={toggleCollapse} />
|
<ToggleButton collapsed={collapsed} onToggle={toggleCollapse} />
|
||||||
{/* Scrollable DocsMenu */}
|
{/* Scrollable Content */}
|
||||||
<ScrollArea className="flex-1 px-0.5 pb-4">
|
<ScrollArea className="flex-1 px-0.5 pb-4">
|
||||||
{!collapsed && <DocsMenu />}
|
{!collapsed && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<ContextPopover />
|
||||||
|
<DocsMenu />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
@@ -81,7 +87,8 @@ export function SheetLeftbar() {
|
|||||||
<div className="flex flex-col gap-2.5 mt-3 mx-2 px-5">
|
<div className="flex flex-col gap-2.5 mt-3 mx-2 px-5">
|
||||||
<NavMenu isSheet />
|
<NavMenu isSheet />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-2 px-5">
|
<div className="mx-2 px-5 space-y-2">
|
||||||
|
<ContextPopover />
|
||||||
<DocsMenu isSheet />
|
<DocsMenu isSheet />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-2/4 px-5">
|
<div className="flex w-2/4 px-5">
|
||||||
|
|||||||
@@ -8,6 +8,23 @@ date: 24-05-2025
|
|||||||
|
|
||||||
> This changelog contains a list of all the changes made to the DocuBook template. It will be updated with each new release and will include information about new features, bug fixes, and other improvements.
|
> This changelog contains a list of all the changes made to the DocuBook template. It will be updated with each new release and will include information about new features, bug fixes, and other improvements.
|
||||||
|
|
||||||
|
<div className="sr-only">
|
||||||
|
### v 1.13.0
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Release version="1.13.0" date="2025-05-29" title="Context Menu for organize file and folder">
|
||||||
|
<Changes type="added">
|
||||||
|
- New ContextMenu component for organizing file and folder
|
||||||
|
- Nested docs folder and file support with context menu
|
||||||
|
</Changes>
|
||||||
|
<Changes type="improved">
|
||||||
|
- improve routes-config with context menu
|
||||||
|
- improve docu.json with context menu
|
||||||
|
- improve leftbar with context menu
|
||||||
|
- improve docs-menu with context menu
|
||||||
|
</Changes>
|
||||||
|
</Release>
|
||||||
|
|
||||||
<div className="sr-only">
|
<div className="sr-only">
|
||||||
### v 1.12.0
|
### v 1.12.0
|
||||||
</div>
|
</div>
|
||||||
@@ -41,9 +41,9 @@ The Card component is a component used to create cards that can be used to displ
|
|||||||
|
|
||||||
<Tabs defaultValue="link" className="pt-5 pb-1">
|
<Tabs defaultValue="link" className="pt-5 pb-1">
|
||||||
<TabsList>
|
<TabsList>
|
||||||
<TabsTrigger value="link">Card with Link & Icon</TabsTrigger>
|
<TabsTrigger value="link">Link & Icon</TabsTrigger>
|
||||||
<TabsTrigger value="horizontal">Card Horizontal</TabsTrigger>
|
<TabsTrigger value="horizontal">Horizontal</TabsTrigger>
|
||||||
<TabsTrigger value="simple">Card Simple</TabsTrigger>
|
<TabsTrigger value="simple">Simple</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="link">
|
<TabsContent value="link">
|
||||||
```markdown
|
```markdown
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
title: Components
|
|
||||||
description: This section provides an overview of the custom components available in DocuBook.
|
|
||||||
date: 29-11-2024
|
|
||||||
---
|
|
||||||
|
|
||||||
Explore the custom components we've defined for easy integration and development within your projects. Each component is designed to enhance your workflow and streamline your development process.
|
|
||||||
|
|
||||||
<Outlet path="getting-started/components" />
|
|
||||||
@@ -90,5 +90,3 @@ For both options, ensure that you add the variable to `tailwind.config.ts`:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For theme and colors, refer to the [Theme section](/docs/getting-started/themes)
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ To get started, you can clone the DocuBook repository directly from GitHub.
|
|||||||
Begin by cloning the DocuBook repository from GitHub:
|
Begin by cloning the DocuBook repository from GitHub:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --branch starter https://gitlab.com/mywildancloud/docubook.git
|
git clone --branch main https://github.com/DocuBook/docubook.git
|
||||||
```
|
```
|
||||||
|
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ DocuBook is proudly **open-source**! 🎉 We believe in creating an accessible,
|
|||||||
|
|
||||||
<Note title="Contribute">
|
<Note title="Contribute">
|
||||||
Interested in helping us improve? Check out our [GitHub
|
Interested in helping us improve? Check out our [GitHub
|
||||||
repository](https://github.com/gitfromwildan/docubook) to get started! From
|
repository](https://github.com/DocuBook/docubook) to get started! From
|
||||||
feature suggestions to bug fixes, all contributions are welcome.
|
feature suggestions to bug fixes, all contributions are welcome.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ description: Get up and running with DocuBook in minutes with this comprehensive
|
|||||||
date: 20-05-2025
|
date: 20-05-2025
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome to DocuBook! This guide will help you set up your documentation site quickly and efficiently.
|
Welcome to DocuBook! This guide will help you set up and customize your documentation site efficiently.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Before we begin, make sure you have the following installed:
|
Before we begin, ensure you have the following installed:
|
||||||
|
|
||||||
- [Git](https://git-scm.com/)
|
- [Git](https://git-scm.com/)
|
||||||
- [Node.js 18+](https://nodejs.org/) or [Bun 1.0+](https://bun.sh/)
|
- [Node.js 18+](https://nodejs.org/) or [Bun 1.0+](https://bun.sh/)
|
||||||
@@ -16,112 +16,130 @@ Before we begin, make sure you have the following installed:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
<Note type="note" title="Note">
|
<Note type="note" title="Initial Setup">
|
||||||
Follow the instructions on the [installation page](/docs/getting-started/installation) to install the required dependencies and set up your project.
|
Follow the [installation guide](/docs/getting-started/installation) to set up your project dependencies and configuration.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## Project Setup
|
## Project Setup
|
||||||
|
|
||||||
### Customize Branding
|
### Configuration
|
||||||
|
|
||||||
<Stepper>
|
<Stepper>
|
||||||
<StepperItem title="Step 1: Add Favicon">
|
<StepperItem title="Add Favicon">
|
||||||
Place your favicon at `public/favicon.ico`
|
Place your favicon at `public/favicon.ico` for browser tab display.
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
<StepperItem title="Step 2: Add Logo">
|
<StepperItem title="Add Logo">
|
||||||
Place your logo at `public/images/docu.svg` (SVG format recommended)
|
Add your logo at `public/images/docu.svg` (SVG format recommended for scalability).
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
<StepperItem title="Step 3: Update Site Info">
|
<StepperItem title="Update Site Information">
|
||||||
Edit `docu.json` to update site name, description, and other settings
|
Customize your site's metadata in `docu.json`:
|
||||||
|
- Site title and description
|
||||||
|
- Navigation structure
|
||||||
|
- Default theme settings
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
</Stepper>
|
</Stepper>
|
||||||
|
|
||||||
## Creating Content
|
## Content Management
|
||||||
|
|
||||||
### File Structure
|
### File Structure
|
||||||
|
|
||||||
DocuBook uses the following structure:
|
DocuBook organizes content in a hierarchical structure:
|
||||||
|
|
||||||
````plaintext
|
```plaintext
|
||||||
contents/
|
contents/
|
||||||
docs/
|
docs/ # Main documentation directory
|
||||||
getting-started/
|
getting-started/ # Section for getting started guides
|
||||||
quick-start-guide/ <-- You are here
|
quick-start-guide/ # Current guide
|
||||||
|
index.mdx # Main content file
|
||||||
|
guides/ # Additional documentation sections
|
||||||
|
components/ # Component-specific documentation
|
||||||
index.mdx
|
index.mdx
|
||||||
guides/
|
```
|
||||||
components/
|
|
||||||
index.mdx
|
|
||||||
````
|
|
||||||
|
|
||||||
### Adding New Pages
|
### Creating New Content
|
||||||
|
|
||||||
<Stepper>
|
<Stepper>
|
||||||
<StepperItem title="Step 1: Create a New Folder">
|
<StepperItem title="1. Create Content Directory">
|
||||||
Create a new folder in `contents/docs/getting-started/` for your content section
|
Organize your documentation by creating a new directory:
|
||||||
```bash
|
```bash
|
||||||
mkdir -p contents/docs/getting-started/your-page-title
|
mkdir -p contents/docs/your-section/your-topic
|
||||||
|
```
|
||||||
|
|
||||||
|
Example for an API reference:
|
||||||
|
```bash
|
||||||
|
mkdir -p contents/docs/api/authentication
|
||||||
```
|
```
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
<StepperItem title="Step 2: Add MDX File">
|
|
||||||
Create an `index.mdx` file with frontmatter:
|
<StepperItem title="2. Create MDX Content">
|
||||||
|
Add an `index.mdx` file with frontmatter metadata:
|
||||||
````markdown
|
````markdown
|
||||||
---
|
---
|
||||||
title: Your Page Title
|
title: Authentication
|
||||||
description: Brief description of your page
|
description: Learn how to implement user authentication
|
||||||
date: 20-05-2025
|
date: 2025-05-29
|
||||||
---
|
---
|
||||||
|
|
||||||
# Your Content Here
|
Your comprehensive guide to implementing authentication in your application.
|
||||||
|
|
||||||
Start writing your documentation using Markdown or MDX components.
|
## Getting Started
|
||||||
|
|
||||||
|
Start by setting up your authentication provider...
|
||||||
````
|
````
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
<StepperItem title="Step 3: Add to Navigation">
|
|
||||||
Update the navigation in `docu.json`:
|
<StepperItem title="3. Update Navigation">
|
||||||
```json:docu.json showLineNumbers {8}
|
Add your new section to the navigation in `docu.json`. Here's how to add the authentication section we created earlier:
|
||||||
|
|
||||||
|
```json:docu.json showLineNumbers {4-16}
|
||||||
{
|
{
|
||||||
"routes": [
|
"routes": [
|
||||||
|
// ... existing routes ...
|
||||||
{
|
{
|
||||||
"title": "Getting Started",
|
"title": "API",
|
||||||
"href": "/getting-started",
|
"href": "/api",
|
||||||
"noLink": true,
|
"noLink": true,
|
||||||
|
"context": {
|
||||||
|
"icon": "Code2",
|
||||||
|
"description": "API Reference and Integration",
|
||||||
|
"title": "API"
|
||||||
|
},
|
||||||
"items": [
|
"items": [
|
||||||
{ "title": "Your Page Title", "href": "/your-page-title" } // Add your page here separated by comma `,`
|
{ "title": "Authentication", "href": "/authentication" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This will add a new "API" section with an "Authentication" page under it. The `context` object defines how this section appears in the navigation, including its icon and description.
|
||||||
</StepperItem>
|
</StepperItem>
|
||||||
</Stepper>
|
</Stepper>
|
||||||
|
|
||||||
## Development
|
## Development Workflow
|
||||||
|
|
||||||
Start the development server:
|
### Local Development
|
||||||
|
|
||||||
|
Start the development server with live reload:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Using npm
|
||||||
npm run dev
|
npm run dev
|
||||||
# or
|
|
||||||
|
# Or using Bun
|
||||||
bun dev
|
bun dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Visit [http://localhost:3000](http://localhost:3000) to see your site.
|
Access your site at [http://localhost:3000](http://localhost:3000)
|
||||||
|
|
||||||
## Building for Production
|
### Building for Production
|
||||||
|
|
||||||
When you're ready to deploy:
|
When ready to deploy:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Build the production version
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
|
# Start the production server
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
## Need Help?
|
|
||||||
|
|
||||||
<Note type="info">
|
|
||||||
Check out the [Components Guide](/docs/getting-started/components) to learn about all available components.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
<Note type="warning">
|
|
||||||
Make sure to commit your changes to version control before deploying.
|
|
||||||
</Note>
|
|
||||||
|
|||||||
27
docu.json
27
docu.json
@@ -61,14 +61,28 @@
|
|||||||
"title": "Getting Started",
|
"title": "Getting Started",
|
||||||
"href": "/getting-started",
|
"href": "/getting-started",
|
||||||
"noLink": true,
|
"noLink": true,
|
||||||
|
"context": {
|
||||||
|
"icon": "Book",
|
||||||
|
"description": "Set up your Documentation",
|
||||||
|
"title": "Guides"
|
||||||
|
},
|
||||||
"items": [
|
"items": [
|
||||||
{ "title": "Introduction", "href": "/introduction" },
|
{ "title": "Introduction", "href": "/introduction" },
|
||||||
{ "title": "Installation", "href": "/installation" },
|
{ "title": "Installation", "href": "/installation" },
|
||||||
{ "title": "Quick Start Guide", "href": "/quick-start-guide" },
|
{ "title": "Quick Start Guide", "href": "/quick-start-guide" },
|
||||||
{ "title": "Project Structure", "href": "/project-structure" },
|
{ "title": "Project Structure", "href": "/project-structure" },
|
||||||
|
{ "title": "Customize", "href": "/customize" }
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Components",
|
"title": "Components",
|
||||||
"href": "/components",
|
"href": "/components",
|
||||||
|
"noLink": true,
|
||||||
|
"context": {
|
||||||
|
"icon": "Layers",
|
||||||
|
"description": "Write with Markdown",
|
||||||
|
"title": "Markdown"
|
||||||
|
},
|
||||||
"items": [
|
"items": [
|
||||||
{ "title": "Accordion", "href": "/accordion" },
|
{ "title": "Accordion", "href": "/accordion" },
|
||||||
{ "title": "Button", "href": "/button" },
|
{ "title": "Button", "href": "/button" },
|
||||||
@@ -88,8 +102,17 @@
|
|||||||
{ "title": "Custom", "href": "/custom" }
|
{ "title": "Custom", "href": "/custom" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "title": "Customize", "href": "/customize" },
|
{
|
||||||
{ "title": "Changelog", "href": "/changelog" }
|
"title": "Changelog",
|
||||||
|
"href": "/changelog",
|
||||||
|
"noLink": true,
|
||||||
|
"context": {
|
||||||
|
"icon": "History",
|
||||||
|
"description": "Updates and changes",
|
||||||
|
"title": "Changelog"
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{ "title": "Version 1.0+", "href": "/version-1" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
import docuConfig from "@/docu.json"; // Import JSON file
|
import docuConfig from "@/docu.json"; // Import JSON file
|
||||||
|
|
||||||
|
export type ContextInfo = {
|
||||||
|
icon: string;
|
||||||
|
description: string;
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type EachRoute = {
|
export type EachRoute = {
|
||||||
title: string;
|
title: string;
|
||||||
href: string;
|
href: string;
|
||||||
noLink?: boolean; // Sekarang mendukung boolean
|
noLink?: boolean;
|
||||||
|
context?: ContextInfo;
|
||||||
items?: EachRoute[];
|
items?: EachRoute[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "docubook",
|
"name": "docubook",
|
||||||
"version": "1.12.0",
|
"version": "1.13.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user