@fumadocs/base-ui 16.11.5 → 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 (75) 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 +6 -0
  10. package/dist/.translations/keys.js +6 -0
  11. package/dist/components/image-zoom.d.ts +2 -2
  12. package/dist/components/image-zoom.js +1 -1
  13. package/dist/components/sidebar/tabs/dropdown.d.ts +2 -3
  14. package/dist/components/sidebar/tabs/dropdown.js +9 -4
  15. package/dist/components/tabs.js +0 -1
  16. package/dist/components/toc/index.js +1 -1
  17. package/dist/components/ui/button.d.ts +1 -1
  18. package/dist/components/ui/popover.js +1 -1
  19. package/dist/components/ui/tabs.d.ts +1 -1
  20. package/dist/components/ui/tabs.js +36 -11
  21. package/dist/layouts/docs/client.js +10 -5
  22. package/dist/layouts/docs/page/slots/toc.js +17 -11
  23. package/dist/layouts/docs/slots/sidebar.js +8 -2
  24. package/dist/layouts/flux/index.d.ts +1 -1
  25. package/dist/layouts/flux/index.js +2 -2
  26. package/dist/layouts/flux/page/slots/toc.js +7 -4
  27. package/dist/layouts/flux/slots/tab-dropdown.js +8 -2
  28. package/dist/layouts/glass/index.d.ts +41 -0
  29. package/dist/layouts/glass/index.js +70 -0
  30. package/dist/layouts/glass/layout-tabs.js +53 -0
  31. package/dist/layouts/glass/page/index.d.ts +31 -0
  32. package/dist/layouts/glass/page/index.js +92 -0
  33. package/dist/layouts/glass/page/slots/breadcrumb.d.ts +7 -0
  34. package/dist/layouts/glass/page/slots/breadcrumb.js +44 -0
  35. package/dist/layouts/glass/page/slots/footer.d.ts +16 -0
  36. package/dist/layouts/glass/page/slots/footer.js +56 -0
  37. package/dist/layouts/glass/page/slots/toc.d.ts +19 -0
  38. package/dist/layouts/glass/page/slots/toc.js +108 -0
  39. package/dist/layouts/glass/slots/header.d.ts +6 -0
  40. package/dist/layouts/glass/slots/header.js +73 -0
  41. package/dist/layouts/glass/slots/sidebar.d.ts +23 -0
  42. package/dist/layouts/glass/slots/sidebar.js +294 -0
  43. package/dist/layouts/home/index.js +2 -2
  44. package/dist/layouts/home/slots/header.d.ts +1 -1
  45. package/dist/layouts/home/slots/header.js +1 -0
  46. package/dist/layouts/notebook/client.js +2 -2
  47. package/dist/layouts/notebook/page/slots/toc.js +17 -11
  48. package/dist/layouts/notebook/slots/header.js +8 -2
  49. package/dist/layouts/notebook/slots/sidebar.js +8 -2
  50. package/dist/layouts/shared/client.d.ts +1 -1
  51. package/dist/layouts/shared/client.js +1 -1
  52. package/dist/layouts/shared/index.d.ts +7 -6
  53. package/dist/layouts/shared/index.js +5 -3
  54. 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
  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.js +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/uncontrolled.d.ts +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.js +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/utils/adjust-svg-ids.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/compute-positioned-style.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/element-tests.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/get-div-img-style.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-img-alt.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-object-fit-style.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-regular-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-src.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-modal-img-transform.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-scale.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-style-ghost.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-modal-img.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-target-dimension.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/parse-position.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/test-has-scalable-src.js +1 -1
  73. package/dist/style.css +985 -885
  74. package/package.json +18 -11
  75. /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,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,
@@ -1,7 +1,7 @@
1
1
  import { ComponentProps } from "react";
2
2
  //#region src/layouts/home/slots/header.d.ts
3
3
  declare const navItemVariants: (props?: ({
4
- variant?: "main" | "icon" | "button" | null | undefined;
4
+ variant?: "icon" | "main" | "button" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
6
  declare function Header(props: ComponentProps<'header'>): import("react").JSX.Element;
7
7
  //#endregion
@@ -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 }) => {
@@ -1,4 +1,4 @@
1
- //#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/utils/adjust-svg-ids.js
1
+ //#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/utils/adjust-svg-ids.js
2
2
  const adjustSvgIDs = (svgEl) => {
3
3
  const newIdSuffix = "-zoom";
4
4
  const attrs = [
@@ -1,6 +1,6 @@
1
1
  import { getScale } from "./get-scale.js";
2
2
  import { parsePosition } from "./parse-position.js";
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/utils/compute-positioned-style.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/utils/compute-positioned-style.js
4
4
  const computePositionedStyle = ({ containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, offset, position, targetHeight, targetWidth, visibleHeight, visibleWidth }) => {
5
5
  const [posLeft = "50%", posTop = "50%"] = position.split(" ");
6
6
  const posX = parsePosition(posLeft, containerWidth - visibleWidth);
@@ -1,4 +1,4 @@
1
- //#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/utils/element-tests.js
1
+ //#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/utils/element-tests.js
2
2
  function isElement(el) {
3
3
  if (typeof Element === "undefined") return false;
4
4
  return el instanceof Element;
@@ -1,6 +1,6 @@
1
1
  import { parsePosition } from "./parse-position.js";
2
2
  import { computePositionedStyle } from "./compute-positioned-style.js";
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/utils/get-div-img-style.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/utils/get-div-img-style.js
4
4
  const getDivImgStyle = ({ backgroundPosition, backgroundSize, containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, offset, targetHeight, targetWidth }) => {
5
5
  const base = {
6
6
  containerHeight,
@@ -1,5 +1,5 @@
1
1
  import { testImg } from "./element-tests.js";
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/utils/get-img-alt.js
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/utils/get-img-alt.js
3
3
  const getImgAlt = (imgEl) => {
4
4
  if (imgEl !== null) if (testImg(imgEl)) return imgEl.alt;
5
5
  else return imgEl.getAttribute("aria-label") ?? void 0;
@@ -1,6 +1,6 @@
1
1
  import { getScale } from "./get-scale.js";
2
2
  import { computePositionedStyle } from "./compute-positioned-style.js";
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/utils/get-img-object-fit-style.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/utils/get-img-object-fit-style.js
4
4
  const getImgObjectFitStyle = ({ containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, objectFit: objectFitParam, objectPosition, offset, targetHeight, targetWidth }) => {
5
5
  let resolvedObjectFit = objectFitParam;
6
6
  if (resolvedObjectFit === "scale-down") if (targetWidth <= containerWidth && targetHeight <= containerHeight) resolvedObjectFit = "none";
@@ -1,5 +1,5 @@
1
1
  import { getScale } from "./get-scale.js";
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/utils/get-img-regular-style.js
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/utils/get-img-regular-style.js
3
3
  const getImgRegularStyle = ({ containerHeight, containerLeft, containerTop, containerWidth, hasScalableSrc, offset, targetHeight, targetWidth }) => {
4
4
  const scale = getScale({
5
5
  containerHeight,
@@ -1,5 +1,5 @@
1
1
  import { testDiv, testImg } from "./element-tests.js";
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/utils/get-img-src.js
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/utils/get-img-src.js
3
3
  const URL_REGEX = /url(?:\(['"]?)(?<url>.*?)(?:['"]?\))/;
4
4
  const getImgSrc = (imgEl) => {
5
5
  if (imgEl !== null) {