@docubook/create 1.11.3 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +102 -0
- package/package.json +1 -1
- package/src/dist/.vscode/accordion.code-snippets +14 -0
- package/src/dist/.vscode/button.code-snippets +16 -0
- package/src/dist/.vscode/card.code-snippets +54 -0
- package/src/dist/.vscode/codeblock.code-snippets +16 -0
- package/src/dist/.vscode/file-tree.code-snippets +53 -0
- package/src/dist/.vscode/image-link.code-snippets +16 -0
- package/src/dist/.vscode/keyboard.code-snippets +23 -0
- package/src/dist/.vscode/metadata.code-snippets +13 -0
- package/src/dist/.vscode/note.code-snippets +38 -0
- package/src/dist/.vscode/release.code-snippets +49 -0
- package/src/dist/.vscode/stepper.code-snippets +24 -0
- package/src/dist/.vscode/table.code-snippets +12 -0
- package/src/dist/.vscode/tabs.code-snippets +33 -0
- package/src/dist/.vscode/tooltips.code-snippets +9 -0
- package/src/dist/.vscode/typography.code-snippets +33 -0
- package/src/dist/.vscode/youtube.code-snippets +9 -0
- package/src/dist/app/page.tsx +2 -2
- package/src/dist/components/context-popover.tsx +133 -0
- package/src/dist/components/docs-menu.tsx +39 -21
- package/src/dist/components/leftbar.tsx +10 -4
- package/src/dist/components/markdown/FileTreeMdx.tsx +119 -0
- package/src/dist/components/search.tsx +36 -4
- package/src/dist/contents/docs/{getting-started/changelog → changelog/version-1}/index.mdx +57 -0
- package/src/dist/contents/docs/{getting-started/components → components}/card/index.mdx +3 -3
- package/src/dist/contents/docs/components/file-tree/index.mdx +109 -0
- package/src/dist/contents/docs/getting-started/customize/index.mdx +0 -2
- package/src/dist/contents/docs/getting-started/installation/index.mdx +1 -1
- package/src/dist/contents/docs/getting-started/introduction/index.mdx +1 -1
- package/src/dist/contents/docs/getting-started/quick-start-guide/index.mdx +78 -60
- package/src/dist/docu.json +47 -28
- package/src/dist/lib/markdown.ts +6 -61
- package/src/dist/lib/routes-config.ts +8 -1
- package/src/dist/package.json +1 -1
- package/src/dist/styles/globals.css +0 -17
- package/src/dist/tailwind.config.ts +0 -1
- package/src/dist/contents/docs/getting-started/components/index.mdx +0 -9
- package/src/dist/next-env.d.ts +0 -5
- package/src/dist/styles/editor.css +0 -57
- /package/src/dist/contents/docs/{getting-started/components → components}/accordion/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/button/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/card-group/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/code-block/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/custom/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/image/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/keyboard/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/link/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/note/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/release-note/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/stepper/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/tabs/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/tooltips/index.mdx +0 -0
- /package/src/dist/contents/docs/{getting-started/components → components}/youtube/index.mdx +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
4
|
+
import { useState, useEffect } from "react";
|
|
5
|
+
import { ROUTES, EachRoute } from "@/lib/routes-config";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
|
8
|
+
import { Button } from "@/components/ui/button";
|
|
9
|
+
import * as LucideIcons from "lucide-react";
|
|
10
|
+
import { ChevronsUpDown, Check, type LucideIcon } from "lucide-react";
|
|
11
|
+
|
|
12
|
+
interface ContextPopoverProps {
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Get all root-level routes with context
|
|
17
|
+
function getContextRoutes(): EachRoute[] {
|
|
18
|
+
return ROUTES.filter(route => route.context);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Get the first item's href from a route
|
|
22
|
+
function getFirstItemHref(route: EachRoute): string {
|
|
23
|
+
return route.items?.[0]?.href ? `${route.href}${route.items[0].href}` : route.href;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Get the active context route from the current path
|
|
27
|
+
function getActiveContextRoute(path: string): EachRoute | undefined {
|
|
28
|
+
if (!path.startsWith('/docs')) return undefined;
|
|
29
|
+
const docPath = path.replace(/^\/docs/, '');
|
|
30
|
+
return getContextRoutes().find(route => docPath.startsWith(route.href));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Get icon component by name
|
|
34
|
+
function getIcon(name: string) {
|
|
35
|
+
const Icon = LucideIcons[name as keyof typeof LucideIcons] as LucideIcon | undefined;
|
|
36
|
+
if (!Icon) return <LucideIcons.FileQuestion className="h-4 w-4" />;
|
|
37
|
+
return <Icon className="h-4 w-4" />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default function ContextPopover({ className }: ContextPopoverProps) {
|
|
41
|
+
const pathname = usePathname();
|
|
42
|
+
const router = useRouter();
|
|
43
|
+
const [activeRoute, setActiveRoute] = useState<EachRoute>();
|
|
44
|
+
const contextRoutes = getContextRoutes();
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (pathname.startsWith("/docs")) {
|
|
48
|
+
setActiveRoute(getActiveContextRoute(pathname));
|
|
49
|
+
} else {
|
|
50
|
+
setActiveRoute(undefined);
|
|
51
|
+
}
|
|
52
|
+
}, [pathname]);
|
|
53
|
+
|
|
54
|
+
if (!pathname.startsWith("/docs") || contextRoutes.length === 0) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<Popover>
|
|
60
|
+
<PopoverTrigger asChild>
|
|
61
|
+
<Button
|
|
62
|
+
variant="ghost"
|
|
63
|
+
className={cn(
|
|
64
|
+
"w-full max-w-[240px] flex items-center justify-between font-semibold text-foreground px-0 pt-8",
|
|
65
|
+
"hover:bg-transparent hover:text-foreground",
|
|
66
|
+
className
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
<div className="flex items-center gap-2">
|
|
70
|
+
{activeRoute?.context?.icon && (
|
|
71
|
+
<span className="text-primary bg-primary/10 border border-primary rounded p-0.5">
|
|
72
|
+
{getIcon(activeRoute.context.icon)}
|
|
73
|
+
</span>
|
|
74
|
+
)}
|
|
75
|
+
<span className="truncate text-sm">
|
|
76
|
+
{activeRoute?.context?.title || activeRoute?.title || 'Select context'}
|
|
77
|
+
</span>
|
|
78
|
+
</div>
|
|
79
|
+
<ChevronsUpDown className="h-4 w-4 text-foreground/50" />
|
|
80
|
+
</Button>
|
|
81
|
+
</PopoverTrigger>
|
|
82
|
+
<PopoverContent
|
|
83
|
+
className="w-64 p-2"
|
|
84
|
+
align="start"
|
|
85
|
+
sideOffset={6}
|
|
86
|
+
>
|
|
87
|
+
<div className="space-y-1">
|
|
88
|
+
{contextRoutes.map((route) => {
|
|
89
|
+
const isActive = activeRoute?.href === route.href;
|
|
90
|
+
const firstItemPath = getFirstItemHref(route);
|
|
91
|
+
const contextPath = `/docs${firstItemPath}`;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<button
|
|
95
|
+
key={route.href}
|
|
96
|
+
onClick={() => router.push(contextPath)}
|
|
97
|
+
className={cn(
|
|
98
|
+
"relative flex w-full items-center gap-2 rounded px-2 py-1.5 text-sm",
|
|
99
|
+
"text-left outline-none transition-colors",
|
|
100
|
+
isActive
|
|
101
|
+
? "bg-primary/20 text-primary"
|
|
102
|
+
: "text-foreground/80 hover:bg-primary/20"
|
|
103
|
+
)}
|
|
104
|
+
>
|
|
105
|
+
{route.context?.icon && (
|
|
106
|
+
<span className={cn(
|
|
107
|
+
"flex h-4 w-4 items-center justify-center",
|
|
108
|
+
isActive ? "text-primary" : "text-foreground/60"
|
|
109
|
+
)}>
|
|
110
|
+
{getIcon(route.context.icon)}
|
|
111
|
+
</span>
|
|
112
|
+
)}
|
|
113
|
+
<div className="flex-1 min-w-0 overflow-hidden">
|
|
114
|
+
<div className="truncate font-medium">
|
|
115
|
+
{route.context?.title || route.title}
|
|
116
|
+
</div>
|
|
117
|
+
{route.context?.description && (
|
|
118
|
+
<div className="text-xs text-muted-foreground truncate text-ellipsis overflow-hidden max-w-full">
|
|
119
|
+
{route.context.description}
|
|
120
|
+
</div>
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
{isActive && (
|
|
124
|
+
<Check className="h-3.5 w-3.5" />
|
|
125
|
+
)}
|
|
126
|
+
</button>
|
|
127
|
+
);
|
|
128
|
+
})}
|
|
129
|
+
</div>
|
|
130
|
+
</PopoverContent>
|
|
131
|
+
</Popover>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -1,44 +1,62 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { ROUTES } from "@/lib/routes-config";
|
|
3
|
+
import { ROUTES, EachRoute } from "@/lib/routes-config";
|
|
4
4
|
import SubLink from "./sublink";
|
|
5
5
|
import { usePathname } from "next/navigation";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
6
7
|
|
|
7
8
|
interface DocsMenuProps {
|
|
8
9
|
isSheet?: boolean;
|
|
9
10
|
className?: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
// Get the current context from the path
|
|
14
|
+
function getCurrentContext(path: string): string | undefined {
|
|
15
|
+
if (!path.startsWith('/docs')) return undefined;
|
|
16
|
+
|
|
17
|
+
// Extract the first segment after /docs/
|
|
18
|
+
const match = path.match(/^\/docs\/([^\/]+)/);
|
|
19
|
+
return match ? match[1] : undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Get the route that matches the current context
|
|
23
|
+
function getContextRoute(contextPath: string): EachRoute | undefined {
|
|
24
|
+
return ROUTES.find(route => {
|
|
25
|
+
const normalizedHref = route.href.replace(/^\/+|\/+$/g, '');
|
|
26
|
+
return normalizedHref === contextPath;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
12
30
|
export default function DocsMenu({ isSheet = false, className = "" }: DocsMenuProps) {
|
|
13
31
|
const pathname = usePathname();
|
|
14
32
|
|
|
15
33
|
// Skip rendering if not on a docs page
|
|
16
34
|
if (!pathname.startsWith("/docs")) return null;
|
|
17
35
|
|
|
36
|
+
// Get the current context
|
|
37
|
+
const currentContext = getCurrentContext(pathname);
|
|
38
|
+
|
|
39
|
+
// Get the route for the current context
|
|
40
|
+
const contextRoute = currentContext ? getContextRoute(currentContext) : undefined;
|
|
41
|
+
|
|
42
|
+
// If no context route is found, don't render anything
|
|
43
|
+
if (!contextRoute) return null;
|
|
44
|
+
|
|
18
45
|
return (
|
|
19
46
|
<nav
|
|
20
47
|
aria-label="Documentation navigation"
|
|
21
|
-
className={className}
|
|
48
|
+
className={cn("transition-all duration-200", className)}
|
|
22
49
|
>
|
|
23
|
-
<ul className="flex flex-col gap-
|
|
24
|
-
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
isSheet,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<li key={`${item.title}-${index}`}>
|
|
38
|
-
<SubLink {...modifiedItems} />
|
|
39
|
-
</li>
|
|
40
|
-
);
|
|
41
|
-
})}
|
|
50
|
+
<ul className="flex flex-col gap-1.5 py-4">
|
|
51
|
+
{/* Display only the items from the current context */}
|
|
52
|
+
<li key={contextRoute.title}>
|
|
53
|
+
<SubLink
|
|
54
|
+
{...contextRoute}
|
|
55
|
+
href={`/docs${contextRoute.href}`}
|
|
56
|
+
level={0}
|
|
57
|
+
isSheet={isSheet}
|
|
58
|
+
/>
|
|
59
|
+
</li>
|
|
42
60
|
</ul>
|
|
43
61
|
</nav>
|
|
44
62
|
);
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
import { Logo, NavMenu } from "@/components/navbar";
|
|
11
11
|
import { Button } from "@/components/ui/button";
|
|
12
12
|
import { AlignLeftIcon, PanelLeftClose, PanelLeftOpen } from "lucide-react";
|
|
13
|
-
import { FooterButtons } from "@/components/footer";
|
|
14
13
|
import { DialogTitle, DialogDescription } from "@/components/ui/dialog";
|
|
15
14
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
16
15
|
import DocsMenu from "@/components/docs-menu";
|
|
17
16
|
import { ModeToggle } from "@/components/theme-toggle";
|
|
17
|
+
import ContextPopover from "@/components/context-popover";
|
|
18
18
|
|
|
19
19
|
// Toggle Button Component
|
|
20
20
|
export function ToggleButton({
|
|
@@ -52,9 +52,14 @@ export function Leftbar() {
|
|
|
52
52
|
${collapsed ? "w-[24px]" : "w-[280px]"} flex flex-col pr-2`}
|
|
53
53
|
>
|
|
54
54
|
<ToggleButton collapsed={collapsed} onToggle={toggleCollapse} />
|
|
55
|
-
{/* Scrollable
|
|
55
|
+
{/* Scrollable Content */}
|
|
56
56
|
<ScrollArea className="flex-1 px-0.5 pb-4">
|
|
57
|
-
{!collapsed &&
|
|
57
|
+
{!collapsed && (
|
|
58
|
+
<div className="space-y-2">
|
|
59
|
+
<ContextPopover />
|
|
60
|
+
<DocsMenu />
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
58
63
|
</ScrollArea>
|
|
59
64
|
</aside>
|
|
60
65
|
);
|
|
@@ -82,7 +87,8 @@ export function SheetLeftbar() {
|
|
|
82
87
|
<div className="flex flex-col gap-2.5 mt-3 mx-2 px-5">
|
|
83
88
|
<NavMenu isSheet />
|
|
84
89
|
</div>
|
|
85
|
-
<div className="mx-2 px-5">
|
|
90
|
+
<div className="mx-2 px-5 space-y-2">
|
|
91
|
+
<ContextPopover />
|
|
86
92
|
<DocsMenu isSheet />
|
|
87
93
|
</div>
|
|
88
94
|
<div className="flex w-2/4 px-5">
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useState, ReactNode, Children, isValidElement, cloneElement } from 'react';
|
|
4
|
+
import { ChevronRight, ChevronDown, File as FileIcon, Folder as FolderIcon, FolderOpen } from 'lucide-react';
|
|
5
|
+
|
|
6
|
+
interface FileTreeProps {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface FileProps {
|
|
12
|
+
name: string;
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const FileComponent = ({ name }: FileProps) => {
|
|
17
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div
|
|
21
|
+
className={`
|
|
22
|
+
flex items-center gap-2 py-1.5 pl-7 pr-3 text-sm
|
|
23
|
+
transition-all duration-200 ease-in-out rounded-md
|
|
24
|
+
${isHovered
|
|
25
|
+
? 'bg-blue-50 dark:bg-blue-900/30'
|
|
26
|
+
: 'hover:bg-gray-50 dark:hover:bg-gray-800/50'}
|
|
27
|
+
`}
|
|
28
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
29
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
30
|
+
>
|
|
31
|
+
<FileIcon className={`h-3.5 w-3.5 transition-colors ${isHovered ? 'text-blue-500' : 'text-gray-400 dark:text-gray-500'}`} />
|
|
32
|
+
<span className="font-mono text-sm text-gray-700 dark:text-gray-300">{name}</span>
|
|
33
|
+
{isHovered && (
|
|
34
|
+
<span className="ml-auto text-xs text-gray-400 dark:text-gray-500">
|
|
35
|
+
{name.split('.').pop()?.toUpperCase()}
|
|
36
|
+
</span>
|
|
37
|
+
)}
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const FolderComponent = ({ name, children }: FileProps) => {
|
|
43
|
+
const [isOpen, setIsOpen] = useState(true); // Set to true by default
|
|
44
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
45
|
+
const hasChildren = React.Children.count(children) > 0;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="relative">
|
|
49
|
+
<div
|
|
50
|
+
className={`
|
|
51
|
+
flex items-center gap-2 py-1.5 pl-4 pr-3 rounded-md cursor-pointer
|
|
52
|
+
transition-all duration-200 ease-in-out
|
|
53
|
+
${isHovered ? 'bg-gray-50 dark:bg-gray-800/50' : ''}
|
|
54
|
+
${isOpen ? 'text-blue-600 dark:text-blue-400' : 'text-gray-800 dark:text-gray-200'}
|
|
55
|
+
`}
|
|
56
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
57
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
58
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
59
|
+
>
|
|
60
|
+
{hasChildren ? (
|
|
61
|
+
<ChevronRight
|
|
62
|
+
className={`h-3.5 w-3.5 transition-transform duration-200 ${isOpen ? 'transform rotate-90' : ''}`}
|
|
63
|
+
/>
|
|
64
|
+
) : (
|
|
65
|
+
<div className="w-3.5" />
|
|
66
|
+
)}
|
|
67
|
+
{isOpen ? (
|
|
68
|
+
<FolderOpen className="h-4 w-4 text-blue-500 dark:text-blue-400" />
|
|
69
|
+
) : (
|
|
70
|
+
<FolderIcon className="h-4 w-4 text-blue-400 dark:text-blue-500" />
|
|
71
|
+
)}
|
|
72
|
+
<span className="font-medium">{name}</span>
|
|
73
|
+
</div>
|
|
74
|
+
{isOpen && hasChildren && (
|
|
75
|
+
<div className="ml-5 border-l-2 border-gray-100 dark:border-gray-700/50 pl-2">
|
|
76
|
+
{children}
|
|
77
|
+
</div>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const Files = ({ children }: { children: ReactNode }) => {
|
|
84
|
+
return (
|
|
85
|
+
<div className="
|
|
86
|
+
rounded-xl border border-gray-100 dark:border-gray-700/50
|
|
87
|
+
bg-white/50 dark:bg-gray-800/30 backdrop-blur-sm
|
|
88
|
+
shadow-sm overflow-hidden
|
|
89
|
+
transition-all duration-200
|
|
90
|
+
hover:shadow-md hover:border-gray-200 dark:hover:border-gray-600/50
|
|
91
|
+
">
|
|
92
|
+
<div className="p-2">
|
|
93
|
+
{Children.map(children, (child, index) => {
|
|
94
|
+
if (isValidElement(child)) {
|
|
95
|
+
return cloneElement(child, { key: index });
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
})}
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const Folder = ({ name, children }: FileProps) => {
|
|
105
|
+
return <FolderComponent name={name}>{children}</FolderComponent>;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const File = ({ name }: FileProps) => {
|
|
109
|
+
return <FileComponent name={name} />;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// MDX Components
|
|
113
|
+
export const FileTreeMdx = {
|
|
114
|
+
Files,
|
|
115
|
+
File,
|
|
116
|
+
Folder,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default FileTreeMdx;
|
|
@@ -17,6 +17,23 @@ import {
|
|
|
17
17
|
import Anchor from "./anchor";
|
|
18
18
|
import { advanceSearch, cn } from "@/lib/utils";
|
|
19
19
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
20
|
+
import { page_routes } from "@/lib/routes-config";
|
|
21
|
+
|
|
22
|
+
// Define the ContextInfo type to match the one in routes-config
|
|
23
|
+
type ContextInfo = {
|
|
24
|
+
icon: string;
|
|
25
|
+
description: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type SearchResult = {
|
|
30
|
+
title: string;
|
|
31
|
+
href: string;
|
|
32
|
+
noLink?: boolean;
|
|
33
|
+
items?: undefined;
|
|
34
|
+
score?: number;
|
|
35
|
+
context?: ContextInfo;
|
|
36
|
+
};
|
|
20
37
|
|
|
21
38
|
export default function Search() {
|
|
22
39
|
const router = useRouter();
|
|
@@ -39,10 +56,25 @@ export default function Search() {
|
|
|
39
56
|
};
|
|
40
57
|
}, []);
|
|
41
58
|
|
|
42
|
-
const filteredResults = useMemo(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
const filteredResults = useMemo<SearchResult[]>(() => {
|
|
60
|
+
const trimmedInput = searchedInput.trim();
|
|
61
|
+
|
|
62
|
+
// If search input is empty or less than 3 characters, show initial suggestions
|
|
63
|
+
if (trimmedInput.length < 3) {
|
|
64
|
+
return page_routes
|
|
65
|
+
.filter((route: { href: string }) => !route.href.endsWith('/')) // Filter out directory routes
|
|
66
|
+
.slice(0, 6) // Limit to 6 posts
|
|
67
|
+
.map((route: { title: string; href: string; noLink?: boolean; context?: ContextInfo }) => ({
|
|
68
|
+
title: route.title,
|
|
69
|
+
href: route.href,
|
|
70
|
+
noLink: route.noLink,
|
|
71
|
+
context: route.context
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// For search with 3 or more characters, use the advance search
|
|
76
|
+
return advanceSearch(trimmedInput) as unknown as SearchResult[];
|
|
77
|
+
}, [searchedInput]);
|
|
46
78
|
|
|
47
79
|
useEffect(() => {
|
|
48
80
|
setSelectedIndex(0);
|
|
@@ -8,6 +8,63 @@ date: 24-05-2025
|
|
|
8
8
|
|
|
9
9
|
> 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.
|
|
10
10
|
|
|
11
|
+
<div className="sr-only">
|
|
12
|
+
### v 1.13.0
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<Release version="1.13.0" date="2025-05-29" title="Context Menu for organize file and folder">
|
|
16
|
+
<Changes type="added">
|
|
17
|
+
- New ContextMenu component for organizing file and folder
|
|
18
|
+
- Nested docs folder and file support with context menu
|
|
19
|
+
</Changes>
|
|
20
|
+
<Changes type="improved">
|
|
21
|
+
- improve routes-config with context menu
|
|
22
|
+
- improve docu.json with context menu
|
|
23
|
+
- improve leftbar with context menu
|
|
24
|
+
- improve docs-menu with context menu
|
|
25
|
+
- improve search dialog limit result to 6 post per suggestion
|
|
26
|
+
- improve search result typing 3 characters to show suggestion
|
|
27
|
+
</Changes>
|
|
28
|
+
</Release>
|
|
29
|
+
|
|
30
|
+
<div className="sr-only">
|
|
31
|
+
### v 1.12.0
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<Release version="1.12.0" date="2025-05-28" title="New File Tree Component and enhancements for existing components or features">
|
|
35
|
+
<Changes type="added">
|
|
36
|
+
- New FileTree component for displaying hierarchical file structures
|
|
37
|
+
- Support for nested folders and files with expand/collapse functionality
|
|
38
|
+
- Hover effects showing file extensions
|
|
39
|
+
- Dark mode support with modern styling
|
|
40
|
+
- Keyboard navigation and accessibility features
|
|
41
|
+
- add toc-observer data attribute to detect toc section
|
|
42
|
+
- cli to copy from path npm registry
|
|
43
|
+
</Changes>
|
|
44
|
+
<Changes type="improved">
|
|
45
|
+
- search dialog hover effect return key
|
|
46
|
+
- search icon showing on mobile screens
|
|
47
|
+
</Changes>
|
|
48
|
+
<Changes type="fixed">
|
|
49
|
+
- fix search dialog on mobile screens
|
|
50
|
+
- fix release note component eslint error on mdx when rendering
|
|
51
|
+
- fix mob-toc callback function
|
|
52
|
+
- fix toc height issue when toc section is longer than screen height
|
|
53
|
+
</Changes>
|
|
54
|
+
<Changes type="removed">
|
|
55
|
+
- remove prompts depedencies
|
|
56
|
+
- remove degit depedencies
|
|
57
|
+
- remove prompts functions
|
|
58
|
+
- remove degit functions
|
|
59
|
+
- remove prompts and degit from package.json
|
|
60
|
+
- remove clone repository using git
|
|
61
|
+
</Changes>
|
|
62
|
+
</Release>
|
|
63
|
+
|
|
64
|
+
<Note type="note" title="Note">
|
|
65
|
+
on this version `1.12.0`, we remove clone repository using git and replace it with cli to copy from path npm registry
|
|
66
|
+
</Note>
|
|
67
|
+
|
|
11
68
|
<div className="sr-only">
|
|
12
69
|
### v 1.11.0
|
|
13
70
|
</div>
|
|
@@ -41,9 +41,9 @@ The Card component is a component used to create cards that can be used to displ
|
|
|
41
41
|
|
|
42
42
|
<Tabs defaultValue="link" className="pt-5 pb-1">
|
|
43
43
|
<TabsList>
|
|
44
|
-
<TabsTrigger value="link">
|
|
45
|
-
<TabsTrigger value="horizontal">
|
|
46
|
-
<TabsTrigger value="simple">
|
|
44
|
+
<TabsTrigger value="link">Link & Icon</TabsTrigger>
|
|
45
|
+
<TabsTrigger value="horizontal">Horizontal</TabsTrigger>
|
|
46
|
+
<TabsTrigger value="simple">Simple</TabsTrigger>
|
|
47
47
|
</TabsList>
|
|
48
48
|
<TabsContent value="link">
|
|
49
49
|
```markdown
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: File Tree Component
|
|
3
|
+
description: A customizable file tree component for displaying hierarchical file structures in your documentation.
|
|
4
|
+
date: 28-05-2025
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
The File Tree component allows you to display hierarchical file structures in your documentation with collapsible folders and files.
|
|
8
|
+
|
|
9
|
+
## Basic Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
<Files>
|
|
13
|
+
<Folder name="src">
|
|
14
|
+
<File name="App.tsx" />
|
|
15
|
+
<File name="index.tsx" />
|
|
16
|
+
<Folder name="components">
|
|
17
|
+
<File name="Button.tsx" />
|
|
18
|
+
<File name="Card.tsx" />
|
|
19
|
+
</Folder>
|
|
20
|
+
<Folder name="pages">
|
|
21
|
+
<File name="Home.tsx" />
|
|
22
|
+
<File name="About.tsx" />
|
|
23
|
+
</Folder>
|
|
24
|
+
</Folder>
|
|
25
|
+
</Files>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Render As:
|
|
29
|
+
<Files>
|
|
30
|
+
<Folder name="src">
|
|
31
|
+
<File name="App.tsx" />
|
|
32
|
+
<File name="index.tsx" />
|
|
33
|
+
<Folder name="components">
|
|
34
|
+
<File name="Button.tsx" />
|
|
35
|
+
<File name="Card.tsx" />
|
|
36
|
+
</Folder>
|
|
37
|
+
<Folder name="pages">
|
|
38
|
+
<File name="Home.tsx" />
|
|
39
|
+
<File name="About.tsx" />
|
|
40
|
+
</Folder>
|
|
41
|
+
</Folder>
|
|
42
|
+
</Files>
|
|
43
|
+
|
|
44
|
+
## Props
|
|
45
|
+
|
|
46
|
+
### Files
|
|
47
|
+
|
|
48
|
+
The root component that wraps the entire file tree.
|
|
49
|
+
|
|
50
|
+
### Folder
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Required | Description |
|
|
53
|
+
|----------|----------|----------|---------------------------------------|
|
|
54
|
+
| name | string | Yes | The name of the folder |
|
|
55
|
+
| children | ReactNode | No | Child elements (File or Folder) |
|
|
56
|
+
|
|
57
|
+
### File
|
|
58
|
+
|
|
59
|
+
| Prop | Type | Required | Description |
|
|
60
|
+
|------|--------|----------|----------------------------|
|
|
61
|
+
| name | string | Yes | The name of the file |
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### Nested Folder Structure
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
<Files>
|
|
70
|
+
<Folder name="project-root">
|
|
71
|
+
<File name="package.json" />
|
|
72
|
+
<File name="tsconfig.json" />
|
|
73
|
+
<Folder name="src">
|
|
74
|
+
<File name="index.ts" />
|
|
75
|
+
<Folder name="components">
|
|
76
|
+
<File name="Button.tsx" />
|
|
77
|
+
<File name="Card.tsx" />
|
|
78
|
+
</Folder>
|
|
79
|
+
</Folder>
|
|
80
|
+
</Folder>
|
|
81
|
+
</Files>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Minimal Example
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
<Files>
|
|
88
|
+
<Folder name="components">
|
|
89
|
+
<File name="Button.tsx" />
|
|
90
|
+
<File name="Input.tsx" />
|
|
91
|
+
</Folder>
|
|
92
|
+
</Files>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Best Practices
|
|
96
|
+
|
|
97
|
+
1. Keep the nesting level reasonable (recommended max 3-4 levels deep)
|
|
98
|
+
2. Use clear and descriptive names for files and folders
|
|
99
|
+
3. Consider the user experience when displaying large file structures
|
|
100
|
+
4. Use consistent naming conventions throughout your file tree
|
|
101
|
+
|
|
102
|
+
## Accessibility
|
|
103
|
+
|
|
104
|
+
The File Tree component includes built-in accessibility features:
|
|
105
|
+
|
|
106
|
+
- Keyboard navigation support
|
|
107
|
+
- ARIA attributes for screen readers
|
|
108
|
+
- Focus management for interactive elements
|
|
109
|
+
- High contrast mode support
|
|
@@ -15,7 +15,7 @@ To get started, you can clone the DocuBook repository directly from GitHub.
|
|
|
15
15
|
Begin by cloning the DocuBook repository from GitHub:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
git clone --branch
|
|
18
|
+
git clone --branch main https://github.com/DocuBook/docubook.git
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
</StepperItem>
|
|
@@ -13,7 +13,7 @@ DocuBook is proudly **open-source**! 🎉 We believe in creating an accessible,
|
|
|
13
13
|
|
|
14
14
|
<Note title="Contribute">
|
|
15
15
|
Interested in helping us improve? Check out our [GitHub
|
|
16
|
-
repository](https://github.com/
|
|
16
|
+
repository](https://github.com/DocuBook/docubook) to get started! From
|
|
17
17
|
feature suggestions to bug fixes, all contributions are welcome.
|
|
18
18
|
</Note>
|
|
19
19
|
|