fumadocs-ui 15.0.6 → 15.0.7

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 (48) hide show
  1. package/css/preset.css +46 -1
  2. package/dist/components/banner.d.ts.map +1 -1
  3. package/dist/components/banner.js +6 -7
  4. package/dist/components/callout.d.ts.map +1 -1
  5. package/dist/components/callout.js +13 -1
  6. package/dist/components/codeblock.d.ts.map +1 -1
  7. package/dist/components/codeblock.js +1 -2
  8. package/dist/components/dialog/search.d.ts.map +1 -1
  9. package/dist/components/dialog/search.js +7 -9
  10. package/dist/components/layout/root-toggle.js +1 -1
  11. package/dist/components/layout/theme-toggle.d.ts.map +1 -1
  12. package/dist/components/layout/theme-toggle.js +4 -4
  13. package/dist/components/layout/toc-clerk.d.ts +1 -1
  14. package/dist/components/layout/toc-clerk.d.ts.map +1 -1
  15. package/dist/components/layout/toc-clerk.js +3 -3
  16. package/dist/components/layout/toc-thumb.d.ts +2 -2
  17. package/dist/components/layout/toc-thumb.d.ts.map +1 -1
  18. package/dist/components/layout/toc-thumb.js +8 -9
  19. package/dist/components/layout/toc.d.ts +7 -2
  20. package/dist/components/layout/toc.d.ts.map +1 -1
  21. package/dist/components/layout/toc.js +18 -11
  22. package/dist/components/tabs.d.ts.map +1 -1
  23. package/dist/components/tabs.js +5 -7
  24. package/dist/components/ui/navigation-menu.js +1 -1
  25. package/dist/i18n.d.ts.map +1 -1
  26. package/dist/i18n.js +3 -6
  27. package/dist/layouts/docs/sidebar.d.ts.map +1 -1
  28. package/dist/layouts/docs/sidebar.js +9 -13
  29. package/dist/layouts/docs.client.d.ts +0 -6
  30. package/dist/layouts/docs.client.d.ts.map +1 -1
  31. package/dist/layouts/docs.client.js +1 -13
  32. package/dist/layouts/docs.d.ts.map +1 -1
  33. package/dist/layouts/docs.js +18 -19
  34. package/dist/layouts/home/navbar.js +1 -1
  35. package/dist/layouts/notebook.client.js +1 -1
  36. package/dist/layouts/notebook.d.ts.map +1 -1
  37. package/dist/layouts/notebook.js +10 -4
  38. package/dist/page.client.d.ts +1 -1
  39. package/dist/page.client.d.ts.map +1 -1
  40. package/dist/page.client.js +27 -9
  41. package/dist/page.d.ts.map +1 -1
  42. package/dist/page.js +5 -5
  43. package/dist/style.css +176 -131
  44. package/dist/theme/typography/styles.js +4 -3
  45. package/package.json +3 -3
  46. package/dist/theme/docs-ui.d.ts +0 -23
  47. package/dist/theme/docs-ui.d.ts.map +0 -1
  48. package/dist/theme/docs-ui.js +0 -58
package/css/preset.css CHANGED
@@ -1,11 +1,21 @@
1
1
  @import './shiki.css';
2
2
  @import './animations.css';
3
3
 
4
- @plugin '../dist/theme/docs-ui.js';
5
4
  @plugin '../dist/theme/typography/index.js';
6
5
 
7
6
  @theme {
8
7
  --spacing-fd-container: 1400px;
8
+ --fd-sidebar-width: 0px;
9
+ --fd-toc-width: 0px;
10
+ --fd-layout-width: 100vw;
11
+ --fd-banner-height: 0px;
12
+ --fd-nav-height: 0px;
13
+ --fd-tocnav-height: 0px;
14
+
15
+ --fd-diff-remove-color: rgba(200, 10, 100, 0.12);
16
+ --fd-diff-remove-symbol-color: rgb(230, 10, 100);
17
+ --fd-diff-add-color: rgba(14, 180, 100, 0.12);
18
+ --fd-diff-add-symbol-color: rgb(10, 200, 100);
9
19
  }
10
20
 
11
21
  @layer base {
@@ -27,6 +37,41 @@
27
37
  }
28
38
  }
29
39
 
