fumadocs-ui 14.3.1 → 14.4.1

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 (66) hide show
  1. package/dist/components/codeblock.d.ts +3 -0
  2. package/dist/components/codeblock.d.ts.map +1 -1
  3. package/dist/components/codeblock.js +7 -10
  4. package/dist/components/layout/nav.d.ts +3 -3
  5. package/dist/components/layout/nav.d.ts.map +1 -1
  6. package/dist/components/layout/nav.js +5 -2
  7. package/dist/components/layout/toc-clerk.d.ts +1 -1
  8. package/dist/components/layout/toc-clerk.d.ts.map +1 -1
  9. package/dist/components/layout/toc-clerk.js +7 -8
  10. package/dist/components/layout/toc-popover.js +1 -1
  11. package/dist/components/layout/toc.d.ts +1 -0
  12. package/dist/components/layout/toc.d.ts.map +1 -1
  13. package/dist/components/layout/toc.js +6 -3
  14. package/dist/components/registry.d.ts.map +1 -1
  15. package/dist/components/registry.js +5 -0
  16. package/dist/components/type-table.d.ts.map +1 -1
  17. package/dist/components/type-table.js +1 -3
  18. package/dist/contexts/search.d.ts +6 -3
  19. package/dist/contexts/search.d.ts.map +1 -1
  20. package/dist/contexts/search.js +3 -0
  21. package/dist/layouts/docs/navbar.d.ts +2 -2
  22. package/dist/layouts/docs/navbar.d.ts.map +1 -1
  23. package/dist/layouts/docs/navbar.js +6 -8
  24. package/dist/layouts/docs/shared.d.ts +41 -0
  25. package/dist/layouts/docs/shared.d.ts.map +1 -0
  26. package/dist/layouts/docs/shared.js +30 -0
  27. package/dist/layouts/docs/sidebar.d.ts +7 -0
  28. package/dist/layouts/docs/sidebar.d.ts.map +1 -1
  29. package/dist/layouts/docs/sidebar.js +46 -20
  30. package/dist/layouts/docs.client.d.ts +0 -4
  31. package/dist/layouts/docs.client.d.ts.map +1 -1
  32. package/dist/layouts/docs.client.js +1 -25
  33. package/dist/layouts/docs.d.ts +2 -33
  34. package/dist/layouts/docs.d.ts.map +1 -1
  35. package/dist/layouts/docs.js +15 -32
  36. package/dist/layouts/home/navbar.d.ts.map +1 -1
  37. package/dist/layouts/home/navbar.js +3 -3
  38. package/dist/layouts/notebook.client.d.ts +3 -0
  39. package/dist/layouts/notebook.client.d.ts.map +1 -0
  40. package/dist/layouts/notebook.client.js +13 -0
  41. package/dist/layouts/notebook.d.ts +11 -0
  42. package/dist/layouts/notebook.d.ts.map +1 -0
  43. package/dist/layouts/notebook.js +56 -0
  44. package/dist/layouts/shared.d.ts +1 -2
  45. package/dist/layouts/shared.d.ts.map +1 -1
  46. package/dist/layouts/shared.js +1 -0
  47. package/dist/page.client.d.ts +3 -0
  48. package/dist/page.client.d.ts.map +1 -1
  49. package/dist/page.client.js +20 -6
  50. package/dist/page.d.ts +8 -2
  51. package/dist/page.d.ts.map +1 -1
  52. package/dist/page.js +5 -7
  53. package/dist/style.css +1 -1
  54. package/dist/tailwind-plugin.d.ts +5 -1
  55. package/dist/tailwind-plugin.d.ts.map +1 -1
  56. package/dist/tailwind-plugin.js +1 -14
  57. package/dist/theme/colors.d.ts +1 -0
  58. package/dist/theme/colors.d.ts.map +1 -1
  59. package/dist/theme/colors.js +15 -14
  60. package/dist/theme/typography.d.ts +27 -4
  61. package/dist/theme/typography.d.ts.map +1 -1
  62. package/dist/theme/typography.js +28 -2
  63. package/package.json +4 -4
  64. package/dist/components/layout/breadcrumb.d.ts +0 -11
  65. package/dist/components/layout/breadcrumb.d.ts.map +0 -1
  66. package/dist/components/layout/breadcrumb.js +0 -20
@@ -1,4 +1,5 @@
1
1
  import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import type { ScrollAreaViewportProps } from '@radix-ui/react-scroll-area';
2
3
  export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
3
4
  /**
4
5
  * Icon of code block
@@ -18,6 +19,7 @@ export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
18
19
  * @defaultValue false
19
20
  */
20
21
  keepBackground?: boolean;
22
+ viewportProps?: ScrollAreaViewportProps;
21
23
  };
22
24
  export declare const Pre: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLPreElement> & import("react").RefAttributes<HTMLPreElement>>;
23
25
  export declare const CodeBlock: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & {
@@ -39,5 +41,6 @@ export declare const CodeBlock: import("react").ForwardRefExoticComponent<HTMLAt
39
41
  * @defaultValue false
40
42
  */
41
43
  keepBackground?: boolean;
44
+ viewportProps?: ScrollAreaViewportProps;
42
45
  } & import("react").RefAttributes<HTMLElement>>;
43
46
  //# sourceMappingURL=codeblock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAUf,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,GAAG,2HAQf,CAAC;AAIF,eAAO,MAAM,SAAS;IAlCpB;;;;OAIG;WACI,SAAS;IAEhB;;;;OAIG;gBACS,OAAO;IAEnB;;;;OAIG;qBACc,OAAO;+CAwFzB,CAAC"}
1
+ {"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,GAAG,2HAQf,CAAC;AAIF,eAAO,MAAM,SAAS;IApCpB;;;;OAIG;WACI,SAAS;IAEhB;;;;OAIG;gBACS,OAAO;IAEnB;;;;OAIG;qBACc,OAAO;oBAER,uBAAuB;+CA+FxC,CAAC"}
@@ -7,10 +7,10 @@ import { ScrollArea, ScrollBar, ScrollViewport, } from '../components/ui/scroll-
7
7
  import { useCopyButton } from '../utils/use-copy-button';
