v.1.13.0 add: context menu
This commit is contained in:
@@ -15,7 +15,7 @@ export default function Home() {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center px-2 py-8 text-center sm:py-36">
|
||||
<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"
|
||||
>
|
||||
<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">
|
||||
<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" />
|
||||
</AnimatedShinyText>
|
||||
</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";
|
||||
|
||||
import { ROUTES } from "@/lib/routes-config";
|
||||
import { ROUTES, EachRoute } from "@/lib/routes-config";
|
||||
import SubLink from "./sublink";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface DocsMenuProps {
|
||||
isSheet?: boolean;
|
||||
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) {
|
||||
const pathname = usePathname();
|
||||
|
||||
// Skip rendering if not on a docs page
|
||||
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 (
|
||||
<nav
|
||||
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">
|
||||
{ROUTES.map((item, index) => {
|
||||
// Normalize href - hapus leading/trailing slashes
|
||||
const normalizedHref = `/${item.href.replace(/^\/+|\/+$/g, '')}`;
|
||||
const itemHref = `/docs${normalizedHref}`;
|
||||
|
||||
const modifiedItems = {
|
||||
...item,
|
||||
href: itemHref,
|
||||
level: 0,
|
||||
isSheet,
|
||||
};
|
||||
|
||||
return (
|
||||
<li key={`${item.title}-${index}`}>
|
||||
<SubLink {...modifiedItems} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
<ul className="flex flex-col gap-1.5 py-4">
|
||||
{/* Display only the items from the current context */}
|
||||
<li key={contextRoute.title}>
|
||||
<SubLink
|
||||
{...contextRoute}
|
||||
href={`/docs${contextRoute.href}`}
|
||||
level={0}
|
||||
isSheet={isSheet}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
|
||||
@@ -14,6 +14,7 @@ import { DialogTitle, DialogDescription } from "@/components/ui/dialog";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import DocsMenu from "@/components/docs-menu";
|
||||
import { ModeToggle } from "@/components/theme-toggle";
|
||||
import ContextPopover from "@/components/context-popover";
|
||||
|
||||
// Toggle Button Component
|
||||
export function ToggleButton({
|
||||
@@ -51,9 +52,14 @@ export function Leftbar() {
|
||||
${collapsed ? "w-[24px]" : "w-[280px]"} flex flex-col pr-2`}
|
||||
>
|
||||
<ToggleButton collapsed={collapsed} onToggle={toggleCollapse} />
|
||||
{/* Scrollable DocsMenu */}
|
||||
{/* Scrollable Content */}
|
||||
<ScrollArea className="flex-1 px-0.5 pb-4">
|
||||
{!collapsed && <DocsMenu />}
|
||||
{!collapsed && (
|
||||
<div className="space-y-2">
|
||||
<ContextPopover />
|
||||
<DocsMenu />
|
||||
</div>
|
||||
)}
|
||||
</ScrollArea>
|
||||
</aside>
|
||||
);
|
||||
@@ -81,7 +87,8 @@ export function SheetLeftbar() {
|
||||
<div className="flex flex-col gap-2.5 mt-3 mx-2 px-5">
|
||||
<NavMenu isSheet />
|
||||
</div>
|
||||
<div className="mx-2 px-5">
|
||||
<div className="mx-2 px-5 space-y-2">
|
||||
<ContextPopover />
|
||||
<DocsMenu isSheet />
|
||||
</div>
|
||||
<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.
|
||||
|
||||
<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">
|
||||
### v 1.12.0
|
||||
</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">
|
||||
<TabsList>
|
||||
<TabsTrigger value="link">Card with Link & Icon</TabsTrigger>
|
||||
<TabsTrigger value="horizontal">Card Horizontal</TabsTrigger>
|
||||
<TabsTrigger value="simple">Card Simple</TabsTrigger>
|
||||
<TabsTrigger value="link">Link & Icon</TabsTrigger>
|
||||
<TabsTrigger value="horizontal">Horizontal</TabsTrigger>
|
||||
<TabsTrigger value="simple">Simple</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="link">
|
||||
```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:
|
||||
|
||||
```bash
|
||||
git clone --branch starter https://gitlab.com/mywildancloud/docubook.git
|
||||
git clone --branch main https://github.com/DocuBook/docubook.git
|
||||
```
|
||||
|
||||
</StepperItem>
|
||||
|
||||
@@ -13,7 +13,7 @@ DocuBook is proudly **open-source**! 🎉 We believe in creating an accessible,
|
||||
|
||||
<Note title="Contribute">
|
||||
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.
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ description: Get up and running with DocuBook in minutes with this comprehensive
|
||||
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
|
||||
|
||||
Before we begin, make sure you have the following installed:
|
||||
Before we begin, ensure you have the following installed:
|
||||
|
||||
- [Git](https://git-scm.com/)
|
||||
- [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
|
||||
|
||||
<Note type="note" title="Note">
|
||||
Follow the instructions on the [installation page](/docs/getting-started/installation) to install the required dependencies and set up your project.
|
||||
<Note type="note" title="Initial Setup">
|
||||
Follow the [installation guide](/docs/getting-started/installation) to set up your project dependencies and configuration.
|
||||
</Note>
|
||||
|
||||
## Project Setup
|
||||
|
||||
### Customize Branding
|
||||
### Configuration
|
||||
|
||||
<Stepper>
|
||||
<StepperItem title="Step 1: Add Favicon">
|
||||
Place your favicon at `public/favicon.ico`
|
||||
<StepperItem title="Add Favicon">
|
||||
Place your favicon at `public/favicon.ico` for browser tab display.
|
||||
</StepperItem>
|
||||
<StepperItem title="Step 2: Add Logo">
|
||||
Place your logo at `public/images/docu.svg` (SVG format recommended)
|
||||
<StepperItem title="Add Logo">
|
||||
Add your logo at `public/images/docu.svg` (SVG format recommended for scalability).
|
||||
</StepperItem>
|
||||
<StepperItem title="Step 3: Update Site Info">
|
||||
Edit `docu.json` to update site name, description, and other settings
|
||||
<StepperItem title="Update Site Information">
|
||||
Customize your site's metadata in `docu.json`:
|
||||
- Site title and description
|
||||
- Navigation structure
|
||||
- Default theme settings
|
||||
</StepperItem>
|
||||
</Stepper>
|
||||
|
||||
## Creating Content
|
||||
## Content Management
|
||||
|
||||
### File Structure
|
||||
|
||||
DocuBook uses the following structure:
|
||||
DocuBook organizes content in a hierarchical structure:
|
||||
|
||||
````plaintext
|
||||
```plaintext
|
||||
contents/
|
||||
docs/
|
||||
getting-started/
|
||||
quick-start-guide/ <-- You are here
|
||||
docs/ # Main documentation directory
|
||||
getting-started/ # Section for getting started guides
|
||||
quick-start-guide/ # Current guide
|
||||
index.mdx # Main content file
|
||||
guides/ # Additional documentation sections
|
||||
components/ # Component-specific documentation
|
||||
index.mdx
|
||||
guides/
|
||||
components/
|
||||
index.mdx
|
||||
````
|
||||
```
|
||||
|
||||
### Adding New Pages
|
||||
### Creating New Content
|
||||
|
||||
<Stepper>
|
||||
<StepperItem title="Step 1: Create a New Folder">
|
||||
Create a new folder in `contents/docs/getting-started/` for your content section
|
||||
<StepperItem title="1. Create Content Directory">
|
||||
Organize your documentation by creating a new directory:
|
||||
```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 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
|
||||
---
|
||||
title: Your Page Title
|
||||
description: Brief description of your page
|
||||
date: 20-05-2025
|
||||
title: Authentication
|
||||
description: Learn how to implement user authentication
|
||||
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 title="Step 3: Add to Navigation">
|
||||
Update the navigation in `docu.json`:
|
||||
```json:docu.json showLineNumbers {8}
|
||||
{
|
||||
|
||||
<StepperItem title="3. Update Navigation">
|
||||
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": [
|
||||
// ... existing routes ...
|
||||
{
|
||||
"title": "Getting Started",
|
||||
"href": "/getting-started",
|
||||
"noLink": true,
|
||||
"items": [
|
||||
{ "title": "Your Page Title", "href": "/your-page-title" } // Add your page here separated by comma `,`
|
||||
]
|
||||
"title": "API",
|
||||
"href": "/api",
|
||||
"noLink": true,
|
||||
"context": {
|
||||
"icon": "Code2",
|
||||
"description": "API Reference and Integration",
|
||||
"title": "API"
|
||||
},
|
||||
"items": [
|
||||
{ "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>
|
||||
</Stepper>
|
||||
|
||||
## Development
|
||||
## Development Workflow
|
||||
|
||||
Start the development server:
|
||||
### Local Development
|
||||
|
||||
Start the development server with live reload:
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm run dev
|
||||
# or
|
||||
|
||||
# Or using Bun
|
||||
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
|
||||
# Build the production version
|
||||
npm run build
|
||||
|
||||
# Start the production server
|
||||
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>
|
||||
|
||||
71
docu.json
71
docu.json
@@ -61,35 +61,58 @@
|
||||
"title": "Getting Started",
|
||||
"href": "/getting-started",
|
||||
"noLink": true,
|
||||
"context": {
|
||||
"icon": "Book",
|
||||
"description": "Set up your Documentation",
|
||||
"title": "Guides"
|
||||
},
|
||||
"items": [
|
||||
{ "title": "Introduction", "href": "/introduction" },
|
||||
{ "title": "Installation", "href": "/installation" },
|
||||
{ "title": "Quick Start Guide", "href": "/quick-start-guide" },
|
||||
{ "title": "Project Structure", "href": "/project-structure" },
|
||||
{
|
||||
"title": "Components",
|
||||
"href": "/components",
|
||||
"items": [
|
||||
{ "title": "Accordion", "href": "/accordion" },
|
||||
{ "title": "Button", "href": "/button" },
|
||||
{ "title": "Card", "href": "/card" },
|
||||
{ "title": "Card Group", "href": "/card-group" },
|
||||
{ "title": "Code Block", "href": "/code-block" },
|
||||
{ "title": "File Tree", "href": "/file-tree" },
|
||||
{ "title": "Image", "href": "/image" },
|
||||
{ "title": "Keyboard", "href": "/keyboard" },
|
||||
{ "title": "Link", "href": "/link" },
|
||||
{ "title": "Note", "href": "/note" },
|
||||
{ "title": "Release Note", "href": "/release-note" },
|
||||
{ "title": "Stepper", "href": "/stepper" },
|
||||
{ "title": "Tabs", "href": "/tabs" },
|
||||
{ "title": "Tooltips", "href": "/tooltips" },
|
||||
{ "title": "Youtube", "href": "/youtube" },
|
||||
{ "title": "Custom", "href": "/custom" }
|
||||
]
|
||||
},
|
||||
{ "title": "Customize", "href": "/customize" },
|
||||
{ "title": "Changelog", "href": "/changelog" }
|
||||
{ "title": "Customize", "href": "/customize" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Components",
|
||||
"href": "/components",
|
||||
"noLink": true,
|
||||
"context": {
|
||||
"icon": "Layers",
|
||||
"description": "Write with Markdown",
|
||||
"title": "Markdown"
|
||||
},
|
||||
"items": [
|
||||
{ "title": "Accordion", "href": "/accordion" },
|
||||
{ "title": "Button", "href": "/button" },
|
||||
{ "title": "Card", "href": "/card" },
|
||||
{ "title": "Card Group", "href": "/card-group" },
|
||||
{ "title": "Code Block", "href": "/code-block" },
|
||||
{ "title": "File Tree", "href": "/file-tree" },
|
||||
{ "title": "Image", "href": "/image" },
|
||||
{ "title": "Keyboard", "href": "/keyboard" },
|
||||
{ "title": "Link", "href": "/link" },
|
||||
{ "title": "Note", "href": "/note" },
|
||||
{ "title": "Release Note", "href": "/release-note" },
|
||||
{ "title": "Stepper", "href": "/stepper" },
|
||||
{ "title": "Tabs", "href": "/tabs" },
|
||||
{ "title": "Tooltips", "href": "/tooltips" },
|
||||
{ "title": "Youtube", "href": "/youtube" },
|
||||
{ "title": "Custom", "href": "/custom" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
|
||||
export type ContextInfo = {
|
||||
icon: string;
|
||||
description: string;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type EachRoute = {
|
||||
title: string;
|
||||
href: string;
|
||||
noLink?: boolean; // Sekarang mendukung boolean
|
||||
noLink?: boolean;
|
||||
context?: ContextInfo;
|
||||
items?: EachRoute[];
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docubook",
|
||||
"version": "1.12.0",
|
||||
"version": "1.13.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
Reference in New Issue
Block a user