fumadocs-ui 8.0.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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/chunk-24NYFO7H.js +31 -0
  4. package/dist/chunk-2ZR5Z6B2.js +105 -0
  5. package/dist/chunk-36MVEJ25.js +39 -0
  6. package/dist/chunk-5EZE3X7G.js +31 -0
  7. package/dist/chunk-5KW7ATCP.js +23 -0
  8. package/dist/chunk-6C3VEZWH.js +9 -0
  9. package/dist/chunk-CBOHU2VN.js +28 -0
  10. package/dist/chunk-EDUYFB4P.js +43 -0
  11. package/dist/chunk-F62NYOL5.js +44 -0
  12. package/dist/chunk-GZQICERS.js +31 -0
  13. package/dist/chunk-IXYX64FW.js +243 -0
  14. package/dist/chunk-KCGRUOMD.js +13 -0
  15. package/dist/chunk-OG3QOLYP.js +43 -0
  16. package/dist/chunk-PLXR6QNH.js +21 -0
  17. package/dist/chunk-UIZNMCLD.js +49 -0
  18. package/dist/chunk-YAHHY62W.js +20 -0
  19. package/dist/components/accordion.d.mts +11 -0
  20. package/dist/components/accordion.js +128 -0
  21. package/dist/components/api.d.mts +20 -0
  22. package/dist/components/api.js +136 -0
  23. package/dist/components/callout.d.mts +13 -0
  24. package/dist/components/callout.js +39 -0
  25. package/dist/components/card.d.mts +12 -0
  26. package/dist/components/card.js +10 -0
  27. package/dist/components/codeblock.d.mts +12 -0
  28. package/dist/components/codeblock.js +14 -0
  29. package/dist/components/dialog/search-algolia.d.mts +15 -0
  30. package/dist/components/dialog/search-algolia.js +39 -0
  31. package/dist/components/dialog/search-default.d.mts +15 -0
  32. package/dist/components/dialog/search-default.js +39 -0
  33. package/dist/components/dialog/search.d.mts +25 -0
  34. package/dist/components/dialog/search.js +13 -0
  35. package/dist/components/files.d.mts +20 -0
  36. package/dist/components/files.js +56 -0
  37. package/dist/components/heading.d.mts +9 -0
  38. package/dist/components/heading.js +8 -0
  39. package/dist/components/image-zoom.d.mts +12 -0
  40. package/dist/components/image-zoom.js +39 -0
  41. package/dist/components/inline-toc.d.mts +11 -0
  42. package/dist/components/inline-toc.js +53 -0
  43. package/dist/components/roll-button.d.mts +14 -0
  44. package/dist/components/roll-button.js +54 -0
  45. package/dist/components/steps.d.mts +10 -0
  46. package/dist/components/steps.js +14 -0
  47. package/dist/components/tabs.d.mts +37 -0
  48. package/dist/components/tabs.js +141 -0
  49. package/dist/components/type-table.d.mts +23 -0
  50. package/dist/components/type-table.js +52 -0
  51. package/dist/i18n-dw7ODAws.d.mts +22 -0
  52. package/dist/i18n.d.mts +21 -0
  53. package/dist/i18n.js +146 -0
  54. package/dist/layout-YB7EFpgW.d.mts +79 -0
  55. package/dist/layout.client.d.mts +4 -0
  56. package/dist/layout.client.js +458 -0
  57. package/dist/layout.d.mts +3 -0
  58. package/dist/layout.js +97 -0
  59. package/dist/mdx.client.d.mts +7 -0
  60. package/dist/mdx.client.js +23 -0
  61. package/dist/mdx.d.mts +36 -0
  62. package/dist/mdx.js +51 -0
  63. package/dist/page.client.d.mts +29 -0
  64. package/dist/page.client.js +168 -0
  65. package/dist/page.d.mts +49 -0
  66. package/dist/page.js +56 -0
  67. package/dist/provider.d.mts +50 -0
  68. package/dist/provider.js +51 -0
  69. package/dist/style.css +1 -0
  70. package/dist/tailwind-plugin.d.ts +36 -0
  71. package/dist/tailwind-plugin.js +481 -0
  72. package/dist/tree-Zwtp9xPv.d.mts +15 -0
  73. package/package.json +97 -0