8
8
  import { buttonVariants } from '../components/ui/button';
9
9
  export const Pre = forwardRef(({ className, ...props }, ref) => {
10
- return (_jsx("pre", { ref: ref, className: cn('max-h-[400px] p-4', className), ...props, children: props.children }));
10
+ return (_jsx("pre", { ref: ref, className: cn('p-4', className), ...props, children: props.children }));
11
11
  });
12
12
  Pre.displayName = 'Pre';
13
- export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground = false, icon, className, ...props }, ref) => {
13
+ export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground = false, icon, viewportProps, ...props }, ref) => {
14
14
  const areaRef = useRef(null);
15
15
  const onCopy = useCallback(() => {
16
16
  const pre = areaRef.current?.getElementsByTagName('pre').item(0);
@@ -22,20 +22,17 @@ export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground =
22
22
  });
23
23
  void navigator.clipboard.writeText(clone.textContent ?? '');
24
24
  }, []);
25
- return (_jsxs("figure", { ref: ref, className: cn('not-prose group fd-codeblock relative my-6 overflow-hidden rounded-lg border bg-fd-secondary/50 text-sm', keepBackground &&
26
- 'bg-[var(--shiki-light-bg)] dark:bg-[var(--shiki-dark-bg)]', className), ...props, children: [title ? (_jsxs("div", { className: "flex flex-row items-center gap-2 border-b bg-fd-muted px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", ...(typeof icon === 'string'
25
+ return (_jsxs("figure", { ref: ref, ...props, className: cn('not-prose group fd-codeblock relative my-6 overflow-hidden rounded-lg border bg-fd-secondary/50 text-sm', keepBackground &&
26
+ 'bg-[var(--shiki-light-bg)] dark:bg-[var(--shiki-dark-bg)]', props.className), children: [title ? (_jsxs("div", { className: "flex flex-row items-center gap-2 border-b bg-fd-muted px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", dangerouslySetInnerHTML: typeof icon === 'string'
27
27
  ? {
28
- dangerouslySetInnerHTML: { __html: icon },
28
+ __html: icon,
29
29
  }
30
- : {
31
- children: icon,
32
- }) })) : null, _jsx("figcaption", { className: "flex-1 truncate text-fd-muted-foreground", children: title }), allowCopy ? (_jsx(CopyButton, { className: "-me-2", onCopy: onCopy })) : null] })) : (allowCopy && (_jsx(CopyButton, { className: "absolute right-2 top-2 z-[2] backdrop-blur-md", onCopy: onCopy }))), _jsxs(ScrollArea, { ref: areaRef, dir: "ltr", children: [_jsx(ScrollViewport, { children: props.children }), _jsx(ScrollBar, { orientation: "horizontal" })] })] }));
30
+ : undefined, children: typeof icon !== 'string' ? icon : null })) : null, _jsx("figcaption", { className: "flex-1 truncate text-fd-muted-foreground", children: title }), allowCopy ? (_jsx(CopyButton, { className: "-me-2", onCopy: onCopy })) : null] })) : (allowCopy && (_jsx(CopyButton, { className: "absolute right-2 top-2 z-[2] backdrop-blur-md", onCopy: onCopy }))), _jsxs(ScrollArea, { ref: areaRef, dir: "ltr", children: [_jsx(ScrollViewport, { ...viewportProps, className: cn('max-h-[400px]', viewportProps?.className), children: props.children }), _jsx(ScrollBar, { orientation: "horizontal" })] })] }));
33
31
  });
34
32
  CodeBlock.displayName = 'CodeBlock';
35
33
  function CopyButton({ className, onCopy, ...props }) {
36
34
  const [checked, onClick] = useCopyButton(onCopy);
37
35
  return (_jsxs("button", { type: "button", className: cn(buttonVariants({
38
36
  color: 'ghost',
39
- className: 'transition-all group-hover:opacity-100',
40
- }), !checked && 'opacity-0', className), "aria-label": "Copy Text", onClick: onClick, ...props, children: [_jsx(Check, { className: cn('size-3.5 transition-transform', !checked && 'scale-0') }), _jsx(Copy, { className: cn('absolute size-3.5 transition-transform', checked && 'scale-0') })] }));
37
+ }), 'transition-opacity group-hover:opacity-100', !checked && 'opacity-0', className), "aria-label": "Copy Text", onClick: onClick, ...props, children: [_jsx(Check, { className: cn('size-3.5 transition-transform', !checked && 'scale-0') }), _jsx(Copy, { className: cn('absolute size-3.5 transition-transform', checked && 'scale-0') })] }));
41
38
  }
@@ -19,10 +19,10 @@ export interface TitleProps {
19
19
  interface NavContextType {
20
20
  isTransparent: boolean;
21
21
  }
22
- export declare const NavContext: import("react").Context<NavContextType>;
23
22
  export declare function NavProvider({ transparentMode, children, }: NavProviderProps & {
24
23
  children: ReactNode;
25
- }): ReactNode;
26
- export declare function Title({ title, url, ...props }: TitleProps & Omit<LinkProps, 'title'>): React.ReactElement;
24
+ }): import("react/jsx-runtime").JSX.Element;
25
+ export declare function useNav(): NavContextType;
26
+ export declare function Title({ title, url, ...props }: TitleProps & Omit<LinkProps, 'title'>): import("react/jsx-runtime").JSX.Element;
27
27
  export {};
28
28
  //# sourceMappingURL=nav.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../../src/components/layout/nav.tsx"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAiB,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,UAAU,yCAErB,CAAC;AAEH,wBAAgB,WAAW,CAAC,EAC1B,eAAwB,EACxB,QAAQ,GACT,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAsBxD;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,YAAY,CAe5D"}
