@fumadocs/base-ui 16.7.0 → 16.7.2

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 (72) hide show
  1. package/css/generated/docs.css +5 -4
  2. package/css/generated/flux.css +3 -3
  3. package/css/generated/home.css +2 -3
  4. package/css/generated/notebook.css +4 -4
  5. package/css/generated/shared.css +2 -1
  6. package/dist/components/accordion.js +2 -2
  7. package/dist/components/dialog/search.js +2 -2
  8. package/dist/components/files.js +3 -3
  9. package/dist/components/heading.js +2 -2
  10. package/dist/components/sidebar/tabs/dropdown.js +1 -1
  11. package/dist/components/toc/index.d.ts +3 -2
  12. package/dist/components/toc/index.js +12 -2
  13. package/dist/components/ui/button.d.ts +1 -1
  14. package/dist/layouts/docs/client.d.ts +3 -3
  15. package/dist/layouts/docs/client.js +20 -23
  16. package/dist/layouts/docs/index.d.ts +1 -1
  17. package/dist/layouts/docs/page/index.d.ts +91 -3
  18. package/dist/layouts/docs/page/index.js +67 -7
  19. package/dist/layouts/docs/page/slots/breadcrumb.js +3 -1
  20. package/dist/layouts/docs/page/slots/container.js +2 -1
  21. package/dist/layouts/docs/page/slots/footer.js +1 -0
  22. package/dist/layouts/docs/page/slots/toc.d.ts +29 -1
  23. package/dist/layouts/docs/page/slots/toc.js +137 -4
  24. package/dist/layouts/docs/slots/container.js +2 -1
  25. package/dist/layouts/docs/slots/header.js +1 -0
  26. package/dist/layouts/docs/slots/sidebar.js +7 -7
  27. package/dist/layouts/flux/index.d.ts +4 -4
  28. package/dist/layouts/flux/index.js +8 -11
  29. package/dist/layouts/flux/page/index.d.ts +79 -3
  30. package/dist/layouts/flux/page/index.js +61 -7
  31. package/dist/layouts/flux/page/slots/breadcrumb.js +1 -0
  32. package/dist/layouts/flux/page/slots/container.js +2 -1
  33. package/dist/layouts/flux/page/slots/footer.js +1 -0
  34. package/dist/layouts/flux/page/slots/toc.d.ts +4 -1
  35. package/dist/layouts/flux/page/slots/toc.js +3 -2
  36. package/dist/layouts/flux/slots/container.js +1 -0
  37. package/dist/layouts/home/index.d.ts +3 -3
  38. package/dist/layouts/home/index.js +6 -8
  39. package/dist/layouts/home/slots/container.js +1 -0
  40. package/dist/layouts/home/slots/header.d.ts +1 -1
  41. package/dist/layouts/home/slots/header.js +5 -5
  42. package/dist/layouts/notebook/client.d.ts +3 -3
  43. package/dist/layouts/notebook/client.js +15 -18
  44. package/dist/layouts/notebook/index.d.ts +1 -1
  45. package/dist/layouts/notebook/page/index.d.ts +91 -3
  46. package/dist/layouts/notebook/page/index.js +67 -7
  47. package/dist/layouts/notebook/page/slots/breadcrumb.js +1 -0
  48. package/dist/layouts/notebook/page/slots/container.js +2 -1
  49. package/dist/layouts/notebook/page/slots/footer.js +1 -0
  50. package/dist/layouts/notebook/page/slots/toc.d.ts +29 -1
  51. package/dist/layouts/notebook/page/slots/toc.js +136 -4
  52. package/dist/layouts/notebook/slots/container.js +1 -0
  53. package/dist/layouts/notebook/slots/sidebar.js +5 -5
  54. package/dist/layouts/shared/client.d.ts +8 -8
  55. package/dist/layouts/shared/client.js +4 -4
  56. package/dist/layouts/shared/index.d.ts +6 -6
  57. package/dist/layouts/shared/page-actions.d.ts +2 -2
  58. package/dist/layouts/shared/page-actions.js +3 -3
  59. package/dist/layouts/shared/slots/search-trigger.d.ts +3 -3
  60. package/dist/page.d.ts +1 -2
  61. package/dist/page.js +1 -2
  62. package/package.json +4 -6
  63. package/dist/layouts/docs/page/client.d.ts +0 -98
  64. package/dist/layouts/docs/page/client.js +0 -110
  65. package/dist/layouts/docs/page/slots/toc-popover.d.ts +0 -31
  66. package/dist/layouts/docs/page/slots/toc-popover.js +0 -141
  67. package/dist/layouts/flux/page/client.d.ts +0 -82
  68. package/dist/layouts/flux/page/client.js +0 -94
  69. package/dist/layouts/notebook/page/client.d.ts +0 -98
  70. package/dist/layouts/notebook/page/client.js +0 -110
  71. package/dist/layouts/notebook/page/slots/toc-popover.d.ts +0 -31
  72. package/dist/layouts/notebook/page/slots/toc-popover.js +0 -141
