fumadocs-ui 14.1.1 → 14.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/{chunk-PZTQPB4U.js → chunk-AFMXKA2S.js} +1 -1
  2. package/dist/chunk-CLF6ZVYS.js +259 -0
  3. package/dist/chunk-DGKCMOIC.js +56 -0
  4. package/dist/{chunk-CPGKWLLV.js → chunk-F534DZID.js} +1 -1
  5. package/dist/{chunk-WRBUXI2A.js → chunk-IL64LMKR.js} +1 -1
  6. package/dist/{chunk-IHIFNFRB.js → chunk-ILBYBJ5C.js} +1 -1
  7. package/dist/{chunk-JUOW3DZK.js → chunk-J6XGK6ZG.js} +3 -3
  8. package/dist/{chunk-ET4TW6M5.js → chunk-UUGCW3UP.js} +16 -2
  9. package/dist/{chunk-5QPVK7QM.js → chunk-VPJMNIJX.js} +65 -65
  10. package/dist/{chunk-V6RONFCQ.js → chunk-W36BQGMB.js} +2 -2
  11. package/dist/{chunk-5KVEK5A7.js → chunk-ZBOI25UW.js} +1 -1
  12. package/dist/components/accordion.js +1 -1
  13. package/dist/components/banner.js +1 -1
  14. package/dist/components/callout.js +2 -2
  15. package/dist/components/codeblock.js +2 -2
  16. package/dist/components/dialog/search-algolia.d.ts +7 -6
  17. package/dist/components/dialog/search-algolia.js +9 -5
  18. package/dist/components/dialog/search-default.d.ts +4 -2
  19. package/dist/components/dialog/search-default.js +6 -4
  20. package/dist/components/dialog/search-orama.d.ts +32 -0
  21. package/dist/components/dialog/search-orama.js +82 -0
  22. package/dist/components/dialog/search.d.ts +9 -17
  23. package/dist/components/dialog/search.js +6 -7
  24. package/dist/components/files.js +1 -1
  25. package/dist/components/heading.js +2 -2
  26. package/dist/components/inline-toc.js +1 -1
  27. package/dist/components/layout/root-toggle.js +2 -2
  28. package/dist/components/type-table.js +1 -1
  29. package/dist/{dynamic-sidebar-MEINO4E2.js → dynamic-sidebar-SYEETGZL.js} +4 -4
  30. package/dist/{edit-on-github-PCTRDRD6.js → edit-on-github-FIYOWWPQ.js} +1 -1
  31. package/dist/layouts/docs.client.js +9 -9
  32. package/dist/layouts/docs.js +3 -3
  33. package/dist/layouts/home.client.js +5 -5
  34. package/dist/mdx.client.js +2 -2
  35. package/dist/mdx.js +3 -3
  36. package/dist/page.client.js +1 -1
  37. package/dist/page.js +1 -1
  38. package/dist/provider.d.ts +5 -3
  39. package/dist/provider.js +1 -1
  40. package/dist/style.css +1 -1
  41. package/dist/tag-list-BsEgfE3x.d.ts +6 -0
  42. package/package.json +12 -14
  43. package/dist/chunk-TYZZJ335.js +0 -295
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  Moon,
9
9
  Sun
10
- } from "./chunk-5QPVK7QM.js";
10
+ } from "./chunk-VPJMNIJX.js";
11
11
  import {
12
12
  twMerge
13
13
  } from "./chunk-TK3TM3MR.js";
