fumadocs-ui 14.7.7 → 15.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/css/animations.css +199 -0
  2. package/css/black.css +37 -0
  3. package/css/catppuccin.css +47 -0
  4. package/css/dusk.css +45 -0
  5. package/css/neutral.css +43 -0
  6. package/css/ocean.css +46 -0
  7. package/css/preset.css +37 -0
  8. package/css/purple.css +37 -0
  9. package/css/shiki.css +65 -0
  10. package/css/style.css +13 -0
  11. package/css/vitepress.css +78 -0
  12. package/dist/components/dialog/search.d.ts +1 -0
  13. package/dist/components/dialog/search.d.ts.map +1 -1
  14. package/dist/components/dialog/search.js +9 -6
  15. package/dist/components/layout/toc.js +1 -1
  16. package/dist/components/ui/button.d.ts +1 -1
  17. package/dist/components/ui/button.d.ts.map +1 -1
  18. package/dist/components/ui/button.js +1 -0
  19. package/dist/components/ui/popover.js +1 -1
  20. package/dist/layouts/docs/sidebar.d.ts.map +1 -1
  21. package/dist/layouts/docs/sidebar.js +44 -17
  22. package/dist/layouts/docs.js +1 -1
  23. package/dist/page.client.js +1 -1
  24. package/dist/style.css +2734 -2482
  25. package/dist/theme/docs-ui.d.ts +23 -0
  26. package/dist/theme/docs-ui.d.ts.map +1 -0
  27. package/dist/theme/docs-ui.js +58 -0
  28. package/dist/theme/typography/index.d.ts +2 -7
  29. package/dist/theme/typography/index.d.ts.map +1 -1
  30. package/dist/theme/typography/index.js +6 -10
  31. package/dist/theme/typography/styles.d.ts +12 -6
  32. package/dist/theme/typography/styles.d.ts.map +1 -1
  33. package/dist/theme/typography/styles.js +31 -25
  34. package/package.json +23 -24
  35. package/dist/tailwind-plugin.d.ts +0 -58
  36. package/dist/tailwind-plugin.d.ts.map +0 -1
  37. package/dist/tailwind-plugin.js +0 -199
  38. package/dist/theme/animations.d.ts +0 -170
  39. package/dist/theme/animations.d.ts.map +0 -1
  40. package/dist/theme/animations.js +0 -95
  41. package/dist/theme/colors.d.ts +0 -12
  42. package/dist/theme/colors.d.ts.map +0 -1
  43. package/dist/theme/colors.js +0 -323
@@ -17,7 +17,7 @@ export function SearchDialog({ open, onOpenChange, footer, links = [], search, o
17
17
  content: name,
18
18
  url: link,
19
19
  })), [links]);