@@ -1,12 +1,15 @@
1
+ "use client";
1
2
  import { __exportAll } from "../../../_virtual/_rolldown/runtime.js";
2
- import { I18nLabel } from "../../../contexts/i18n.js";
3
+ import { I18nLabel, useI18n } from "../../../contexts/i18n.js";
3
4
  import { cn } from "../../../utils/cn.js";
4
5
  import { buttonVariants } from "../../../components/ui/button.js";
6
+ import { TOC, TOCPopover, TOCProvider } from "./slots/toc.js";
5
7
  import { Footer } from "./slots/footer.js";
6
8
  import { Breadcrumb } from "./slots/breadcrumb.js";
7
- import { DocsPage, PageLastUpdate, useDocsPage } from "./client.js";
9
+ import { Container } from "./slots/container.js";
8
10
  import { MarkdownCopyButton, ViewOptionsPopover } from "../../shared/page-actions.js";
9
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { createContext, use, useEffect, useState } from "react";
12
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
13
  import { Edit } from "lucide-react";
11
14
  //#region src/layouts/docs/page/index.tsx
12
15
  var page_exports = /* @__PURE__ */ __exportAll({
@@ -22,6 +25,48 @@ var page_exports = /* @__PURE__ */ __exportAll({
22
25
  ViewOptionsPopover: () => ViewOptionsPopover,
23
26
  useDocsPage: () => useDocsPage
24
27
  });
28
+ const PageContext = createContext(null);
29
+ function useDocsPage() {
30
+ const context = use(PageContext);
31
+ if (!context) throw new Error("Please use page components under <DocsPage /> (`fumadocs-ui/layouts/docs/page`).");
32
+ return context;
33
+ }
34
+ function DocsPage({ tableOfContent: { enabled: tocEnabled, single, ...tocProps } = {}, tableOfContentPopover: { enabled: tocPopoverEnabled, ...tocPopoverProps } = {}, breadcrumb: { enabled: breadcrumbEnabled = true, ...breadcrumb } = {}, footer: { enabled: footerEnabled = true, ...footer } = {}, full = false, toc = [], slots: defaultSlots = {}, children, ...containerProps }) {
35
+ tocEnabled ??= Boolean(!full && (toc.length > 0 || tocProps.footer || tocProps.header));
36
+ tocPopoverEnabled ??= Boolean(toc.length > 0 || tocPopoverProps.header || tocPopoverProps.footer);
37
+ const slots = {
38
+ breadcrumb: defaultSlots.breadcrumb ?? Breadcrumb,
39
+ footer: defaultSlots.footer ?? Footer,
40
+ toc: defaultSlots.toc ?? {
41
+ provider: TOCProvider,
42
+ main: TOC,
43
+ popover: TOCPopover
44
+ },
45
+ container: defaultSlots.container ?? Container
46
+ };
47
+ return /* @__PURE__ */ jsx(PageContext, {
48
+ value: {
49
+ props: { full },
50
+ slots
51
+ },
52
+ children: /* @__PURE__ */ jsxs(slots.toc.provider, {
53
+ single,
54
+ toc: tocEnabled || tocPopoverEnabled ? toc : [],
55
+ children: [
56
+ tocPopoverEnabled && (tocPopoverProps.component ?? /* @__PURE__ */ jsx(slots.toc.popover, { ...tocPopoverProps })),
57
+ /* @__PURE__ */ jsxs(slots.container, {
58
+ ...containerProps,
59
+ children: [
60
+ breadcrumbEnabled && (breadcrumb.component ?? /* @__PURE__ */ jsx(slots.breadcrumb, { ...breadcrumb })),
61
+ children,
62
+ footerEnabled && (footer.component ?? /* @__PURE__ */ jsx(slots.footer, { ...footer }))
63
+ ]
64
+ }),
65
+ tocEnabled && (tocProps.component ?? /* @__PURE__ */ jsx(slots.toc.main, { ...tocProps }))
66
+ ]
67
+ })
68
+ });
69
+ }
25
70
  function EditOnGitHub(props) {
26
71
  return /* @__PURE__ */ jsx("a", {
27
72
  target: "_blank",
@@ -29,10 +74,9 @@ function EditOnGitHub(props) {
29
74
  ...props,
30
75
  className: cn(buttonVariants({
31
76
  color: "secondary",
32
- size: "sm",
33
- className: "gap-1.5 not-prose"
34
- }), props.className),
35
- children: props.children ?? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Edit, { className: "size-3.5" }), /* @__PURE__ */ jsx(I18nLabel, { label: "editOnGithub" })] })
77
+ size: "sm"
78
+ }), "gap-1.5 not-prose", props.className),
79
+ children: props.children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Edit, { className: "size-3.5" }), /* @__PURE__ */ jsx(I18nLabel, { label: "editOnGithub" })] })
36
80
  });
37
81
  }
