fumadocs-ui 15.4.2 → 15.5.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 (76) hide show
  1. package/css/preset.css +12 -0
  2. package/dist/components/accordion.d.ts +4 -2
  3. package/dist/components/accordion.d.ts.map +1 -1
  4. package/dist/components/accordion.js +18 -10
  5. package/dist/components/dialog/search-algolia.d.ts +3 -2
  6. package/dist/components/dialog/search-algolia.d.ts.map +1 -1
  7. package/dist/components/dialog/search-algolia.js +17 -6
  8. package/dist/components/dialog/search-default.d.ts +3 -2
  9. package/dist/components/dialog/search-default.d.ts.map +1 -1
  10. package/dist/components/dialog/search-default.js +18 -6
  11. package/dist/components/dialog/search-orama.d.ts +3 -2
  12. package/dist/components/dialog/search-orama.d.ts.map +1 -1
  13. package/dist/components/dialog/search-orama.js +17 -6
  14. package/dist/components/dialog/search.d.ts +46 -19
  15. package/dist/components/dialog/search.d.ts.map +1 -1
  16. package/dist/components/dialog/search.js +93 -42
  17. package/dist/components/layout/sidebar.d.ts.map +1 -1
  18. package/dist/components/layout/sidebar.js +7 -5
  19. package/dist/components/layout/toc-clerk.d.ts +2 -4
  20. package/dist/components/layout/toc-clerk.d.ts.map +1 -1
  21. package/dist/components/layout/toc-clerk.js +8 -4
  22. package/dist/components/layout/toc.d.ts +6 -18
  23. package/dist/components/layout/toc.d.ts.map +1 -1
  24. package/dist/components/layout/toc.js +14 -16
  25. package/dist/components/tabs.d.ts +7 -7
  26. package/dist/components/tabs.d.ts.map +1 -1
  27. package/dist/components/tabs.js +7 -4
  28. package/dist/components/ui/button.d.ts +1 -1
  29. package/dist/components/ui/button.d.ts.map +1 -1
  30. package/dist/components/ui/button.js +2 -1
  31. package/dist/contexts/search.d.ts +10 -2
  32. package/dist/contexts/search.d.ts.map +1 -1
  33. package/dist/contexts/search.js +3 -1
  34. package/dist/layouts/docs/page-client.d.ts +30 -0
  35. package/dist/layouts/docs/page-client.d.ts.map +1 -0
  36. package/dist/{page-client.js → layouts/docs/page-client.js} +56 -40
  37. package/dist/layouts/docs/page.d.ts +16 -0
  38. package/dist/layouts/docs/page.d.ts.map +1 -0
  39. package/dist/layouts/docs/page.js +26 -0
  40. package/dist/layouts/docs/shared.d.ts +0 -3
  41. package/dist/layouts/docs/shared.d.ts.map +1 -1
  42. package/dist/layouts/docs/shared.js +0 -3
  43. package/dist/layouts/docs-client.d.ts +1 -0
  44. package/dist/layouts/docs-client.d.ts.map +1 -1
  45. package/dist/layouts/docs-client.js +10 -2
  46. package/dist/layouts/docs.d.ts +2 -11
  47. package/dist/layouts/docs.d.ts.map +1 -1
  48. package/dist/layouts/docs.js +20 -25
  49. package/dist/layouts/home/navbar.d.ts.map +1 -1
  50. package/dist/layouts/home/navbar.js +1 -5
  51. package/dist/layouts/home.d.ts +1 -2
  52. package/dist/layouts/home.d.ts.map +1 -1
  53. package/dist/layouts/home.js +8 -6
  54. package/dist/layouts/notebook-client.d.ts +5 -4
  55. package/dist/layouts/notebook-client.d.ts.map +1 -1
  56. package/dist/layouts/notebook-client.js +12 -6
  57. package/dist/layouts/notebook.d.ts.map +1 -1
  58. package/dist/layouts/notebook.js +18 -22
  59. package/dist/layouts/shared.d.ts +0 -9
  60. package/dist/layouts/shared.d.ts.map +1 -1
  61. package/dist/layouts/shared.js +0 -22
  62. package/dist/page.d.ts +25 -18
  63. package/dist/page.d.ts.map +1 -1
  64. package/dist/page.js +12 -18
  65. package/dist/provider/base.d.ts +1 -1
  66. package/dist/provider/base.d.ts.map +1 -1
  67. package/dist/style.css +47 -95
  68. package/dist/utils/merge-refs.d.ts +3 -0
  69. package/dist/utils/merge-refs.d.ts.map +1 -0
  70. package/dist/utils/merge-refs.js +12 -0
  71. package/package.json +8 -8
  72. package/dist/components/ui/hide-if-empty.d.ts +0 -10
  73. package/dist/components/ui/hide-if-empty.d.ts.map +0 -1
  74. package/dist/components/ui/hide-if-empty.js +0 -66
  75. package/dist/page-client.d.ts +0 -28
  76. package/dist/page-client.d.ts.map +0 -1