package/dist/i18n.js ADDED
@@ -0,0 +1,146 @@
1
+ "use client";
2
+ import {
3
+ I18nContext,
4
+ useI18n
5
+ } from "./chunk-YAHHY62W.js";
6
+ import {
7
+ cn
8
+ } from "./chunk-KCGRUOMD.js";
9
+ import "./chunk-6C3VEZWH.js";
10
+
11
+ // src/i18n.tsx
12
+ import { useCallback } from "react";
13
+ import { useRouter, usePathname } from "next/navigation";
14
+
15
+ // src/components/ui/select.tsx
16
+ import * as SelectPrimitive from "@radix-ui/react-select";
17
+ import { Check, ChevronDown } from "lucide-react";
18
+ import * as React from "react";
19
+ import { jsx, jsxs } from "react/jsx-runtime";
20
+ var Select = SelectPrimitive.Root;
21
+ var SelectValue = SelectPrimitive.Value;
22
+ var SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
23
+ SelectPrimitive.Trigger,
24
+ {
25
+ ref,
26
+ className: cn(
27
+ "flex h-10 w-full items-center justify-between rounded-md border border-input px-3 py-2 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground",
28
+ className
29
+ ),
30
+ ...props,
31
+ children: [
32
+ children,
33
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 opacity-50" }) })
34
+ ]
35
+ }
36
+ ));
37
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
38
+ var SelectContent = React.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
39
+ SelectPrimitive.Content,
40
+ {
41
+ ref,
42
+ className: cn(
43
+ "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=closed]:animate-popover-out data-[state=open]:animate-popover-in",
44
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
45
+ className
46
+ ),
47
+ position,
48
+ ...props,
49
+ children: /* @__PURE__ */ jsx(
50
+ SelectPrimitive.Viewport,
51
+ {
52
+ className: cn(
53
+ "p-1",
54
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
55
+ ),
56
+ children
57
+ }
58
+ )
59
+ }
60
+ ) }));
61
+ SelectContent.displayName = SelectPrimitive.Content.displayName;
62
+ var SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
63
+ SelectPrimitive.Label,
64
+ {
65
+ ref,
66
+ className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
67
+ ...props
68
+ }
69
+ ));
70
+ SelectLabel.displayName = SelectPrimitive.Label.displayName;
71
+ var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
72
+ SelectPrimitive.Item,
73
+ {
74
+ ref,
75
+ className: cn(
76
+ "relative flex w-full select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
77
+ className
78
+ ),
79
+ ...props,
80
+ children: [
81
+ /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "size-4" }) }) }),
82
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
83
+ ]
84
+ }
85
+ ));
86
+ SelectItem.displayName = SelectPrimitive.Item.displayName;
87
+ var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
88
+ SelectPrimitive.Separator,
89
+ {
90
+ ref,
91
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
92
+ ...props
93
+ }
94
+ ));
95
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
96
+
97
+ // src/i18n.tsx
98
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
99
+ function LanguageSelect({ ...props }) {
100
+ const context = useI18n();
101
+ if (!context.translations)
102
+ throw new Error("Missing prop `translations`");
103
+ const languages = Object.entries(context.translations);
104
+ return /* @__PURE__ */ jsxs2(Select, { value: context.locale, onValueChange: context.onChange, ...props, children: [
105
+ /* @__PURE__ */ jsx2(SelectTrigger, { children: /* @__PURE__ */ jsx2(SelectValue, { placeholder: context.text.chooseLanguage }) }),
106
+ /* @__PURE__ */ jsx2(SelectContent, { children: languages.map(([lang, { name }]) => /* @__PURE__ */ jsx2(SelectItem, { value: lang, children: name }, lang)) })
107
+ ] });
108
+ }
109
+ function I18nProvider({
110
+ translations = {},
111
+ locale: forceLocale,
112
+ children
113
+ }) {
114
+ const localeIndex = 1;
115
+ const router = useRouter();
116
+ const pathname = usePathname();
117
+ const context = useI18n();
118
+ const segments = pathname.split("/");
119
+ const locale = forceLocale ?? segments[localeIndex];
120
+ const onChange = useCallback(
121
+ (v) => {
122
+ segments[localeIndex] = v;
123
+ router.push(segments.join("/"));
124
+ },
125
+ [segments, router]
126
+ );
127
+ return /* @__PURE__ */ jsx2(
128
+ I18nContext.Provider,
129
+ {
130
+ value: {
131
+ locale,
132
+ translations,
133
+ text: {
134
+ ...context.text,
135
+ ...translations[locale]
136
+ },
137
+ onChange
138
+ },
139
+ children
140
+ }
141
+ );
142
+ }
143
+ export {
144
+ I18nProvider,
145
+ LanguageSelect
146
+ };
@@ -0,0 +1,79 @@
1
+ import { PageTree } from 'fumadocs-core/server';
2
+ import { ReactNode, HTMLAttributes } from 'react';
3
+
4
+ interface NavLinkProps {
5
+ icon: ReactNode;
6
+ href: string;
7
+ label: string;
8
+ external?: boolean;
9
+ }
10
+ interface NavProps {
11
+ title: ReactNode;
12
+ /**
13
+ * Redirect url of title
14
+ * @defaultValue '/'
15
+ */
16
+ url?: string;
17
+ items: LinkItem[];
18
+ links: NavLinkProps[];
19
+ enableSidebar: boolean;
20
+ collapsibleSidebar: boolean;
21
+ /**
22
+ * When to use transparent navbar
23
+ * @defaultValue none
24
+ */
25
+ transparentMode?: 'always' | 'top' | 'none';
26
+ children?: ReactNode;
27
+ }
28
+ declare function Nav({ title, url, links, items, transparentMode, enableSidebar, collapsibleSidebar, children, }: NavProps): JSX.Element;
29
+
30
+ interface SidebarProps {
31
+ items: LinkItem[];
32
+ /**
33
+ * Open folders by default if their level is lower or equal to a specific level
34
+ * (Starting from 1)
35
+ *
36
+ * @defaultValue 1
37
+ */
38
+ defaultOpenLevel?: number;
39
+ banner?: ReactNode;
40
+ footer?: ReactNode;
41
+ }
42
+ declare function Sidebar({ banner, footer, items, defaultOpenLevel, }: SidebarProps): JSX.Element;
43
+
44
+ interface LinkItem {
45
+ url: string;
46
+ icon?: ReactNode;
47
+ text: string;
48
+ external?: boolean;
49
+ }
50
+ interface NavOptions extends Omit<NavProps, 'enableSidebar' | 'collapsibleSidebar' | 'items'> {
51
+ enabled: boolean;
52
+ component: ReactNode;
53
+ /**
54
+ * Github url displayed on the navbar
55
+ */
56
+ githubUrl: string;
57
+ }
58
+ interface SidebarOptions extends Omit<SidebarProps, 'items'> {
59
+ enabled: boolean;
60
+ component: ReactNode;
61
+ collapsible: boolean;
62
+ }
63
+ interface BaseLayoutProps {
64
+ links?: LinkItem[];
65
+ /**
66
+ * Replace or disable navbar
67
+ */
68
+ nav?: Partial<NavOptions>;
69
+ children: ReactNode;
70
+ }
71
+ interface DocsLayoutProps extends BaseLayoutProps {
72
+ tree: PageTree.Root;
73
+ sidebar?: Partial<SidebarOptions>;
74
+ containerProps?: HTMLAttributes<HTMLDivElement>;
75
+ }
76
+ declare function Layout({ nav, links, children, }: BaseLayoutProps): JSX.Element;
77
+ declare function DocsLayout({ nav, sidebar, links, containerProps, tree, children, }: DocsLayoutProps): JSX.Element;
78
+
79
+ export { type BaseLayoutProps as B, type DocsLayoutProps as D, type LinkItem as L, Nav as N, Sidebar as S, Layout as a, DocsLayout as b };
@@ -0,0 +1,4 @@
1
+ export { T as TreeContextProvider } from './tree-Zwtp9xPv.mjs';
2
+ export { N as Nav, S as Sidebar } from './layout-YB7EFpgW.mjs';
3
+ import 'fumadocs-core/server';
4
+ import 'react';
@@ -0,0 +1,458 @@
1
+ "use client";
2
+ import {
3
+ useSidebarCollapse
4
+ } from "./chunk-PLXR6QNH.js";
5
+ import {
6
+ TreeContextProvider,
7
+ useTreeContext
8
+ } from "./chunk-UIZNMCLD.js";
9
+ import {
10
+ ScrollArea
11
+ } from "./chunk-OG3QOLYP.js";
12
+ import {
13
+ Popover,
14
+ PopoverContent,
15
+ PopoverTrigger
16
+ } from "./chunk-GZQICERS.js";
17
+ import {
18
+ hasActive,
19
+ isActive
20
+ } from "./chunk-EDUYFB4P.js";
21
+ import {
22
+ useSearchContext
23
+ } from "./chunk-36MVEJ25.js";
24
+ import {
25
+ useI18n
26
+ } from "./chunk-YAHHY62W.js";
27
+ import {
28
+ Collapsible,
29
+ CollapsibleContent,
30
+ CollapsibleTrigger
31
+ } from "./chunk-5EZE3X7G.js";
32
+ import {
33
+ buttonVariants
34
+ } from "./chunk-5KW7ATCP.js";
35
+ import {
36
+ cn
37
+ } from "./chunk-KCGRUOMD.js";
38
+ import "./chunk-6C3VEZWH.js";
39
+
40
+ // src/components/nav.tsx
41
+ import { cva as cva2 } from "class-variance-authority";
42
+ import {
43
+ MenuIcon,
44
+ MoreVerticalIcon,
45
+ SearchIcon,
46
+ SidebarCloseIcon,
47
+ SidebarOpenIcon
48
+ } from "lucide-react";
49
+ import Link from "fumadocs-core/link";
50
+ import { SidebarTrigger } from "fumadocs-core/sidebar";
51
+ import { usePathname } from "next/navigation";
52
+ import {
53
+ forwardRef,
54
+ useEffect,
55
+ useState,
56
+ useCallback as useCallback2
57
+ } from "react";
58
+ import { PopoverClose } from "@radix-ui/react-popover";
59
+
60
+ // src/components/theme-toggle.tsx
61
+ import { cva } from "class-variance-authority";
62
+ import { MoonIcon, SunIcon } from "lucide-react";
63
+ import { useTheme } from "next-themes";
64
+ import { useCallback } from "react";
65
+ import { jsx, jsxs } from "react/jsx-runtime";
66
+ var buttonVariants2 = cva("size-7 rounded-full p-1.5 text-muted-foreground", {
67
+ variants: {
68
+ dark: {
69
+ true: "dark:bg-accent dark:text-accent-foreground",
70
+ false: "bg-accent text-accent-foreground dark:bg-transparent dark:text-muted-foreground"
71
+ }
72
+ }
73
+ });
74
+ function ThemeToggle({
75
+ className,
76
+ ...props
77
+ }) {
78
+ const { setTheme, resolvedTheme } = useTheme();
79
+ const onToggle = useCallback(() => {
80
+ setTheme(resolvedTheme === "dark" ? "light" : "dark");
81
+ }, [setTheme, resolvedTheme]);
82
+ return /* @__PURE__ */ jsxs(
83
+ "button",
84
+ {
85
+ type: "button",
86
+ className: cn(
87
+ "inline-flex items-center rounded-full border p-0.5",
88
+ className
89
+ ),
90
+ "aria-label": "Toggle Theme",
91
+ onClick: onToggle,
92
+ ...props,
93
+ children: [
94
+ /* @__PURE__ */ jsx(SunIcon, { className: cn(buttonVariants2({ dark: false })) }),
95
+ /* @__PURE__ */ jsx(MoonIcon, { className: cn(buttonVariants2({ dark: true })) })
96
+ ]
97
+ }
98
+ );
99
+ }
100
+
101
+ // src/components/nav.tsx
102
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
103
+ function Nav({
104
+ title,
105
+ url = "/",
106
+ links,
107
+ items,
108
+ transparentMode = "none",
109
+ enableSidebar,
110
+ collapsibleSidebar,
111
+ children
112
+ }) {
113
+ const [transparent, setTransparent] = useState(transparentMode !== "none");
114
+ useEffect(() => {
115
+ if (transparentMode !== "top")
116
+ return;
117
+ const listener = () => {
118
+ setTransparent(window.scrollY < 10);
119
+ };
120
+ listener();
121
+ window.addEventListener("scroll", listener);
122
+ return () => {
123
+ window.removeEventListener("scroll", listener);
124
+ };
125
+ }, [transparentMode]);
126
+ return /* @__PURE__ */ jsx2(
127
+ "header",
128
+ {
129
+ className: cn(
130
+ "sticky top-0 z-50 h-16 border-b backdrop-blur-md transition-colors",
131
+ transparent ? "border-transparent" : "border-foreground/10 bg-background/50"
132
+ ),
133
+ children: /* @__PURE__ */ jsxs2("nav", { className: "container flex h-full flex-row items-center gap-4", children: [
134
+ /* @__PURE__ */ jsx2(Link, { href: url, className: "inline-flex items-center font-bold", children: title }),
135
+ children,
136
+ items.map((item) => /* @__PURE__ */ jsx2(NavItem, { item, className: "max-lg:hidden" }, item.url)),
137
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-row items-center justify-end md:gap-2", children: [
138
+ /* @__PURE__ */ jsx2(SearchToggle, {}),
139
+ enableSidebar ? /* @__PURE__ */ jsxs2(Fragment, { children: [
140
+ /* @__PURE__ */ jsx2(ThemeToggle, { className: "max-md:hidden" }),
141
+ /* @__PURE__ */ jsx2(SidebarToggle, { collapsible: collapsibleSidebar })
142
+ ] }) : /* @__PURE__ */ jsxs2(Popover, { children: [
143
+ /* @__PURE__ */ jsx2(ThemeToggle, { className: "max-lg:hidden" }),
144
+ /* @__PURE__ */ jsx2(
145
+ PopoverTrigger,
146
+ {
147
+ className: cn(
148
+ buttonVariants({
149
+ size: "icon",
150
+ color: "ghost",
151
+ className: "lg:hidden"
152
+ })
153
+ ),
154
+ children: /* @__PURE__ */ jsx2(MoreVerticalIcon, {})
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsxs2(PopoverContent, { className: "flex min-w-[260px] flex-col px-3 py-1", children: [
158
+ items.map((item) => /* @__PURE__ */ jsx2(PopoverClose, { asChild: true, children: /* @__PURE__ */ jsx2(
159
+ NavItem,
160
+ {
161
+ item,
162
+ className: "py-2 text-medium font-medium"
163
+ }
164
+ ) }, item.url)),
165
+ /* @__PURE__ */ jsx2(ThemeToggle, { className: "w-fit" })
166
+ ] })
167
+ ] }),
168
+ /* @__PURE__ */ jsx2(
169
+ "div",
170
+ {
171
+ className: cn(
172
+ "flex flex-row items-center border-l pl-2 max-md:hidden",
173
+ links.length === 0 && "hidden"
174
+ ),
175
+ children: links.map((item) => /* @__PURE__ */ jsx2(
176
+ Link,
177
+ {
178
+ "aria-label": item.label,
179
+ href: item.href,
180
+ external: item.external,
181
+ className: cn(buttonVariants({ size: "icon", color: "ghost" })),
182
+ children: item.icon
183
+ },
184
+ item.href
185
+ ))
186
+ }
187
+ )
188
+ ] })
189
+ ] })
190
+ }
191
+ );
192
+ }
193
+ var shortcut = cva2("rounded-md border bg-background px-1.5");
194
+ function SearchToggle() {
195
+ const { setOpenSearch } = useSearchContext();
196
+ const { text } = useI18n();
197
+ const onClick = useCallback2(() => {
198
+ setOpenSearch(true);
199
+ }, [setOpenSearch]);
200
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
201
+ /* @__PURE__ */ jsx2(
202
+ "button",
203
+ {
204
+ type: "button",
205
+ className: cn(
206
+ buttonVariants({
207
+ size: "icon",
208
+ color: "ghost",
209
+ className: "md:hidden"
210
+ })
211
+ ),
212
+ "aria-label": "Open Search",
213
+ onClick,
214
+ children: /* @__PURE__ */ jsx2(SearchIcon, {})
215
+ }
216
+ ),
217
+ /* @__PURE__ */ jsxs2(
218
+ "button",
219
+ {
220
+ type: "button",
221
+ className: "inline-flex w-full max-w-[240px] items-center gap-2 rounded-full border bg-secondary/50 p-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground max-md:hidden",
222
+ onClick,
223
+ children: [
224
+ /* @__PURE__ */ jsx2(SearchIcon, { "aria-label": "Open Search", className: "ml-1 size-4" }),
225
+ text.search,
226
+ /* @__PURE__ */ jsxs2("div", { className: "ml-auto inline-flex gap-0.5 text-xs", children: [
227
+ /* @__PURE__ */ jsx2("kbd", { className: shortcut(), children: "\u2318" }),
228
+ /* @__PURE__ */ jsx2("kbd", { className: shortcut(), children: "K" })
229
+ ] })
230
+ ]
231
+ }
232
+ )
233
+ ] });
234
+ }
235
+ function SidebarToggle({ collapsible }) {
236
+ const [open, setOpen] = useSidebarCollapse();
237
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
238
+ /* @__PURE__ */ jsx2(
239
+ SidebarTrigger,
240
+ {
241
+ "aria-label": "Toggle Sidebar",
242
+ className: cn(
243
+ buttonVariants({
244
+ size: "icon",
245
+ color: "ghost",
246
+ className: "md:hidden"
247
+ })
248
+ ),
249
+ children: /* @__PURE__ */ jsx2(MenuIcon, {})
250
+ }
251
+ ),
252
+ collapsible ? /* @__PURE__ */ jsx2(
253
+ "button",
254
+ {
255
+ type: "button",
256
+ "aria-label": "Toggle Sidebar",
257
+ onClick: () => {
258
+ setOpen(!open);
259
+ },
260
+ className: cn(
261
+ buttonVariants({
262
+ color: "outline",
263
+ size: "icon",
264
+ className: "rounded-full max-md:hidden"
265
+ })
266
+ ),
267
+ children: open ? /* @__PURE__ */ jsx2(SidebarCloseIcon, {}) : /* @__PURE__ */ jsx2(SidebarOpenIcon, {})
268
+ }
269
+ ) : null
270
+ ] });
271
+ }
272
+ var NavItem = forwardRef(({ item, className, ...props }, ref) => {
273
+ const { text, url, external } = item;
274
+ const pathname = usePathname();
275
+ return /* @__PURE__ */ jsx2(
276
+ Link,
277
+ {
278
+ ref,
279
+ href: url,
280
+ external,
281
+ className: cn(
282
+ "text-sm text-muted-foreground",
283
+ isActive(url, pathname) ? "font-medium text-accent-foreground" : "transition-colors hover:text-accent-foreground",
284
+ className
285
+ ),
286
+ ...props,
287
+ children: text
288
+ }
289
+ );
290
+ });
291
+ NavItem.displayName = "NavItem";
292
+
293
+ // src/components/sidebar.tsx
294
+ import { cva as cva3 } from "class-variance-authority";
295
+ import { ChevronDown } from "lucide-react";
296
+ import * as Base from "fumadocs-core/sidebar";
297
+ import { usePathname as usePathname2 } from "next/navigation";
298
+ import { createContext, useContext, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
299
+ import Link2 from "fumadocs-core/link";
300
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
301
+ var itemVariants = cva3(
302
+ "flex flex-row items-center gap-2 rounded-md px-2 py-1.5 text-muted-foreground [&_svg]:size-4",
303
+ {
304
+ variants: {
305
+ active: {
306
+ true: "bg-primary/10 font-medium text-primary",
307
+ false: "hover:bg-accent/50 hover:text-accent-foreground/80"
308
+ }
309
+ }
310
+ }
311
+ );
312
+ var SidebarContext = createContext({
313
+ defaultOpenLevel: 1
314
+ });
315
+ function Sidebar({
316
+ banner,
317
+ footer,
318
+ items = [],
319
+ defaultOpenLevel = 1
320
+ }) {
321
+ const [open] = useSidebarCollapse();
322
+ const { root } = useTreeContext();
323
+ return /* @__PURE__ */ jsx3(
324
+ Base.SidebarList,
325
+ {
326
+ minWidth: 768,
327
+ className: cn(
328
+ "flex w-full flex-col text-medium",
329
+ !open ? "md:hidden" : "md:sticky md:top-16 md:h-body md:w-[240px] md:text-sm xl:w-[260px]",
330
+ "max-md:fixed max-md:inset-0 max-md:z-40 max-md:bg-background/80 max-md:pt-16 max-md:backdrop-blur-md max-md:data-[open=false]:hidden"
331
+ ),
332
+ children: /* @__PURE__ */ jsxs3(SidebarContext.Provider, { value: { defaultOpenLevel }, children: [
333
+ /* @__PURE__ */ jsx3(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-8 pb-10 pt-4 max-md:px-4 md:pr-3 md:pt-10", children: [
334
+ banner,
335
+ /* @__PURE__ */ jsx3("div", { className: "lg:hidden", children: items.map((item) => /* @__PURE__ */ jsx3(BaseItem, { item, nested: true }, item.url)) }),
336
+ /* @__PURE__ */ jsx3(NodeList, { items: root.children })
337
+ ] }) }),
338
+ /* @__PURE__ */ jsxs3(
339
+ "div",
340
+ {
341
+ className: cn(
342
+ "flex flex-row items-center gap-2 border-t py-2 max-md:px-4",
343
+ !footer && "md:hidden"
344
+ ),
345
+ children: [
346
+ footer,
347
+ /* @__PURE__ */ jsx3(ThemeToggle, { className: "md:hidden" })
348
+ ]
349
+ }
350
+ )
351
+ ] })
352
+ }
353
+ );
354
+ }
355
+ function NodeList({ items, level = 0, ...props }) {
356
+ return /* @__PURE__ */ jsx3("div", { ...props, children: items.map((item) => {
357
+ const id = `${item.type}_${item.name}`;
358
+ switch (item.type) {
359
+ case "separator":
360
+ return /* @__PURE__ */ jsx3(SeparatorNode, { item }, id);
361
+ case "folder":
362
+ return /* @__PURE__ */ jsx3(Folder, { item, level: level + 1 }, id);
363
+ default:
364
+ return /* @__PURE__ */ jsx3(
365
+ BaseItem,
366
+ {
367
+ item: { text: item.name, url: item.url, icon: item.icon }
368
+ },
369
+ item.url
370
+ );
371
+ }
372
+ }) });
373
+ }
374
+ function BaseItem({
375
+ item,
376
+ nested = false
377
+ }) {
378
+ const pathname = usePathname2();
379
+ const active = isActive(item.url, pathname, nested);
380
+ return /* @__PURE__ */ jsxs3(
381
+ Link2,
382
+ {
383
+ href: item.url,
384
+ external: item.external,
385
+ className: cn(itemVariants({ active })),
386
+ children: [
387
+ item.icon,
388
+ item.text
389
+ ]
390
+ }
391
+ );
392
+ }
393
+ function Folder({
394
+ item: { name, children, index, icon },
395
+ level
396
+ }) {
397
+ const { defaultOpenLevel } = useContext(SidebarContext);
398
+ const pathname = usePathname2();
399
+ const active = index && isActive(index.url, pathname, false);
400
+ const childActive = useMemo(
401
+ () => hasActive(children, pathname),
402
+ [children, pathname]
403
+ );
404
+ const [extend, setExtend] = useState2(
405
+ active || childActive || defaultOpenLevel >= level
406
+ );
407
+ useEffect2(() => {
408
+ if (active || childActive)
409
+ setExtend(true);
410
+ }, [active, childActive]);
411
+ const content = /* @__PURE__ */ jsxs3(Fragment2, { children: [
412
+ icon,
413
+ name,
414
+ /* @__PURE__ */ jsx3(
415
+ ChevronDown,
416
+ {
417
+ onClick: (e) => {
418
+ setExtend((prev) => !prev);
419
+ e.preventDefault();
420
+ },
421
+ className: cn("ml-auto transition-transform", !extend && "-rotate-90")
422
+ }
423
+ )
424
+ ] });
425
+ return /* @__PURE__ */ jsxs3(
426
+ Collapsible,
427
+ {
428
+ open: extend,
429
+ onOpenChange: !index || active ? setExtend : void 0,
430
+ children: [
431
+ /* @__PURE__ */ jsx3(
432
+ CollapsibleTrigger,
433
+ {
434
+ className: cn(itemVariants({ active, className: "w-full" })),
435
+ asChild: true,
436
+ children: index ? /* @__PURE__ */ jsx3(Link2, { href: index.url, children: content }) : /* @__PURE__ */ jsx3("button", { type: "button", children: content })
437
+ }
438
+ ),
439
+ /* @__PURE__ */ jsx3(CollapsibleContent, { children: /* @__PURE__ */ jsx3(
440
+ NodeList,
441
+ {
442
+ className: "ml-4 flex flex-col border-l py-2 pl-2",
443
+ items: children,
444
+ level
445
+ }
446
+ ) })
447
+ ]
448
+ }
449
+ );
450
+ }
451
+ function SeparatorNode({ item }) {
452
+ return /* @__PURE__ */ jsx3("p", { className: "mb-2 mt-8 px-2 font-medium first:mt-0", children: item.name });
453
+ }
454
+ export {
455
+ Nav,
456
+ Sidebar,
457
+ TreeContextProvider
458
+ };
@@ -0,0 +1,3 @@
1
+ import 'fumadocs-core/server';
2
+ import 'react';
3
+ export { B as BaseLayoutProps, b as DocsLayout, D as DocsLayoutProps, a as Layout, L as LinkItem } from './layout-YB7EFpgW.mjs';