fumadocs-ui 13.4.5 → 13.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,237 +0,0 @@
1
- import {
2
- LargeSearchToggle,
3
- LinkItem
4
- } from "./chunk-N47AX4K6.js";
5
- import {
6
- useTreeContext
7
- } from "./chunk-LSTPTAZ5.js";
8
- import {
9
- ScrollArea,
10
- ScrollViewport
11
- } from "./chunk-2FLZOPQN.js";
12
- import {
13
- hasActive,
14
- isActive
15
- } from "./chunk-UOD2T27N.js";
16
- import {
17
- useSearchContext
18
- } from "./chunk-ET4TW6M5.js";
19
- import {
20
- Collapsible,
21
- CollapsibleContent,
22
- CollapsibleTrigger
23
- } from "./chunk-TQJ6YPJ3.js";
24
- import {
25
- itemVariants
26
- } from "./chunk-EDNTYBXS.js";
27
- import {
28
- twMerge
29
- } from "./chunk-TK3TM3MR.js";
30
-
31
- // src/components/layout/sidebar.tsx
32
- import { ChevronDown, ExternalLinkIcon } from "lucide-react";
33
- import * as Base from "fumadocs-core/sidebar";
34
- import { usePathname } from "next/navigation";
35
- import {
36
- createContext,
37
- useCallback,
38
- useContext,
39
- useMemo,
40
- useState
41
- } from "react";
42
- import Link from "fumadocs-core/link";
43
- import { useOnChange } from "fumadocs-core/utils/use-on-change";
44
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
45
- var defaultComponents = {
46
- Folder: FolderNode,
47
- Separator: SeparatorNode,
48
- Item: PageNode
49
- };
50
- var Context = createContext({
51
- defaultOpenLevel: 0,
52
- components: defaultComponents,
53
- prefetch: true
54
- });
55
- function Sidebar({
56
- components,
57
- defaultOpenLevel = 0,
58
- items,
59
- prefetch = true,
60
- ...props
61
- }) {
62
- const search = useSearchContext();
63
- const hasSearch = search.enabled && !props.hideSearch;
64
- const context = useMemo(
65
- () => ({
66
- defaultOpenLevel,
67
- components: { ...defaultComponents, ...components },
68
- prefetch
69
- }),
70
- [components, defaultOpenLevel, prefetch]
71
- );
72
- return /* @__PURE__ */ jsx(Context.Provider, { value: context, children: /* @__PURE__ */ jsxs(
73
- Base.SidebarList,
74
- {
75
- id: "nd-sidebar",
76
- blockScrollingWidth: 768,
77
- ...props.aside,
78
- className: twMerge(
79
- "fixed z-30 flex flex-col bg-fd-card text-sm md:sticky md:top-0 md:h-dvh md:w-[var(--fd-c-sidebar)] md:min-w-[var(--fd-sidebar-width)] md:border-e md:ps-[calc(var(--fd-c-sidebar)-var(--fd-sidebar-width))]",
80
- "max-md:inset-0 max-md:bg-fd-background/80 max-md:pt-14 max-md:text-[15px] max-md:backdrop-blur-md max-md:data-[open=false]:hidden",
81
- props.aside?.className
82
- ),
83
- children: [
84
- hasSearch || props.banner ? /* @__PURE__ */ jsxs(
85
- "div",
86
- {
87
- ...props.bannerProps,
88
- className: twMerge(
89
- "flex flex-col gap-1 px-4 pt-2 md:px-3 md:pt-4",
90
- props.bannerProps?.className
91
- ),
92
- children: [
93
- props.banner,
94
- hasSearch ? /* @__PURE__ */ jsx(LargeSearchToggle, { className: "rounded-lg max-md:hidden" }) : null
95
- ]
96
- }
97
- ) : null,
98
- /* @__PURE__ */ jsx(ViewportContent, { items }),
99
- props.footer ? /* @__PURE__ */ jsx(
100
- "div",
101
- {
102
- ...props.footerProps,
103
- className: twMerge(
104
- "flex flex-row items-center border-t py-1 max-md:px-4 md:mx-3",
105
- props.footerProps?.className
106
- ),
107
- children: props.footer
108
- }
109
- ) : null
110
- ]
111
- }
112
- ) });
113
- }
114
- function ViewportContent({
115
- items
116
- }) {
117
- const { root } = useTreeContext();
118
- return /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxs(
119
- ScrollViewport,
120
- {
121
- style: {
122
- maskImage: "linear-gradient(to bottom, transparent 2px, white 24px)"
123
- },
124
- children: [
125
- items.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-col px-4 pt-6 md:hidden", children: items.map((item, i) => /* @__PURE__ */ jsx(LinkItem, { item, on: "menu" }, i)) }) : null,
126
- /* @__PURE__ */ jsx(NodeList, { items: root.children, className: "px-4 py-6 md:px-3" })
127
- ]
128
- }
129
- ) });
130
- }
131
- function NodeList({
132
- items,
133
- level = 0,
134
- ...props
135
- }) {
136
- const { components } = useContext(Context);
137
- return /* @__PURE__ */ jsx("div", { ...props, children: items.map((item, i) => {
138
- const id = `${item.type}_${i.toString()}`;
139
- switch (item.type) {
140
- case "separator":
141
- return /* @__PURE__ */ jsx(components.Separator, { item }, id);
142
- case "folder":
143
- return /* @__PURE__ */ jsx(components.Folder, { item, level: level + 1 }, id);
144
- default:
145
- return /* @__PURE__ */ jsx(components.Item, { item }, item.url);
146
- }
147
- }) });
148
- }
149
- function PageNode({
150
- item: { icon, external = false, url, name }
151
- }) {
152
- const pathname = usePathname();
153
- const active = isActive(url, pathname, false);
154
- const { prefetch } = useContext(Context);
155
- return /* @__PURE__ */ jsxs(
156
- Link,
157
- {
158
- href: url,
159
- external,
160
- className: twMerge(itemVariants({ active })),
161
- prefetch,
162
- children: [
163
- icon ?? (external ? /* @__PURE__ */ jsx(ExternalLinkIcon, {}) : null),
164
- name
165
- ]
166
- }
167
- );
168
- }
169
- function FolderNode({
170
- item,
171
- level
172
- }) {
173
- const { defaultOpenLevel, prefetch } = useContext(Context);
174
- const pathname = usePathname();
175
- const active = item.index !== void 0 && isActive(item.index.url, pathname, false);
176
- const childActive = useMemo(
177
- () => hasActive(item.children, pathname),
178
- [item.children, pathname]
179
- );
180
- const shouldExtend = active || childActive || (item.defaultOpen ?? defaultOpenLevel >= level);
181
- const [open, setOpen] = useState(shouldExtend);
182
- useOnChange(shouldExtend, (v) => {
183
- if (v) setOpen(v);
184
- });
185
- const onClick = useCallback(
186
- (e) => {
187
- if (
188
- // clicking on icon
189
- e.target.hasAttribute("data-icon") || active
190
- ) {
191
- setOpen((prev) => !prev);
192
- e.preventDefault();
193
- }
194
- },
195
- [active]
196
- );
197
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
198
- item.icon,
199
- item.name,
200
- /* @__PURE__ */ jsx(
201
- ChevronDown,
202
- {
203
- "data-icon": true,
204
- className: twMerge("ms-auto transition-transform", !open && "-rotate-90")
205
- }
206
- )
207
- ] });
208
- return /* @__PURE__ */ jsxs(Collapsible, { open, onOpenChange: setOpen, children: [
209
- item.index ? /* @__PURE__ */ jsx(
210
- Link,
211
- {
212
- className: twMerge(itemVariants({ active })),
213
- href: item.index.url,
214
- onClick,
215
- prefetch,
216
- children: content
217
- }
218
- ) : /* @__PURE__ */ jsx(CollapsibleTrigger, { className: twMerge(itemVariants({ active })), children: content }),
219
- /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(
220
- NodeList,
221
- {
222
- className: "ms-2 flex flex-col border-s py-2 ps-2",
223
- items: item.children,
224
- level
225
- }
226
- ) })
227
- ] });
228
- }
229
- function SeparatorNode({
230
- item
231
- }) {
232
- return /* @__PURE__ */ jsx("p", { className: "mb-2 mt-8 px-2 font-medium first:mt-0", children: item.name });
233
- }
234
-
235
- export {
236
- Sidebar
237
- };
@@ -1,106 +0,0 @@
1
- "use client";
2
- import {
3
- Sidebar
4
- } from "./chunk-VTGJREY6.js";
5
- import "./chunk-N47AX4K6.js";
6
- import "./chunk-LSTPTAZ5.js";
7
- import "./chunk-2FLZOPQN.js";
8
- import "./chunk-CP67AHDD.js";
9
- import "./chunk-UOD2T27N.js";
10
- import "./chunk-ET4TW6M5.js";
11
- import {
12
- useSidebar
13
- } from "./chunk-27HFSL7N.js";
14
- import "./chunk-EFMHXXHW.js";
15
- import "./chunk-TQJ6YPJ3.js";
16
- import {
17
- buttonVariants
18
- } from "./chunk-EDNTYBXS.js";
19
- import {
20
- twMerge
21
- } from "./chunk-TK3TM3MR.js";
22
- import "./chunk-MLKGABMK.js";
23
-
24
- // src/components/layout/dynamic-sidebar.tsx
25
- import { useCallback, useRef, useState } from "react";
26
- import { SidebarIcon } from "lucide-react";
27
- import { useOnChange } from "fumadocs-core/utils/use-on-change";
28
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
- function DynamicSidebar(props) {
30
- const { collapsed, setCollapsed } = useSidebar();
31
- const [hover, setHover] = useState(false);
32
- const timerRef = useRef(0);
33
- const closeTimeRef = useRef(0);
34
- const onCollapse = useCallback(() => {
35
- setCollapsed((v) => !v);
36
- }, [setCollapsed]);
37
- useOnChange(collapsed, () => {
38
- setHover(false);
39
- closeTimeRef.current = Date.now() + 150;
40
- });
41
- const onEnter = useCallback((e) => {
42
- if (e.pointerType === "touch" || closeTimeRef.current > Date.now()) return;
43
- window.clearTimeout(timerRef.current);
44
- setHover(true);
45
- }, []);
46
- const onLeave = useCallback((e) => {
47
- if (e.pointerType === "touch") return;
48
- window.clearTimeout(timerRef.current);
49
- timerRef.current = window.setTimeout(
50
- () => {
51
- setHover(false);
52
- closeTimeRef.current = Date.now() + 150;
53
- },
54
- Math.min(e.clientX, document.body.clientWidth - e.clientX) > 100 ? 0 : 500
55
- );
56
- }, []);
57
- return /* @__PURE__ */ jsxs(Fragment, { children: [
58
- collapsed ? /* @__PURE__ */ jsx(
59
- "div",
60
- {
61
- className: "fixed inset-y-0 start-0 w-6 max-md:hidden xl:w-[50px]",
62
- onPointerEnter: onEnter,
63
- onPointerLeave: onLeave
64
- }
65
- ) : null,
66
- collapsed ? /* @__PURE__ */ jsx(
67
- "button",
68
- {
69
- type: "button",
70
- "aria-label": "Collapse Sidebar",
71
- className: twMerge(
72
- buttonVariants({
73
- color: "secondary",
74
- size: "icon",
75
- className: "fixed start-4 bottom-2 z-10 max-md:hidden"
76
- })
77
- ),
78
- onClick: onCollapse,
79
- children: /* @__PURE__ */ jsx(SidebarIcon, {})
80
- }
81
- ) : null,
82
- /* @__PURE__ */ jsx(
83
- Sidebar,
84
- {
85
- ...props,
86
- aside: {
87
- "data-collapse": collapsed,
88
- "data-hover": hover,
89
- onPointerEnter: onEnter,
90
- onPointerLeave: onLeave,
91
- "aria-hidden": Boolean(collapsed && !hover),
92
- className: twMerge(
93
- "md:transition-[transform,padding,width,margin]",
94
- collapsed && [
95
- "md:top-1 md:me-fd-sidebar-offset md:h-[calc(100dvh-4px)] md:w-[var(--fd-sidebar-width)] md:animate-fd-sidebar-collapse md:rounded-xl md:border md:ps-0 md:shadow-md",
96
- hover ? "md:translate-x-1 rtl:md:-translate-x-1" : "md:translate-x-[calc(var(--fd-sidebar-width)*-1)] rtl:md:translate-x-[var(--fd-sidebar-width)]"
97
- ]
98
- )
99
- }
100
- }
101
- )
102
- ] });
103
- }
104
- export {
105
- DynamicSidebar
106
- };