@@ -47,20 +47,22 @@ export function Sidebar({ defaultOpenLevel = 0, prefetch = true, collapsible = t
47
47
  const state = open ? 'open' : 'closed';
48
48
  return (_jsxs(Context.Provider, { value: context, children: [_jsx(Presence, { present: open, children: _jsx("div", { "data-state": state, className: "fixed z-40 inset-0 bg-black/30 backdrop-blur-sm data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out", onClick: () => setOpen(false) }) }), _jsx(Presence, { present: open, children: ({ present }) => (_jsx(RemoveScroll, { as: "aside", enabled: present, id: "nd-sidebar-mobile", ...props, "data-state": state, className: cn('fixed text-[15px] flex flex-col py-2 rounded-e-2xl border-e start-0 inset-y-0 w-[85%] max-w-[380px] z-40 bg-fd-background data-[state=open]:animate-fd-sidebar-in data-[state=closed]:animate-fd-sidebar-out', !present && 'invisible', props.className), children: props.children })) })] }));
49
49
  }
50
- return (_jsx("aside", { id: "nd-sidebar", ...props, "data-collapsed": collapsed, className: cn('sticky shrink-0 flex flex-col items-end top-(--fd-sidebar-top) z-20 bg-fd-card text-sm h-(--fd-sidebar-height) w-(--fd-sidebar-width) *:w-(--fd-sidebar-width) border-e max-md:hidden', collapsed && [
50
+ return (_jsx("aside", { id: "nd-sidebar", ...props, "data-collapsed": collapsed, className: cn('fixed start-0 flex flex-col items-end top-(--fd-sidebar-top) bottom-(--fd-sidebar-margin) z-20 bg-fd-card text-sm border-e max-md:hidden *:w-(--fd-sidebar-width)', collapsed && [
51
51
  'rounded-xl border',
52
52
  hover
53
53
  ? 'z-50 translate-x-2 shadow-lg'
54
54
  : 'opacity-0 -translate-x-(--fd-sidebar-offset) rtl:translate-x-(--fd-sidebar-offset)',
55
55
  ], props.className), style: {
56
- transition: ['top', 'opacity', 'margin', 'translate', 'width']
57
- .map((v) => `${v} ease 200ms`)
56
+ transition: ['top', 'opacity', 'translate', 'width']
57
+ .map((v) => `${v} ease 250ms`)
58
58
  .join(', '),
59
+ ...props.style,
59
60
  '--fd-sidebar-offset': 'calc(100% - 16px)',
60
61
  '--fd-sidebar-margin': collapsed ? '0.5rem' : '0px',
62
+ width: collapsed
63
+ ? 'var(--fd-sidebar-width)'
64
+ : 'calc(var(--fd-sidebar-width) + var(--fd-layout-offset))',
61
65
  '--fd-sidebar-top': `calc(var(--fd-banner-height) + var(--fd-nav-height) + var(--fd-sidebar-margin))`,
62
- '--fd-sidebar-height': 'calc(100dvh - var(--fd-sidebar-top) - var(--fd-sidebar-margin))',
63
- ...props.style,
64
66
  }, onPointerEnter: (e) => {
65
67
  if (!collapsible ||
66
68
  !collapsed ||
@@ -1,5 +1,3 @@
1
- import type { TOCItemType } from 'fumadocs-core/server';
2
- export default function ClerkTOCItems({ items }: {
3
- items: TOCItemType[];
4
- }): import("react/jsx-runtime").JSX.Element;
1
+ import { type ComponentProps } from 'react';
2
+ export default function ClerkTOCItems({ ref, className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
5
3
  //# 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;AAOxD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,2CA2FxE"}
1
+ {"version":3,"file":"toc-clerk.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-clerk.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAA+B,MAAM,OAAO,CAAC;AAOzE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,2CAsGvB"}
@@ -4,9 +4,13 @@ import * as Primitive from 'fumadocs-core/toc';
4
4
  import { useEffect, useRef, useState } from 'react';
5
5
  import { cn } from '../../utils/cn.js';
6
6
  import { TocThumb } from '../../components/layout/toc-thumb.js';
7
- import { TocItemsEmpty } from '../../components/layout/toc.js';
8
- export default function ClerkTOCItems({ items }) {
7
+ import { useTOCItems } from '../../components/layout/toc.js';
8
+ import { mergeRefs } from '../../utils/merge-refs.js';
9
+ import { useI18n } from '../../contexts/i18n.js';
10
+ export default function ClerkTOCItems({ ref, className, ...props }) {
9
11
  const containerRef = useRef(null);
12
+ const items = useTOCItems();
13
+ const { text } = useI18n();
10
14
  const [svg, setSvg] = useState();
11
15
  useEffect(() => {
12
16
  if (!containerRef.current)
@@ -44,14 +48,14 @@ export default function ClerkTOCItems({ items }) {
44
48
  };
45
49
  }, [items]);
46
50
  if (items.length === 0)
47
- return _jsx(TocItemsEmpty, {});
51
+ return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
48
52
  return (_jsxs(_Fragment, { children: [svg ? (_jsx("div", { className: "absolute start-0 top-0 rtl:-scale-x-100", style: {
49
53
  width: svg.width,
50
54
  height: svg.height,
51
55
  maskImage: `url("data:image/svg+xml,${
52
56
  // Inline SVG
53
57
  encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${svg.width} ${svg.height}"><path d="${svg.path}" stroke="black" stroke-width="1" fill="none" /></svg>`)}")`,
54
- }, children: _jsx(TocThumb, { containerRef: containerRef, className: "mt-(--fd-top) h-(--fd-height) bg-fd-primary transition-all" }) })) : null, _jsx("div", { className: "flex flex-col", ref: containerRef, children: items.map((item, i) => (_jsx(TOCItem, { item: item, upper: items[i - 1]?.depth, lower: items[i + 1]?.depth }, item.url))) })] }));
58
+ }, children: _jsx(TocThumb, { containerRef: containerRef, className: "mt-(--fd-top) h-(--fd-height) bg-fd-primary transition-all" }) })) : null, _jsx("div", { ref: mergeRefs(containerRef, ref), className: cn('flex flex-col', className), ...props, children: items.map((item, i) => (_jsx(TOCItem, { item: item, upper: items[i - 1]?.depth, lower: items[i + 1]?.depth }, item.url))) })] }));
55
59
  }
56
60
  function getItemOffset(depth) {
57
61
  if (depth <= 2)
@@ -1,20 +1,8 @@
1
1
  import type { TOCItemType } from 'fumadocs-core/server';
2
- import { type ComponentProps, type HTMLAttributes, type ReactNode } from 'react';
3
- export interface TOCProps {
4
- /**
5
- * Custom content in TOC container, before the main TOC
6
- */
7
- header?: ReactNode;
8
- /**
9
- * Custom content in TOC container, after the main TOC
10
- */
11
- footer?: ReactNode;
12
- children: ReactNode;
13
- }
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;
16
- export declare function TOCScrollArea(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
17
- export declare function TOCItems({ items }: {
18
- items: TOCItemType[];
19
- }): import("react/jsx-runtime").JSX.Element;
2
+ import * as Primitive from 'fumadocs-core/toc';
3
+ import { type ComponentProps } from 'react';
4
+ export declare function useTOCItems(): TOCItemType[];
5
+ export declare function TOCProvider({ toc, children, ...props }: ComponentProps<typeof Primitive.AnchorProvider>): import("react/jsx-runtime").JSX.Element;
6
+ export declare function TOCScrollArea({ ref, className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
7
+ export declare function TOCItems({ ref, className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
20
8
  //# sourceMappingURL=toc.d.ts.map
@@ -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,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAMf,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,2CAyBxD;AAED,wBAAgB,aAAa,4CAQ5B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAiBzD;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,2CAqB3D"}
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;AACxD,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,cAAc,EAAqC,MAAM,OAAO,CAAC;AAQ/E,wBAAgB,WAAW,IAAI,WAAW,EAAE,CAE3C;AAED,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,2CAQjD;AAED,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,2CAiBvB;AAED,wBAAgB,QAAQ,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,2CAgC3E"}
@@ -1,31 +1,29 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as Primitive from 'fumadocs-core/toc';
4
- import { useRef, } from 'react';
4
+ import { createContext, useContext, useRef } from 'react';
5
5
  import { cn } from '../../utils/cn.js';
6
6
  import { useI18n } from '../../contexts/i18n.js';
7
7
  import { TocThumb } from '../../components/layout/toc-thumb.js';
8
- import { usePageStyles } from '../../contexts/layout.js';
9
- export function Toc(props) {
10
- const { toc } = usePageStyles();
11
- return (_jsx("div", { id: "nd-toc", ...props, className: cn('sticky top-[calc(var(--fd-banner-height)+var(--fd-nav-height))] h-(--fd-toc-height) pb-2 pt-12', toc, props.className), style: {
12
- ...props.style,
13
- '--fd-toc-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
14
- }, children: _jsx("div", { className: "flex h-full w-(--fd-toc-width) max-w-full flex-col pe-4", children: props.children }) }));
8
+ import { mergeRefs } from '../../utils/merge-refs.js';
9
+ const TOCContext = createContext([]);
10
+ export function useTOCItems() {
11
+ return useContext(TOCContext);
15
12
  }
16
- export function TocItemsEmpty() {
17
- const { text } = useI18n();
18
- return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
13
+ export function TOCProvider({ toc, children, ...props }) {
14
+ return (_jsx(TOCContext, { value: toc, children: _jsx(Primitive.AnchorProvider, { toc: toc, ...props, children: children }) }));
19
15
  }
20
- export function TOCScrollArea(props) {
16
+ export function TOCScrollArea({ ref, className, ...props }) {
21
17
  const viewRef = useRef(null);
22
- return (_jsx("div", { ...props, ref: viewRef, className: cn('relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3', props.className), children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: props.children }) }));
18
+ return (_jsx("div", { ref: mergeRefs(viewRef, ref), className: cn('relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3', className), ...props, children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: props.children }) }));
23
19
  }
24
- export function TOCItems({ items }) {
20
+ export function TOCItems({ ref, className, ...props }) {
25
21
  const containerRef = useRef(null);
22
+ const items = useTOCItems();
23
+ const { text } = useI18n();
26
24
  if (items.length === 0)
27
- return _jsx(TocItemsEmpty, {});
28
- return (_jsxs(_Fragment, { children: [_jsx(TocThumb, { containerRef: containerRef, className: "absolute top-(--fd-top) h-(--fd-height) w-px bg-fd-primary transition-all" }), _jsx("div", { ref: containerRef, className: "flex flex-col border-s border-fd-foreground/10", children: items.map((item) => (_jsx(TOCItem, { item: item }, item.url))) })] }));
25
+ return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
26
+ return (_jsxs(_Fragment, { children: [_jsx(TocThumb, { containerRef: containerRef, className: "absolute top-(--fd-top) h-(--fd-height) w-px bg-fd-primary transition-all" }), _jsx("div", { ref: mergeRefs(ref, containerRef), className: cn('flex flex-col border-s border-fd-foreground/10', className), ...props, children: items.map((item) => (_jsx(TOCItem, { item: item }, item.url))) })] }));
29
27
  }
30
28
  function TOCItem({ item }) {
31
29
  return (_jsx(Primitive.TOCItem, { href: item.url, className: cn('prose 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', item.depth <= 2 && 'ps-3', item.depth === 3 && 'ps-6', item.depth >= 4 && 'ps-8'), children: item.title }));
@@ -1,6 +1,6 @@
1
- import type { TabsContentProps, TabsProps as BaseProps } from '@radix-ui/react-tabs';
2
- import { type ReactNode } from 'react';
3
- export interface TabsProps extends BaseProps {
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ import * as Primitive from './ui/tabs.js';
3
+ export interface TabsProps extends ComponentProps<typeof Primitive.Tabs> {
4
4
  /**
5
5
  * Identifier for Sharing value of tabs
6
6
  */
@@ -30,13 +30,13 @@ export interface TabsProps extends BaseProps {
30
30
  }
31
31
  export declare const TabsList: import("react").ForwardRefExoticComponent<Omit<import("@radix-ui/react-tabs").TabsListProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
32
32
  export declare const TabsTrigger: import("react").ForwardRefExoticComponent<Omit<import("@radix-ui/react-tabs").TabsTriggerProps & import("react").RefAttributes<HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
33
- export declare function Tabs({ groupId, items, persist, label, defaultIndex, updateAnchor, defaultValue, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
34
- export type TabProps = Omit<TabsContentProps, 'value'> & {
33
+ export declare function Tabs({ ref, className, groupId, items, persist, label, defaultIndex, updateAnchor, defaultValue, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
34
+ export interface TabProps extends Omit<ComponentProps<typeof Primitive.TabsContent>, 'value'> {
35
35
  /**
36
36
  * Value of tab, detect from index if unspecified.
37
37
  */
38
38
  value?: string;
39
- };
39
+ }
40
40
  export declare function Tab({ value, ...props }: TabProps): import("react/jsx-runtime").JSX.Element;
41
- export declare function TabsContent({ value, className, ...props }: TabsContentProps): import("react/jsx-runtime").JSX.Element;
41
+ export declare function TabsContent({ value, className, ...props }: ComponentProps<typeof Primitive.TabsContent>): import("react/jsx-runtime").JSX.Element;
42
42
  //# sourceMappingURL=tabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/components/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,IAAI,SAAS,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AAuBf,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAcD,eAAO,MAAM,QAAQ,sMAAqB,CAAC;AAC3C,eAAO,MAAM,WAAW,+MAAwB,CAAC;AAEjD,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,KAAK,EACL,OAAe,EACf,KAAK,EACL,YAAgB,EAChB,YAAoB,EACpB,YAAmE,EACnE,GAAG,KAAK,EACT,EAAE,SAAS,2CAmFX;AAED,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IACvD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CAgBhD;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,2CAoB3E"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/components/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAQf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAsBvC,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,OAAO,SAAS,CAAC,IAAI,CAAC;IACtE;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAcD,eAAO,MAAM,QAAQ,sMAAqB,CAAC;AAC3C,eAAO,MAAM,WAAW,+MAAwB,CAAC;AAEjD,wBAAgB,IAAI,CAAC,EACnB,GAAG,EACH,SAAS,EACT,OAAO,EACP,KAAK,EACL,OAAe,EACf,KAAK,EACL,YAAgB,EAChB,YAAoB,EACpB,YAAmE,EACnE,GAAG,KAAK,EACT,EAAE,SAAS,2CAsFX;AAED,MAAM,WAAW,QACf,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IACnE;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CAgBhD;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,WAAW,CAAC,2CAoB9C"}
@@ -1,9 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useState, } from 'react';
3
+ import { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, } from 'react';
4
4
  import { cn } from '../utils/cn.js';
5
5
  import * as Primitive from './ui/tabs.js';
6
6
  import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
7
+ import { mergeRefs } from '../utils/merge-refs.js';
7
8
  const listeners = new Map();
8
9
  function addChangeListener(id, listener) {
9
10
  const list = listeners.get(id) ?? [];
@@ -23,7 +24,8 @@ function useTabContext() {
23
24
  }
24
25
  export const TabsList = Primitive.TabsList;
25
26
  export const TabsTrigger = Primitive.TabsTrigger;
26
- export function Tabs({ groupId, items, persist = false, label, defaultIndex = 0, updateAnchor = false, defaultValue = items ? escapeValue(items[defaultIndex]) : undefined, ...props }) {
27
+ export function Tabs({ ref, className, groupId, items, persist = false, label, defaultIndex = 0, updateAnchor = false, defaultValue = items ? escapeValue(items[defaultIndex]) : undefined, ...props }) {
28
+ const tabsRef = useRef(null);
27
29
  const [value, setValue] = useState(defaultValue);
28
30
  const valueToIdMap = useMemo(() => new Map(), []);
29
31
  const collection = useMemo(() => [], []);
@@ -52,11 +54,12 @@ export function Tabs({ groupId, items, persist = false, label, defaultIndex = 0,
52
54
  for (const [value, id] of valueToIdMap.entries()) {
53
55
  if (id === hash) {
54
56
  setValue(value);
57
+ tabsRef.current?.scrollIntoView();
55
58
  break;
56
59
  }
57
60
  }
58
61
  }, [valueToIdMap]);
59
- return (_jsxs(Primitive.Tabs, { value: value, onValueChange: (v) => {
62
+ return (_jsxs(Primitive.Tabs, { ref: mergeRefs(ref, tabsRef), value: value, onValueChange: (v) => {
60
63
  if (updateAnchor) {
61
64
  const id = valueToIdMap.get(v);
62
65
  if (id) {
@@ -75,7 +78,7 @@ export function Tabs({ groupId, items, persist = false, label, defaultIndex = 0,
75
78
  else {
76
79
  setValue(v);
77
80
  }
78
- }, ...props, className: cn('my-4', props.className), children: [items && (_jsxs(TabsList, { children: [label && (_jsx("span", { className: "text-sm font-medium my-auto me-auto", children: label })), items.map((item) => (_jsx(TabsTrigger, { value: escapeValue(item), children: item }, item)))] })), _jsx(TabsContext.Provider, { value: useMemo(() => ({ items, valueToIdMap, collection }), [valueToIdMap, collection, items]), children: props.children })] }));
81
+ }, className: cn('my-4', className), ...props, children: [items && (_jsxs(TabsList, { children: [label && (_jsx("span", { className: "text-sm font-medium my-auto me-auto", children: label })), items.map((item) => (_jsx(TabsTrigger, { value: escapeValue(item), children: item }, item)))] })), _jsx(TabsContext.Provider, { value: useMemo(() => ({ items, valueToIdMap, collection }), [valueToIdMap, collection, items]), children: props.children })] }));
79
82
  }
80
83
  export function Tab({ value, ...props }) {
81
84
  const { items } = useTabContext();
@@ -1,7 +1,7 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  export declare const buttonVariants: (props?: ({
3
3
  color?: "primary" | "outline" | "ghost" | "secondary" | null | undefined;
4
- size?: "sm" | "icon" | "icon-sm" | null | undefined;
4
+ size?: "sm" | "icon" | "icon-sm" | "icon-xs" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
6
  export type ButtonProps = VariantProps<typeof buttonVariants>;
7
7
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,cAAc;;;8EAmB1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,cAAc;;;8EAoB1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { cva } from 'class-variance-authority';
2
- export const buttonVariants = cva('inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50', {
2
+ export const buttonVariants = cva('inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none', {
3
3
  variants: {
4
4
  color: {
5
5
  primary: 'bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80',
@@ -11,6 +11,7 @@ export const buttonVariants = cva('inline-flex items-center justify-center round
11
11
  sm: 'gap-1 px-2 py-1.5 text-xs',
12
12
  icon: 'p-1.5 [&_svg]:size-5',
13
13
  'icon-sm': 'p-1.5 [&_svg]:size-4.5',
14
+ 'icon-xs': 'p-1 [&_svg]:size-4',
14
15
  },
15
16
  },
16
17
  });
@@ -1,5 +1,4 @@
1
1
  import { type ComponentType, type ReactNode } from 'react';
2
- import type { SearchLink, SharedProps } from '../components/dialog/search.js';
3
2
  interface HotKey {
4
3
  display: ReactNode;
5
4
  /**
@@ -7,6 +6,15 @@ interface HotKey {
7
6
  */
8
7
  key: string | ((e: KeyboardEvent) => boolean);
9
8
  }
9
+ export interface SharedProps {
10
+ open: boolean;
11
+ onOpenChange: (open: boolean) => void;
12
+ }
13
+ export type SearchLink = [name: string, href: string];
14
+ export interface TagItem {
15
+ name: string;
16
+ value: string;
17
+ }
10
18
  export interface SearchProviderProps {
11
19
  /**
12
20
  * Preload search dialog before opening it
@@ -33,7 +41,7 @@ export interface SearchProviderProps {
33
41
  /**
34
42
  * Additional props to the dialog
35
43
  */
36
- options?: Partial<SharedProps>;
44
+ options?: Partial<SharedProps & Record<string, unknown>>;
37
45
  children?: ReactNode;
38
46
  }
39
47
  interface SearchContextType {
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/contexts/search.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAG1E,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"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/contexts/search.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAGf,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,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEtD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;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,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAEzD,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,2CAwCrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,aAI/D"}
@@ -42,7 +42,9 @@ export function SearchProvider({ SearchDialog, children, preload = true, options
42
42
  window.removeEventListener('keydown', handler);
43
43
  };
44
44
  }, [hotKey]);
45
- 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
+ return (_jsxs(SearchContext.Provider, { value: useMemo(() => ({ enabled: true, hotKey, setOpenSearch: setIsOpen }), [hotKey]), children: [isOpen !== undefined && (_jsx(SearchDialog, { open: isOpen, onOpenChange: setIsOpen,
46
+ // @ts-expect-error -- insert prop for official UIs
47
+ links: links, ...options })), children] }));
46
48
  }
47
49
  /**
48
50
  * Show children only when search is enabled via React Context
@@ -0,0 +1,30 @@
1
+ import { type ComponentProps } from 'react';
2
+ import type { PageTree } from 'fumadocs-core/server';
3
+ import { type BreadcrumbOptions } from 'fumadocs-core/breadcrumb';
4
+ import { type AnchorProviderProps } from 'fumadocs-core/toc';
5
+ export declare function PageTOCPopoverTrigger(props: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
6
+ export declare function PageTOCPopoverContent(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
7
+ export declare function PageTOCPopover(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
8
+ export interface RootProps extends ComponentProps<'div'> {
9
+ toc: Omit<AnchorProviderProps, 'children'>;
10
+ }
11
+ export declare function PageRoot({ toc, children, ...props }: RootProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function PageLastUpdate({ date: value, ...props }: Omit<ComponentProps<'p'>, 'children'> & {
13
+ date: Date | string;
14
+ }): import("react/jsx-runtime").JSX.Element;
15
+ type Item = Pick<PageTree.Item, 'name' | 'description' | 'url'>;
16
+ export interface FooterProps extends ComponentProps<'div'> {
17
+ /**
18
+ * Items including information for the next and previous page
19
+ */
20
+ items?: {
21
+ previous?: Item;
22
+ next?: Item;
23
+ };
24
+ }
25
+ export declare function PageFooter({ items, ...props }: FooterProps): import("react/jsx-runtime").JSX.Element;
26
+ export type BreadcrumbProps = BreadcrumbOptions & ComponentProps<'div'>;
27
+ export declare function PageBreadcrumb({ includeRoot, includeSeparator, includePage, ...props }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element | null;
28
+ export declare function PageTOC(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
29
+ export {};
30
+ //# sourceMappingURL=page-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-client.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/page-client.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAMpB,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAWlC,OAAO,EAAE,KAAK,mBAAmB,EAAmB,MAAM,mBAAmB,CAAC;AAO9E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAiDpE;AA4DD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAUjE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAuD1D;AAED,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,KAAK,CAAC;IACtD,GAAG,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;CAC5C;AAED,wBAAgB,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,2CAqB9D;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EAAE,KAAK,EACX,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG;IAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,2CAiBjE;AAED,KAAK,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,KAAK,CAAC,CAAC;AAChE,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,KAAK,CAAC;IACxD;;OAEG;IACH,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,IAAI,CAAC,EAAE,IAAI,CAAC;KACb,CAAC;CACH;AAyBD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,2CAiC1D;AA8BD,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AAExE,wBAAgB,cAAc,CAAC,EAC7B,WAAmB,EACnB,gBAAgB,EAChB,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,eAAe,kDA6CjB;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAiBnD"}
@@ -1,27 +1,30 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Fragment, useEffect, useMemo, useRef, useState, } from 'react';
4
- import { ChevronDown, ChevronLeft, ChevronRight } from './icons.js';
4
+ import { ChevronDown, ChevronLeft, ChevronRight } from '../../icons.js';
5
5
  import Link from 'fumadocs-core/link';
6
- import { cn } from './utils/cn.js';
7
- import { useI18n } from './contexts/i18n.js';
8
- import { useTreeContext, useTreePath } from './contexts/tree.js';
6
+ import { cn } from '../../utils/cn.js';
7
+ import { useI18n } from '../../contexts/i18n.js';
8
+ import { useTreeContext, useTreePath } from '../../contexts/tree.js';
9
9
  import { createContext, usePathname } from 'fumadocs-core/framework';
10
10
  import { getBreadcrumbItemsFromPath, } from 'fumadocs-core/breadcrumb';
11
- import { useNav, usePageStyles } from './contexts/layout.js';
12
- import { isActive } from './utils/is-active.js';
11
+ import { useNav } from '../../contexts/layout.js';
12
+ import { isActive } from '../../utils/is-active.js';
13
13
  import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
14
- import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from './components/ui/collapsible.js';
15
- import * as Primitive from 'fumadocs-core/toc';
14
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../components/ui/collapsible.js';
15
+ import { useSidebar } from '../../contexts/sidebar.js';
16
+ import { TOCProvider, useTOCItems } from '../../components/layout/toc.js';
17
+ import { useActiveAnchor } from 'fumadocs-core/toc';
16
18
  const TocPopoverContext = createContext('TocPopoverContext');
17
- export function TocPopoverTrigger({ items, ...props }) {
19
+ export function PageTOCPopoverTrigger(props) {
18
20
  const { text } = useI18n();
19
21
  const { open } = TocPopoverContext.use();
20
- const active = Primitive.useActiveAnchor();
22
+ const items = useTOCItems();
23
+ const active = useActiveAnchor();
21
24
  const selected = useMemo(() => items.findIndex((item) => active === item.url.slice(1)), [items, active]);
22
25
  const path = useTreePath().at(-1);
23
26
  const showItem = selected !== -1 && !open;
24
- return (_jsxs(CollapsibleTrigger, { ...props, className: cn('flex flex-row items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:shrink-0 [&_svg]:size-4 md:px-6', props.className), children: [_jsx(ProgressCircle, { value: (selected + 1) / items.length, max: 1, className: cn(open && 'text-fd-primary') }), _jsxs("span", { className: "grid flex-1 *:my-auto *:row-start-1 *:col-start-1", children: [_jsx("span", { className: cn('truncate transition-all', open && 'text-fd-foreground', showItem && 'opacity-0 -translate-y-full pointer-events-none'), children: path?.name ?? text.toc }), _jsx("span", { className: cn('truncate transition-all', !showItem && 'opacity-0 translate-y-full pointer-events-none'), children: items[selected]?.title })] }), _jsx(ChevronDown, { className: cn('transition-transform mx-0.5', open && 'rotate-180') })] }));
27
+ return (_jsxs(CollapsibleTrigger, { ...props, className: cn('flex w-full h-(--fd-tocnav-height) items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:shrink-0 [&_svg]:size-4 md:px-6', props.className), children: [_jsx(ProgressCircle, { value: (selected + 1) / Math.max(1, items.length), max: 1, className: cn(open && 'text-fd-primary') }), _jsxs("span", { className: "grid flex-1 *:my-auto *:row-start-1 *:col-start-1", children: [_jsx("span", { className: cn('truncate transition-all', open && 'text-fd-foreground', showItem && 'opacity-0 -translate-y-full pointer-events-none'), children: path?.name ?? text.toc }), _jsx("span", { className: cn('truncate transition-all', !showItem && 'opacity-0 translate-y-full pointer-events-none'), children: items[selected]?.title })] }), _jsx(ChevronDown, { className: cn('transition-transform mx-0.5', open && 'rotate-180') })] }));
25
28
  }
26
29
  function clamp(input, min, max) {
27
30
  if (input < min)
@@ -44,13 +47,13 @@ function ProgressCircle({ value, strokeWidth = 2, size = 24, min = 0, max = 100,
44
47
  };
45
48
  return (_jsxs("svg", { role: "progressbar", viewBox: `0 0 ${size} ${size}`, "aria-valuenow": normalizedValue, "aria-valuemin": min, "aria-valuemax": max, ...restSvgProps, children: [_jsx("circle", { ...circleProps, className: "stroke-current/25" }), _jsx("circle", { ...circleProps, stroke: "currentColor", strokeDasharray: circumference, strokeDashoffset: circumference - progress, strokeLinecap: "round", transform: `rotate(-90 ${size / 2} ${size / 2})`, className: "transition-all" })] }));
46
49
  }
47
- export function TocPopoverContent(props) {
48
- return (_jsx(CollapsibleContent, { "data-toc-popover": "", ...props, className: cn('flex flex-col max-h-[50vh]', props.className), children: props.children }));
50
+ export function PageTOCPopoverContent(props) {
51
+ return (_jsx(CollapsibleContent, { "data-toc-popover": "", ...props, className: cn('flex flex-col px-4 max-h-[50vh] md:px-6', props.className), children: props.children }));
49
52
  }
50
- export function TocPopover(props) {
53
+ export function PageTOCPopover(props) {
51
54
  const ref = useRef(null);
52
55
  const [open, setOpen] = useState(false);
53
- const { tocNav } = usePageStyles();
56
+ const { collapsed } = useSidebar();
54
57
  const { isTransparent } = useNav();
55
58
  const onClick = useEffectEvent((e) => {
56
59
  if (!open)
@@ -64,30 +67,35 @@ export function TocPopover(props) {
64
67
  window.removeEventListener('click', onClick);
65
68
  };
66
69
  }, [onClick]);
67
- return (_jsx("div", { ...props, className: cn('sticky overflow-visible z-10', tocNav, props.className), style: {
68
- ...props.style,
69
- top: 'calc(var(--fd-banner-height) + var(--fd-nav-height))',
70
- }, children: _jsx(TocPopoverContext.Provider, { value: useMemo(() => ({
71
- open,
72
- setOpen,
73
- }), [setOpen, open]), children: _jsx(Collapsible, { open: open, onOpenChange: setOpen, asChild: true, children: _jsx("header", { ref: ref, id: "nd-tocnav", ...props, className: cn('border-b backdrop-blur-sm transition-colors', (!isTransparent || open) && 'bg-fd-background/80', open && 'shadow-lg'), children: props.children }) }) }) }));
74
- }
75
- export function PageBody(props) {
76
- const { page } = usePageStyles();
77
- return (_jsx("div", { id: "nd-page", ...props, className: cn('flex w-full min-w-0 flex-col', page, props.className), children: props.children }));
70
+ return (_jsx(TocPopoverContext.Provider, { value: useMemo(() => ({
71
+ open,
72
+ setOpen,
73
+ }), [setOpen, open]), children: _jsx(Collapsible, { open: open, onOpenChange: setOpen, asChild: true, children: _jsx("header", { ref: ref, id: "nd-tocnav", ...props, className: cn('fixed inset-x-0 z-10 border-b backdrop-blur-sm transition-colors xl:hidden', (!isTransparent || open) && 'bg-fd-background/80', open && 'shadow-lg', props.className), style: {
74
+ ...props.style,
75
+ top: 'calc(var(--fd-banner-height) + var(--fd-nav-height))',
76
+ insetInlineStart: collapsed
77
+ ? '0px'
78
+ : 'calc(var(--fd-sidebar-width) + var(--fd-layout-offset))',
79
+ }, children: props.children }) }) }));
78
80
  }
79
- export function PageArticle(props) {
80
- const { article } = usePageStyles();
81
- return (_jsx("article", { ...props, className: cn('flex w-full flex-1 flex-col gap-6 px-4 md:px-6 pt-8 md:pt-12 xl:px-12 xl:mx-auto', article, props.className), children: props.children }));
81
+ export function PageRoot({ toc, children, ...props }) {
82
+ const { collapsed } = useSidebar();
83
+ return (_jsx(TOCProvider, { ...toc, children: _jsx("div", { id: "nd-page", ...props, className: cn('flex flex-1 mx-auto w-full', props.className), style: {
84
+ paddingTop: 'calc(var(--fd-nav-height) + var(--fd-tocnav-height))',
85
+ maxWidth: collapsed
86
+ ? 'var(--fd-page-width)'
87
+ : 'min(var(--fd-page-width),calc(var(--fd-layout-width) - var(--fd-sidebar-width)))',
88
+ ...props.style,
89
+ }, children: children }) }));
82
90
  }
83
- export function LastUpdate(props) {
91
+ export function PageLastUpdate({ date: value, ...props }) {
84
92
  const { text } = useI18n();
85
93
  const [date, setDate] = useState('');
86
94
  useEffect(() => {
87
95
  // to the timezone of client
88
- setDate(props.date.toLocaleDateString());
89
- }, [props.date]);
90
- return (_jsxs("p", { className: "text-sm text-fd-muted-foreground", children: [text.lastUpdate, " ", date] }));
96
+ setDate(new Date(value).toLocaleDateString());
97
+ }, [value]);
98
+ return (_jsxs("p", { ...props, className: cn('text-sm text-fd-muted-foreground', props.className), children: [text.lastUpdate, " ", date] }));
91
99
  }
92
100
  function scanNavigationList(tree) {
93
101
  const list = [];
@@ -106,7 +114,7 @@ function scanNavigationList(tree) {
106
114
  return list;
107
115
  }
108
116
  const listCache = new WeakMap();
109
- export function Footer({ items }) {
117
+ export function PageFooter({ items, ...props }) {
110
118
  const { root } = useTreeContext();
111
119
  const pathname = usePathname();
112
120
  const { previous, next } = useMemo(() => {
@@ -123,26 +131,34 @@ export function Footer({ items }) {
123
131
  next: list[idx + 1],
124
132
  };
125
133
  }, [items, pathname, root]);
126
- return (_jsxs("div", { className: cn('@container grid gap-4 pb-6', previous && next ? 'grid-cols-2' : 'grid-cols-1'), children: [previous ? _jsx(FooterItem, { item: previous, index: 0 }) : null, next ? _jsx(FooterItem, { item: next, index: 1 }) : null] }));
134
+ return (_jsxs("div", { ...props, className: cn('@container grid gap-4 pb-6', previous && next ? 'grid-cols-2' : 'grid-cols-1', props.className), children: [previous ? _jsx(FooterItem, { item: previous, index: 0 }) : null, next ? _jsx(FooterItem, { item: next, index: 1 }) : null] }));
127
135
  }
128
136
  function FooterItem({ item, index }) {
129
137
  const { text } = useI18n();
130
138
  const Icon = index === 0 ? ChevronLeft : ChevronRight;
131
139
  return (_jsxs(Link, { href: item.url, className: cn('flex flex-col gap-2 rounded-lg border p-4 text-sm transition-colors hover:bg-fd-accent/80 hover:text-fd-accent-foreground @max-lg:col-span-full', index === 1 && 'text-end'), children: [_jsxs("div", { className: cn('inline-flex items-center gap-1.5 font-medium', index === 1 && 'flex-row-reverse'), children: [_jsx(Icon, { className: "-mx-1 size-4 shrink-0 rtl:rotate-180" }), _jsx("p", { children: item.name })] }), _jsx("p", { className: "text-fd-muted-foreground truncate", children: item.description ?? (index === 0 ? text.previousPage : text.nextPage) })] }));
132
140
  }
133
- export function Breadcrumb(options) {
141
+ export function PageBreadcrumb({ includeRoot = false, includeSeparator, includePage = false, ...props }) {
134
142
  const path = useTreePath();
135
143
  const { root } = useTreeContext();
136
144
  const items = useMemo(() => {
137
145
  return getBreadcrumbItemsFromPath(root, path, {
138
- includePage: options.includePage ?? false,
139
- ...options,
146
+ includePage,
147
+ includeSeparator,
148
+ includeRoot,
140
149
  });
141
- }, [options, path, root]);
150
+ }, [includePage, includeRoot, includeSeparator, path, root]);
142
151
  if (items.length === 0)
143
152
  return null;
144
- return (_jsx("div", { className: "flex flex-row items-center gap-1.5 text-[15px] text-fd-muted-foreground", children: items.map((item, i) => {
153
+ return (_jsx("div", { ...props, className: cn('flex items-center gap-1.5 text-[15px] text-fd-muted-foreground', props.className), children: items.map((item, i) => {
145
154
  const className = cn('truncate', i === items.length - 1 && 'text-fd-primary font-medium');
146
155
  return (_jsxs(Fragment, { children: [i !== 0 && _jsx("span", { className: "text-fd-foreground/30", children: "/" }), item.url ? (_jsx(Link, { href: item.url, className: cn(className, 'transition-opacity hover:opacity-80'), children: item.name })) : (_jsx("span", { className: className, children: item.name }))] }, i));
147
156
  }) }));
148
157
  }
158
+ export function PageTOC(props) {
159
+ return (_jsx("div", { id: "nd-toc", ...props, className: cn('sticky pb-2 pt-12 max-xl:hidden', props.className), style: {
160
+ ...props.style,
161
+ top: 'calc(var(--fd-banner-height) + var(--fd-nav-height))',
162
+ height: 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
163
+ }, children: _jsx("div", { className: "flex h-full w-(--fd-toc-width) max-w-full flex-col pe-4", children: props.children }) }));
164
+ }
@@ -0,0 +1,16 @@
1
+ import { type ComponentProps } from 'react';
2
+ import { type BreadcrumbProps, type FooterProps, PageBreadcrumb, PageFooter, PageLastUpdate, PageRoot, PageTOC, PageTOCPopover, PageTOCPopoverContent, PageTOCPopoverTrigger, type RootProps } from './page-client.js';
3
+ /**
4
+ * Apply `prose` on div
5
+ */
6
+ export declare function PageProse(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
7
+ export declare function PageTOCTitle(props: ComponentProps<'h2'>): import("react/jsx-runtime").JSX.Element;
8
+ export declare function PageTOCItems({ variant, ...props }: ComponentProps<'div'> & {
9
+ variant?: 'clerk' | 'normal';
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ export declare function PageTOCPopoverItems({ variant, ...props }: ComponentProps<'div'> & {
12
+ variant?: 'clerk' | 'normal';
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ export declare function PageArticle(props: ComponentProps<'article'>): import("react/jsx-runtime").JSX.Element;
15
+ export { PageRoot, PageBreadcrumb, PageFooter, PageLastUpdate, PageTOC, PageTOCPopover, PageTOCPopoverTrigger, PageTOCPopoverContent, type FooterProps, type BreadcrumbProps, type RootProps, };
16
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/page.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,cAAc,EACd,UAAU,EACV,cAAc,EACd,QAAQ,EACR,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAMvB;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAMrD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,2CAavD;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAkB,EAClB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAE,2CAM1D;AAED,wBAAgB,mBAAmB,CAAC,EAClC,OAAkB,EAClB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAE,2CAM1D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,2CAY3D;AAED,OAAO,EACL,QAAQ,EACR,cAAc,EACd,UAAU,EACV,cAAc,EACd,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,GACf,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../../utils/cn.js';
3
+ import { PageBreadcrumb, PageFooter, PageLastUpdate, PageRoot, PageTOC, PageTOCPopover, PageTOCPopoverContent, PageTOCPopoverTrigger, } from './page-client.js';
4
+ import { TOCItems, TOCScrollArea } from '../../components/layout/toc.js';
5
+ import { Text } from '../../icons.js';
6
+ import { I18nLabel } from '../../contexts/i18n.js';
7
+ import ClerkTOCItems from '../../components/layout/toc-clerk.js';
8
+ /**
9
+ * Apply `prose` on div
10
+ */
11
+ export function PageProse(props) {
12
+ return (_jsx("div", { ...props, className: cn('prose', props.className), children: props.children }));
13
+ }
14
+ export function PageTOCTitle(props) {
15
+ return (_jsxs("h3", { ...props, className: cn('inline-flex items-center gap-1.5 text-sm text-fd-muted-foreground', props.className), children: [_jsx(Text, { className: "size-4" }), _jsx(I18nLabel, { label: "toc" })] }));
16
+ }
17
+ export function PageTOCItems({ variant = 'normal', ...props }) {
18
+ return (_jsx(TOCScrollArea, { ...props, children: variant === 'clerk' ? _jsx(ClerkTOCItems, {}) : _jsx(TOCItems, {}) }));
19
+ }
20
+ export function PageTOCPopoverItems({ variant = 'normal', ...props }) {
21
+ return (_jsx(TOCScrollArea, { ...props, children: variant === 'clerk' ? _jsx(ClerkTOCItems, {}) : _jsx(TOCItems, {}) }));
22
+ }
23
+ export function PageArticle(props) {
24
+ return (_jsx("article", { ...props, className: cn('flex min-w-0 w-full flex-col gap-6 px-4 pt-8 md:px-6 md:mx-auto xl:pt-12 xl:px-12', props.className), children: props.children }));
25
+ }
26
+ export { PageRoot, PageBreadcrumb, PageFooter, PageLastUpdate, PageTOC, PageTOCPopover, PageTOCPopoverTrigger, PageTOCPopoverContent, };
@@ -4,9 +4,6 @@ import type { PageTree } from 'fumadocs-core/server';
4
4
  import type { ReactNode } from 'react';
5
5
  import type { Option } from '../../components/layout/root-toggle.js';
6
6
  import { type GetSidebarTabsOptions } from '../../utils/get-sidebar-tabs.js';
7
- export declare const layoutVariables: {
8
- '--fd-layout-offset': string;
9
- };
10
7
  export interface SidebarOptions extends SidebarProps {
11
8
  components?: Partial<SidebarComponents>;
12
9
  /**