1
+ {"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../../src/components/layout/nav.tsx"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAIf,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD,wBAAgB,WAAW,CAAC,EAC1B,eAAwB,EACxB,QAAQ,GACT,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAsB5C;AAED,wBAAgB,MAAM,IAAI,cAAc,CAEvC;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,2CAevC"}
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import Link from 'fumadocs-core/link';
4
- import { createContext, useEffect, useState } from 'react';
4
+ import { createContext, useContext, useEffect, useState, } from 'react';
5
5
  import { cn } from '../../utils/cn';
6
6
  import { useI18n } from '../../contexts/i18n';
7
- export const NavContext = createContext({
7
+ const NavContext = createContext({
8
8
  isTransparent: false,
9
9
  });
10
10
  export function NavProvider({ transparentMode = 'none', children, }) {
@@ -23,6 +23,9 @@ export function NavProvider({ transparentMode = 'none', children, }) {
23
23
  }, [transparentMode]);
24
24
  return (_jsx(NavContext.Provider, { value: { isTransparent: transparent }, children: children }));
25
25
  }
26
+ export function useNav() {
27
+ return useContext(NavContext);
28
+ }
26
29
  export function Title({ title, url, ...props }) {
27
30
  const { locale } = useI18n();
28
31
  return (_jsx(Link, { href: url ?? (locale ? `/${locale}` : '/'), ...props, className: cn('inline-flex items-center gap-2.5 font-semibold', props.className), children: title }));
@@ -2,5 +2,5 @@ import type { TOCItemType } from 'fumadocs-core/server';
2
2
  export default function ClerkTOCItems({ items, isMenu, }: {
3
3
  items: TOCItemType[];
4
4
  isMenu?: boolean;
5
- }): React.ReactElement;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
6
  //# sourceMappingURL=toc-clerk.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toc-clerk.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-clerk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,KAAK,CAAC,YAAY,CAsGrB"}
1
+ {"version":3,"file":"toc-clerk.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-clerk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CAgGA"}
@@ -3,11 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as Primitive from 'fumadocs-core/toc';
4
4
  import { useEffect, useRef, useState } from 'react';
5
5
  import { cn } from '../../utils/cn';
6
- import { useI18n } from '../../contexts/i18n';
7
6
  import { TocThumb } from '../../components/layout/toc-thumb';
8
7
  import { ScrollArea, ScrollViewport } from '../ui/scroll-area';
8
+ import { TocItemsEmpty } from '../../components/layout/toc';
9
9
  export default function ClerkTOCItems({ items, isMenu = false, }) {
10
- const { text } = useI18n();
11
10
  const viewRef = useRef(null);
12
11
  const containerRef = useRef(null);
13
12
  const [svg, setSvg] = useState();
@@ -47,7 +46,7 @@ export default function ClerkTOCItems({ items, isMenu = false, }) {
47
46
  };
48
47
  }, [items]);
49
48
  if (items.length === 0)
50
- return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
49
+ return _jsx(TocItemsEmpty, {});
51
50
  return (_jsx(ScrollArea, { className: cn('flex flex-col', isMenu && '-ms-3'), children: _jsxs(ScrollViewport, { className: "relative min-h-0", ref: viewRef, children: [svg ? (_jsx("div", { className: "absolute start-0 top-0 rtl:-scale-x-100", style: {
52
51
  width: svg.width,
53
52
  height: svg.height,
@@ -58,19 +57,19 @@ export default function ClerkTOCItems({ items, isMenu = false, }) {
58
57
  }
59
58
  function getItemOffset(depth) {
60
59
  if (depth <= 2)
61
- return 16;
60
+ return 14;
62
61
  if (depth === 3)
63
- return 32;
64
- return 48;
62
+ return 26;
63
+ return 36;
65
64
  }
66
65
  function getLineOffset(depth) {
67
- return depth >= 3 ? 12 : 0;
66
+ return depth >= 3 ? 10 : 0;
68
67
  }
69
68
  function TOCItem({ item, upper = item.depth, lower = item.depth, }) {
70
69
  const offset = getLineOffset(item.depth), upperOffset = getLineOffset(upper), lowerOffset = getLineOffset(lower);
71
70
  return (_jsxs(Primitive.TOCItem, { href: item.url, style: {
72
71
  paddingInlineStart: getItemOffset(item.depth),
73
- }, className: "prose relative py-2 text-sm text-fd-muted-foreground transition-colors [overflow-wrap:anywhere] first:pt-0 last:pb-0 data-[active=true]:text-fd-primary", children: [offset !== upperOffset ? (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", className: "absolute -top-2 start-0 size-4 rtl:-scale-x-100", children: _jsx("line", { x1: upperOffset, y1: "0", x2: offset, y2: "16", className: "stroke-fd-foreground/10", strokeWidth: "1" }) })) : null, _jsx("div", { className: cn('absolute inset-y-0 w-px bg-fd-foreground/10', offset !== upperOffset && 'top-2', offset !== lowerOffset && 'bottom-2'), style: {
72
+ }, className: "prose relative py-1.5 text-sm text-fd-muted-foreground transition-colors [overflow-wrap:anywhere] first:pt-0 last:pb-0 data-[active=true]:text-fd-primary", children: [offset !== upperOffset ? (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", className: "absolute -top-1.5 start-0 size-4 rtl:-scale-x-100", children: _jsx("line", { x1: upperOffset, y1: "0", x2: offset, y2: "12", className: "stroke-fd-foreground/10", strokeWidth: "1" }) })) : null, _jsx("div", { className: cn('absolute inset-y-0 w-px bg-fd-foreground/10', offset !== upperOffset && 'top-1.5', offset !== lowerOffset && 'bottom-1.5'), style: {
74
73
  insetInlineStart: offset,
75
74
  } }), item.title] }));
76
75
  }
@@ -13,7 +13,7 @@ export function TocPopoverTrigger({ items, ...props }) {
13
13
  const current = useMemo(() => {
14
14
  return items.find((item) => active === item.url.slice(1))?.title;
15
15
  }, [items, active]);
16
- return (_jsxs(PopoverTrigger, { ...props, className: cn('inline-flex items-center gap-2 text-nowrap px-4 py-2 text-start md:px-3', props.className), children: [_jsx(Text, { className: "size-4 shrink-0" }), text.toc, current ? (_jsxs(_Fragment, { children: [_jsx(ChevronRight, { className: "-mx-1.5 size-4 shrink-0 text-fd-muted-foreground" }), _jsx("span", { className: "truncate text-fd-muted-foreground", children: current })] })) : null] }));
16
+ return (_jsxs(PopoverTrigger, { ...props, className: cn('inline-flex items-center gap-2 text-nowrap px-4 py-2 text-start', props.className), children: [_jsx(Text, { className: "size-4 shrink-0" }), text.toc, current ? (_jsxs(_Fragment, { children: [_jsx(ChevronRight, { className: "-mx-1.5 size-4 shrink-0 text-fd-muted-foreground" }), _jsx("span", { className: "truncate text-fd-muted-foreground", children: current })] })) : null] }));
17
17
  }
18
18
  export function TocPopoverContent(props) {
19
19
  return (_jsx(PopoverContent, { hideWhenDetached: true, alignOffset: 16, align: "start", side: "bottom", "data-toc-popover": "", ...props, className: cn('flex max-h-[var(--radix-popover-content-available-height)] w-[260px] flex-col gap-4 p-3', props.className), children: props.children }));
@@ -12,6 +12,7 @@ export interface TOCProps {
12
12
  children: ReactNode;
13
13
  }
14
14
  export declare function Toc(props: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
15
+ export declare function TocItemsEmpty(): import("react/jsx-runtime").JSX.Element;
15
16
  export declare function TOCItems({ items, isMenu, }: {
16
17
  items: TOCItemType[];
17
18
  isMenu?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"toc.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAMpE,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAoBxD;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CAmCA"}
1
+ {"version":3,"file":"toc.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAMpE,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAoBxD;AAED,wBAAgB,aAAa,4CAQ5B;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CA6BA"}
@@ -7,17 +7,20 @@ import { useI18n } from '../../contexts/i18n';
7
7
  import { TocThumb } from '../../components/layout/toc-thumb';
8
8
  import { ScrollArea, ScrollViewport } from '../ui/scroll-area';
9
9
  export function Toc(props) {
10
- return (_jsx("div", { ...props, "data-toc": "", className: cn('sticky top-fd-layout-top h-[var(--fd-toc-height)] flex-1 pb-2 pe-2 pt-12 max-lg:hidden', props.className), style: {
10
+ return (_jsx("div", { ...props, "data-toc": "", className: cn('sticky top-fd-layout-top h-[var(--fd-toc-height)] flex-1 pb-2 pt-12', props.className), style: {
11
11
  ...props.style,
12
12
  '--fd-toc-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
13
13
  }, children: props.children }));
14
14
  }
15
- export function TOCItems({ items, isMenu = false, }) {
15
+ export function TocItemsEmpty() {
16
16
  const { text } = useI18n();
17
+ return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
18
+ }
19
+ export function TOCItems({ items, isMenu = false, }) {
17
20
  const containerRef = useRef(null);
18
21
  const viewRef = useRef(null);
19
22
  if (items.length === 0)
20
- return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
23
+ return _jsx(TocItemsEmpty, {});
21
24
  return (_jsx(ScrollArea, { className: cn('flex flex-col', isMenu && '-ms-3'), children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: _jsxs(ScrollViewport, { className: "relative min-h-0 text-sm", ref: viewRef, children: [_jsx(TocThumb, { containerRef: containerRef, className: "absolute start-0 mt-[var(--fd-top)] h-[var(--fd-height)] w-px bg-fd-primary transition-all" }), _jsx("div", { ref: containerRef, className: cn('flex flex-col', !isMenu && 'border-s border-fd-foreground/10'), children: items.map((item) => (_jsx(TOCItem, { item: item }, item.url))) })] }) }) }));
22
25
  }
23
26
  function TOCItem({ item }) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AASpD,eAAO,MAAM,QAAQ,EAAE,QA8DtB,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AASpD,eAAO,MAAM,QAAQ,EAAE,QAmEtB,CAAC"}
@@ -34,6 +34,11 @@ export const registry = {
34
34
  files: ['../layouts/home.tsx'],
35
35
  mapImportPath: contextsMap,
36
36
  },
37
+ {
38
+ name: 'layouts/page',
39
+ files: ['components:../page.tsx'],
40
+ mapImportPath: contextsMap,
41
+ },
37
42
  { name: 'accordion', files: ['accordion.tsx'] },
38
43
  { name: 'banner', files: ['banner.tsx'] },
39
44
  { name: 'callout', files: ['callout.tsx'] },
@@ -1 +1 @@
1
- {"version":3,"file":"type-table.d.ts","sourceRoot":"","sources":["../../src/components/type-table.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAWrE;AAED,UAAU,UAAU;IAClB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAcD,wBAAgB,SAAS,CAAC,EACxB,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC,GAAG,KAAK,CAAC,YAAY,CA8CrB"}
1
+ {"version":3,"file":"type-table.d.ts","sourceRoot":"","sources":["../../src/components/type-table.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAWrE;AAED,UAAU,UAAU;IAClB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD,wBAAgB,SAAS,CAAC,EACxB,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAClC,GAAG,KAAK,CAAC,YAAY,CA8CrB"}
@@ -8,8 +8,6 @@ import { Popover, PopoverContent, PopoverTrigger, } from '../components/ui/popov
8
8
  export function Info({ children }) {
9
9
  return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { children: _jsx(InfoIcon, { className: "size-4" }) }), _jsx(PopoverContent, { className: "prose max-h-[400px] min-w-[220px] max-w-[400px] overflow-auto text-sm prose-no-margin", children: children })] }));
10
10
  }
11
- const th = cva('p-2 font-medium first:pl-0 last:pr-0');
12
- const td = cva('p-2 first:pl-0 last:pr-0');
13
11
  const field = cva('inline-flex flex-row items-center gap-1');
14
12
  const code = cva('rounded-md bg-fd-secondary p-1 text-fd-secondary-foreground', {
15
13
  variants: {
@@ -17,5 +15,5 @@ const code = cva('rounded-md bg-fd-secondary p-1 text-fd-secondary-foreground',
17
15
  },
18
16
  });
19
17
  export function TypeTable({ type, }) {
20
- return (_jsx("div", { className: "not-prose overflow-auto whitespace-nowrap", children: _jsxs("table", { className: "my-4 w-full text-left text-sm text-fd-muted-foreground", children: [_jsx("thead", { className: "border-b", children: _jsxs("tr", { children: [_jsx("th", { className: cn(th(), 'w-[45%]'), children: "Prop" }), _jsx("th", { className: cn(th(), 'w-[30%]'), children: "Type" }), _jsx("th", { className: cn(th(), 'w-1/4'), children: "Default" })] }) }), _jsx("tbody", { className: "border-collapse divide-y divide-fd-border", children: Object.entries(type).map(([key, value]) => (_jsxs("tr", { children: [_jsx("td", { className: td(), children: _jsxs("div", { className: field(), children: [_jsx("code", { className: cn(code({ color: 'primary' })), children: key }), value.description ? _jsx(Info, { children: value.description }) : null] }) }), _jsx("td", { className: td(), children: _jsxs("div", { className: field(), children: [_jsx("code", { className: code(), children: value.type }), value.typeDescription ? (_jsx(Info, { children: value.typeDescription })) : null, value.typeDescriptionLink ? (_jsx(Link, { href: value.typeDescriptionLink, children: _jsx(InfoIcon, { className: "size-4" }) })) : null] }) }), _jsx("td", { className: td(), children: value.default ? (_jsx("code", { className: code(), children: value.default })) : (_jsx("span", { children: "-" })) })] }, key))) })] }) }));
18
+ return (_jsx("div", { className: "overflow-auto whitespace-nowrap", children: _jsxs("table", { className: "text-sm text-fd-muted-foreground", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "w-[45%]", children: "Prop" }), _jsx("th", { className: "w-[30%]", children: "Type" }), _jsx("th", { className: "w-1/4", children: "Default" })] }) }), _jsx("tbody", { children: Object.entries(type).map(([key, value]) => (_jsxs("tr", { children: [_jsx("td", { children: _jsxs("div", { className: field(), children: [_jsx("code", { className: cn(code({ color: 'primary' })), children: key }), value.description ? _jsx(Info, { children: value.description }) : null] }) }), _jsx("td", { children: _jsxs("div", { className: field(), children: [_jsx("code", { className: code(), children: value.type }), value.typeDescription ? (_jsx(Info, { children: value.typeDescription })) : null, value.typeDescriptionLink ? (_jsx(Link, { href: value.typeDescriptionLink, children: _jsx(InfoIcon, { className: "size-4" }) })) : null] }) }), _jsx("td", { children: value.default ? (_jsx("code", { className: code(), children: value.default })) : (_jsx("span", { children: "-" })) })] }, key))) })] }) }));
21
19
  }
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from 'react';
1
+ import { type ComponentType, type ReactNode } from 'react';
2
2
  import type { SearchLink, SharedProps } from '../components/dialog/search';
3
3
  interface HotKey {
4
4
  display: ReactNode;
@@ -29,7 +29,7 @@ export interface SearchProviderProps {
29
29
  *
30
30
  * It receives the `open` and `onOpenChange` prop, can be lazy loaded with `next/dynamic`
31
31
  */
32
- SearchDialog: React.ComponentType<SharedProps>;
32
+ SearchDialog: ComponentType<SharedProps>;
33
33
  /**
34
34
  * Additional props to the dialog
35
35
  */
@@ -42,7 +42,10 @@ interface SearchContextType {
42
42
  setOpenSearch: (value: boolean) => void;
43
43
  }
44
44
  export declare function useSearchContext(): SearchContextType;
45
- export declare function SearchProvider({ SearchDialog, children, preload, options, hotKey, links, }: SearchProviderProps): React.ReactElement;
45
+ export declare function SearchProvider({ SearchDialog, children, preload, options, hotKey, links, }: SearchProviderProps): import("react/jsx-runtime").JSX.Element;
46
+ /**
47
+ * Show children only when search is enabled via React Context
48
+ */
46
49
  export declare function SearchOnly({ children }: {
47
50
  children: ReactNode;
48
51
  }): ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/contexts/search.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE1E,UAAU,MAAM;IACd,OAAO,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IAErB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;;;OAIG;IACH,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAE/C;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAQD,wBAAgB,gBAAgB,IAAI,iBAAiB,CAEpD;AAcD,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,QAAQ,EACR,OAAc,EACd,OAAO,EACP,MASC,EACD,KAAK,GACN,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAuC1C;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,aAI/D"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/contexts/search.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE1E,UAAU,MAAM;IACd,OAAO,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IAErB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;;;OAIG;IACH,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAEzC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAQD,wBAAgB,gBAAgB,IAAI,iBAAiB,CAEpD;AAcD,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,QAAQ,EACR,OAAc,EACd,OAAO,EACP,MASC,EACD,KAAK,GACN,EAAE,mBAAmB,2CAuCrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,aAI/D"}
@@ -43,6 +43,9 @@ export function SearchProvider({ SearchDialog, children, preload = true, options
43
43
  }, [hotKey]);
44
44
  return (_jsxs(SearchContext.Provider, { value: useMemo(() => ({ enabled: true, hotKey, setOpenSearch: setIsOpen }), [hotKey]), children: [isOpen !== undefined && (_jsx(SearchDialog, { open: isOpen, onOpenChange: setIsOpen, links: links, ...options })), children] }));
45
45
  }
46
+ /**
47
+ * Show children only when search is enabled via React Context
48
+ */
46
49
  export function SearchOnly({ children }) {
47
50
  const search = useSearchContext();
48
51
  if (search.enabled)
@@ -1,4 +1,4 @@
1
- import { type HTMLAttributes } from 'react';
1
+ import { type ButtonHTMLAttributes, type HTMLAttributes } from 'react';
2
2
  export declare function Navbar(props: HTMLAttributes<HTMLElement>): import("react/jsx-runtime").JSX.Element;
3
- export declare function NavbarSidebarTrigger(): import("react/jsx-runtime").JSX.Element;
3
+ export declare function NavbarSidebarTrigger(props: ButtonHTMLAttributes<HTMLButtonElement>): import("react/jsx-runtime").JSX.Element;
4
4
  //# sourceMappingURL=navbar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navbar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/navbar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAc,MAAM,OAAO,CAAC;AAOxD,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC,2CAiBxD;AAED,wBAAgB,oBAAoB,4CAgBnC"}
1
+ {"version":3,"file":"navbar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/navbar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAOvE,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,WAAW,CAAC,2CAgBxD;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAkB/C"}
@@ -1,22 +1,20 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useSidebar } from '../../contexts/sidebar';
4
- import { useContext } from 'react';
5
- import { NavContext } from '../../components/layout/nav';
4
+ import { useNav } from '../../components/layout/nav';
6
5
  import { cn } from '../../utils/cn';
7
6
  import { SidebarTrigger } from 'fumadocs-core/sidebar';
8
7
  import { buttonVariants } from '../../components/ui/button';
9
8
  import { Menu, X } from 'lucide-react';
10
9
  export function Navbar(props) {
11
10
  const { open } = useSidebar();
12
- const { isTransparent } = useContext(NavContext);
13
- return (_jsx("header", { id: "nd-subnav", ...props, className: cn('sticky top-[var(--fd-banner-height)] z-40 flex flex-row items-center border-b border-fd-foreground/10 px-4 transition-colors', (!isTransparent || open) && 'bg-fd-background/80 backdrop-blur-lg', props.className), children: props.children }));
11
+ const { isTransparent } = useNav();
12
+ return (_jsx("header", { ...props, className: cn('sticky top-[var(--fd-banner-height)] z-30 flex flex-row items-center border-b border-fd-foreground/10 px-4 transition-colors', (!isTransparent || open) && 'bg-fd-background/80 backdrop-blur-lg', props.className), children: props.children }));
14
13
  }
15
- export function NavbarSidebarTrigger() {
14
+ export function NavbarSidebarTrigger(props) {
16
15
  const { open } = useSidebar();
17
- return (_jsx(SidebarTrigger, { className: cn(buttonVariants({
16
+ return (_jsx(SidebarTrigger, { ...props, className: cn(buttonVariants({
18
17
  color: 'ghost',
19
18
  size: 'icon',
20
- className: '-me-2 md:hidden',
21
- })), children: open ? _jsx(X, {}) : _jsx(Menu, {}) }));
19
+ }), props.className), children: open ? _jsx(X, {}) : _jsx(Menu, {}) }));
22
20
  }
@@ -0,0 +1,41 @@
1
+ import { type LinkItemType } from '../../layouts/links';
2
+ import { type SidebarProps } from '../../layouts/docs/sidebar';
3
+ import type { PageTree } from 'fumadocs-core/server';
4
+ import { type TabOptions } from '../../utils/get-sidebar-tabs';
5
+ import type { FC, ReactNode } from 'react';
6
+ import type { Option } from '../../components/layout/root-toggle';
7
+ export interface SidebarOptions extends SidebarProps {
8
+ enabled: boolean;
9
+ component: ReactNode;
10
+ collapsible?: boolean;
11
+ components?: Partial<SidebarComponents>;
12
+ /**
13
+ * Root Toggle options
14
+ */
15
+ tabs?: Option[] | TabOptions | false;
16
+ banner?: ReactNode;
17
+ footer?: ReactNode;
18
+ /**
19
+ * Hide search trigger
20
+ *
21
+ * @defaultValue false
22
+ */
23
+ hideSearch?: boolean;
24
+ }
25
+ export interface SidebarComponents {
26
+ Item: FC<{
27
+ item: PageTree.Item;
28
+ }>;
29
+ Folder: FC<{
30
+ item: PageTree.Folder;
31
+ level: number;
32
+ }>;
33
+ Separator: FC<{
34
+ item: PageTree.Separator;
35
+ }>;
36
+ }
37
+ export declare function SidebarLinkItem({ item }: {
38
+ item: LinkItemType;
39
+ }): string | number | bigint | boolean | Iterable<ReactNode> | Promise<import("react").AwaitedReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
40
+ export declare function getSidebarTabsFromOptions(options: SidebarOptions['tabs'], tree: PageTree.Root): Option[] | undefined;
41
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/shared.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAE9D,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IAErB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAExC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,KAAK,CAAC;IAErC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;KAAE,CAAC,CAAC;IAClC,MAAM,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,SAAS,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,qKA+C/D;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI,wBASpB"}
@@ -0,0 +1,30 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { BaseLinkItem } from '../../layouts/links';
3
+ import { SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarItem, } from '../../layouts/docs/sidebar';
4
+ import { cn } from '../../utils/cn';
5
+ import { buttonVariants } from '../../components/ui/button';
6
+ import { getSidebarTabs } from '../../utils/get-sidebar-tabs';
7
+ export function SidebarLinkItem({ item }) {
8
+ if (item.type === 'menu')
9
+ return (_jsxs(SidebarFolder, { level: 1, children: [item.url ? (_jsxs(SidebarFolderLink, { href: item.url, children: [item.icon, item.text] })) : (_jsxs(SidebarFolderTrigger, { children: [item.icon, item.text] })), _jsx(SidebarFolderContent, { children: item.items.map((child, i) => (_jsx(SidebarLinkItem, { item: child }, i))) })] }));
10
+ if (item.type === 'button') {
11
+ return (_jsxs(BaseLinkItem, { item: item, className: cn(buttonVariants({
12
+ color: 'secondary',
13
+ className: 'gap-1.5 [&_svg]:size-4',
14
+ })), children: [item.icon, item.text] }));
15
+ }
16
+ if (item.type === 'custom')
17
+ return item.children;
18
+ return (_jsx(SidebarItem, { href: item.url, icon: item.icon, external: item.external, children: item.text }));
19
+ }
20
+ export function getSidebarTabsFromOptions(options, tree) {
21
+ if (Array.isArray(options)) {
22
+ return options;
23
+ }
24
+ else if (typeof options === 'object') {
25
+ return getSidebarTabs(tree, options);
26
+ }
27
+ else if (options !== false) {
28
+ return getSidebarTabs(tree);
29
+ }
30
+ }
@@ -2,6 +2,7 @@ import { type ButtonHTMLAttributes, type HTMLAttributes, type ReactNode } from '
2
2
  import { type LinkProps } from 'fumadocs-core/link';
3
3
  import { type ScrollAreaProps } from '@radix-ui/react-scroll-area';
4
4
  import type { CollapsibleContentProps, CollapsibleTriggerProps } from '@radix-ui/react-collapsible';
5
+ import type { SidebarComponents } from '../../layouts/docs/shared';
5
6
  export interface SidebarProps extends HTMLAttributes<HTMLElement> {
6
7
  /**
7
8
  * Open folders by default if their level is lower or equal to a specific level
@@ -37,4 +38,10 @@ export declare function SidebarFolderTrigger(props: CollapsibleTriggerProps): im
37
38
  export declare function SidebarFolderLink(props: LinkProps): import("react/jsx-runtime").JSX.Element;
38
39
  export declare function SidebarFolderContent(props: CollapsibleContentProps): import("react/jsx-runtime").JSX.Element;
39
40
  export declare function SidebarCollapseTrigger(props: ButtonHTMLAttributes<HTMLButtonElement>): import("react/jsx-runtime").JSX.Element;
41
+ /**
42
+ * Render sidebar items from page tree
43
+ */
44
+ export declare function SidebarPageTree(props: {
45
+ components?: Partial<SidebarComponents>;
46
+ }): ReactNode[];
40
47
  //# sourceMappingURL=sidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/sidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EAEnB,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAInE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA6BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,2CA4DrD;AAED,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;CAAE,2CAuC3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAYrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,2CAY3E;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAiBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,GAAG,KAAK,EACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,2CAkBA;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAelE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CA0CjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAQlE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAuB/C"}
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/sidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EAEnB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAInE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA6BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,2CAqDrD;AAED,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;CAAE,2CAuC3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAYrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,2CAY3E;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAiBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,GAAG,KAAK,EACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,2CAkBA;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAelE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAiCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAQlE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAwB/C;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,eA2CA"}
@@ -1,9 +1,9 @@
1
1
  'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ChevronDown, ExternalLink, SidebarIcon } from 'lucide-react';
4
4
  import * as Base from 'fumadocs-core/sidebar';
5
5
  import { usePathname } from 'next/navigation';
6
- import { createContext, useCallback, useContext, useLayoutEffect, useMemo, useRef, useState, } from 'react';
6
+ import { createContext, useCallback, useContext, useMemo, useRef, useState, } from 'react';
7
7
  import Link from 'fumadocs-core/link';
8
8
  import { useOnChange } from 'fumadocs-core/utils/use-on-change';
9
9
  import { cn } from '../../utils/cn';
@@ -13,6 +13,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../comp
13
13
  import { useSidebar } from '../../contexts/sidebar';
14
14
  import { buttonVariants } from '../../components/ui/button';
15
15
  import { cva } from 'class-variance-authority';
16
+ import { useTreeContext, useTreePath } from '../../contexts/tree';
16
17
  const itemVariants = cva('flex flex-row items-center gap-2 rounded-md px-3 py-2 text-fd-muted-foreground transition-colors duration-100 [overflow-wrap:anywhere] md:px-2 md:py-1.5 [&_svg]:size-4', {
17
18
  variants: {
18
19
  active: {
@@ -49,10 +50,10 @@ export function CollapsibleSidebar(props) {
49
50
  ? 0
50
51
  : 500);
51
52
  }, []);
52
- return (_jsxs(_Fragment, { children: [_jsx(SidebarCollapseTrigger, { className: cn('fixed bottom-3 start-2 z-20 transition-opacity max-md:hidden', (!collapsed || hover) && 'opacity-0') }), _jsx(Sidebar, { ...props, onPointerEnter: onEnter, onPointerLeave: onLeave, className: cn('transition-[flex,margin,opacity,transform]', collapsed &&
53
- 'md:-me-[var(--fd-sidebar-offset)] md:flex-initial md:translate-x-[calc(var(--fd-sidebar-offset)*-1)] rtl:md:translate-x-[var(--fd-sidebar-offset)]', collapsed && hover && 'md:translate-x-0', collapsed && !hover && 'md:z-10 md:opacity-0', props.className), style: {
54
- '--fd-sidebar-offset': 'calc(var(--fd-sidebar-width) - 30px)',
55
- } })] }));
53
+ return (_jsx(Sidebar, { ...props, onPointerEnter: onEnter, onPointerLeave: onLeave, "data-collapsed": collapsed, className: cn('transition-[flex,margin,opacity,transform]', collapsed &&
54
+ 'md:-me-[var(--fd-sidebar-width)] md:flex-initial md:translate-x-[calc(var(--fd-sidebar-offset)*-1)] rtl:md:translate-x-[var(--fd-sidebar-offset)]', collapsed && hover && 'z-50 md:translate-x-0', collapsed && !hover && 'md:opacity-0', props.className), style: {
55
+ '--fd-sidebar-offset': 'calc(var(--fd-sidebar-width) - 20px)',
56
+ } }));
56
57
  }
57
58
  export function Sidebar({ defaultOpenLevel = 0, prefetch = true, inner, ...props }) {
58
59
  const context = useMemo(() => {
@@ -64,7 +65,7 @@ export function Sidebar({ defaultOpenLevel = 0, prefetch = true, inner, ...props
64
65
  return (_jsx(Context.Provider, { value: context, children: _jsx(Base.SidebarList, { id: "nd-sidebar", blockScrollingWidth: 768, ...props, className: cn('fixed top-fd-layout-top z-30 bg-fd-card text-sm md:sticky md:h-[var(--fd-sidebar-height)] md:flex-1', 'max-md:inset-x-0 max-md:bottom-0 max-md:bg-fd-background/80 max-md:text-[15px] max-md:backdrop-blur-lg max-md:data-[open=false]:invisible', props.className), style: {
65
66
  ...props.style,
66
67
  '--fd-sidebar-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
67
- }, children: _jsx("div", { ...inner, className: cn('flex size-full flex-col pt-2 md:ms-auto md:w-[var(--fd-sidebar-width)] md:border-e md:pt-4', inner?.className), children: props.children }) }) }));
68
+ }, children: _jsx("div", { ...inner, className: cn('flex size-full max-w-full flex-col pt-2 md:ms-auto md:w-[var(--fd-sidebar-width)] md:border-e md:pt-4', inner?.className), children: props.children }) }) }));
68
69
  }
69
70
  export function SidebarHeader(props) {
70
71
  return (_jsx("div", { ...props, className: cn('flex flex-col gap-2 px-4 empty:hidden md:px-3', props.className), children: props.children }));
@@ -105,17 +106,9 @@ export function SidebarFolderLink(props) {
105
106
  const { prefetch } = useInternalContext();
106
107
  const pathname = usePathname();
107
108
  const active = props.href !== undefined && isActive(props.href, pathname, false);
108
- useLayoutEffect(() => {
109
- if (active) {
110
- setOpen(true);
111
- }
112
- }, [active, setOpen]);
113
109
  return (_jsxs(Link, { ...props, "data-active": active, className: cn(itemVariants({ active }), 'w-full pe-3.5 md:pe-1.5', props.className), onClick: (e) => {
114
- if (
115
- // clicking on icon
116
- e.target.hasAttribute('data-icon') ||
117
- active) {
118
- setOpen((prev) => !prev);
110
+ setOpen((prev) => !active || !prev);
111
+ if (e.target.hasAttribute('data-icon')) {
119
112
  e.preventDefault();
120
113
  }
121
114
  }, prefetch: prefetch, children: [props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
@@ -124,13 +117,13 @@ export function SidebarFolderContent(props) {
124
117
  return (_jsx(CollapsibleContent, { ...props, children: _jsx("div", { className: "ms-3 border-s py-1.5 ps-1.5 md:ms-2 md:ps-2", children: props.children }) }));
125
118
  }
126
119
  export function SidebarCollapseTrigger(props) {
127
- const { setCollapsed } = useSidebar();
128
- return (_jsx("button", { type: "button", "aria-label": "Collapse Sidebar", ...props, className: cn(buttonVariants({
120
+ const { collapsed, setCollapsed } = useSidebar();
121
+ return (_jsx("button", { type: "button", "aria-label": "Collapse Sidebar", "data-collapsed": collapsed, ...props, className: cn(buttonVariants({
129
122
  color: 'ghost',
130
123
  size: 'icon',
131
124
  }), props.className), onClick: () => {
132
125
  setCollapsed((prev) => !prev);
133
- }, children: _jsx(SidebarIcon, {}) }));
126
+ }, children: props.children ?? _jsx(SidebarIcon, {}) }));
134
127
  }
135
128
  function useFolderContext() {
136
129
  const ctx = useContext(FolderContext);
@@ -144,3 +137,36 @@ function useInternalContext() {
144
137
  throw new Error('<Sidebar /> component required.');
145
138
  return ctx;
146
139
  }
140
+ /**
141
+ * Render sidebar items from page tree
142
+ */
143
+ export function SidebarPageTree(props) {
144
+ const { root } = useTreeContext();
145
+ return useMemo(() => {
146
+ function renderSidebarList(items, level) {
147
+ const { Separator, Item, Folder } = props.components ?? {};
148
+ return items.map((item, i) => {
149
+ const id = `${item.type}_${i.toString()}`;
150
+ switch (item.type) {
151
+ case 'separator':
152
+ if (Separator)
153
+ return _jsx(Separator, { item: item }, id);
154
+ return _jsx(SidebarSeparator, { children: item.name }, id);
155
+ case 'folder':
156
+ if (Folder)
157
+ return _jsx(Folder, { item: item, level: level + 1 }, id);
158
+ return (_jsx(PageTreeFolder, { item: item, level: level + 1, children: renderSidebarList(item.children, level + 1) }, id));
159
+ default:
160
+ if (Item)
161
+ return _jsx(Item, { item: item }, item.url);
162
+ return (_jsx(SidebarItem, { href: item.url, external: item.external, icon: item.icon, children: item.name }, item.url));
163
+ }
164
+ });
165
+ }
166
+ return renderSidebarList(root.children, 1);
167
+ }, [root, props.components]);
168
+ }
169
+ function PageTreeFolder({ item, children, level, }) {
170
+ const path = useTreePath();
171
+ return (_jsxs(SidebarFolder, { defaultOpen: item.defaultOpen || path.includes(item), level: level + 1, children: [item.index ? (_jsxs(SidebarFolderLink, { href: item.index.url, external: item.index.external, children: [item.icon, item.name] })) : (_jsxs(SidebarFolderTrigger, { children: [item.icon, item.name] })), _jsx(SidebarFolderContent, { children: children })] }));
172
+ }