38
82
  /**
@@ -60,5 +104,21 @@ function DocsTitle({ children, className, ...props }) {
60
104
  children
61
105
  });
62
106
  }
107
+ function PageLastUpdate({ date: value, ...props }) {
108
+ const { text } = useI18n();
109
+ const [date, setDate] = useState("");
110
+ useEffect(() => {
111
+ setDate(value.toLocaleDateString());
112
+ }, [value]);
113
+ return /* @__PURE__ */ jsxs("p", {
114
+ ...props,
115
+ className: cn("text-sm text-fd-muted-foreground", props.className),
116
+ children: [
117
+ text.lastUpdate,
118
+ " ",
119
+ date
120
+ ]
121
+ });
122
+ }
63
123
  //#endregion
64
124
  export { DocsBody, DocsDescription, DocsPage, DocsTitle, EditOnGitHub, MarkdownCopyButton, Breadcrumb as PageBreadcrumb, Footer as PageFooter, PageLastUpdate, ViewOptionsPopover, page_exports, useDocsPage };
@@ -1,8 +1,10 @@
1
+ "use client";
1
2
  import { cn } from "../../../../utils/cn.js";
2
3
  import { useTreeContext, useTreePath } from "../../../../contexts/tree.js";
3
4
  import { Fragment, useMemo } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { ChevronRight, Link } from "lucide-react";
6
+ import Link from "fumadocs-core/link";
7
+ import { ChevronRight } from "lucide-react";
6
8
  import { getBreadcrumbItemsFromPath } from "fumadocs-core/breadcrumb";
7
9
  //#region src/layouts/docs/page/slots/breadcrumb.tsx