@@ -0,0 +1,259 @@
1
+ import {
2
+ buttonVariants
3
+ } from "./chunk-QKOA6KEZ.js";
4
+ import {
5
+ FileText,
6
+ Hash,
7
+ LoaderCircle,
8
+ Search,
9
+ Text
10
+ } from "./chunk-VPJMNIJX.js";
11
+ import {
12
+ twMerge
13
+ } from "./chunk-TK3TM3MR.js";
14
+ import {
15
+ useSearchContext
16
+ } from "./chunk-UUGCW3UP.js";
17
+ import {
18
+ useSidebar
19
+ } from "./chunk-27HFSL7N.js";
20
+ import {
21
+ useI18n
22
+ } from "./chunk-EFMHXXHW.js";
23
+
24
+ // src/components/dialog/search.tsx
25
+ import { useRouter } from "next/navigation";
26
+ import {
27
+ useMemo,
28
+ useEffect,
29
+ useState,
30
+ useRef
31
+ } from "react";
32
+ import {
33
+ Dialog,
34
+ DialogContent,
35
+ DialogOverlay,
36
+ DialogTitle
37
+ } from "@radix-ui/react-dialog";
38
+ import { jsx, jsxs } from "react/jsx-runtime";
39
+ function SearchDialog({
40
+ open,
41
+ onOpenChange,
42
+ footer,
43
+ links = [],
44
+ ...props
45
+ }) {
46
+ const { text } = useI18n();
47
+ const defaultItems = useMemo(
48
+ () => links.map(([name, link]) => ({
49
+ type: "page",
50
+ id: name,
51
+ content: name,
52
+ url: link
53
+ })),
54
+ [links]
55
+ );
56
+ return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange, children: [
57
+ /* @__PURE__ */ jsx(DialogOverlay, { className: "fixed inset-0 z-50 bg-fd-background/50 backdrop-blur-sm data-[state=closed]:animate-fd-fade-out data-[state=open]:animate-fd-fade-in" }),
58
+ /* @__PURE__ */ jsxs(
59
+ DialogContent,
60
+ {
61
+ "aria-describedby": void 0,
62
+ className: "fixed left-1/2 top-[10vh] z-50 w-[98vw] max-w-screen-sm origin-left -translate-x-1/2 rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-lg data-[state=closed]:animate-fd-dialog-out data-[state=open]:animate-fd-dialog-in",
63
+ children: [
64
+ /* @__PURE__ */ jsx(DialogTitle, { className: "hidden", children: text.search }),
65
+ /* @__PURE__ */ jsx(
66
+ SearchInput,
67
+ {
68
+ search: props.search,
69
+ onSearchChange: props.onSearchChange,
70
+ isLoading: props.isLoading
71
+ }
72
+ ),
73
+ /* @__PURE__ */ jsx(
74
+ SearchList,
75
+ {
76
+ items: props.results === "empty" ? defaultItems : props.results,
77
+ hideResults: props.results === "empty" && defaultItems.length === 0
78
+ }
79
+ ),
80
+ footer ? /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-col border-t p-3", children: footer }) : null
81
+ ]
82
+ }
83
+ )
84
+ ] });
85
+ }
86
+ var icons = {
87
+ text: /* @__PURE__ */ jsx(Text, { className: "size-4 text-fd-muted-foreground" }),
88
+ heading: /* @__PURE__ */ jsx(Hash, { className: "size-4 text-fd-muted-foreground" }),
89
+ page: /* @__PURE__ */ jsx(FileText, { className: "size-4 text-fd-muted-foreground" })
90
+ };
91
+ function SearchInput({ search, onSearchChange, isLoading }) {
92
+ const { text } = useI18n();
93
+ const { setOpenSearch } = useSearchContext();
94
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2 px-3", children: [
95
+ /* @__PURE__ */ jsx(LoadingIndicator, { isLoading: isLoading ?? false }),
96
+ /* @__PURE__ */ jsx(
97
+ "input",
98
+ {
99
+ value: search,
100
+ onChange: (e) => {
101
+ onSearchChange(e.target.value);
102
+ },
103
+ placeholder: text.search,
104
+ className: "w-0 flex-1 bg-transparent py-3 text-base placeholder:text-fd-muted-foreground focus-visible:outline-none"
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsx(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ "aria-label": "Close Search",
112
+ onClick: () => {
113
+ setOpenSearch(false);
114
+ },
115
+ className: twMerge(
116
+ buttonVariants({
117
+ color: "outline",
118
+ className: "text-xs p-1.5"
119
+ })
120
+ ),
121
+ children: "Esc"
122
+ }
123
+ )
124
+ ] });
125
+ }
126
+ function SearchList({ items, hideResults = false }) {
127
+ const [active, setActive] = useState();
128
+ const { text } = useI18n();
129
+ const router = useRouter();
130
+ const sidebar = useSidebar();
131
+ const { setOpenSearch } = useSearchContext();
132
+ if (items.length > 0 && (!active || items.every((item) => item.id !== active))) {
133
+ setActive(items[0].id);
134
+ }
135
+ const listenerRef = useRef();
136
+ listenerRef.current = (e) => {
137
+ if (e.key === "ArrowDown" || e.key == "ArrowUp") {
138
+ setActive((cur) => {
139
+ const idx = items.findIndex((item) => item.id === cur);
140
+ if (idx === -1) return items.at(0)?.id;
141
+ return items.at(
142
+ (e.key === "ArrowDown" ? idx + 1 : idx - 1) % items.length
143
+ )?.id;
144
+ });
145
+ e.preventDefault();
146
+ }
147
+ if (e.key === "Enter") {
148
+ const selected = items.find((item) => item.id === active);
149
+ if (selected) onOpen(selected.url);
150
+ e.preventDefault();
151
+ }
152
+ };
153
+ useEffect(() => {
154
+ const listener = (e) => {
155
+ listenerRef.current?.(e);
156
+ };
157
+ window.addEventListener("keydown", listener);
158
+ return () => {
159
+ window.removeEventListener("keydown", listener);
160
+ };
161
+ }, []);
162
+ const onOpen = (url) => {
163
+ router.push(url);
164
+ setOpenSearch(false);
165
+ sidebar.setOpen(false);
166
+ };
167
+ return /* @__PURE__ */ jsxs(
168
+ "div",
169
+ {
170
+ className: twMerge(
171
+ "flex max-h-[460px] flex-col overflow-y-auto border-t p-2",
172
+ hideResults && "hidden"
173
+ ),
174
+ children: [
175
+ items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-12 text-center text-sm", children: text.searchNoResult }) : null,
176
+ items.map((item) => /* @__PURE__ */ jsxs(
177
+ CommandItem,
178
+ {
179
+ value: item.id,
180
+ active,
181
+ onActiveChange: setActive,
182
+ onClick: () => {
183
+ onOpen(item.url);
184
+ },
185
+ children: [
186
+ item.type !== "page" ? /* @__PURE__ */ jsx(
187
+ "div",
188
+ {
189
+ role: "none",
190
+ className: "ms-2 h-full min-h-10 w-px bg-fd-border"
191
+ }
192
+ ) : null,
193
+ icons[item.type],
194
+ /* @__PURE__ */ jsx("p", { className: "w-0 flex-1 truncate", children: item.content })
195
+ ]
196
+ },
197
+ item.id
198
+ ))
199
+ ]
200
+ }
201
+ );
202
+ }
203
+ function LoadingIndicator({ isLoading }) {
204
+ return /* @__PURE__ */ jsxs("div", { className: "relative size-4", children: [
205
+ /* @__PURE__ */ jsx(
206
+ LoaderCircle,
207
+ {
208
+ className: twMerge(
209
+ "absolute size-full animate-spin text-fd-primary transition-opacity",
210
+ !isLoading && "opacity-0"
211
+ )
212
+ }
213
+ ),
214
+ /* @__PURE__ */ jsx(
215
+ Search,
216
+ {
217
+ className: twMerge(
218
+ "absolute size-full text-fd-muted-foreground transition-opacity",
219
+ isLoading && "opacity-0"
220
+ )
221
+ }
222
+ )
223
+ ] });
224
+ }
225
+ function CommandItem({
226
+ active,
227
+ onActiveChange,
228
+ value,
229
+ ...props
230
+ }) {
231
+ const ref = useRef(null);
232
+ useEffect(() => {
233
+ const element = ref.current;
234
+ if (active === value && element) {
235
+ element.scrollIntoView({
236
+ block: "nearest"
237
+ });
238
+ }
239
+ }, [active, value]);
240
+ return /* @__PURE__ */ jsx(
241
+ "button",
242
+ {
243
+ ref,
244
+ type: "button",
245
+ "aria-selected": active === value,
246
+ onPointerMove: () => onActiveChange(value),
247
+ ...props,
248
+ className: twMerge(
249
+ "flex min-h-10 select-none flex-row items-center gap-2.5 rounded-lg px-2 text-start text-sm aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-selected:bg-fd-accent aria-selected:text-fd-accent-foreground",
250
+ props.className
251
+ ),
252
+ children: props.children
253
+ }
254
+ );
255
+ }
256
+
257
+ export {
258
+ SearchDialog
259
+ };
@@ -0,0 +1,56 @@
1
+ import {
2
+ twMerge
3
+ } from "./chunk-TK3TM3MR.js";
4
+
5
+ // src/components/dialog/tag-list.tsx
6
+ import { cva } from "class-variance-authority";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var itemVariants = cva(
9
+ "rounded-md border px-2 py-0.5 text-xs font-medium text-fd-muted-foreground transition-colors",
10
+ {
11
+ variants: {
12
+ active: {
13
+ true: "bg-fd-accent text-fd-accent-foreground"
14
+ }
15
+ }
16
+ }
17
+ );
18
+ function TagsList({
19
+ tag,
20
+ onTagChange,
21
+ items,
22
+ allowClear,
23
+ ...props
24
+ }) {
25
+ return /* @__PURE__ */ jsxs(
26
+ "div",
27
+ {
28
+ ...props,
29
+ className: twMerge("flex flex-row items-center gap-1", props.className),
30
+ children: [
31
+ items.map((item) => /* @__PURE__ */ jsx(
32
+ "button",
33
+ {
34
+ type: "button",
35
+ className: twMerge(itemVariants({ active: tag === item.value })),
36
+ onClick: () => {
37
+ if (tag === item.value && allowClear) {
38
+ onTagChange(void 0);
39
+ } else {
40
+ onTagChange(item.value);
41
+ }
42
+ },
43
+ tabIndex: -1,
44
+ children: item.name
45
+ },
46
+ item.value
47
+ )),
48
+ props.children
49
+ ]
50
+ }
51
+ );
52
+ }
53
+
54
+ export {
55
+ TagsList
56
+ };
@@ -2,7 +2,7 @@ import {
2
2
  CircleX,
3
3
  Info,
4
4
  TriangleAlert
5
- } from "./chunk-5QPVK7QM.js";
5
+ } from "./chunk-VPJMNIJX.js";
6
6
  import {
7
7
  twMerge
8
8
  } from "./chunk-TK3TM3MR.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-IVBHRX3O.js";
