fumadocs-ui 15.4.2 → 15.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) 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/layout/sidebar.d.ts.map +1 -1
  6. package/dist/components/layout/sidebar.js +7 -5
  7. package/dist/components/layout/toc-clerk.d.ts +2 -4
  8. package/dist/components/layout/toc-clerk.d.ts.map +1 -1
  9. package/dist/components/layout/toc-clerk.js +8 -4
  10. package/dist/components/layout/toc.d.ts +6 -18
  11. package/dist/components/layout/toc.d.ts.map +1 -1
  12. package/dist/components/layout/toc.js +14 -16
  13. package/dist/components/ui/button.d.ts +1 -1
  14. package/dist/components/ui/button.d.ts.map +1 -1
  15. package/dist/components/ui/button.js +2 -1
  16. package/dist/layouts/docs/page-client.d.ts +30 -0
  17. package/dist/layouts/docs/page-client.d.ts.map +1 -0
  18. package/dist/{page-client.js → layouts/docs/page-client.js} +56 -40
  19. package/dist/layouts/docs/page.d.ts +16 -0
  20. package/dist/layouts/docs/page.d.ts.map +1 -0
  21. package/dist/layouts/docs/page.js +26 -0
  22. package/dist/layouts/docs/shared.d.ts +0 -3
  23. package/dist/layouts/docs/shared.d.ts.map +1 -1
  24. package/dist/layouts/docs/shared.js +0 -3
  25. package/dist/layouts/docs-client.d.ts +1 -0
  26. package/dist/layouts/docs-client.d.ts.map +1 -1
  27. package/dist/layouts/docs-client.js +10 -2
  28. package/dist/layouts/docs.d.ts.map +1 -1
  29. package/dist/layouts/docs.js +6 -13
  30. package/dist/layouts/home/navbar.d.ts.map +1 -1
  31. package/dist/layouts/home/navbar.js +1 -5
  32. package/dist/layouts/notebook-client.d.ts +5 -4
  33. package/dist/layouts/notebook-client.d.ts.map +1 -1
  34. package/dist/layouts/notebook-client.js +12 -6
  35. package/dist/layouts/notebook.d.ts.map +1 -1
  36. package/dist/layouts/notebook.js +6 -14
  37. package/dist/layouts/shared.d.ts +1 -1
  38. package/dist/layouts/shared.d.ts.map +1 -1
  39. package/dist/layouts/shared.js +4 -5
  40. package/dist/page.d.ts +25 -18
  41. package/dist/page.d.ts.map +1 -1
  42. package/dist/page.js +9 -18
  43. package/dist/style.css +47 -90
  44. package/dist/utils/merge-refs.d.ts +3 -0
  45. package/dist/utils/merge-refs.d.ts.map +1 -0
  46. package/dist/utils/merge-refs.js +12 -0
  47. package/package.json +8 -8
  48. package/dist/page-client.d.ts +0 -28
  49. package/dist/page-client.d.ts.map +0 -1
package/css/preset.css CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  @theme {
7
7
  --spacing-fd-container: 1400px;
8
+ --fd-page-width: 1200px;
8
9
  --fd-sidebar-width: 0px;
9
10
  --fd-toc-width: 0px;
10
11
  --fd-layout-width: 100vw;
@@ -242,6 +243,17 @@
242
243
  [data-rmiz-modal-overlay='visible'] {
243
244
  background-color: var(--color-fd-background);
244
245
  }
246
+
247
+ :root,
248
+ #nd-docs-layout {
249
+ --fd-layout-offset: max(calc(50vw - var(--fd-layout-width) / 2), 0px);
250
+ }
251
+ }
252
+
253
+ @variant max-xl {
254
+ #nd-docs-layout:has([data-toc-popover]) {
255
+ --fd-tocnav-height: calc(var(--spacing) * 10);
256
+ }
245
257
  }
246
258
 