8
10
  function Breadcrumb({ includeRoot, includeSeparator, includePage, ...props }) {
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../../../../utils/cn.js";
2
- import { useDocsPage } from "../client.js";
3
+ import { useDocsPage } from "../index.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  //#region src/layouts/docs/page/slots/container.tsx
5
6
  function Container(props) {
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { useI18n } from "../../../../contexts/i18n.js";
2
3
  import { cn } from "../../../../utils/cn.js";
3
4
  import { isActive } from "../../../../utils/urls.js";
@@ -1,7 +1,10 @@
1
+ import { TOCProviderProps as TOCProviderProps$1 } from "../../../../components/toc/index.js";
1
2
  import { ComponentProps, ReactNode } from "react";
2
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
3
4
 
4
5
  //#region src/layouts/docs/page/slots/toc.d.ts
6
+ type TOCProviderProps = TOCProviderProps$1;
7
+ declare function TOCProvider(props: TOCProviderProps): react_jsx_runtime0.JSX.Element;
5
8
  interface TOCProps {
6
9
  container?: ComponentProps<'div'>;
7
10
  /**
@@ -23,5 +26,30 @@ declare function TOC({
23
26
  footer,
24
27
  style
25
28
  }: TOCProps): react_jsx_runtime0.JSX.Element;
29
+ interface TOCPopoverProps {
30
+ container?: ComponentProps<'div'>;
31
+ trigger?: ComponentProps<'button'>;
32
+ content?: ComponentProps<'div'>;
33
+ /**
34
+ * Custom content in TOC container, before the main TOC
35
+ */
36
+ header?: ReactNode;
37
+ /**
38
+ * Custom content in TOC container, after the main TOC
39
+ */
40
+ footer?: ReactNode;
41
+ /**
42
+ * @defaultValue 'normal'
43
+ */
44
+ style?: 'normal' | 'clerk';
45
+ }
46
+ declare function TOCPopover({
47
+ container,
48
+ trigger,
49
+ content,
50
+ header,
51
+ footer,
52
+ style
53
+ }: TOCPopoverProps): react_jsx_runtime0.JSX.Element;
26
54
  //#endregion
27
- export { TOC, TOCProps };
55
+ export { TOC, TOCPopover, TOCPopoverProps, TOCProps, TOCProvider, TOCProviderProps };
@@ -1,12 +1,20 @@
1
1
  "use client";
2
- import { I18nLabel } from "../../../../contexts/i18n.js";
2
+ import { I18nLabel, useI18n } from "../../../../contexts/i18n.js";
3
3
  import { cn } from "../../../../utils/cn.js";
4
- import { TOCScrollArea } from "../../../../components/toc/index.js";
4
+ import { TOCProvider as TOCProvider$1, TOCScrollArea, useActiveAnchor, useTOCItems } from "../../../../components/toc/index.js";
5
5
  import { TOCItems } from "../../../../components/toc/default.js";
6
6
  import { TOCItems as TOCItems$1 } from "../../../../components/toc/clerk.js";
7
+ import { useTreePath } from "../../../../contexts/tree.js";
8
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../../../components/ui/collapsible.js";
9
+ import { useDocsLayout } from "../../client.js";
10
+ import "../../index.js";
11
+ import { createContext, use, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
7
12
  import { jsx, jsxs } from "react/jsx-runtime";
8
- import { Text } from "lucide-react";
13
+ import { ChevronDown, Text } from "lucide-react";
9
14
  //#region src/layouts/docs/page/slots/toc.tsx
15
+ function TOCProvider(props) {
16
+ return /* @__PURE__ */ jsx(TOCProvider$1, { ...props });
17
+ }
10
18
  function TOC({ container, header, footer, style }) {
11
19
  return /* @__PURE__ */ jsxs("div", {
12
20
  id: "nd-toc",
@@ -24,5 +32,130 @@ function TOC({ container, header, footer, style }) {
24
32
  ]
25
33
  });
26
34
  }
35
+ const TocPopoverContext = createContext(null);
36
+ function TOCPopover({ container, trigger, content, header, footer, style }) {
37
+ return /* @__PURE__ */ jsxs(PageTOCPopover, {
38
+ ...container,
39
+ children: [/* @__PURE__ */ jsx(PageTOCPopoverTrigger, { ...trigger }), /* @__PURE__ */ jsxs(PageTOCPopoverContent, {
40
+ ...content,
41
+ children: [
42
+ header,
43
+ /* @__PURE__ */ jsx(TOCScrollArea, { children: style === "clerk" ? /* @__PURE__ */ jsx(TOCItems$1, {}) : /* @__PURE__ */ jsx(TOCItems, {}) }),
44
+ footer
45
+ ]
46
+ })]
47
+ });
48
+ }
49
+ function PageTOCPopover({ className, children, ...rest }) {
50
+ const ref = useRef(null);
51
+ const [open, setOpen] = useState(false);
52
+ const { isNavTransparent } = useDocsLayout();
53
+ const onClick = useEffectEvent((e) => {
54
+ if (!open) return;
55
+ if (ref.current && !ref.current.contains(e.target)) setOpen(false);
56
+ });
57
+ useEffect(() => {
58
+ window.addEventListener("click", onClick);
59
+ return () => {
60
+ window.removeEventListener("click", onClick);
61
+ };
62
+ }, []);
63
+ return /* @__PURE__ */ jsx(TocPopoverContext, {
64
+ value: useMemo(() => ({
65
+ open,
66
+ setOpen
67
+ }), [setOpen, open]),
68
+ children: /* @__PURE__ */ jsx(Collapsible, {
69
+ open,
70
+ onOpenChange: setOpen,
71
+ "data-toc-popover": "",
72
+ className: cn("sticky top-(--fd-docs-row-2) z-10 [grid-area:toc-popover] h-(--fd-toc-popover-height) xl:hidden max-xl:layout:[--fd-toc-popover-height:--spacing(10)]", className),
73
+ ...rest,
74
+ children: /* @__PURE__ */ jsx("header", {
75
+ ref,
76
+ className: cn("border-b backdrop-blur-sm transition-colors", (!isNavTransparent || open) && "bg-fd-background/80", open && "shadow-lg"),
77
+ children
78
+ })
79
+ })
80
+ });
81
+ }
82
+ function PageTOCPopoverTrigger({ className, ...props }) {
83
+ const { text } = useI18n();
84
+ const { open } = use(TocPopoverContext);
85
+ const items = useTOCItems();
86
+ const active = useActiveAnchor();
87
+ const selected = useMemo(() => items.findIndex((item) => active === item.url.slice(1)), [items, active]);
88
+ const path = useTreePath().at(-1);
89
+ const showItem = selected !== -1 && !open;
90
+ return /* @__PURE__ */ jsxs(CollapsibleTrigger, {
91
+ className: cn("flex w-full h-10 items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:size-4 md:px-6", className),
92
+ "data-toc-popover-trigger": "",
93
+ ...props,
94
+ children: [
95
+ /* @__PURE__ */ jsx(ProgressCircle, {
96
+ value: (selected + 1) / Math.max(1, items.length),
97
+ max: 1,
98
+ className: cn("shrink-0", open && "text-fd-primary")
99
+ }),
100
+ /* @__PURE__ */ jsxs("span", {
101
+ className: "grid flex-1 *:my-auto *:row-start-1 *:col-start-1",
102
+ children: [/* @__PURE__ */ jsx("span", {
103
+ className: cn("truncate transition-[opacity,translate,color]", open && "text-fd-foreground", showItem && "opacity-0 -translate-y-full pointer-events-none"),
104
+ children: path?.name ?? text.toc
105
+ }), /* @__PURE__ */ jsx("span", {
106
+ className: cn("truncate transition-[opacity,translate]", !showItem && "opacity-0 translate-y-full pointer-events-none"),
107
+ children: items[selected]?.title
108
+ })]
109
+ }),
110
+ /* @__PURE__ */ jsx(ChevronDown, { className: cn("shrink-0 transition-transform mx-0.5", open && "rotate-180") })
111
+ ]
112
+ });
113
+ }
114
+ function clamp(input, min, max) {
115
+ if (input < min) return min;
116
+ if (input > max) return max;
117
+ return input;
118
+ }
119
+ function ProgressCircle({ value, strokeWidth = 2, size = 24, min = 0, max = 100, ...restSvgProps }) {
120
+ const normalizedValue = clamp(value, min, max);
121
+ const radius = (size - strokeWidth) / 2;
122
+ const circumference = 2 * Math.PI * radius;
123
+ const progress = normalizedValue / max * circumference;
124
+ const circleProps = {
125
+ cx: size / 2,
126
+ cy: size / 2,
127
+ r: radius,
128
+ fill: "none",
129
+ strokeWidth
130
+ };
131
+ return /* @__PURE__ */ jsxs("svg", {
132
+ role: "progressbar",
133
+ viewBox: `0 0 ${size} ${size}`,
134
+ "aria-valuenow": normalizedValue,
135
+ "aria-valuemin": min,
136
+ "aria-valuemax": max,
137
+ ...restSvgProps,
138
+ children: [/* @__PURE__ */ jsx("circle", {
139
+ ...circleProps,
140
+ className: "stroke-current/25"
141
+ }), /* @__PURE__ */ jsx("circle", {
142
+ ...circleProps,
143
+ stroke: "currentColor",
144
+ strokeDasharray: circumference,
145
+ strokeDashoffset: circumference - progress,
146
+ strokeLinecap: "round",
147
+ transform: `rotate(-90 ${size / 2} ${size / 2})`,
148
+ className: "transition-all"
149
+ })]
150
+ });
151
+ }
152
+ function PageTOCPopoverContent(props) {
153
+ return /* @__PURE__ */ jsx(CollapsibleContent, {
154
+ "data-toc-popover-content": "",
155
+ ...props,
156
+ className: cn("flex flex-col px-4 max-h-[50vh] md:px-6", props.className),
157
+ children: props.children
158
+ });
159
+ }
27
160
  //#endregion
28
- export { TOC };
161
+ export { TOC, TOCPopover, TOCProvider };
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  import { cn } from "../../../utils/cn.js";
2
- import "../index.js";
3
3
  import { useDocsLayout } from "../client.js";
4
+ import "../index.js";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  //#region src/layouts/docs/slots/container.tsx
6
7
  function Container(props) {
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../../../utils/cn.js";
2
3
  import { buttonVariants } from "../../../components/ui/button.js";
3
4
  import { useDocsLayout } from "../client.js";
@@ -2,20 +2,20 @@
2
2
  import { cn } from "../../../utils/cn.js";
3
3
  import { buttonVariants } from "../../../components/ui/button.js";
4
4
  import { mergeRefs } from "../../../utils/merge-refs.js";
5
- import { ScrollArea, ScrollViewport } from "../../../components/ui/scroll-area.js";
6
- import { SidebarCollapseTrigger as SidebarCollapseTrigger$1, SidebarContent as SidebarContent$1, SidebarDrawerContent, SidebarDrawerOverlay, SidebarFolder as SidebarFolder$1, SidebarFolderContent as SidebarFolderContent$1, SidebarFolderLink as SidebarFolderLink$1, SidebarFolderTrigger as SidebarFolderTrigger$1, SidebarItem as SidebarItem$1, SidebarProvider as SidebarProvider$1, SidebarSeparator as SidebarSeparator$1, SidebarTrigger as SidebarTrigger$1, base_exports, useFolder, useFolderDepth } from "../../../components/sidebar/base.js";
7
- import { createPageTreeRenderer } from "../../../components/sidebar/page-tree.js";
8
5
  import { Popover, PopoverContent, PopoverTrigger } from "../../../components/ui/popover.js";
9
6
  import { SearchTrigger } from "../../shared/slots/search-trigger.js";
10
7
  import { LinkItem } from "../../shared/client.js";
11
8
  import { isLayoutTabActive } from "../../shared/index.js";
9
+ import { ScrollArea, ScrollViewport } from "../../../components/ui/scroll-area.js";
10
+ import { SidebarCollapseTrigger as SidebarCollapseTrigger$1, SidebarContent as SidebarContent$1, SidebarDrawerContent, SidebarDrawerOverlay, SidebarFolder as SidebarFolder$1, SidebarFolderContent as SidebarFolderContent$1, SidebarFolderLink as SidebarFolderLink$1, SidebarFolderTrigger as SidebarFolderTrigger$1, SidebarItem as SidebarItem$1, SidebarProvider as SidebarProvider$1, SidebarSeparator as SidebarSeparator$1, SidebarTrigger as SidebarTrigger$1, base_exports, useFolder, useFolderDepth } from "../../../components/sidebar/base.js";
11
+ import { createPageTreeRenderer } from "../../../components/sidebar/page-tree.js";
12
12
  import { createLinkItemRenderer } from "../../../components/sidebar/link-item.js";
13
13
  import { useDocsLayout } from "../client.js";
14
14
  import { useMemo, useRef, useState } from "react";
15
15
  import { usePathname } from "fumadocs-core/framework";
16
16
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
17
  import Link from "fumadocs-core/link";
18
- import { Check, ChevronsUpDown, Languages, Sidebar as Sidebar$1 } from "lucide-react";
18
+ import { Check, ChevronsUpDown, Languages, SidebarIcon } from "lucide-react";
19
19
  import { cva } from "class-variance-authority";
20
20
  //#region src/layouts/docs/slots/sidebar.tsx
21
21
  const itemVariants = cva("relative flex flex-row items-center gap-2 rounded-lg p-2 text-start text-fd-muted-foreground wrap-anywhere [&_svg]:size-4 [&_svg]:shrink-0", { variants: {
@@ -53,7 +53,7 @@ function Sidebar({ footer, banner, collapsible = true, components, ...rest }) {
53
53
  size: "icon-sm",
54
54
  className: "mb-auto text-fd-muted-foreground"
55
55
  })),
56
- children: /* @__PURE__ */ jsx(Sidebar$1, {})
56
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
57
57
  })
58
58
  ]
59
59
  }),