9
9
  import {
10
10
  ChevronDown
11
- } from "./chunk-5QPVK7QM.js";
11
+ } from "./chunk-VPJMNIJX.js";
12
12
  import {
13
13
  twMerge
14
14
  } from "./chunk-TK3TM3MR.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Link
3
- } from "./chunk-5QPVK7QM.js";
3
+ } from "./chunk-VPJMNIJX.js";
4
4
  import {
5
5
  twMerge
6
6
  } from "./chunk-TK3TM3MR.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LargeSearchToggle
3
- } from "./chunk-V6RONFCQ.js";
3
+ } from "./chunk-W36BQGMB.js";
4
4
  import {
5
5
  isActive
6
6
  } from "./chunk-CDPVENXR.js";
@@ -16,13 +16,13 @@ import {
16
16
  import {
17
17
  ChevronDown,
18
18
  ExternalLink
19
- } from "./chunk-5QPVK7QM.js";
19
+ } from "./chunk-VPJMNIJX.js";
20
20
  import {
21
21
  twMerge
22
22
  } from "./chunk-TK3TM3MR.js";
23
23
  import {
24
24
  useSearchContext
25
- } from "./chunk-ET4TW6M5.js";
25
+ } from "./chunk-UUGCW3UP.js";
26
26
  import {
27
27
  useTreeContext
28
28
  } from "./chunk-YL3MZH7N.js";
