@fumadocs/base-ui 16.11.4 → 16.12.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 (76) hide show
  1. package/css/generated/docs.css +1 -1
  2. package/css/generated/flux.css +1 -1
  3. package/css/generated/glass.css +1 -0
  4. package/css/generated/home.css +1 -1
  5. package/css/generated/notebook.css +1 -1
  6. package/css/generated/shared.css +1 -1
  7. package/css/lib/base.css +2 -1
  8. package/css/preset.css +0 -1
  9. package/dist/.translations/index.d.ts +7 -0
  10. package/dist/.translations/keys.js +7 -0
  11. package/dist/components/codeblock.d.ts +2 -1
  12. package/dist/components/image-zoom.d.ts +2 -2
  13. package/dist/components/image-zoom.js +1 -1
  14. package/dist/components/sidebar/base.js +6 -2
  15. package/dist/components/sidebar/tabs/dropdown.d.ts +2 -3
  16. package/dist/components/sidebar/tabs/dropdown.js +9 -4
  17. package/dist/components/tabs.js +0 -1
  18. package/dist/components/toc/index.js +1 -1
  19. package/dist/components/ui/popover.js +1 -1
  20. package/dist/components/ui/tabs.d.ts +1 -1
  21. package/dist/components/ui/tabs.js +36 -11
  22. package/dist/layouts/docs/client.js +10 -5
  23. package/dist/layouts/docs/page/slots/toc.js +17 -11
  24. package/dist/layouts/docs/slots/sidebar.js +8 -2
  25. package/dist/layouts/flux/index.d.ts +1 -1
  26. package/dist/layouts/flux/index.js +2 -2
  27. package/dist/layouts/flux/page/slots/toc.js +7 -4
  28. package/dist/layouts/flux/slots/sidebar.js +6 -0
  29. package/dist/layouts/flux/slots/tab-dropdown.js +8 -2
  30. package/dist/layouts/glass/index.d.ts +41 -0
  31. package/dist/layouts/glass/index.js +70 -0
  32. package/dist/layouts/glass/layout-tabs.js +53 -0
  33. package/dist/layouts/glass/page/index.d.ts +31 -0
  34. package/dist/layouts/glass/page/index.js +92 -0
  35. package/dist/layouts/glass/page/slots/breadcrumb.d.ts +7 -0
  36. package/dist/layouts/glass/page/slots/breadcrumb.js +44 -0
  37. package/dist/layouts/glass/page/slots/footer.d.ts +16 -0
  38. package/dist/layouts/glass/page/slots/footer.js +56 -0
  39. package/dist/layouts/glass/page/slots/toc.d.ts +19 -0
  40. package/dist/layouts/glass/page/slots/toc.js +108 -0
  41. package/dist/layouts/glass/slots/header.d.ts +6 -0
  42. package/dist/layouts/glass/slots/header.js +73 -0
  43. package/dist/layouts/glass/slots/sidebar.d.ts +23 -0
  44. package/dist/layouts/glass/slots/sidebar.js +294 -0
  45. package/dist/layouts/home/index.js +2 -2
  46. package/dist/layouts/home/slots/header.js +1 -0
  47. package/dist/layouts/notebook/client.js +2 -2
  48. package/dist/layouts/notebook/page/slots/toc.js +17 -11
  49. package/dist/layouts/notebook/slots/header.js +8 -2
  50. package/dist/layouts/notebook/slots/sidebar.js +8 -2
  51. package/dist/layouts/shared/client.d.ts +1 -1
  52. package/dist/layouts/shared/client.js +1 -1
  53. package/dist/layouts/shared/index.d.ts +7 -6
  54. package/dist/layouts/shared/index.js +5 -3
  55. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/controlled.d.ts +1 -1
  56. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/controlled.js +1 -1
  57. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/uncontrolled.d.ts +1 -1
  58. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/uncontrolled.js +1 -1
  59. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/adjust-svg-ids.js +1 -1
  60. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/compute-positioned-style.js +1 -1
  61. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/element-tests.js +1 -1
  62. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-div-img-style.js +1 -1
  63. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-img-alt.js +1 -1
  64. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-img-object-fit-style.js +1 -1
  65. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-img-regular-style.js +1 -1
  66. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-img-src.js +1 -1
  67. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-modal-img-transform.js +1 -1
  68. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-scale.js +1 -1
  69. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-style-ghost.js +1 -1
  70. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-style-modal-img.js +1 -1
  71. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/get-target-dimension.js +1 -1
  72. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/parse-position.js +1 -1
  73. package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/utils/test-has-scalable-src.js +1 -1
  74. package/dist/style.css +985 -885
  75. package/package.json +18 -11
  76. /package/dist/node_modules/.pnpm/{react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7 → react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8}/node_modules/react-medium-image-zoom/dist/index.d.ts +0 -0
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { cn } from "../../../utils/cn.js";
3
+ import { buttonVariants } from "../../../components/ui/button.js";
4
+ import { LayoutTabsDropdown } from "../layout-tabs.js";
5
+ import { useGlassLayout } from "../index.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { ChevronsUpDown, LanguagesIcon, MessageCircleIcon, SidebarIcon } from "lucide-react";
8
+ import { useTranslations } from "@fuma-translate/react";
9
+ import { Drawer } from "@base-ui/react/drawer";
10
+ //#region src/layouts/glass/slots/header.tsx
11
+ const baseVariants = "rounded-full bg-fd-popover/80 text-fd-popover-foreground border backdrop-blur-sm shadow-sm";
12
+ function Header({ className, ...props }) {
13
+ const { props: { tabs, aiChat }, slots } = useGlassLayout();
14
+ const t = useTranslations();
15
+ const sidebar = slots.sidebar.use();
16
+ return /* @__PURE__ */ jsxs("div", {
17
+ className: cn("sticky flex flex-row justify-end gap-2 [grid-area:left-margin/left-margin/right/right] z-20 px-4 md:top-0 md:pt-2 md:px-2 md:h-12 md:bg-linear-to-b md:from-fd-background max-md:bottom-0 max-md:mt-auto max-md:h-16 max-md:pb-4 max-md:bg-linear-to-t max-md:from-fd-background", className),
18
+ ...props,
19
+ children: [
20
+ sidebar.collapsible && sidebar.collapsed && /* @__PURE__ */ jsx("button", {
21
+ "aria-label": t("Show Sidebar", { note: "sidebar" }),
22
+ className: cn(buttonVariants({
23
+ size: "icon-sm",
24
+ variant: "secondary"
25
+ }), baseVariants, "size-10 me-auto shrink-0 max-md:hidden"),
26
+ onClick: () => sidebar.setCollapsed(false),
27
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
28
+ }),
29
+ slots.searchTrigger && /* @__PURE__ */ jsx(slots.searchTrigger.sm, {
30
+ color: "secondary",
31
+ size: "icon",
32
+ className: cn(baseVariants, "size-12 shrink-0 md:hidden")
33
+ }),
34
+ tabs.length > 0 && /* @__PURE__ */ jsx(LayoutTabsDropdown, {
35
+ tabs,
36
+ size: "lg",
37
+ className: cn(baseVariants, "min-w-0 ps-4 pe-3 flex-1 [&_svg]:size-5 md:hidden")
38
+ }),
39
+ slots.searchTrigger && /* @__PURE__ */ jsx("div", {
40
+ className: "@container flex justify-end flex-1 max-md:hidden",
41
+ children: /* @__PURE__ */ jsx(slots.searchTrigger.full, { className: cn(baseVariants, "text-fd-muted-foreground ps-3 w-full @sm:max-w-[200px]") })
42
+ }),
43
+ aiChat && !aiChat.open && /* @__PURE__ */ jsxs("button", {
44
+ className: cn(buttonVariants({ variant: "secondary" }), baseVariants, "px-3 gap-2 text-fd-muted-foreground shrink-0 max-md:hidden"),
45
+ onClick: () => aiChat.onOpenChange(true),
46
+ children: [/* @__PURE__ */ jsx(MessageCircleIcon, { className: "size-4" }), t("Ask AI", { note: "AI chat button" })]
47
+ }),
48
+ slots.languageSelect && /* @__PURE__ */ jsxs(slots.languageSelect.root, {
49
+ className: cn(baseVariants, "px-3 rounded-full max-md:hidden"),
50
+ children: [
51
+ /* @__PURE__ */ jsx(LanguagesIcon, { className: "size-4 text-fd-muted-foreground shrink-0" }),
52
+ /* @__PURE__ */ jsx(slots.languageSelect.text, {}),
53
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-3.5 text-fd-muted-foreground shrink-0" })
54
+ ]
55
+ }),
56
+ slots.themeSwitch && /* @__PURE__ */ jsx(slots.themeSwitch, { className: cn(baseVariants, "shrink-0 px-1.5 max-md:hidden") }),
57
+ /* @__PURE__ */ jsx(Drawer.Trigger, {
58
+ handle: slots.sidebar.drawerHandle,
59
+ render: (props, { open }) => /* @__PURE__ */ jsx("button", {
60
+ ...props,
61
+ className: cn(buttonVariants({
62
+ variant: "secondary",
63
+ size: "icon"
64
+ }), baseVariants, "shrink-0 size-12 md:hidden"),
65
+ "aria-label": open ? t("Close Sidebar", { note: "aria-label" }) : t("Open Sidebar", { note: "aria-label" }),
66
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
67
+ })
68
+ })
69
+ ]
70
+ });
71
+ }
72
+ //#endregion
73
+ export { Header };
@@ -0,0 +1,23 @@
1
+ import { ComponentProps, ReactNode } from "react";
2
+ import { Drawer } from "@base-ui/react/drawer";
3
+ //#region src/layouts/glass/slots/sidebar.d.ts
4
+ declare const drawerHandle: Drawer.Handle<unknown>;
5
+ interface SidebarProviderProps {
6
+ /** @default true */
7
+ collapsible?: boolean;
8
+ children: ReactNode;
9
+ }
10
+ declare function SidebarProvider({ children, collapsible }: SidebarProviderProps): import("react").JSX.Element;
11
+ declare function useSidebar(): {
12
+ collapsible: boolean;
13
+ collapsed: boolean;
14
+ setCollapsed: (v: boolean) => void;
15
+ };
16
+ interface SidebarDrawerProps {
17
+ contentProps?: ComponentProps<'div'>;
18
+ }
19
+ declare function SidebarDrawer({ contentProps }: SidebarDrawerProps): import("react").JSX.Element;
20
+ type SidebarProps = ComponentProps<'aside'>;
21
+ declare function Sidebar({ className, children, ...props }: SidebarProps): import("react").JSX.Element;
22
+ //#endregion
23
+ export { Sidebar, SidebarDrawer, SidebarDrawerProps, SidebarProps, SidebarProvider, SidebarProviderProps, drawerHandle, useSidebar };
@@ -0,0 +1,294 @@
1
+ "use client";
2
+ import { cn } from "../../../utils/cn.js";
3
+ import { buttonVariants } from "../../../components/ui/button.js";
4
+ import { useTreeContext, useTreePath } from "../../../contexts/tree.js";
5
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../../components/ui/collapsible.js";
6
+ import { isLinkItemActive } from "../../shared/index.js";
7
+ import { ScrollArea, ScrollViewport } from "../../../components/ui/scroll-area.js";
8
+ import { LayoutTabsDropdown } from "../layout-tabs.js";
9
+ import { useGlassLayout } from "../index.js";
10
+ import Link from "fumadocs-core/link";
11
+ import { usePathname } from "fumadocs-core/framework";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ import { ChevronDown, ChevronsUpDown, LanguagesIcon, MessageCircleIcon, SidebarIcon, XIcon } from "lucide-react";
14
+ import { cva } from "class-variance-authority";
15
+ import { cloneElement, createContext, use, useMemo, useState } from "react";
16
+ import { useTranslations } from "@fuma-translate/react";
17
+ import { useOnChange } from "fumadocs-core/utils/use-on-change";
18
+ import { Drawer } from "@base-ui/react/drawer";
19
+ //#region src/layouts/glass/slots/sidebar.tsx
20
+ const drawerHandle = Drawer.createHandle();
21
+ const itemTriggerVariants = cva("inline-flex items-center gap-2 rounded-lg px-2.5 py-2 md:py-1.5 [&_svg]:size-4 outline-none focus-visible:ring-2 focus-visible:ring-fd-ring", { variants: { active: {
22
+ true: "bg-fd-primary/10 text-fd-primary",
23
+ false: "text-fd-muted-foreground hover:bg-fd-accent hover:text-fd-accent-foreground"
24
+ } } });
25
+ const Context = createContext(null);
26
+ function SidebarProvider({ children, collapsible = true }) {
27
+ const [collapsed, setCollapsed] = useState(false);
28
+ return /* @__PURE__ */ jsx(Context, {
29
+ value: useMemo(() => ({
30
+ collapsible,
31
+ collapsed,
32
+ setCollapsed
33
+ }), [collapsible, collapsed]),
34
+ children
35
+ });
36
+ }
37
+ function useSidebar() {
38
+ const v = use(Context);
39
+ if (!v) throw new Error("Missing <SidebarProvider />");
40
+ return v;
41
+ }
42
+ function SidebarDrawer({ contentProps }) {
43
+ const { menuItems, props: { aiChat }, slots } = useGlassLayout();
44
+ const { root } = useTreeContext();
45
+ const t = useTranslations();
46
+ return /* @__PURE__ */ jsx(Drawer.Root, {
47
+ handle: drawerHandle,
48
+ swipeDirection: "right",
49
+ children: /* @__PURE__ */ jsxs(Drawer.Portal, {
50
+ className: "z-40",
51
+ children: [/* @__PURE__ */ jsx(Drawer.Backdrop, { className: "[--bleed:3rem] fixed inset-0 min-h-dvh bg-fd-overlay backdrop-blur-sm opacity-[calc(1-var(--drawer-swipe-progress))] transition-opacity duration-450 ease-[cubic-bezier(0.32,0.72,0,1)] data-swiping:duration-0 data-ending-style:opacity-0 data-starting-style:opacity-0 data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] supports-[-webkit-touch-callout:none]:absolute" }), /* @__PURE__ */ jsx(Drawer.Viewport, {
52
+ className: "[--viewport-padding:0px] supports-[-webkit-touch-callout:none]:[--viewport-padding:0.625rem] fixed inset-0 flex items-stretch justify-end p-(--viewport-padding)",
53
+ children: /* @__PURE__ */ jsx(Drawer.Popup, {
54
+ id: "nd-mobile-sidebar",
55
+ className: cn("relative [--bleed:3rem] supports-[-webkit-touch-callout:none]:[--bleed:0px] w-[360px] h-full max-w-[calc(100vw-3rem+var(--bleed))] pr-(--bleed) -mr-(--bleed) border-l bg-fd-background text-fd-foreground text-[0.9375rem] outline-none shadow-md touch-auto [transform:translateX(var(--drawer-swipe-movement-x))] transition-transform duration-450 ease-[cubic-bezier(0.32,0.72,0,1)] data-swiping:select-none data-ending-style:[transform:translateX(calc(100%-var(--bleed)+var(--viewport-padding)+2px))] data-starting-style:[transform:translateX(calc(100%-var(--bleed)+var(--viewport-padding)+2px))] supports-[-webkit-touch-callout:none]:border supports-[-webkit-touch-callout:none]:rounded-xl", "[scrollbar-width:none] overflow-y-auto"),
56
+ children: /* @__PURE__ */ jsxs(Drawer.Content, {
57
+ ...contentProps,
58
+ className: cn("flex flex-col min-h-full px-3", contentProps?.className),
59
+ children: [
60
+ /* @__PURE__ */ jsxs("div", {
61
+ className: "sticky flex flex-col gap-2 top-0 pt-4 pb-2 bg-fd-background shadow-lg shadow-fd-background",
62
+ children: [/* @__PURE__ */ jsxs("div", {
63
+ className: "flex items-center gap-1.5 ps-2.5",
64
+ children: [
65
+ /* @__PURE__ */ jsx(Drawer.Title, { render: /* @__PURE__ */ jsx(slots.navTitle, { className: "flex items-center font-semibold gap-2 flex-1" }) }),
66
+ aiChat && /* @__PURE__ */ jsxs("button", {
67
+ className: cn(buttonVariants({
68
+ variant: "secondary",
69
+ size: "sm"
70
+ }), "rounded-full h-8 gap-1.5"),
71
+ onClick: () => {
72
+ aiChat.onOpenChange(!aiChat.open);
73
+ drawerHandle.close();
74
+ },
75
+ children: [/* @__PURE__ */ jsx(MessageCircleIcon, { className: "size-4 text-fd-muted-foreground" }), t("Ask AI", { note: "AI chat button" })]
76
+ }),
77
+ /* @__PURE__ */ jsx(Drawer.Close, {
78
+ "aria-label": t("Close Sidebar", { note: "aria-label" }),
79
+ className: cn(buttonVariants({
80
+ variant: "secondary",
81
+ size: "icon-sm"
82
+ }), "rounded-full"),
83
+ children: /* @__PURE__ */ jsx(XIcon, {})
84
+ })
85
+ ]
86
+ }), slots.languageSelect && /* @__PURE__ */ jsxs(slots.languageSelect.root, {
87
+ variant: "secondary",
88
+ className: "px-2.5 gap-2 rounded-lg",
89
+ children: [
90
+ /* @__PURE__ */ jsx(LanguagesIcon, { className: "size-4 text-fd-muted-foreground shrink-0" }),
91
+ /* @__PURE__ */ jsx(slots.languageSelect.text, {}),
92
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ms-auto size-3.5 text-fd-muted-foreground shrink-0" })
93
+ ]
94
+ })]
95
+ }),
96
+ /* @__PURE__ */ jsxs("div", {
97
+ className: "flex flex-col py-2 flex-1",
98
+ children: [menuItems.map((item, i) => item.type !== "icon" && /* @__PURE__ */ jsx(SidebarLinkItem, { item }, i)), root.children.map((item, i) => cloneElement(renderNode(item), { key: i }))]
99
+ }),
100
+ /* @__PURE__ */ jsxs("div", {
101
+ className: "flex items-center sticky bottom-0 bg-fd-background px-1 pt-2 pb-4 border-t mt-2 empty:hidden",
102
+ children: [menuItems.map((item, i) => item.type === "icon" && /* @__PURE__ */ jsx(SidebarIconLinkItem, { item }, i)), slots.themeSwitch && /* @__PURE__ */ jsx(slots.themeSwitch, { className: "p-0 ms-auto" })]
103
+ })
104
+ ]
105
+ })
106
+ })
107
+ })]
108
+ })
109
+ });
110
+ }
111
+ function Sidebar({ className, children, ...props }) {
112
+ const { menuItems, props: { tabs }, slots } = useGlassLayout();
113
+ const { root } = useTreeContext();
114
+ const { collapsible, collapsed, setCollapsed } = useSidebar();
115
+ const t = useTranslations({ note: "sidebar" });
116
+ return /* @__PURE__ */ jsxs("aside", {
117
+ id: "nd-sidebar",
118
+ className: cn("sticky flex flex-col transition-transform [grid-area:left] my-2 ms-2 z-30 top-2 border rounded-2xl bg-fd-popover/80 text-fd-popover-foreground text-sm backdrop-blur-sm shadow-sm h-[calc(100dvh---spacing(4))] max-md:hidden md:layout:[--fd-left-width:280px]", collapsed && "w-[calc(280px---spacing(2))] -translate-x-[280px] md:layout:[--fd-left-width:0px]", className),
119
+ ...props,
120
+ children: [
121
+ /* @__PURE__ */ jsxs("div", {
122
+ className: "flex items-start gap-1 pt-4 px-3.5 empty:hidden",
123
+ children: [/* @__PURE__ */ jsx(slots.navTitle, { className: "flex text-sm items-center font-semibold gap-2 me-auto" }), /* @__PURE__ */ jsxs("div", {
124
+ className: "flex -mt-1.5 -me-1.5 empty:hidden",
125
+ children: [menuItems.map((item, i) => item.type === "icon" && /* @__PURE__ */ jsx(SidebarIconLinkItem, { item }, i)), collapsible && /* @__PURE__ */ jsx("button", {
126
+ "aria-label": collapsed ? t("Show Sidebar") : t("Hide Sidebar"),
127
+ className: cn(buttonVariants({
128
+ variant: "ghost",
129
+ size: "icon-sm"
130
+ }), "text-fd-muted-foreground"),
131
+ onClick: () => setCollapsed(!collapsed),
132
+ children: /* @__PURE__ */ jsx(SidebarIcon, {})
133
+ })]
134
+ })]
135
+ }),
136
+ tabs.length > 0 && /* @__PURE__ */ jsx(LayoutTabsDropdown, {
137
+ tabs,
138
+ className: "min-w-0 bg-fd-secondary text-fd-secondary-foreground rounded-xl px-2.5 py-2 [&_svg]:size-4 border rounded-xl shadow-sm mx-2 mt-2.5 empty:hidden"
139
+ }),
140
+ /* @__PURE__ */ jsx(ScrollArea, {
141
+ className: "min-h-0 flex-1",
142
+ children: /* @__PURE__ */ jsxs(ScrollViewport, {
143
+ className: "flex flex-col p-2 [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent))]",
144
+ children: [menuItems.map((item, i) => item.type !== "icon" && /* @__PURE__ */ jsx(SidebarLinkItem, { item }, i)), root.children.map((item, i) => cloneElement(renderNode(item), { key: i }))]
145
+ })
146
+ }),
147
+ children
148
+ ]
149
+ });
150
+ }
151
+ function SidebarIconLinkItem({ item, className }) {
152
+ return /* @__PURE__ */ jsx(Link, {
153
+ href: item.url,
154
+ external: item.external,
155
+ "aria-label": item.label,
156
+ className: cn(buttonVariants({
157
+ variant: "ghost",
158
+ size: "icon-sm"
159
+ }), "text-fd-muted-foreground", className),
160
+ onClick: () => {
161
+ drawerHandle.close();
162
+ },
163
+ children: item.icon
164
+ });
165
+ }
166
+ function SidebarLinkItem({ item, className }) {
167
+ const pathname = usePathname();
168
+ const [open, setOpen] = useState(true);
169
+ switch (item.type) {
170
+ case "custom": return /* @__PURE__ */ jsx("div", {
171
+ className,
172
+ children: item.children
173
+ });
174
+ case "menu": {
175
+ const rightIcon = /* @__PURE__ */ jsx(ChevronDown, { className: cn("ms-auto text-fd-muted-foreground size-3.5! transition-transform", !open && "-rotate-90") });
176
+ return /* @__PURE__ */ jsxs(Collapsible, {
177
+ open,
178
+ onOpenChange: setOpen,
179
+ className: cn("mt-4 first:mt-0", className),
180
+ children: [item.url ? /* @__PURE__ */ jsxs("div", {
181
+ className: "flex w-full px-2.5 py-1.5 font-medium",
182
+ children: [/* @__PURE__ */ jsxs(Link, {
183
+ href: item.url,
184
+ external: item.external,
185
+ className: cn("inline-flex items-center gap-2 [&_svg]:size-4", isLinkItemActive(item, pathname) ? "text-fd-primary" : "hover:underline hover:decoration-fd-muted-foreground hover:underline-offset-4 hover:decoration-dashed hover:text-fd-accent-foreground"),
186
+ onClick: () => {
187
+ drawerHandle.close();
188
+ },
189
+ children: [item.icon, item.text]
190
+ }), /* @__PURE__ */ jsx(CollapsibleTrigger, {
191
+ className: "flex-1",
192
+ children: rightIcon
193
+ })]
194
+ }) : /* @__PURE__ */ jsxs(CollapsibleTrigger, {
195
+ className: "w-full px-2.5 py-1.5 font-medium inline-flex items-center gap-2 [&_svg]:size-4",
196
+ children: [
197
+ item.icon,
198
+ item.text,
199
+ rightIcon
200
+ ]
201
+ }), /* @__PURE__ */ jsx(CollapsibleContent, {
202
+ className: "flex flex-col",
203
+ children: item.items.map((item, i) => /* @__PURE__ */ jsx(SidebarLinkItem, { item }, i))
204
+ })]
205
+ });
206
+ }
207
+ default: return /* @__PURE__ */ jsxs(Link, {
208
+ href: item.url,
209
+ external: item.external,
210
+ className: cn(itemTriggerVariants({
211
+ active: isLinkItemActive(item, pathname),
212
+ className
213
+ })),
214
+ onClick: () => {
215
+ drawerHandle.close();
216
+ },
217
+ children: [item.icon, item.text]
218
+ });
219
+ }
220
+ }
221
+ function renderNode(node) {
222
+ if (node.type === "page") return /* @__PURE__ */ jsx(SidebarItem, { item: node });
223
+ if (node.type === "folder") return /* @__PURE__ */ jsx(SidebarFolder, { folder: node });
224
+ return /* @__PURE__ */ jsxs("p", {
225
+ className: "mt-4 w-full px-2.5 py-1.5 font-medium inline-flex items-center gap-2 [&_svg]:size-4 empty:hidden first:mt-0",
226
+ children: [node.icon, node.name]
227
+ });
228
+ }
229
+ function SidebarItem({ item }) {
230
+ const path = useTreePath();
231
+ return /* @__PURE__ */ jsxs(Link, {
232
+ href: item.url,
233
+ external: item.external,
234
+ className: itemTriggerVariants({ active: isNodeInPath(item, path) }),
235
+ onClick: () => {
236
+ drawerHandle.close();
237
+ },
238
+ children: [item.icon, item.name]
239
+ });
240
+ }
241
+ function SidebarFolder({ folder }) {
242
+ const path = useTreePath();
243
+ const shouldOpen = (folder.defaultOpen ?? true) || isNodeInPath(folder, path);
244
+ const [open, setOpen] = useState(shouldOpen);
245
+ useOnChange(shouldOpen, () => shouldOpen && setOpen(true));
246
+ if (folder.collapsible === false) return /* @__PURE__ */ jsxs(Fragment, { children: [folder.index ? /* @__PURE__ */ jsxs(Link, {
247
+ href: folder.index.url,
248
+ external: folder.index.external,
249
+ className: cn("inline-flex px-2.5 py-1.5 font-medium items-center gap-2 [&_svg]:size-4 mt-4 first:mt-0", isNodeInPath(folder.index, path) ? "text-fd-primary" : "hover:underline hover:decoration-fd-muted-foreground hover:underline-offset-4 hover:decoration-dashed hover:text-fd-accent-foreground"),
250
+ onClick: () => {
251
+ drawerHandle.close();
252
+ },
253
+ children: [folder.icon, folder.name]
254
+ }) : /* @__PURE__ */ jsxs("div", {
255
+ className: "w-full px-3 py-1.5 font-medium inline-flex items-center gap-2 [&_svg]:size-4 mt-4 first:mt-0",
256
+ children: [folder.icon, folder.name]
257
+ }), folder.children.map((item, i) => cloneElement(renderNode(item), { key: i }))] });
258
+ const rightIcon = /* @__PURE__ */ jsx(ChevronDown, { className: cn("ms-auto text-fd-muted-foreground size-3.5! transition-transform", !open && "-rotate-90") });
259
+ return /* @__PURE__ */ jsxs(Collapsible, {
260
+ open,
261
+ onOpenChange: setOpen,
262
+ className: "mt-4 first:mt-0",
263
+ children: [folder.index ? /* @__PURE__ */ jsxs("div", {
264
+ className: "flex w-full px-2.5 py-1.5 font-medium",
265
+ children: [/* @__PURE__ */ jsxs(Link, {
266
+ href: folder.index.url,
267
+ external: folder.index.external,
268
+ className: cn("inline-flex items-center gap-2 [&_svg]:size-4", isNodeInPath(folder.index, path) ? "text-fd-primary" : "hover:underline hover:decoration-fd-muted-foreground hover:underline-offset-4 hover:decoration-dashed hover:text-fd-accent-foreground"),
269
+ onClick: () => {
270
+ drawerHandle.close();
271
+ },
272
+ children: [folder.icon, folder.name]
273
+ }), /* @__PURE__ */ jsx(CollapsibleTrigger, {
274
+ className: "flex-1",
275
+ children: rightIcon
276
+ })]
277
+ }) : /* @__PURE__ */ jsxs(CollapsibleTrigger, {
278
+ className: "w-full px-2.5 py-1.5 font-medium inline-flex items-center gap-2 [&_svg]:size-4",
279
+ children: [
280
+ folder.icon,
281
+ folder.name,
282
+ rightIcon
283
+ ]
284
+ }), /* @__PURE__ */ jsx(CollapsibleContent, {
285
+ className: "flex flex-col",
286
+ children: folder.children.map((item, i) => cloneElement(renderNode(item), { key: i }))
287
+ })]
288
+ });
289
+ }
290
+ function isNodeInPath(node, path) {
291
+ return path.some((other) => other.$id === node.$id || other === node);
292
+ }
293
+ //#endregion
294
+ export { Sidebar, SidebarDrawer, SidebarProvider, drawerHandle, useSidebar };
@@ -12,12 +12,12 @@ function useHomeLayout() {
12
12
  if (!context) throw new Error("Please use this component under <HomeLayout /> (`fumadocs-ui/layouts/home`).");
13
13
  return context;
14
14
  }