@@ -111,7 +111,7 @@ function Sidebar({ footer, banner, collapsible = true, components, ...rest }) {
111
111
  size: "icon-sm",
112
112
  className: "p-2"
113
113
  })),
114
- children: /* @__PURE__ */ jsx(Sidebar$1, {})
114
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
115
115
  })
116
116
  ]
117
117
  }),
@@ -174,7 +174,7 @@ function SidebarContent({ ref: refProp, className, children, ...props }) {
174
174
  size: "icon-sm",
175
175
  className: "rounded-lg"
176
176
  })),
177
- children: /* @__PURE__ */ jsx(Sidebar$1, {})
177
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
178
178
  }), /* @__PURE__ */ jsx(SearchTrigger, {
179
179
  className: "rounded-lg",
180
180
  hideIfDisabled: true
@@ -9,9 +9,9 @@ import { motion } from "motion/react";
9
9
 
10
10
  //#region src/layouts/flux/index.d.ts
11
11
  interface DocsSlots extends BaseSlots {
12
- container?: FC<ComponentProps<'div'>>;
13
- tabDropdown?: FC<TabDropdownProps>;
14
- sidebar?: {
12
+ container: FC<ComponentProps<'div'>>;
13
+ tabDropdown: FC<TabDropdownProps>;
14
+ sidebar: {
15
15
  provider: FC<SidebarProviderProps>;
16
16
  trigger: FC<ComponentProps<'button'>>;
17
17
  root: FC<SidebarProps>;
@@ -26,7 +26,7 @@ interface DocsLayoutProps extends BaseLayoutProps {
26
26
  tree: PageTree.Root;
27
27
  sidebar?: SidebarOptions;
28
28
  tabs?: LayoutTab[] | GetLayoutTabsOptions | false;
29
- slots?: DocsSlots;
29
+ slots?: Partial<DocsSlots>;
30
30
  renderNavigationPanel?: (props: NavigationPanelProps) => ReactNode;
31
31
  containerProps?: ComponentProps<'div'>;
32
32
  }
@@ -44,16 +44,6 @@ function DocsLayout(props) {
44
44
  useSidebar
45
45
  }
46
46
  };
47
- let content = /* @__PURE__ */ jsxs(Fragment$1, { children: [sidebarEnabled && slots.sidebar && /* @__PURE__ */ jsx(slots.sidebar.root, { ...sidebarProps }), children] });
48
- if (slots.container) content = /* @__PURE__ */ jsx(slots.container, {
49
- ...containerProps,
50
- children: content
51
- });
52
- if (slots.sidebar) content = /* @__PURE__ */ jsx(slots.sidebar.provider, {
53
- defaultOpenLevel,
54
- prefetch,
55
- children: content
56
- });
57
47
  return /* @__PURE__ */ jsx(LayoutContext, {
58
48
  value: {
59
49
  props: baseProps,
@@ -62,7 +52,14 @@ function DocsLayout(props) {
62
52
  },
63
53
  children: /* @__PURE__ */ jsxs(TreeContextProvider, {
64
54
  tree,
65
- children: [content, renderNavigationPanel({
55
+ children: [/* @__PURE__ */ jsx(slots.sidebar.provider, {
56
+ defaultOpenLevel,
57
+ prefetch,
58
+ children: /* @__PURE__ */ jsxs(slots.container, {
59
+ ...containerProps,
60
+ children: [sidebarEnabled && /* @__PURE__ */ jsx(slots.sidebar.root, { ...sidebarProps }), children]
61
+ })
62
+ }), renderNavigationPanel({
66
63
  head: /* @__PURE__ */ jsxs(Fragment$1, { children: [slots.navTitle && /* @__PURE__ */ jsx(slots.navTitle, { className: "inline-flex items-center gap-2.5 text-sm font-semibold" }), nav.children] }),
67
64
  tabDropdown: slots.tabDropdown && tabs.length > 0 && /* @__PURE__ */ jsx(slots.tabDropdown, {
68
65
  className: "flex-1",
@@ -1,11 +1,81 @@
1
1
  import { MarkdownCopyButton, ViewOptionsPopover } from "../../shared/page-actions.js";
2
+ import { TOCProps, TOCProviderProps } from "./slots/toc.js";
2
3
  import { Footer, FooterProps } from "./slots/footer.js";
3
4
  import { Breadcrumb, BreadcrumbProps } from "./slots/breadcrumb.js";
4
- import { DocsPage, DocsPageProps, DocsPageSlots, PageLastUpdate, useDocsPage } from "./client.js";
5
- import { ComponentProps } from "react";
5
+ import { ComponentProps, FC, ReactNode } from "react";
6
6
  import * as react_jsx_runtime0 from "react/jsx-runtime";
7
+ import { TOCItemType } from "fumadocs-core/toc";
7
8
 
8
9
  //#region src/layouts/flux/page/index.d.ts
10
+ interface DocsPageProps extends ComponentProps<'article'> {
11
+ toc?: TOCItemType[];
12
+ /**
13
+ * Extend the page to fill all available space
14
+ *
15
+ * @defaultValue false
16
+ */
17
+ full?: boolean;
18
+ children?: ReactNode;
19
+ slots?: Partial<DocsPageSlots>;
20
+ footer?: FooterOptions;
21
+ breadcrumb?: BreadcrumbOptions;
22
+ tableOfContent?: TableOfContentOptions;
23
+ }
24
+ interface TableOfContentOptions extends Pick<TOCProviderProps, 'single'>, TOCProps {
25
+ enabled?: boolean;
26
+ /**
27
+ * @deprecated use `slots.toc` instead.
28
+ */
29
+ component?: ReactNode;
30
+ }
31
+ interface BreadcrumbOptions extends BreadcrumbProps {
32
+ enabled?: boolean;
33
+ /**
34
+ * @deprecated use `slots.breadcrumb` instead.
35
+ */
36
+ component?: ReactNode;
37
+ }
38
+ interface FooterOptions extends FooterProps {
39
+ enabled?: boolean;
40
+ /**
41
+ * @deprecated use `slots.footer` instead.
42
+ */
43
+ component?: ReactNode;
44
+ }
45
+ interface DocsPageSlots {
46
+ toc: {
47
+ provider: FC<TOCProviderProps>;
48
+ main: FC<TOCProps>;
49
+ };
50
+ container: FC<ComponentProps<'article'>>;
51
+ footer: FC<FooterProps>;
52
+ breadcrumb: FC<BreadcrumbProps>;
53
+ }
54
+ type PageSlotsProps = Pick<DocsPageProps, 'full'>;
55
+ declare function useDocsPage(): {
56
+ props: PageSlotsProps;
57
+ slots: DocsPageSlots;
58
+ };
59
+ declare function DocsPage({
60
+ tableOfContent: {
61
+ enabled: tocEnabled,
62
+ single,
63
+ ...tocProps
64
+ },
65
+ breadcrumb: {
66
+ enabled: breadcrumbEnabled,
67
+ ...breadcrumb
68
+ },
69
+ footer: {
70
+ enabled: footerEnabled,
71
+ ...footer
72
+ },
73
+ full,
74
+ toc,
75
+ slots: defaultSlots,
76
+ children,
77
+ ...containerProps
78
+ }: DocsPageProps): react_jsx_runtime0.JSX.Element;
9
79
  declare function EditOnGitHub(props: ComponentProps<'a'>): react_jsx_runtime0.JSX.Element;
10
80
  /**
11
81
  * Add typography styles
@@ -25,5 +95,11 @@ declare function DocsTitle({
25
95
  className,
26
96
  ...props
27
97
  }: ComponentProps<'h1'>): react_jsx_runtime0.JSX.Element;
98
+ declare function PageLastUpdate({
99
+ date: value,
100
+ ...props
101
+ }: Omit<ComponentProps<'p'>, 'children'> & {
102
+ date: Date;
103
+ }): react_jsx_runtime0.JSX.Element;
28
104
  //#endregion
29
- export { type BreadcrumbProps, DocsBody, DocsDescription, DocsPage, type DocsPageProps, type DocsPageSlots, DocsTitle, EditOnGitHub, type FooterProps, MarkdownCopyButton, Breadcrumb as PageBreadcrumb, Footer as PageFooter, PageLastUpdate, ViewOptionsPopover, useDocsPage };
105
+ export { type BreadcrumbProps, DocsBody, DocsDescription, DocsPage, DocsPageProps, DocsTitle, EditOnGitHub, type FooterProps, MarkdownCopyButton, Breadcrumb as PageBreadcrumb, Footer as PageFooter, PageLastUpdate, ViewOptionsPopover, useDocsPage };
@@ -1,13 +1,52 @@
1
- import { I18nLabel } from "../../../contexts/i18n.js";
1
+ "use client";
2
+ import { I18nLabel, useI18n } from "../../../contexts/i18n.js";
2
3
  import { cn } from "../../../utils/cn.js";
3
4
  import { buttonVariants } from "../../../components/ui/button.js";
4
5
  import { MarkdownCopyButton, ViewOptionsPopover } from "../../shared/page-actions.js";
6
+ import { TOC, TOCProvider } from "./slots/toc.js";
5
7
  import { Footer } from "./slots/footer.js";
6
8
  import { Breadcrumb } from "./slots/breadcrumb.js";
7
- import { DocsPage, PageLastUpdate, useDocsPage } from "./client.js";
8
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import { Container } from "./slots/container.js";
10
+ import { createContext, use, useEffect, useState } from "react";
11
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
12
  import { Edit } from "lucide-react";
10
13
  //#region src/layouts/flux/page/index.tsx
14
+ const PageContext = createContext(null);
15
+ function useDocsPage() {
16
+ const context = use(PageContext);
17
+ if (!context) throw new Error("Please use page components under <DocsPage /> (`fumadocs-ui/layouts/flux/page`).");
18
+ return context;
19
+ }
20
+ function DocsPage({ tableOfContent: { enabled: tocEnabled, single, ...tocProps } = {}, breadcrumb: { enabled: breadcrumbEnabled = true, ...breadcrumb } = {}, footer: { enabled: footerEnabled = true, ...footer } = {}, full = false, toc = [], slots: defaultSlots = {}, children, ...containerProps }) {
21
+ tocEnabled ??= Boolean(toc.length > 0 || tocProps.header || tocProps.footer);
22
+ const slots = {
23
+ breadcrumb: defaultSlots.breadcrumb ?? Breadcrumb,
24
+ footer: defaultSlots.footer ?? Footer,
25
+ container: defaultSlots.container ?? Container,
26
+ toc: defaultSlots.toc ?? {
27
+ provider: TOCProvider,
28
+ main: TOC
29
+ }
30
+ };
31
+ return /* @__PURE__ */ jsx(PageContext, {
32
+ value: {
33
+ props: { full },
34
+ slots
35
+ },
36
+ children: /* @__PURE__ */ jsxs(slots.toc.provider, {
37
+ single,
38
+ toc: tocEnabled ? toc : [],
39
+ children: [tocEnabled && (tocProps.component ?? /* @__PURE__ */ jsx(slots.toc.main, { ...tocProps })), /* @__PURE__ */ jsxs(slots.container, {
40
+ ...containerProps,
41
+ children: [
42
+ breadcrumbEnabled && (breadcrumb.component ?? /* @__PURE__ */ jsx(slots.breadcrumb, { ...breadcrumb })),
43
+ children,
44
+ footerEnabled && (footer.component ?? /* @__PURE__ */ jsx(slots.footer, { ...footer }))
45
+ ]
46
+ })]
47
+ })
48
+ });
49
+ }
11
50
  function EditOnGitHub(props) {
12
51
  return /* @__PURE__ */ jsx("a", {
13
52
  target: "_blank",
@@ -15,10 +54,9 @@ function EditOnGitHub(props) {
15
54
  ...props,
16
55
  className: cn(buttonVariants({
17
56
  color: "secondary",
18
- size: "sm",
19
- className: "gap-1.5 not-prose"
20
- }), props.className),
21
- children: props.children ?? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Edit, { className: "size-3.5" }), /* @__PURE__ */ jsx(I18nLabel, { label: "editOnGithub" })] })
57
+ size: "sm"
58
+ }), "gap-1.5 not-prose", props.className),
59
+ children: props.children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Edit, { className: "size-3.5" }), /* @__PURE__ */ jsx(I18nLabel, { label: "editOnGithub" })] })
22
60
  });
23
61
  }
24
62
  /**
@@ -46,5 +84,21 @@ function DocsTitle({ children, className, ...props }) {
46
84
  children
47
85
  });
48
86
  }
87
+ function PageLastUpdate({ date: value, ...props }) {
88
+ const { text } = useI18n();
89
+ const [date, setDate] = useState("");
90
+ useEffect(() => {
91
+ setDate(value.toLocaleDateString());
92
+ }, [value]);
93
+ return /* @__PURE__ */ jsxs("p", {
94
+ ...props,
95
+ className: cn("text-sm text-fd-muted-foreground", props.className),
96
+ children: [
97
+ text.lastUpdate,
98
+ " ",
99
+ date
100
+ ]
101
+ });
102
+ }
49
103
  //#endregion
50
104
  export { DocsBody, DocsDescription, DocsPage, DocsTitle, EditOnGitHub, MarkdownCopyButton, Breadcrumb as PageBreadcrumb, Footer as PageFooter, PageLastUpdate, ViewOptionsPopover, useDocsPage };
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { cn } from "../../../../utils/cn.js";
2
3
  import { useTreeContext, useTreePath } from "../../../../contexts/tree.js";
3
4
  import { Fragment, useMemo } from "react";
@@ -1,5 +1,6 @@
1
+ "use client";
1
2
  import { cn } from "../../../../utils/cn.js";
2
- import { useDocsPage } from "../client.js";
3
+ import { useDocsPage } from "../index.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  //#region src/layouts/flux/page/slots/container.tsx
5
6
  function Container(props) {
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { useI18n } from "../../../../contexts/i18n.js";
2
3
  import { cn } from "../../../../utils/cn.js";
3
4
  import { isActive } from "../../../../utils/urls.js";