@@ -1,5 +1,11 @@
1
1
  // src/contexts/search.tsx
2
- import { createContext, useContext, useEffect, useMemo, useState } from "react";
2
+ import {
3
+ createContext,
4
+ useContext,
5
+ useEffect,
6
+ useMemo,
7
+ useState
8
+ } from "react";
3
9
  import { jsx, jsxs } from "react/jsx-runtime";
4
10
  var SearchContext = createContext({
5
11
  enabled: false,
@@ -9,6 +15,14 @@ var SearchContext = createContext({
9
15
  function useSearchContext() {
10
16
  return useContext(SearchContext);
11
17
  }
18
+ function MetaOrControl() {
19
+ const [key, setKey] = useState("\u2318");
20
+ useEffect(() => {
21
+ const isWindows = window.navigator.userAgent.includes("Windows");
22
+ if (isWindows) setKey("Ctrl");
23
+ }, []);
24
+ return key;
25
+ }
12
26
  function SearchProvider({
13
27
  SearchDialog,
14
28
  children,
@@ -17,7 +31,7 @@ function SearchProvider({
17
31
  hotKey = [
18
32
  {
19
33
  key: (e) => e.metaKey || e.ctrlKey,
20
- display: "\u2318"
34
+ display: /* @__PURE__ */ jsx(MetaOrControl, {})
21
35
  },
22
36
  {
23
37
  key: "k",