15
- const { useProvider } = baseSlots({ useProps() {
15
+ const { useBaseSlots } = baseSlots({ useProps() {
16
16
  return useHomeLayout().props;
17
17
  } });
18
18
  function HomeLayout(props) {
19
19
  const { nav: { enabled: navEnabled = true } = {}, slots: defaultSlots, children, i18n: _i18n, githubUrl: _githubUrl, links: _links, themeSwitch: _themeSwitch, searchToggle: _searchToggle, ...rest } = props;
20
- const { baseSlots, baseProps } = useProvider(props);
20
+ const { baseSlots, baseProps } = useBaseSlots(props);
21
21
  const linkItems = useLinkItems(props);
22
22
  const slots = {
23
23
  ...baseSlots,
@@ -52,6 +52,7 @@ function Header(props) {
52
52
  }, []);
53
53
  const list = /* @__PURE__ */ jsxs(NavigationMenu.List, {
54
54
  ref: listRef,
55
+ render: /* @__PURE__ */ jsx("div", {}),
55
56
  className: "flex h-14 w-full mx-auto max-w-(--fd-layout-width) items-center px-4",
56
57
  children: [
57
58
  slots.navTitle && /* @__PURE__ */ jsx(slots.navTitle, { className: "inline-flex items-center gap-2.5 font-semibold" }),
@@ -9,7 +9,7 @@ import { Header } from "./slots/header.js";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { createContext, use } from "react";
11
11
  //#region src/layouts/notebook/client.tsx
12
- const { useProvider } = baseSlots({ useProps() {
12
+ const { useBaseSlots } = baseSlots({ useProps() {
13
13
  return useNotebookLayout().props;
14
14
  } });
15
15
  const LayoutContext = createContext(null);
@@ -22,7 +22,7 @@ function LayoutBody(props) {
22
22
  const { nav: { enabled: navEnabled = true, transparentMode: navTransparentMode = "none" } = {}, sidebar: { defaultOpenLevel, prefetch, ...sidebarProps } = {}, slots: defaultSlots, tabMode = "sidebar", tabs, tree, containerProps, children } = props;
23
23
  const isTop = useIsScrollTop({ enabled: navTransparentMode === "top" }) ?? true;
24
24
  const isNavTransparent = navTransparentMode === "top" ? isTop : navTransparentMode === "always";
25
- const { baseSlots, baseProps } = useProvider(props);
25
+ const { baseSlots, baseProps } = useBaseSlots(props);
26
26
  const linkItems = useLinkItems(props);
27
27
  const slots = {
28
28
  ...baseSlots,
@@ -33,10 +33,13 @@ function TOC({ container, header, footer, style = "normal", list }) {
33
33
  className: "inline-flex items-center gap-1.5 text-sm text-fd-muted-foreground",
34
34
  children: [/* @__PURE__ */ jsx(Text, { className: "size-4" }), t("On this page")]
35
35
  }),
36
- /* @__PURE__ */ jsx(TOCScrollArea, { children: /* @__PURE__ */ jsxs(TOCItems, {
37
- ...list,
38
- children: [items.length === 0 && /* @__PURE__ */ jsx(TOCEmpty, {}), items.map((item) => /* @__PURE__ */ jsx(TOCItem, { item }, item.url))]
39
- }) }),
36
+ /* @__PURE__ */ jsx(TOCScrollArea, {
37
+ className: "ms-px",
38
+ children: /* @__PURE__ */ jsxs(TOCItems, {
39
+ ...list,
40
+ children: [items.length === 0 && /* @__PURE__ */ jsx(TOCEmpty, {}), items.map((item) => /* @__PURE__ */ jsx(TOCItem, { item }, item.url))]
41
+ })
42
+ }),
40
43
  footer
41
44
  ]
42
45
  });
@@ -79,13 +82,16 @@ function TOCPopover({ container, trigger, content, header, footer, style = "norm
79
82
  ...content,
80
83
  children: [
81
84
  header,
82
- /* @__PURE__ */ jsx(TOCScrollArea, { children: /* @__PURE__ */ jsxs(TOCItems, {
83
- ...list,
84
- children: [items.length === 0 && /* @__PURE__ */ jsx(TOCEmpty, {}), items.map((item) => /* @__PURE__ */ jsx(TOCItem, {
85
- item,
86
- onClick: onClickItem
87
- }, item.url))]
88
- }) }),
85
+ /* @__PURE__ */ jsx(TOCScrollArea, {
86
+ className: "ms-px",
87
+ children: /* @__PURE__ */ jsxs(TOCItems, {
88
+ ...list,
89
+ children: [items.length === 0 && /* @__PURE__ */ jsx(TOCEmpty, {}), items.map((item) => /* @__PURE__ */ jsx(TOCItem, {
90
+ item,
91
+ onClick: onClickItem
92
+ }, item.url))]
93
+ })
94
+ }),
89
95
  footer
90
96
  ]
91
97
  })]
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../../../utils/cn.js";
3
3
  import { buttonVariants } from "../../../components/ui/button.js";
4
+ import { useTreePath } from "../../../contexts/tree.js";
4
5
  import { Popover, PopoverContent, PopoverTrigger } from "../../../components/ui/popover.js";
5
6
  import { LinkItem } from "../../shared/client.js";
6
7
  import { isLayoutTabActive } from "../../shared/index.js";
@@ -101,9 +102,14 @@ function Header(props) {
101
102
  }
102
103
  function LayoutHeaderTabs({ tabs, className, ...props }) {
103
104
  const pathname = usePathname();
105
+ const path = useTreePath();
104
106
  const selectedIdx = useMemo(() => {
105
- return tabs.findLastIndex((option) => isLayoutTabActive(option, pathname));
106
- }, [tabs, pathname]);
107
+ return tabs.findLastIndex((option) => isLayoutTabActive(option, path, pathname));
108
+ }, [
109
+ tabs,
110
+ path,
111
+ pathname
112
+ ]);
107
113
  return /* @__PURE__ */ jsx("div", {
108
114
  className: cn("flex flex-row items-end gap-6", className),
109
115
  ...props,
@@ -2,6 +2,7 @@
2
2
  import { cn } from "../../../utils/cn.js";
3
3
  import { buttonVariants } from "../../../components/ui/button.js";
4
4
  import { mergeRefs } from "../../../utils/merge-refs.js";
5
+ import { useTreePath } from "../../../contexts/tree.js";
5
6
  import { Popover, PopoverContent, PopoverTrigger } from "../../../components/ui/popover.js";
6
7
  import { LinkItem } from "../../shared/client.js";
7
8
  import { isLayoutTabActive } from "../../shared/index.js";
@@ -242,9 +243,14 @@ function SidebarTabsDropdown({ options, placeholder, ...props }) {
242
243
  const [open, setOpen] = useState(false);
243
244
  const { closeOnRedirect } = useSidebar();
244
245
  const pathname = usePathname();
246
+ const path = useTreePath();
245
247
  const selected = useMemo(() => {
246
- return options.findLast((item) => isLayoutTabActive(item, pathname));
247
- }, [options, pathname]);
248
+ return options.findLast((item) => isLayoutTabActive(item, path, pathname));
249
+ }, [
250
+ options,
251
+ path,
252
+ pathname
253
+ ]);
248
254
  const onClick = () => {
249
255
  closeOnRedirect.current = false;
250
256
  setOpen(false);
@@ -28,7 +28,7 @@ interface BaseSlotsProps<P extends BaseLayoutProps = BaseLayoutProps> extends Pi
28
28
  declare function baseSlots({ useProps }: {
29
29
  useProps: () => BaseSlotsProps;
30
30
  }): {
31
- useProvider(options: BaseLayoutProps): {
31
+ useBaseSlots(options: BaseLayoutProps): {
32
32
  baseSlots: BaseSlots;
33
33
  baseProps: BaseSlotsProps;
34
34
  };
@@ -56,7 +56,7 @@ function baseSlots({ useProps }) {
56
56
  children: title
57
57
  });
58
58
  }
59
- return { useProvider(options) {
59
+ return { useBaseSlots(options) {
60
60
  const { locales = [] } = useI18n();
61
61
  const { nav, slots = {}, i18n = locales.length > 1, searchToggle: { enabled: searchToggleEnabled = true, ...searchToggle } = {}, themeSwitch: { enabled: themeSwitchEnabled = true, ...themeSwitch } = {} } = options;
62
62
  return {
@@ -2,8 +2,8 @@ import { FullSearchTriggerProps, SearchTriggerProps } from "./slots/search-trigg
2
2
  import { ThemeSwitchProps } from "./slots/theme-switch.js";
3
3
  import { BaseSlots, BaseSlotsProps, LinkItem, baseSlots } from "./client.js";
4
4
  import { ComponentProps, FC, ReactNode } from "react";
5
- import * as PageTree from "fumadocs-core/page-tree";
6
5
  import { I18nConfig } from "fumadocs-core/i18n";
6
+ import * as PageTree from "fumadocs-core/page-tree";
7
7
  //#region src/layouts/shared/index.d.ts
8
8
  interface NavOptions {
9
9
  enabled?: boolean;
@@ -82,7 +82,7 @@ interface GetLayoutTabsOptions {
82
82
  transform?: (option: LayoutTab, node: PageTree.Folder) => LayoutTab | null;
83
83
  }
84
84
  declare function getLayoutTabs(tree: PageTree.Root, { transform }?: GetLayoutTabsOptions): LayoutTab[];
85
- declare function isLayoutTabActive(tab: LayoutTab, pathname: string): boolean;
85
+ declare function isLayoutTabActive(tab: LayoutTab, path: PageTree.Node[], pathname: string): boolean;
86
86
  interface Filterable {
87
87
  /**
88
88
  * Restrict where the item is displayed
@@ -159,11 +159,12 @@ type LinkItemType = MainItemType | IconItemType | ButtonItemType | MenuItemType
159
159
  * Get link items with shortcuts
160
160
  */
161
161
  declare function resolveLinkItems({ links, githubUrl }: Pick<BaseLayoutProps, 'links' | 'githubUrl'>): LinkItemType[];
162
- declare function useLinkItems({ githubUrl, links }: Pick<BaseLayoutProps, 'links' | 'githubUrl'>): {
162
+ interface GroupedLinkItems {
163
+ all: LinkItemType[];
163
164
  navItems: LinkItemType[];
164
165
  menuItems: LinkItemType[];
165
- all: LinkItemType[];
166
- };
166
+ }
167
+ declare function useLinkItems({ githubUrl, links }: Pick<BaseLayoutProps, 'links' | 'githubUrl'>): GroupedLinkItems;
167
168
  declare function isLinkItemActive(link: LinkItemType, pathname: string): boolean;
168
169
  //#endregion
169
- export { BaseLayoutProps, type BaseSlots, type BaseSlotsProps, ButtonItemType, CustomItemType, GetLayoutTabsOptions, IconItemType, LayoutTab, LinkItem, LinkItemType, MainItemType, MenuItemType, NavOptions, baseSlots, getLayoutTabs, isLayoutTabActive, isLinkItemActive, resolveLinkItems, useLinkItems };
170
+ export { BaseLayoutProps, type BaseSlots, type BaseSlotsProps, ButtonItemType, CustomItemType, GetLayoutTabsOptions, GroupedLinkItems, IconItemType, LayoutTab, LinkItem, LinkItemType, MainItemType, MenuItemType, NavOptions, baseSlots, getLayoutTabs, isLayoutTabActive, isLinkItemActive, resolveLinkItems, useLinkItems };
@@ -2,7 +2,6 @@ import { isActive, normalize } from "../../utils/urls.js";
2
2
  import { LinkItem, baseSlots } from "./client.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { useMemo } from "react";
5
- import * as PageTree from "fumadocs-core/page-tree";
6
5
  //#region src/layouts/shared/index.tsx
7
6
  const defaultTransform = (option, node) => {
8
7
  if (!node.icon) return option;
@@ -38,8 +37,11 @@ function getLayoutTabs(tree, { transform = defaultTransform } = {}) {
38
37
  if (tree.fallback) next(tree.fallback, true);
39
38
  return results;
40
39
  }
41
- function isLayoutTabActive(tab, pathname) {
42
- if (tab.$folder) return PageTree.findPath(tab.$folder.children, (node) => node.type === "page" && isActive(node.url, pathname)) !== null;
40
+ function isLayoutTabActive(tab, path, pathname) {
41
+ if (tab.$folder) {
42
+ const folder = tab.$folder;
43
+ return path.some((node) => node.type === "folder" && (node.$id === folder.$id || node === folder));
44
+ }
43
45
  if (tab.urls) return tab.urls.has(normalize(pathname));
44
46
  return isActive(tab.url, pathname, true);
45
47
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/react-medium-image-zoom/dist/controlled.d.ts
2
+ //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/react-medium-image-zoom/dist/controlled.d.ts
3
3
  type ModalState = 'LOADED' | 'LOADING' | 'UNLOADED' | 'UNLOADING';
4
4
  interface ControlledProps {
5
5
  a11yNameButtonUnzoom?: string;
@@ -6,7 +6,7 @@ import { getStyleGhost } from "./utils/get-style-ghost.js";
6
6
  import { getStyleModalImg } from "./utils/get-style-modal-img.js";
7
7
  import React from "react";
8
8
  import ReactDOM from "react-dom";
9
- //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/react-medium-image-zoom/dist/controlled.js
9
+ //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/react-medium-image-zoom/dist/controlled.js
10
10
  const IMAGE_QUERY = [
11
11
  "img",
12
12
  "svg",
@@ -1,6 +1,6 @@
1
1
  import { ControlledProps } from "./controlled.js";
2
2
  import React from "react";
3
- //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/react-medium-image-zoom/dist/uncontrolled.d.ts
3
+ //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/react-medium-image-zoom/dist/uncontrolled.d.ts
4
4
  type UncontrolledProps = Omit<ControlledProps, 'isZoomed'>;
5
5
  //#endregion
6
6
  export { UncontrolledProps };
@@ -1,6 +1,6 @@
1
1
  import { Controlled } from "./controlled.js";
2
2
  import React from "react";
3
- //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/react-medium-image-zoom/dist/uncontrolled.js
3
+ //#region ../../node_modules/.pnpm/react-medium-image-zoom@5.4.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/react-medium-image-zoom/dist/uncontrolled.js
4
4
  function Uncontrolled({ onZoomChange, ...props }) {
5
5
  const [isZoomed, setIsZoomed] = React.useState(false);
6
6
  const handleZoomChange = React.useCallback((value, { event }) => {