247
259
  @utility fd-scroll-container {
@@ -1,7 +1,9 @@
1
1
  import type { AccordionMultipleProps, AccordionSingleProps } from '@radix-ui/react-accordion';
2
2
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
3
+ import { type ReactNode } from 'react';
3
4
  export declare const Accordions: import("react").ForwardRefExoticComponent<(Omit<AccordionSingleProps, "value" | "onValueChange"> | Omit<AccordionMultipleProps, "value" | "onValueChange">) & import("react").RefAttributes<HTMLDivElement>>;
4
- export declare const Accordion: import("react").ForwardRefExoticComponent<Omit<Omit<AccordionPrimitive.AccordionItemProps & import("react").RefAttributes<HTMLDivElement>, "ref">, "value"> & {
5
- title: string;
5
+ export declare const Accordion: import("react").ForwardRefExoticComponent<Omit<Omit<AccordionPrimitive.AccordionItemProps & import("react").RefAttributes<HTMLDivElement>, "ref">, "title" | "value"> & {
6
+ title: string | ReactNode;
7
+ value?: string;
6
8
  } & import("react").RefAttributes<HTMLDivElement>>;
7
9
  //# sourceMappingURL=accordion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAYhE,eAAO,MAAM,UAAU,8MA+BrB,CAAC;AAIH,eAAO,MAAM,SAAS;WAGX,MAAM;kDA0Bf,CAAC"}
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAGL,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAMf,eAAO,MAAM,UAAU,8MAuCrB,CAAC;AAIH,eAAO,MAAM,SAAS;WAMX,MAAM,GAAG,SAAS;YACjB,MAAM;kDAiCjB,CAAC"}
@@ -2,32 +2,40 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
4
4
  import { Check, ChevronRight, Link as LinkIcon } from '../icons.js';
5
- import { forwardRef, useEffect, useState, } from 'react';
5
+ import { forwardRef, useEffect, useRef, useState, } from 'react';
6
6
  import { cn } from '../utils/cn.js';
7
7
  import { useCopyButton } from '../utils/use-copy-button.js';
8
8
  import { buttonVariants } from '../components/ui/button.js';
9
+ import { mergeRefs } from '../utils/merge-refs.js';
9
10
  export const Accordions = forwardRef(({ type = 'single', className, defaultValue, ...props }, ref) => {
10
- const [value, setValue] = useState(type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []));
11
+ const rootRef = useRef(null);
12
+ const composedRef = mergeRefs(ref, rootRef);
13
+ const [value, setValue] = useState(() => type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []));
11
14
  useEffect(() => {
12
15
  const id = window.location.hash.substring(1);
13
- if (id.length > 0)
14
- setValue((prev) => (typeof prev === 'string' ? id : [id, ...prev]));
16
+ const element = rootRef.current;
17
+ if (!element || id.length === 0)
18
+ return;
19
+ const selected = document.getElementById(id);
20
+ if (!selected || !element.contains(selected))
21
+ return;
22
+ const value = selected.getAttribute('data-accordion-value');
23
+ if (value)
24
+ setValue((prev) => (typeof prev === 'string' ? value : [value, ...prev]));
15
25
  }, []);
16
26
  return (
17
27
  // @ts-expect-error -- Multiple types
18
- _jsx(AccordionPrimitive.Root, { type: type, ref: ref, value: value, onValueChange: setValue, collapsible: type === 'single' ? true : undefined, className: cn('divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card', className), ...props }));
28
+ _jsx(AccordionPrimitive.Root, { type: type, ref: composedRef, value: value, onValueChange: setValue, collapsible: type === 'single' ? true : undefined, className: cn('divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card', className), ...props }));
19
29
  });
20
30
  Accordions.displayName = 'Accordions';
21
- export const Accordion = forwardRef(({ title, className, id, children, ...props }, ref) => {
22
- return (_jsxs(AccordionPrimitive.Item, { ref: ref,
23
- // Use `id` instead if presents
24
- value: id ?? title, className: cn('group/accordion relative scroll-m-20', className), ...props, children: [_jsxs(AccordionPrimitive.Header, { id: id, className: "not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent", children: [_jsxs(AccordionPrimitive.Trigger, { className: "flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none", children: [_jsx(ChevronRight, { className: "size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]/accordion:rotate-90" }), title] }), id ? _jsx(CopyButton, { id: id }) : null] }), _jsx(AccordionPrimitive.Content, { className: "overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down", children: _jsx("div", { className: "px-4 pb-2 text-[15px] prose-no-margin", children: children }) })] }));
31
+ export const Accordion = forwardRef(({ title, className, id, value = String(title), children, ...props }, ref) => {
32
+ return (_jsxs(AccordionPrimitive.Item, { ref: ref, value: value, className: cn('scroll-m-24', className), ...props, children: [_jsxs(AccordionPrimitive.Header, { id: id, "data-accordion-value": value, className: "not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent", children: [_jsxs(AccordionPrimitive.Trigger, { className: "group flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none", children: [_jsx(ChevronRight, { className: "size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-90" }), title] }), id ? _jsx(CopyButton, { id: id }) : null] }), _jsx(AccordionPrimitive.Content, { className: "overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down", children: _jsx("div", { className: "px-4 pb-2 text-[15px] prose-no-margin", children: children }) })] }));
25
33
  });
26
34
  function CopyButton({ id }) {
27
35
  const [checked, onClick] = useCopyButton(() => {
28
36
  const url = new URL(window.location.href);
29
37
  url.hash = id;
30
- void navigator.clipboard.writeText(url.toString());
38
+ return navigator.clipboard.writeText(url.toString());
31
39
  });
32
40
  return (_jsx("button", { type: "button", "aria-label": "Copy Link", className: cn(buttonVariants({
33
41
  color: 'ghost',
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/sidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,EAAE,EAEP,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,YAAY,2CAgHd;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAcrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,2CAkB1D;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAsBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,2CAgBA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,uBAAuB,2CAqBzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAsCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAqBlE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgBrE;AAgBD,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,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC1E,SAAS,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,2CAuDA"}
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/sidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,EAAE,EAEP,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,YAAY,2CAiHd;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAcrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,2CAkB1D;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAsBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,2CAgBA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,uBAAuB,2CAqBzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAsCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAqBlE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgBrE;AAgBD,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,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC1E,SAAS,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,2CAuDA"}
@@ -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,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
  });
@@ -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
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/shared.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,KAAK,iBAAiB,EAMtB,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAElC,eAAO,MAAM,eAAe;;CAE3B,CAAC;AAEF,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAExC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,qBAAqB,GAAG,KAAK,CAAC;IAEhD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAmCA;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI,wBASpB"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/shared.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,KAAK,iBAAiB,EAMtB,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAExC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,qBAAqB,GAAG,KAAK,CAAC;IAEhD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAmCA;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI,wBASpB"}
@@ -1,9 +1,6 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarItem, } from '../../components/layout/sidebar.js';
3
3
  import { getSidebarTabs, } from '../../utils/get-sidebar-tabs.js';
4
- export const layoutVariables = {
5
- '--fd-layout-offset': 'max(calc(50vw - var(--fd-layout-width) / 2), 0px)',
6
- };
7
4
  export function SidebarLinkItem({ item, ...props }) {
8
5
  if (item.type === 'menu')
9
6
  return (_jsxs(SidebarFolder, { ...props, 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))) })] }));