40
+ @layer utilities {
41
+ .fd-steps {
42
+ counter-reset: step;
43
+ border-left-width: 1px;
44
+ margin-left: 1rem;
45
+ padding-left: 1.75rem;
46
+ position: relative;
47
+ }
48
+
49
+ .fd-step:before {
50
+ background-color: var(--color-fd-secondary);
51
+ color: var(--color-fd-secondary-foreground);
52
+ content: counter(step);
53
+ counter-increment: step;
54
+ border-radius: 9999px;
55
+ justify-content: center;
56
+ align-items: center;
57
+ width: 2rem;
58
+ height: 2rem;
59
+ font-size: 0.875rem;
60
+ line-height: 1.25rem;
61
+ display: flex;
62
+ position: absolute;
63
+ left: -1rem;
64
+ }
65
+
66
+ .prose-no-margin > :first-child {
67
+ margin-top: 0;
68
+ }
69
+
70
+ .prose-no-margin > :last-child {
71
+ margin-bottom: 0;
72
+ }
73
+ }
74
+
30
75
  @utility container {
31
76
  margin-inline: auto;
32
77
  padding-inline: 1rem;
@@ -1 +1 @@
1
- {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/components/banner.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAoC,MAAM,OAAO,CAAC;AAK9E,wBAAgB,MAAM,CAAC,EACrB,EAAE,EACF,OAAkB,EAClB,YAAmB,EACnB,MAAe,EACf,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG;IAClC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,kDAoEA"}
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/components/banner.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAKjE,wBAAgB,MAAM,CAAC,EACrB,EAAE,EACF,OAAkB,EAClB,YAAmB,EACnB,MAAe,EACf,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG;IAClC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,kDAkEA"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useState } from 'react';
3
+ import { useEffect, useState } from 'react';
4
4
  import { X } from 'lucide-react';
5
5
  import { cn } from '../utils/cn.js';
6
6
  import { buttonVariants } from '../components/ui/button.js';
@@ -11,11 +11,6 @@ export function Banner({ id, variant = 'normal', changeLayout = true, height = '
11
11
  if (globalKey)
12
12
  setOpen(localStorage.getItem(globalKey) !== 'true');
13
13
  }, [globalKey]);
14
- const onClick = useCallback(() => {
15
- setOpen(false);
16
- if (globalKey)
17
- localStorage.setItem(globalKey, 'true');
18
- }, [globalKey]);
19
14
  if (!open)
20
15
  return null;
21
16
  return (_jsxs("div", { id: id, ...props, className: cn('sticky top-0 z-40 flex flex-row items-center justify-center bg-fd-secondary px-4 text-center text-sm font-medium', variant === 'rainbow' && 'bg-fd-background', !open && 'hidden', props.className), style: {
@@ -24,7 +19,11 @@ export function Banner({ id, variant = 'normal', changeLayout = true, height = '
24
19
  ? `:root:not(.${globalKey}) { --fd-banner-height: ${height}; }`
25
20
  : `:root { --fd-banner-height: ${height}; }` })) : null, globalKey ? (_jsx("style", { children: `.${globalKey} #${id} { display: none; }` })) : null, globalKey ? (_jsx("script", { dangerouslySetInnerHTML: {
26
21
  __html: `if (localStorage.getItem('${globalKey}') === 'true') document.documentElement.classList.add('${globalKey}');`,
27
- } })) : null, variant === 'rainbow' ? rainbowLayer : null, props.children, id ? (_jsx("button", { type: "button", "aria-label": "Close Banner", onClick: onClick, className: cn(buttonVariants({
22
+ } })) : null, variant === 'rainbow' ? rainbowLayer : null, props.children, id ? (_jsx("button", { type: "button", "aria-label": "Close Banner", onClick: () => {
23
+ setOpen(false);
24
+ if (globalKey)
25
+ localStorage.setItem(globalKey, 'true');
26
+ }, className: cn(buttonVariants({
28
27
  color: 'ghost',
29
28
  className: 'absolute end-2 top-1/2 -translate-y-1/2 text-fd-muted-foreground',
30
29
  size: 'icon',
@@ -1 +1 @@
1
- {"version":3,"file":"callout.d.ts","sourceRoot":"","sources":["../../src/components/callout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBxE,eAAO,MAAM,OAAO;YAZV,SAAS;IACjB;;OAEG;WACI,MAAM,GAAG,MAAM,GAAG,OAAO;IAEhC;;OAEG;WACI,SAAS;kDA+BjB,CAAC"}
1
+ {"version":3,"file":"callout.d.ts","sourceRoot":"","sources":["../../src/components/callout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAiCxE,eAAO,MAAM,OAAO;YAzBV,SAAS;IACjB;;OAEG;WACI,MAAM,GAAG,MAAM,GAAG,OAAO;IAEhC;;OAEG;WACI,SAAS;kDA8CjB,CAAC"}
@@ -2,8 +2,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { AlertTriangle, CircleX, Info } from 'lucide-react';
3
3
  import { forwardRef } from 'react';
4
4
  import { cn } from '../utils/cn.js';
5
+ import { cva } from 'class-variance-authority';
6
+ const calloutVariants = cva('my-6 flex flex-row gap-2 rounded-lg border border-s-2 bg-fd-card p-3 text-sm text-fd-card-foreground shadow-md', {
7
+ variants: {
8
+ type: {
9
+ info: 'border-s-blue-500/50',
10
+ warn: 'border-s-orange-500/50',
11
+ error: 'border-s-red-500/50',
12
+ },
13
+ },
14
+ });
5
15
  export const Callout = forwardRef(({ className, children, title, type = 'info', icon, ...props }, ref) => {
6
- return (_jsxs("div", { ref: ref, className: cn('my-6 flex flex-row gap-2 rounded-lg border bg-fd-card p-3 text-sm text-fd-card-foreground shadow-md', className), ...props, children: [icon ??
16
+ return (_jsxs("div", { ref: ref, className: cn(calloutVariants({
17
+ type: type,
18
+ }), className), ...props, children: [icon ??
7
19
  {
8
20
  info: _jsx(Info, { className: "size-5 fill-blue-500 text-fd-card" }),
9
21
  warn: (_jsx(AlertTriangle, { className: "size-5 fill-orange-500 text-fd-card" })),
@@ -1 +1 @@
1
- {"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,GAAG,2HAYf,CAAC;AAIF,eAAO,MAAM,SAAS;IAxCpB;;;;OAIG;WACI,SAAS;IAEhB;;;;OAIG;gBACS,OAAO;IAEnB;;;;OAIG;qBACc,OAAO;oBAER,uBAAuB;+CAmGxC,CAAC"}
1
+ {"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAE3E,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,GAAG,2HAYf,CAAC;AAIF,eAAO,MAAM,SAAS;IAxCpB;;;;OAIG;WACI,SAAS;IAEhB;;;;OAIG;gBACS,OAAO;IAEnB;;;;OAIG;qBACc,OAAO;oBAER,uBAAuB;+CAkGxC,CAAC"}
@@ -22,8 +22,7 @@ export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground =
22
22
  });
23
23
  void navigator.clipboard.writeText(clone.textContent ?? '');
24
24
  }, []);
25
- return (_jsxs("figure", { ref: ref, ...props, className: cn('not-prose group fd-codeblock relative my-6 overflow-hidden rounded-lg border bg-fd-secondary/50 text-sm', keepBackground &&
26
- 'bg-[var(--shiki-light-bg)] dark:bg-[var(--shiki-dark-bg)]', props.className), children: [title ? (_jsxs("div", { className: "flex flex-row items-center gap-2 border-b bg-fd-muted px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", dangerouslySetInnerHTML: typeof icon === 'string'
25
+ return (_jsxs("figure", { ref: ref, ...props, className: cn('not-prose group fd-codeblock relative my-6 overflow-hidden rounded-lg border bg-fd-secondary/50 text-sm', keepBackground && 'bg-(--shiki-light-bg) dark:bg-(--shiki-dark-bg)', props.className), children: [title ? (_jsxs("div", { className: "flex flex-row items-center gap-2 border-b bg-fd-muted px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", dangerouslySetInnerHTML: typeof icon === 'string'
27
26
  ? {
28
27
  __html: icon,
29
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,SAAS,EAMd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,UAAU,iBAAkB,SAAQ,WAAW;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAEvC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAU,EACV,MAAM,EACN,cAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAyDnB;AAiKD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1B,KAAK,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,cAAc,CAAC;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAaD,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,WAAW,EACX,KAAK,EACL,UAAU,EACV,GAAG,KAAK,EACT,EAAE,aAAa,2CAkCf"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,SAAS,EAKd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,UAAU,iBAAkB,SAAQ,WAAW;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAEvC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAU,EACV,MAAM,EACN,cAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAyDnB;AA4JD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1B,KAAK,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,cAAc,CAAC;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAaD,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,WAAW,EACX,KAAK,EACL,UAAU,EACV,GAAG,KAAK,EACT,EAAE,aAAa,2CAkCf"}
@@ -2,13 +2,14 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { FileText, Hash, Loader2, SearchIcon, Text } from 'lucide-react';
4
4
  import { useRouter } from 'next/navigation';
5
- import { useMemo, useEffect, useState, useRef, useCallback, } from 'react';
5
+ import { useMemo, useEffect, useState, useCallback, } from 'react';
6
6
  import { useI18n } from '../../contexts/i18n.js';
7
7
  import { cn } from '../../utils/cn.js';
8
8
  import { useSidebar } from '../../contexts/sidebar.js';
9
9
  import { buttonVariants } from '../../components/ui/button.js';
10
10
  import { Dialog, DialogContent, DialogOverlay, DialogTitle, } from '@radix-ui/react-dialog';
11
11
  import { cva } from 'class-variance-authority';
12
+ import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
12
13
  export function SearchDialog({ open, onOpenChange, footer, links = [], search, onSearchChange, isLoading, ...props }) {
13
14
  const { text } = useI18n();
14
15
  const defaultItems = useMemo(() => links.map(([name, link]) => ({
@@ -46,7 +47,7 @@ function SearchResults({ items, onSelect, ...props }) {
46
47
  onSelect?.(url);
47
48
  sidebar.setOpen(false);
48
49
  };
49
- function onKey(e) {
50
+ const onKey = useEffectEvent((e) => {
50
51
  if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {
51
52
  setActive((cur) => {
52
53
  const idx = items.findIndex((item) => item.id === cur);
@@ -62,16 +63,13 @@ function SearchResults({ items, onSelect, ...props }) {
62
63
  onOpen(selected);
63
64
  e.preventDefault();
64
65
  }
65
- }
66
- const listenerRef = useRef(onKey);
67
- listenerRef.current = onKey;
66
+ });
68
67
  useEffect(() => {
69
- const listener = (e) => listenerRef.current?.(e);
70
- window.addEventListener('keydown', listener);
68
+ window.addEventListener('keydown', onKey);
71
69
  return () => {
72
- window.removeEventListener('keydown', listener);
70
+ window.removeEventListener('keydown', onKey);
73
71
  };
74
- }, []);
72
+ }, [onKey]);
75
73
  return (_jsxs("div", { ...props, className: cn('flex max-h-[460px] flex-col overflow-y-auto border-t p-2', props.className), children: [items.length === 0 ? (_jsx("div", { className: "py-12 text-center text-sm", children: text.searchNoResult })) : null, items.map((item) => (_jsxs(CommandItem, { value: item.id, active: active, onActiveChange: setActive, onClick: () => {
76
74
  onOpen(item);
77
75
  }, children: [item.type !== 'page' ? (_jsx("div", { role: "none", className: "ms-2 h-full min-h-10 w-px bg-fd-border" })) : null, icons[item.type], _jsx("p", { className: "w-0 flex-1 truncate", children: item.content })] }, item.id)))] }));
@@ -22,7 +22,7 @@ export function RootToggle({ options, placeholder, ...props }) {
22
22
  setOpen(false);
23
23
  };
24
24
  const item = selected ? _jsx(Item, { ...selected }) : placeholder;
25
- return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [item ? (_jsxs(PopoverTrigger, { ...props, className: cn('flex flex-row items-center gap-2 rounded-lg ps-2 pe-4 py-1.5 hover:bg-fd-accent/50 hover:text-fd-accent-foreground', props.className), children: [item, _jsx(ChevronsUpDown, { className: "size-4 text-fd-muted-foreground" })] })) : null, _jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] overflow-hidden p-0", children: options.map((item) => (_jsx(Link, { href: item.url, onClick: onClick, ...item.props, className: cn('flex w-full flex-row items-center gap-2 px-2 py-1.5', selected === item
25
+ return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [item ? (_jsxs(PopoverTrigger, { ...props, className: cn('flex flex-row items-center gap-2 rounded-lg ps-2 pe-4 py-1.5 hover:bg-fd-accent/50 hover:text-fd-accent-foreground', props.className), children: [item, _jsx(ChevronsUpDown, { className: "size-4 text-fd-muted-foreground" })] })) : null, _jsx(PopoverContent, { className: "w-(--radix-popover-trigger-width) overflow-hidden p-0", children: options.map((item) => (_jsx(Link, { href: item.url, onClick: onClick, ...item.props, className: cn('flex w-full flex-row items-center gap-2 px-2 py-1.5', selected === item
26
26
  ? 'bg-fd-accent text-fd-accent-foreground'
27
27
  : 'hover:bg-fd-accent/50', item.props?.className), children: _jsx(Item, { ...item }) }, item.url))) })] }));
28
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/layout/theme-toggle.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAA6B,MAAM,OAAO,CAAC;AAkBvE,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAmB,EACnB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG;IAC/B,IAAI,CAAC,EAAE,YAAY,GAAG,mBAAmB,CAAC;CAC3C,2CAsDA"}
1
+ {"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/layout/theme-toggle.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAA6B,MAAM,OAAO,CAAC;AAqBvE,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,IAAmB,EACnB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG;IAC/B,IAAI,CAAC,EAAE,YAAY,GAAG,mBAAmB,CAAC;CAC3C,2CAuDA"}
@@ -5,7 +5,7 @@ import { Moon, Sun, Airplay } from 'lucide-react';
5
5
  import { useTheme } from 'next-themes';
6
6
  import { useLayoutEffect, useState } from 'react';
7
7
  import { cn } from '../../utils/cn.js';
8
- const itemVariants = cva('size-7 rounded-full p-1.5 text-fd-muted-foreground', {
8
+ const itemVariants = cva('size-6.5 rounded-full p-1.5 text-fd-muted-foreground', {
9
9
  variants: {
10
10
  active: {
11
11
  true: 'bg-fd-accent text-fd-accent-foreground',
@@ -24,15 +24,15 @@ export function ThemeToggle({ className, mode = 'light-dark', ...props }) {
24
24
  useLayoutEffect(() => {
25
25
  setMounted(true);
26
26
  }, []);
27
- const container = cn('inline-flex items-center rounded-full border p-[3px]', className);
27
+ const container = cn('inline-flex items-center rounded-full border p-1', className);
28
28
  if (mode === 'light-dark') {
29
29
  const value = mounted ? resolvedTheme : null;
30
30
  return (_jsx("button", { className: container, "aria-label": `Toggle Theme`, onClick: () => setTheme(value === 'light' ? 'dark' : 'light'), "data-theme-toggle": "", ...props, children: full.map(([key, Icon]) => {
31
31
  if (key === 'system')
32
32
  return;
33
- return (_jsx(Icon, { className: cn(itemVariants({ active: value === key })) }, key));
33
+ return (_jsx(Icon, { fill: "currentColor", className: cn(itemVariants({ active: value === key })) }, key));
34
34
  }) }));
35
35
  }
36
36
  const value = mounted ? theme : null;
37
- return (_jsx("div", { className: container, "data-theme-toggle": "", ...props, children: full.map(([key, Icon]) => (_jsx("button", { "aria-label": key, className: cn(itemVariants({ active: value === key })), onClick: () => setTheme(key), children: _jsx(Icon, { className: "size-full" }) }, key))) }));
37
+ return (_jsx("div", { className: container, "data-theme-toggle": "", ...props, children: full.map(([key, Icon]) => (_jsx("button", { "aria-label": key, className: cn(itemVariants({ active: value === key })), onClick: () => setTheme(key), children: _jsx(Icon, { className: "size-full", fill: "currentColor" }) }, key))) }));
38
38
  }
@@ -1,5 +1,5 @@
1
1
  import type { TOCItemType } from 'fumadocs-core/server';
2
- export default function ClerkTOCItems({ items, isMenu, }: {
2
+ export default function ClerkTOCItems({ items, }: {
3
3
  items: TOCItemType[];
4
4
  isMenu?: boolean;
5
5
  }): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"toc-clerk.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-clerk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CAgGA"}
1
+ {"version":3,"file":"toc-clerk.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-clerk.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,KAAK,GACN,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CAgGA"}
@@ -6,7 +6,7 @@ import { cn } from '../../utils/cn.js';
6
6
  import { TocThumb } from '../../components/layout/toc-thumb.js';
7
7
  import { ScrollArea, ScrollViewport } from '../ui/scroll-area.js';
8
8
  import { TocItemsEmpty } from '../../components/layout/toc.js';
9
- export default function ClerkTOCItems({ items, isMenu = false, }) {
9
+ export default function ClerkTOCItems({ items, }) {
10
10
  const viewRef = useRef(null);
11
11
  const containerRef = useRef(null);
12
12
  const [svg, setSvg] = useState();
@@ -47,13 +47,13 @@ export default function ClerkTOCItems({ items, isMenu = false, }) {
47
47
  }, [items]);
48
48
  if (items.length === 0)
49
49
  return _jsx(TocItemsEmpty, {});
50
- return (_jsx(ScrollArea, { className: cn('flex flex-col', isMenu && '-ms-3'), children: _jsxs(ScrollViewport, { className: "relative min-h-0", ref: viewRef, children: [svg ? (_jsx("div", { className: "absolute start-0 top-0 rtl:-scale-x-100", style: {
50
+ return (_jsx(ScrollArea, { className: "flex flex-col ps-px", children: _jsxs(ScrollViewport, { className: "relative min-h-0", ref: viewRef, children: [svg ? (_jsx("div", { className: "absolute start-0 top-0 rtl:-scale-x-100", style: {
51
51
  width: svg.width,
52
52
  height: svg.height,
53
53
  maskImage: `url("data:image/svg+xml,${
54
54
  // Inline SVG
55
55
  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>`)}")`,
56
- }, children: _jsx(TocThumb, { containerRef: containerRef, className: "mt-[var(--fd-top)] h-[var(--fd-height)] bg-fd-primary transition-all" }) })) : null, _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: _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))) }) })] }) }));
56
+ }, children: _jsx(TocThumb, { containerRef: containerRef, className: "mt-(--fd-top) h-(--fd-height) bg-fd-primary transition-all" }) })) : null, _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: _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))) }) })] }) }));
57
57
  }
58
58
  function getItemOffset(depth) {
59
59
  if (depth <= 2)
@@ -1,6 +1,6 @@
1
- import { type HTMLAttributes, type ReactNode, type RefObject } from 'react';
1
+ import { type HTMLAttributes, type RefObject } from 'react';
2
2
  export type TOCThumb = [top: number, height: number];
3
3
  export declare function TocThumb({ containerRef, ...props }: HTMLAttributes<HTMLDivElement> & {
4
4
  containerRef: RefObject<HTMLElement | null>;
5
- }): ReactNode;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
6
  //# sourceMappingURL=toc-thumb.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toc-thumb.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-thumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAIf,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAgCrD,wBAAgB,QAAQ,CAAC,EACvB,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG;IAClC,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC7C,GAAG,SAAS,CAgCZ"}
1
+ {"version":3,"file":"toc-thumb.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc-thumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAK/E,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAgCrD,wBAAgB,QAAQ,CAAC,EACvB,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG;IAClC,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC7C,2CA8BA"}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useRef, } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import * as Primitive from 'fumadocs-core/toc';
4
4
  import { useOnChange } from 'fumadocs-core/utils/use-on-change';
5
+ import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
5
6
  function calc(container, active) {
6
7
  if (active.length === 0 || container.clientHeight === 0) {
7
8
  return [0, 0];
@@ -26,24 +27,22 @@ function update(element, info) {
26
27
  export function TocThumb({ containerRef, ...props }) {
27
28
  const active = Primitive.useActiveAnchors();
28
29
  const thumbRef = useRef(null);
29
- const activeRef = useRef(active);
30
- activeRef.current = active;
30
+ const onResize = useEffectEvent(() => {
31
+ if (!containerRef.current || !thumbRef.current)
32
+ return;
33
+ update(thumbRef.current, calc(containerRef.current, active));
34
+ });
31
35
  useEffect(() => {
32
36
  if (!containerRef.current)
33
37
  return;
34
38
  const container = containerRef.current;
35
- const onResize = () => {
36
- if (!thumbRef.current)
37
- return;
38
- update(thumbRef.current, calc(container, activeRef.current));
39
- };
40
39
  onResize();
41
40
  const observer = new ResizeObserver(onResize);
42
41
  observer.observe(container);
43
42
  return () => {
44
43
  observer.disconnect();
45
44
  };
46
- }, [containerRef]);
45
+ }, [containerRef, onResize]);
47
46
  useOnChange(active, () => {
48
47
  if (!containerRef.current || !thumbRef.current)
49
48
  return;
@@ -1,6 +1,7 @@
1
1
  import type { TOCItemType } from 'fumadocs-core/server';
2
- import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import { type ComponentProps, type HTMLAttributes, type ReactNode } from 'react';
3
3
  import type { PopoverContentProps, PopoverTriggerProps } from '@radix-ui/react-popover';
4
+ import { Collapsible } from '../../components/ui/collapsible.js';
4
5
  export interface TOCProps {
5
6
  /**
6
7
  * Custom content in TOC container, before the main TOC
@@ -18,9 +19,13 @@ export declare function TOCItems({ items, isMenu, }: {
18
19
  items: TOCItemType[];
19
20
  isMenu?: boolean;
20
21
  }): import("react/jsx-runtime").JSX.Element;
21
- export declare const TocPopover: import("react").FC<import("@radix-ui/react-popover").PopoverProps>;
22
+ type MakeRequired<T, K extends keyof T> = T & {
23
+ [P in K]-?: T[P];
24
+ };
25
+ export declare function TocPopover({ open, onOpenChange, ref: _ref, ...props }: MakeRequired<ComponentProps<typeof Collapsible>, 'open' | 'onOpenChange'>): import("react/jsx-runtime").JSX.Element;
22
26
  export declare function TocPopoverTrigger({ items, ...props }: PopoverTriggerProps & {
23
27
  items: TOCItemType[];
24
28
  }): import("react/jsx-runtime").JSX.Element;
25
29
  export declare function TocPopoverContent(props: PopoverContentProps): import("react/jsx-runtime").JSX.Element;
30
+ export {};
26
31
  //# 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,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAmB,MAAM,OAAO,CAAC;AAU7E,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAIjC,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,QAAQ,CAAC,EACvB,KAAK,EACL,MAAc,GACf,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CA6BA;AAkBD,eAAO,MAAM,UAAU,oEAAU,CAAC;AAElC,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,GAAG,KAAK,EACT,EAAE,mBAAmB,GAAG;IAAE,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,2CAyBhD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,2CAiB3D"}
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,EAEnB,KAAK,cAAc,EACnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,WAAW,EAGZ,MAAM,6BAA6B,CAAC;AAErC,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,QAAQ,CAAC,EACvB,KAAK,EACL,MAAM,GACP,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,2CAgCA;AAkBD,KAAK,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG;KAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAOnE,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,YAAY,EACZ,GAAG,EAAE,IAAI,EACT,GAAG,KAAK,EACT,EAAE,YAAY,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,2CAgB3E;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,GAAG,KAAK,EACT,EAAE,mBAAmB,GAAG;IAAE,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,2CAmChD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,2CAU3D"}
@@ -1,44 +1,51 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as Primitive from 'fumadocs-core/toc';
4
- import { useMemo, useRef } from 'react';
4
+ import { createContext, use, useMemo, 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
8
  import { ScrollArea, ScrollViewport } from '../ui/scroll-area.js';
9
- import { Popover, PopoverContent, PopoverTrigger, } from '../../components/ui/popover.js';
10
9
  import { ChevronRight, Text } from 'lucide-react';
11
10
  import { usePageStyles } from '../../contexts/layout.js';
11
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../components/ui/collapsible.js';
12
12
  export function Toc(props) {
13
13
  const { toc } = usePageStyles();
14
- return (_jsx("div", { id: "nd-toc", ...props, className: cn('sticky top-[calc(var(--fd-banner-height)+var(--fd-nav-height))] h-[var(--fd-toc-height)] pb-2 pt-12', toc, props.className), style: {
14
+ 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: {
15
15
  ...props.style,
16
16
  '--fd-toc-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
17
- }, children: _jsx("div", { className: "flex h-full w-[var(--fd-toc-width)] max-w-full flex-col gap-3 pe-4", children: props.children }) }));
17
+ }, children: _jsx("div", { className: "flex h-full w-(--fd-toc-width) max-w-full flex-col gap-3 pe-4", children: props.children }) }));
18
18
  }
19
19
  export function TocItemsEmpty() {
20
20
  const { text } = useI18n();
21
21
  return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
22
22
  }
23
- export function TOCItems({ items, isMenu = false, }) {
23
+ export function TOCItems({ items, isMenu, }) {
24
24
  const containerRef = useRef(null);
25
25
  const viewRef = useRef(null);
26
26
  if (items.length === 0)
27
27
  return _jsx(TocItemsEmpty, {});
28
- return (_jsx(ScrollArea, { className: cn('flex flex-col', isMenu && '-ms-3'), children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: _jsxs(ScrollViewport, { className: "relative min-h-0 text-sm", ref: viewRef, children: [_jsx(TocThumb, { containerRef: containerRef, className: "absolute start-0 mt-[var(--fd-top)] h-[var(--fd-height)] w-px bg-fd-primary transition-all" }), _jsx("div", { ref: containerRef, className: cn('flex flex-col', !isMenu && 'border-s border-fd-foreground/10'), children: items.map((item) => (_jsx(TOCItem, { item: item }, item.url))) })] }) }) }));
28
+ return (_jsx(ScrollArea, { className: "flex flex-col ps-px", children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: _jsxs(ScrollViewport, { className: cn('relative min-h-0 text-sm', isMenu && 'mt-2 mb-4 mx-4 md:mx-6'), ref: viewRef, children: [_jsx(TocThumb, { containerRef: containerRef, className: "absolute start-0 mt-(--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))) })] }) }) }));
29
29
  }
30
30
  function TOCItem({ item }) {
31
- 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.5', item.depth === 3 && 'ps-6', item.depth >= 4 && 'ps-8'), children: item.title }));
31
+ 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 }));
32
+ }
33
+ const Context = createContext(null);
34
+ export function TocPopover({ open, onOpenChange, ref: _ref, ...props }) {
35
+ return (_jsx(Collapsible, { open: open, onOpenChange: onOpenChange, ...props, children: _jsx(Context, { value: useMemo(() => ({
36
+ open,
37
+ setOpen: onOpenChange,
38
+ }), [onOpenChange, open]), children: props.children }) }));
32
39
  }
33
- export const TocPopover = Popover;
34
40
  export function TocPopoverTrigger({ items, ...props }) {
35
41
  const { text } = useI18n();
42
+ const { open } = use(Context);
36
43
  const active = Primitive.useActiveAnchor();
37
44
  const current = useMemo(() => {
38
45
  return items.find((item) => active === item.url.slice(1))?.title;
39
46
  }, [items, active]);
40
- return (_jsxs(PopoverTrigger, { ...props, className: cn('inline-flex items-center gap-2 text-nowrap px-4 py-2 text-start', props.className), children: [_jsx(Text, { className: "size-4 shrink-0" }), text.toc, current ? (_jsxs(_Fragment, { children: [_jsx(ChevronRight, { className: "-mx-1.5 size-4 shrink-0 text-fd-muted-foreground" }), _jsx("span", { className: "truncate text-fd-muted-foreground", children: current })] })) : null] }));
47
+ return (_jsxs(CollapsibleTrigger, { ...props, className: cn('inline-flex items-center text-sm gap-2 text-nowrap px-4 py-2 text-start md:px-6 md:py-3', props.className), children: [_jsx(Text, { className: "size-4 shrink-0" }), text.toc, _jsx(ChevronRight, { className: cn('size-4 shrink-0 text-fd-muted-foreground transition-all', !current && 'opacity-0', open ? 'rotate-90' : '-ms-1.5') }), _jsx("span", { className: cn('truncate text-fd-muted-foreground transition-opacity -ms-1.5', (!current || open) && 'opacity-0'), children: current })] }));
41
48
  }
42
49
  export function TocPopoverContent(props) {
43
- return (_jsx(PopoverContent, { hideWhenDetached: true, alignOffset: 16, align: "start", side: "bottom", "data-toc-popover": "", ...props, className: cn('flex max-h-[var(--radix-popover-content-available-height)] w-[260px] flex-col gap-4 p-3', props.className), children: props.children }));
50
+ return (_jsx(CollapsibleContent, { "data-toc-popover": "", className: "flex flex-col max-h-[50vh]", ...props, children: props.children }));
44
51
  }
@@ -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;AAY9B,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,CAAC;AAmBrB,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,KAAU,EACV,OAAe,EACf,YAAgB,EAChB,YAAoB,EACpB,GAAG,KAAK,EACT,EAAE,SAAS,2CAqFX;AAMD,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IACvD;;OAEG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CA6B3D"}
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;AAW9B,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,SAAS,EAAE,CAAC;AAmBrB,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,KAAU,EACV,OAAe,EACf,YAAgB,EAChB,YAAoB,EACpB,GAAG,KAAK,EACT,EAAE,SAAS,2CAgFX;AAMD,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IACvD;;OAEG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CA6B3D"}
@@ -1,8 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useMemo, useState, createContext, useContext, useRef, useLayoutEffect, useId, useEffect, } from 'react';
3
+ import { useMemo, useState, createContext, useContext, useLayoutEffect, useId, useEffect, } from 'react';
4
4
  import { cn } from '../utils/cn.js';
5
5
  import * as Primitive from './ui/tabs.js';
6
+ import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
6
7
  export { Primitive };
7
8
  const listeners = new Map();
8
9
  function addChangeListener(id, listener) {
@@ -21,16 +22,13 @@ export function Tabs({ groupId, items = [], persist = false, defaultIndex = 0, u
21
22
  const valueToIdMap = useMemo(() => new Map(), []);
22
23
  // eslint-disable-next-line react-hooks/exhaustive-deps -- re-reconstruct the collection if items changed
23
24
  const collection = useMemo(() => createCollection(), [items]);
24
- const onChange = (v) => {
25
+ const onUpdate = useEffectEvent((v) => {
25
26
  if (values.includes(v))
26
27
  setValue(v);
27
- };
28
- const onChangeRef = useRef(onChange);
29
- onChangeRef.current = onChange;
28
+ });
30
29
  useLayoutEffect(() => {
31
30
  if (!groupId)
32
31
  return;
33
- const onUpdate = (v) => onChangeRef.current(v);
34
32
  const previous = persist
35
33
  ? localStorage.getItem(groupId)
36
34
  : sessionStorage.getItem(groupId);
@@ -40,7 +38,7 @@ export function Tabs({ groupId, items = [], persist = false, defaultIndex = 0, u
40
38
  return () => {
41
39
  removeChangeListener(groupId, onUpdate);
42
40
  };
43
- }, [groupId, persist]);
41
+ }, [groupId, onUpdate, persist]);
44
42
  useLayoutEffect(() => {
45
43
  const hash = window.location.hash.slice(1);
46
44
  if (!hash)
@@ -12,6 +12,6 @@ NavigationMenuTrigger.displayName = Primitive.Trigger.displayName;
12
12
  const NavigationMenuContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(Primitive.Content, { ref: ref, className: cn('absolute inset-x-0 top-0 data-[motion=from-end]:animate-fd-enterFromRight data-[motion=from-start]:animate-fd-enterFromLeft data-[motion=to-end]:animate-fd-exitToRight data-[motion=to-start]:animate-fd-exitToLeft', className), ...props })));
13
13
  NavigationMenuContent.displayName = Primitive.Content.displayName;
14
14
  const NavigationMenuLink = Primitive.Link;
15
- const NavigationMenuViewport = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: "flex w-full justify-center", children: _jsx(Primitive.Viewport, { ...props, className: cn('relative h-[var(--radix-navigation-menu-viewport-height)] w-full origin-[top_center] overflow-hidden text-fd-popover-foreground transition-[width,height] duration-300 data-[state=closed]:animate-fd-nav-menu-out data-[state=open]:animate-fd-nav-menu-in', className) }) })));
15
+ const NavigationMenuViewport = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: "flex w-full justify-center", children: _jsx(Primitive.Viewport, { ...props, className: cn('relative h-(--radix-navigation-menu-viewport-height) w-full origin-[top_center] overflow-hidden text-fd-popover-foreground transition-[width,height] duration-300 data-[state=closed]:animate-fd-nav-menu-out data-[state=open]:animate-fd-nav-menu-in', className) }) })));
16
16
  NavigationMenuViewport.displayName = Primitive.Viewport.displayName;
17
17
  export { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuContent, NavigationMenuTrigger, NavigationMenuLink, NavigationMenuViewport, };
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,SAAS,EAAU,MAAM,OAAO,CAAC;AAE5D,OAAO,EAEL,KAAK,YAAY,EAEjB,mBAAmB,EACnB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAEzB,UAAU,iBAAiB;IACzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAE/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAY,EACZ,MAAM,EACN,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAuCnB;AAED,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAEL,KAAK,YAAY,EAEjB,mBAAmB,EACnB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAGzB,UAAU,iBAAiB;IACzB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAE/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAY,EACZ,MAAM,EACN,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAkCnB;AAED,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,CAAC"}
package/dist/i18n.js CHANGED
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useCallback, useRef } from 'react';
4
3
  import { useRouter, usePathname } from 'next/navigation';
5
4
  import { useI18n, I18nContext, defaultTranslations, } from './contexts/i18n.js';
5
+ import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
6
6
  export function I18nProvider({ locales = [], locale, ...props }) {
7
7
  const context = useI18n();
8
8
  const router = useRouter();
9
9
  const pathname = usePathname();
10
- const onChangeCallback = (value) => {
10
+ const onChange = useEffectEvent((value) => {
11
11
  const segments = pathname.split('/').filter((v) => v.length > 0);
12
12
  // If locale prefix hidden
13
13
  if (segments[0] !== locale) {
@@ -18,10 +18,7 @@ export function I18nProvider({ locales = [], locale, ...props }) {
18
18
  }
19
19
  router.push(`/${segments.join('/')}`);
20
20
  router.refresh();
21
- };
22
- const onChangeRef = useRef(onChangeCallback);
23
- onChangeRef.current = onChangeCallback;
24
- const onChange = useCallback((v) => onChangeRef.current(v), []);
21
+ });
25
22
  return (_jsx(I18nContext.Provider, { value: {
26
23
  locale,
27
24
  locales,
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/sidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EAEnB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAInE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,2CAqDrD;AAED,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;CAAE,2CAwC3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAarD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,2CAe3E;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,cAAc,CAAC,GAAG;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,2CAgBA;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAqBlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAmCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAmBlE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAwB/C;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,eAsDA"}
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/layouts/docs/sidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,cAAc,EAEnB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,2CAqDrD;AAED,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;CAAE,2CAwC3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAYlE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAarD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,2CAkB3E;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,cAAc,CAAC,GAAG;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,2CAgBA;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAqBlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAmCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAmBlE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAiB/C;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,eAuDA"}