@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.
Files changed (54) hide show
  1. package/bun.lock +102 -0
  2. package/package.json +1 -1
  3. package/src/dist/.vscode/accordion.code-snippets +14 -0
  4. package/src/dist/.vscode/button.code-snippets +16 -0
  5. package/src/dist/.vscode/card.code-snippets +54 -0
  6. package/src/dist/.vscode/codeblock.code-snippets +16 -0
  7. package/src/dist/.vscode/file-tree.code-snippets +53 -0
  8. package/src/dist/.vscode/image-link.code-snippets +16 -0
  9. package/src/dist/.vscode/keyboard.code-snippets +23 -0
  10. package/src/dist/.vscode/metadata.code-snippets +13 -0
  11. package/src/dist/.vscode/note.code-snippets +38 -0
  12. package/src/dist/.vscode/release.code-snippets +49 -0
  13. package/src/dist/.vscode/stepper.code-snippets +24 -0
  14. package/src/dist/.vscode/table.code-snippets +12 -0
  15. package/src/dist/.vscode/tabs.code-snippets +33 -0
  16. package/src/dist/.vscode/tooltips.code-snippets +9 -0
  17. package/src/dist/.vscode/typography.code-snippets +33 -0
  18. package/src/dist/.vscode/youtube.code-snippets +9 -0
  19. package/src/dist/app/page.tsx +2 -2
  20. package/src/dist/components/context-popover.tsx +133 -0
  21. package/src/dist/components/docs-menu.tsx +39 -21
  22. package/src/dist/components/leftbar.tsx +10 -4
  23. package/src/dist/components/markdown/FileTreeMdx.tsx +119 -0
  24. package/src/dist/components/search.tsx +36 -4
  25. package/src/dist/contents/docs/{getting-started/changelog → changelog/version-1}/index.mdx +57 -0
  26. package/src/dist/contents/docs/{getting-started/components → components}/card/index.mdx +3 -3
  27. package/src/dist/contents/docs/components/file-tree/index.mdx +109 -0
  28. package/src/dist/contents/docs/getting-started/customize/index.mdx +0 -2
  29. package/src/dist/contents/docs/getting-started/installation/index.mdx +1 -1
  30. package/src/dist/contents/docs/getting-started/introduction/index.mdx +1 -1
  31. package/src/dist/contents/docs/getting-started/quick-start-guide/index.mdx +78 -60
  32. package/src/dist/docu.json +47 -28
  33. package/src/dist/lib/markdown.ts +6 -61
  34. package/src/dist/lib/routes-config.ts +8 -1
  35. package/src/dist/package.json +1 -1
  36. package/src/dist/styles/globals.css +0 -17
  37. package/src/dist/tailwind.config.ts +0 -1
  38. package/src/dist/contents/docs/getting-started/components/index.mdx +0 -9
  39. package/src/dist/next-env.d.ts +0 -5
  40. package/src/dist/styles/editor.css +0 -57
  41. /package/src/dist/contents/docs/{getting-started/components → components}/accordion/index.mdx +0 -0
  42. /package/src/dist/contents/docs/{getting-started/components → components}/button/index.mdx +0 -0
  43. /package/src/dist/contents/docs/{getting-started/components → components}/card-group/index.mdx +0 -0
  44. /package/src/dist/contents/docs/{getting-started/components → components}/code-block/index.mdx +0 -0
  45. /package/src/dist/contents/docs/{getting-started/components → components}/custom/index.mdx +0 -0
  46. /package/src/dist/contents/docs/{getting-started/components → components}/image/index.mdx +0 -0
  47. /package/src/dist/contents/docs/{getting-started/components → components}/keyboard/index.mdx +0 -0
  48. /package/src/dist/contents/docs/{getting-started/components → components}/link/index.mdx +0 -0
  49. /package/src/dist/contents/docs/{getting-started/components → components}/note/index.mdx +0 -0
  50. /package/src/dist/contents/docs/{getting-started/components → components}/release-note/index.mdx +0 -0
  51. /package/src/dist/contents/docs/{getting-started/components → components}/stepper/index.mdx +0 -0
  52. /package/src/dist/contents/docs/{getting-started/components → components}/tabs/index.mdx +0 -0
  53. /package/src/dist/contents/docs/{getting-started/components → components}/tooltips/index.mdx +0 -0
  54. /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-3.5 mt-5 pr-2 pb-6">
24
- {ROUTES.map((item, index) => {
25
- // Normalize href - hapus leading/trailing slashes
26
- const normalizedHref = `/${item.href.replace(/^\/+|\/+$/g, '')}`;
27
- const itemHref = `/docs${normalizedHref}`;
28
-
29
- const modifiedItems = {
30
- ...item,
31
- href: itemHref,
32
- level: 0,
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 DocsMenu */}
55
+ {/* Scrollable Content */}
56
56
  <ScrollArea className="flex-1 px-0.5 pb-4">
57
- {!collapsed && <DocsMenu />}
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
- () => advanceSearch(searchedInput.trim()),
44
- [searchedInput]
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">Card with Link & Icon</TabsTrigger>
45
- <TabsTrigger value="horizontal">Card Horizontal</TabsTrigger>
46
- <TabsTrigger value="simple">Card Simple</TabsTrigger>
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
@@ -90,5 +90,3 @@ For both options, ensure that you add the variable to `tailwind.config.ts`:
90
90
  }
91
91
  }
92
92
  ```
93
-
94
- 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.
15
15
  Begin by cloning the DocuBook repository from GitHub:
16
16
 
17
17
  ```bash
18
- git clone --branch starter https://gitlab.com/mywildancloud/docubook.git
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/gitfromwildan/docubook) to get started! From
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