20
- return (_jsxs(Dialog, { open: open, onOpenChange: onOpenChange, children: [_jsx(DialogOverlay, { className: "fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=closed]:animate-fd-fade-out data-[state=open]:animate-fd-fade-in" }), _jsxs(DialogContent, { "aria-describedby": undefined, className: "fixed left-1/2 top-[10vh] z-50 w-[98vw] max-w-screen-sm origin-left -translate-x-1/2 rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-lg data-[state=closed]:animate-fd-dialog-out data-[state=open]:animate-fd-dialog-in", children: [_jsx(DialogTitle, { className: "hidden", children: text.search }), _jsxs("div", { className: "flex flex-row items-center gap-2 px-3", children: [_jsx(LoadingIndicator, { isLoading: isLoading ?? false }), _jsx("input", { value: search, onChange: (e) => {
20
+ return (_jsxs(Dialog, { open: open, onOpenChange: onOpenChange, children: [_jsx(DialogOverlay, { className: "fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=closed]:animate-fd-fade-out data-[state=open]:animate-fd-fade-in" }), _jsxs(DialogContent, { "aria-describedby": undefined, className: "fixed left-1/2 top-[10vh] z-50 w-[98vw] max-w-screen-sm -translate-x-1/2 rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-lg data-[state=closed]:animate-fd-dialog-out data-[state=open]:animate-fd-dialog-in", children: [_jsx(DialogTitle, { className: "hidden", children: text.search }), _jsxs("div", { className: "flex flex-row items-center gap-2 px-3", children: [_jsx(LoadingIndicator, { isLoading: isLoading ?? false }), _jsx("input", { value: search, onChange: (e) => {
21
21
  onSearchChange(e.target.value);
22
22
  }, placeholder: text.search, className: "w-0 flex-1 bg-transparent py-3 text-base placeholder:text-fd-muted-foreground focus-visible:outline-none" }), _jsx("button", { type: "button", "aria-label": "Close Search", onClick: () => onOpenChange(false), className: cn(buttonVariants({
23
23
  color: 'outline',
@@ -38,8 +38,11 @@ function SearchResults({ items, onSelect, ...props }) {
38
38
  (!active || items.every((item) => item.id !== active))) {
39
39
  setActive(items[0].id);
40
40
  }
41
- const onOpen = (url) => {
42
- router.push(url);
41
+ const onOpen = ({ external, url }) => {
42
+ if (external)
43
+ window.open(url, '_blank')?.focus();
44
+ else
45
+ router.push(url);
43
46
  onSelect?.(url);
44
47
  sidebar.setOpen(false);
45
48
  };
@@ -56,7 +59,7 @@ function SearchResults({ items, onSelect, ...props }) {
56
59
  if (e.key === 'Enter') {
57
60
  const selected = items.find((item) => item.id === active);
58
61
  if (selected)
59
- onOpen(selected.url);
62
+ onOpen(selected);
60
63
  e.preventDefault();
61
64
  }
62
65
  }
@@ -70,7 +73,7 @@ function SearchResults({ items, onSelect, ...props }) {
70
73
  };
71
74
  }, []);
72
75
  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: () => {
73
- onOpen(item.url);
76
+ onOpen(item);
74
77
  }, 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)))] }));
75
78
  }
76
79
  function LoadingIndicator({ isLoading }) {
@@ -93,7 +96,7 @@ const itemVariants = cva('rounded-md border px-2 py-0.5 text-xs font-medium text
93
96
  },
94
97
  });
95
98
  export function TagsList({ tag, onTagChange, items, allowClear, ...props }) {
96
- return (_jsxs("div", { ...props, className: cn('flex flex-row items-center gap-1', props.className), children: [items.map((item) => (_jsx("button", { type: "button", "data-active": tag === item.value, className: cn(itemVariants({ active: tag === item.value }), item.props?.className), onClick: () => {
99
+ return (_jsxs("div", { ...props, className: cn('flex flex-row items-center gap-1 flex-wrap', props.className), children: [items.map((item) => (_jsx("button", { type: "button", "data-active": tag === item.value, className: cn(itemVariants({ active: tag === item.value }), item.props?.className), onClick: () => {
97
100
  if (tag === item.value && allowClear) {
98
101
  onTagChange(undefined);
99
102
  }
@@ -11,7 +11,7 @@ import { ChevronRight, Text } from 'lucide-react';
11
11
  import { usePageStyles } from '../../contexts/layout';
12
12
  export function Toc(props) {
13
13
  const { toc } = usePageStyles();
14
- return (_jsx("div", { id: "nd-toc", ...props, className: cn('sticky top-fd-layout-top 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-[var(--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
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 }) }));
@@ -1,5 +1,5 @@
1
1
  export declare const buttonVariants: (props?: ({
2
- color?: "outline" | "ghost" | "secondary" | null | undefined;
2
+ color?: "primary" | "outline" | "ghost" | "secondary" | null | undefined;
3
3
  size?: "sm" | "icon" | null | undefined;
4
4
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
5
5
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc;;;8EAgB1B,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc;;;8EAkB1B,CAAC"}
@@ -2,6 +2,7 @@ import { cva } from 'class-variance-authority';
2
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', {
3
3
  variants: {
4
4
  color: {
5
+ primary: 'bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80',
5
6
  outline: 'border hover:bg-fd-accent hover:text-fd-accent-foreground',
6
7
  ghost: 'hover:bg-fd-accent hover:text-fd-accent-foreground',
7
8
  secondary: 'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground',
@@ -5,7 +5,7 @@ import * as React from 'react';
5
5
  import { cn } from '../../utils/cn';
6
6
  const Popover = PopoverPrimitive.Root;
7
7
  const PopoverTrigger = PopoverPrimitive.Trigger;
8
- const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { ref: ref, align: align, sideOffset: sideOffset, side: "bottom", className: cn('z-50 min-w-[220px] max-w-[98vw] rounded-lg border bg-fd-popover p-2 text-sm text-fd-popover-foreground shadow-md focus-visible:outline-none data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in', className), ...props }) })));
8
+ const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { ref: ref, align: align, sideOffset: sideOffset, side: "bottom", className: cn('z-50 min-w-[220px] max-w-[98vw] rounded-lg border bg-fd-popover p-2 text-sm text-fd-popover-foreground shadow-lg focus-visible:outline-none data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in', className), ...props }) })));
9
9
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
10
10
  const PopoverClose = PopoverPrimitive.PopoverClose;
11
11
  export { Popover, PopoverTrigger, PopoverContent, PopoverClose };
@@ -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;AA6BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,2CAqDrD;AAED,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,KAAK,EACL,GAAG,KAAK,EACT,EAAE,YAAY,GAAG;IAAE,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;CAAE,2CAuC3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CASlE;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,2CAS3E;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAiBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,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,2CAelE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CA8BjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAQlE;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,2CAwB/C;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,eAqDA"}
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,2CASlE;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"}
@@ -14,16 +14,16 @@ import { useSidebar } from '../../contexts/sidebar';
14
14
  import { buttonVariants } from '../../components/ui/button';
15
15
  import { cva } from 'class-variance-authority';
16
16
  import { useTreeContext, useTreePath } from '../../contexts/tree';
17
- const itemVariants = cva('flex flex-row items-center gap-2 rounded-md p-2 text-start text-fd-muted-foreground [overflow-wrap:anywhere] md:py-1.5 [&_svg]:size-4 [&_svg]:shrink-0', {
17
+ const itemVariants = cva('relative flex flex-row items-center gap-2 rounded-md p-2 text-start text-fd-muted-foreground [overflow-wrap:anywhere] md:py-1.5 [&_svg]:size-4 [&_svg]:shrink-0', {
18
18
  variants: {
19
19
  active: {
20
- true: 'bg-fd-primary/10 font-medium text-fd-primary',
20
+ true: 'bg-fd-primary/10 text-fd-primary',
21
21
  false: 'transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none',
22
22
  },
23
23
  },
24
24
  });
25
- const Context = createContext(undefined);
26
- const FolderContext = createContext(undefined);
25
+ const Context = createContext(null);
26
+ const FolderContext = createContext(null);
27
27
  export function CollapsibleSidebar(props) {
28
28
  const { collapsed } = useSidebar();
29
29
  const [hover, setHover] = useState(false);
@@ -60,9 +60,10 @@ export function Sidebar({ defaultOpenLevel = 0, prefetch = true, inner, ...props
60
60
  return {
61
61
  defaultOpenLevel,
62
62
  prefetch,
63
+ level: 1,
63
64
  };
64
65
  }, [defaultOpenLevel, prefetch]);
65
- return (_jsx(Context.Provider, { value: context, children: _jsx(Base.SidebarList, { id: "nd-sidebar", blockScrollingWidth: 768, ...props, className: cn('fixed top-fd-layout-top z-30 bg-fd-card text-sm md:sticky md:h-[var(--fd-sidebar-height)]', 'max-md:inset-x-0 max-md:bottom-0 max-md:bg-fd-background/80 max-md:text-[15px] max-md:backdrop-blur-lg max-md:data-[open=false]:invisible', props.className), style: {
66
+ return (_jsx(Context.Provider, { value: context, children: _jsx(Base.SidebarList, { id: "nd-sidebar", blockScrollingWidth: 768, ...props, className: cn('fixed top-[calc(var(--fd-banner-height)+var(--fd-nav-height))] z-30 bg-fd-card text-sm md:sticky md:h-[var(--fd-sidebar-height)]', 'max-md:inset-x-0 max-md:bottom-0 max-md:bg-fd-background/80 max-md:text-[15px] max-md:backdrop-blur-lg max-md:data-[open=false]:invisible', props.className), style: {
66
67
  ...props.style,
67
68
  '--fd-sidebar-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
68
69
  }, children: _jsx("div", { ...inner, className: cn('flex size-full max-w-full flex-col pt-2 md:ms-auto md:w-[var(--fd-sidebar-width)] md:border-e md:pt-4', inner?.className), children: props.children }) }) }));
@@ -79,13 +80,20 @@ export function SidebarViewport(props) {
79
80
  }, children: props.children }) }));
80
81
  }
81
82
  export function SidebarSeparator(props) {
82
- return (_jsx("p", { ...props, className: cn('mb-2 px-2 text-sm font-medium', props.className), children: props.children }));
83
+ const { level } = useInternalContext();
84
+ return (_jsx("p", { ...props, className: cn('mb-2 px-2 text-sm font-medium', props.className), style: {
85
+ paddingInlineStart: getOffset(level),
86
+ ...props.style,
87
+ }, children: props.children }));
83
88
  }
84
89
  export function SidebarItem({ icon, ...props }) {
85
90
  const pathname = usePathname();
86
91
  const active = props.href !== undefined && isActive(props.href, pathname, false);
87
- const { prefetch } = useInternalContext();
88
- return (_jsxs(Link, { ...props, "data-active": active, className: cn(itemVariants({ active }), props.className), prefetch: prefetch, children: [icon ?? (props.external ? _jsx(ExternalLink, {}) : null), props.children] }));
92
+ const { prefetch, level } = useInternalContext();
93
+ return (_jsxs(Link, { ...props, "data-active": active, className: cn(itemVariants({ active }), props.className), prefetch: prefetch, style: {
94
+ paddingInlineStart: getOffset(level),
95
+ ...props.style,
96
+ }, children: [_jsx(Border, { level: level, active: active }), icon ?? (props.external ? _jsx(ExternalLink, {}) : null), props.children] }));
89
97
  }
90
98
  export function SidebarFolder({ defaultOpen = false, ...props }) {
91
99
  const [open, setOpen] = useState(defaultOpen);
@@ -96,12 +104,16 @@ export function SidebarFolder({ defaultOpen = false, ...props }) {
96
104
  return (_jsx(Collapsible, { open: open, onOpenChange: setOpen, ...props, children: _jsx(FolderContext.Provider, { value: useMemo(() => ({ open, setOpen }), [open]), children: props.children }) }));
97
105
  }
98
106
  export function SidebarFolderTrigger(props) {
107
+ const { level } = useInternalContext();
99
108
  const { open } = useFolderContext();
100
- return (_jsxs(CollapsibleTrigger, { ...props, className: cn(itemVariants({ active: false }), 'w-full'), children: [props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
109
+ return (_jsxs(CollapsibleTrigger, { ...props, className: cn(itemVariants({ active: false }), 'w-full'), style: {
110
+ paddingInlineStart: getOffset(level),
111
+ ...props.style,
112
+ }, children: [_jsx(Border, { level: level }), props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
101
113
  }
102
114
  export function SidebarFolderLink(props) {
103
115
  const { open, setOpen } = useFolderContext();
104
- const { prefetch } = useInternalContext();
116
+ const { prefetch, level } = useInternalContext();
105
117
  const pathname = usePathname();
106
118
  const active = props.href !== undefined && isActive(props.href, pathname, false);
107
119
  return (_jsxs(Link, { ...props, "data-active": active, className: cn(itemVariants({ active }), 'w-full', props.className), onClick: (e) => {
@@ -112,10 +124,17 @@ export function SidebarFolderLink(props) {
112
124
  else {
113
125
  setOpen((prev) => !active || !prev);
114
126
  }
115
- }, prefetch: prefetch, children: [props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
127
+ }, prefetch: prefetch, style: {
128
+ paddingInlineStart: getOffset(level),
129
+ ...props.style,
130
+ }, children: [_jsx(Border, { level: level, active: active }), props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
116
131
  }
117
132
  export function SidebarFolderContent(props) {
118
- return (_jsx(CollapsibleContent, { ...props, children: _jsx("div", { className: "ms-3 border-s py-1.5 ps-1.5 md:ms-2", children: props.children }) }));
133
+ const ctx = useInternalContext();
134
+ return (_jsx(CollapsibleContent, { ...props, className: cn('relative', props.className), children: _jsxs(Context, { value: useMemo(() => ({
135
+ ...ctx,
136
+ level: ctx.level + 1,
137
+ }), [ctx]), children: [_jsx("div", { className: "absolute w-px inset-y-0 bg-fd-border start-3" }), props.children] }) }));
119
138
  }
120
139
  export function SidebarCollapseTrigger(props) {
121
140
  const { collapsed, setCollapsed } = useSidebar();
@@ -147,7 +166,7 @@ export function SidebarPageTree(props) {
147
166
  const { Separator, Item, Folder } = props.components ?? {};
148
167
  function renderSidebarList(items, level) {
149
168
  return items.map((item, i) => {
150
- const id = `${item.type}_${i.toString()}`;
169
+ const id = `${item.type}_${i}`;
151
170
  if (item.type === 'separator') {
152
171
  if (Separator)
153
172
  return _jsx(Separator, { item: item }, id);
@@ -157,7 +176,7 @@ export function SidebarPageTree(props) {
157
176
  const children = renderSidebarList(item.children, level + 1);
158
177
  if (Folder)
159
178
  return (_jsx(Folder, { item: item, level: level, children: children }, id));
160
- return (_jsx(PageTreeFolder, { item: item, level: level, children: children }, id));
179
+ return (_jsx(PageTreeFolder, { item: item, children: children }, id));
161
180
  }
162
181
  if (Item)
163
182
  return _jsx(Item, { item: item }, item.url);
@@ -167,8 +186,16 @@ export function SidebarPageTree(props) {
167
186
  return renderSidebarList(root.children, 1);
168
187
  }, [root, props.components]);
169
188
  }
170
- function PageTreeFolder({ item, children, level, }) {
171
- const { defaultOpenLevel } = useInternalContext();
189
+ function PageTreeFolder({ item, ...props }) {
190
+ const { defaultOpenLevel, level } = useInternalContext();
172
191
  const path = useTreePath();
173
- return (_jsxs(SidebarFolder, { defaultOpen: (item.defaultOpen ?? defaultOpenLevel >= level) || path.includes(item), children: [item.index ? (_jsxs(SidebarFolderLink, { href: item.index.url, external: item.index.external, children: [item.icon, item.name] })) : (_jsxs(SidebarFolderTrigger, { children: [item.icon, item.name] })), _jsx(SidebarFolderContent, { children: children })] }));
192
+ return (_jsxs(SidebarFolder, { defaultOpen: (item.defaultOpen ?? defaultOpenLevel >= level) || path.includes(item), children: [item.index ? (_jsxs(SidebarFolderLink, { href: item.index.url, external: item.index.external, ...props, children: [item.icon, item.name] })) : (_jsxs(SidebarFolderTrigger, { ...props, children: [item.icon, item.name] })), _jsx(SidebarFolderContent, { children: props.children })] }));
193
+ }
194
+ function getOffset(level) {
195
+ return `calc(var(--spacing) * ${(level > 1 ? level : 0) * 2 + 2})`;
196
+ }
197
+ function Border({ level, active }) {
198
+ if (level <= 1)
199
+ return null;
200
+ return (_jsx("div", { className: cn('absolute w-px inset-y-2 z-[2] start-3', active && 'bg-fd-primary') }));
174
201
  }
@@ -21,7 +21,7 @@ export function DocsLayout({ nav: { enabled: navEnabled = true, component: navRe
21
21
  const links = getLinks(props.links ?? [], props.githubUrl);
22
22
  const Aside = collapsible ? CollapsibleSidebar : Sidebar;
23
23
  const tabs = getSidebarTabsFromOptions(tabOptions, props.tree) ?? [];
24
- const variables = cn('[--fd-tocnav-height:36px] md:[--fd-sidebar-width:268px] xl:[--fd-toc-width:268px] xl:[--fd-tocnav-height:0px]', !navReplace && navEnabled
24
+ const variables = cn('[--fd-tocnav-height:36px] md:[--fd-sidebar-width:268px] xl:md:[--fd-sidebar-width:286px] xl:[--fd-toc-width:286px] xl:[--fd-tocnav-height:0px]', !navReplace && navEnabled
25
25
  ? '[--fd-nav-height:3.5rem] md:[--fd-nav-height:0px]'
26
26
  : undefined);
27
27
  const pageStyles = {
@@ -17,7 +17,7 @@ export function TocNav(props) {
17
17
  const { open } = useSidebar();
18
18
  const { tocNav } = usePageStyles();
19
19
  const { isTransparent } = useNav();
20
- return (_jsx("header", { id: "nd-tocnav", ...props, className: cn('sticky top-fd-layout-top z-10 flex flex-row items-center border-b border-fd-foreground/10 text-sm backdrop-blur-md transition-colors', !isTransparent && 'bg-fd-background/80', open && 'opacity-0', tocNav, props.className), style: {
20
+ return (_jsx("header", { id: "nd-tocnav", ...props, className: cn('sticky top-[calc(var(--fd-banner-height)+var(--fd-nav-height))] z-10 flex flex-row items-center border-b border-fd-foreground/10 text-sm backdrop-blur-md transition-colors', !isTransparent && 'bg-fd-background/80', open && 'opacity-0', tocNav, props.className), style: {
21
21
  ...props.style,
22
22
  '--fd-toc-top-with-offset': 'calc(4px + var(--fd-banner-height) + var(--fd-nav-height))',
23
23
  }, children: props.children }));