fumadocs-ui 12.4.1 → 12.5.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 (45) hide show
  1. package/dist/{chunk-NZA3MCPM.js → chunk-AAS47F5B.js} +65 -145
  2. package/dist/{docs.client.js → chunk-CIVJB4ZT.js} +20 -179
  3. package/dist/chunk-FMI5QZTV.js +21 -0
  4. package/dist/{chunk-BZ53GHJX.js → chunk-INUQLSIT.js} +66 -18
  5. package/dist/{chunk-KH555T4I.js → chunk-QQAMPLSA.js} +1 -1
  6. package/dist/{chunk-NUPTR2L5.js → chunk-QZBW7643.js} +6 -10
  7. package/dist/chunk-V7IGWU5C.js +13 -0
  8. package/dist/{chunk-6JD7NGHG.js → chunk-YKLVLKDA.js} +4 -6
  9. package/dist/{chunk-VUIQ7ZYI.js → chunk-YSCK5YFO.js} +1 -0
  10. package/dist/{chunk-3F57TIUQ.js → chunk-YXSAWF3G.js} +9 -6
  11. package/dist/chunk-ZMEQF77D.js +89 -0
  12. package/dist/components/accordion.js +2 -2
  13. package/dist/components/api.d.ts +17 -2
  14. package/dist/components/api.js +20 -7
  15. package/dist/components/banner.js +1 -1
  16. package/dist/components/callout.d.ts +1 -1
  17. package/dist/components/codeblock.js +2 -2
  18. package/dist/components/dialog/search-algolia.d.ts +10 -2
  19. package/dist/components/dialog/search-algolia.js +41 -7
  20. package/dist/components/dialog/search-default.d.ts +6 -2
  21. package/dist/components/dialog/search-default.js +21 -7
  22. package/dist/components/dialog/search.d.ts +16 -5
  23. package/dist/components/dialog/search.js +8 -5
  24. package/dist/components/files.d.ts +1 -0
  25. package/dist/components/layout/language-toggle.js +1 -1
  26. package/dist/components/layout/root-toggle.js +11 -4
  27. package/dist/components/roll-button.js +1 -1
  28. package/dist/components/tabs.d.ts +3 -5
  29. package/dist/components/tabs.js +1 -1
  30. package/dist/{docs.client.d.ts → docs-layout.client.d.ts} +4 -5
  31. package/dist/docs-layout.client.js +83 -0
  32. package/dist/dynamic-sidebar-DCHFPBYF.js +123 -0
  33. package/dist/{layout.client.d.ts → home-layout.client.d.ts} +1 -2
  34. package/dist/{layout.client.js → home-layout.client.js} +10 -7
  35. package/dist/home-layout.d.ts +7 -0
  36. package/dist/home-layout.js +29 -0
  37. package/dist/layout.d.ts +29 -3
  38. package/dist/layout.js +17 -22
  39. package/dist/{layout-ZAteQVYk.d.ts → layout.shared-GQuo9xqE.d.ts} +12 -65
  40. package/dist/mdx.client.js +2 -2
  41. package/dist/provider.d.ts +1 -1
  42. package/dist/provider.js +5 -4
  43. package/dist/sidebar-C7MbvaPk.d.ts +39 -0
  44. package/dist/style.css +1 -1
  45. package/package.json +15 -7
@@ -1,23 +1,27 @@
1
- import {
2
- useSidebar
3
- } from "./chunk-3F57TIUQ.js";
4
1
  import {
5
2
  useSearchContext
6
3
  } from "./chunk-ET4TW6M5.js";
4
+ import {
5
+ useSidebar
6
+ } from "./chunk-YXSAWF3G.js";
7
7
  import {
8
8
  useI18n
9
9
  } from "./chunk-HLGNIWUN.js";
10
10
  import {
11
11
  buttonVariants
12
- } from "./chunk-VUIQ7ZYI.js";
12
+ } from "./chunk-YSCK5YFO.js";
13
13
  import {
14
14
  twMerge
15
15
  } from "./chunk-TK3TM3MR.js";
16
16
 
17
17
  // src/components/dialog/search.tsx
18
- import { FileTextIcon, HashIcon, TextIcon } from "lucide-react";
18
+ import { FileText, Hash, Text } from "lucide-react";
19
19
  import { useRouter } from "next/navigation";
20
- import { useMemo, useCallback } from "react";
20
+ import {
21
+ useMemo,
22
+ useCallback
23
+ } from "react";
24
+ import { cva } from "class-variance-authority";
21
25
 
22
26
  // src/components/ui/command.tsx
23
27
  import { Command as CommandPrimitive } from "cmdk";
@@ -151,32 +155,35 @@ function SearchDialog({
151
155
  })),
152
156
  [links]
153
157
  );
154
- return /* @__PURE__ */ jsx2(CommandDialog, { open, onOpenChange, footer, children: /* @__PURE__ */ jsx2(Search2, { defaultItems, ...props }) });
158
+ return /* @__PURE__ */ jsx2(CommandDialog, { open, onOpenChange, footer, children: /* @__PURE__ */ jsx2(
159
+ Search2,
160
+ {
161
+ ...props,
162
+ items: props.results === "empty" ? defaultItems : props.results,
163
+ hideResults: props.results === "empty" && defaultItems.length === 0
164
+ }
165
+ ) });
155
166
  }
156
167
  var icons = {
157
- text: /* @__PURE__ */ jsx2(TextIcon, {}),
158
- heading: /* @__PURE__ */ jsx2(HashIcon, {}),
159
- page: /* @__PURE__ */ jsx2(FileTextIcon, {})
168
+ text: /* @__PURE__ */ jsx2(Text, {}),
169
+ heading: /* @__PURE__ */ jsx2(Hash, {}),
170
+ page: /* @__PURE__ */ jsx2(FileText, {})
160
171
  };
161
172
  function Search2({
162
173
  search,
163
174
  onSearchChange,
164
- defaultItems = [],
165
- results
175
+ items,
176
+ hideResults = false
166
177
  }) {
167
178
  const { text } = useI18n();
168
179
  const router = useRouter();
169
180
  const { setOpenSearch } = useSearchContext();
170
181
  const sidebar = useSidebar();
171
- const items = results === "empty" ? defaultItems : results;
172
- const hideList = results === "empty" && defaultItems.length === 0;
173
182
  const onOpen = (url) => {
174
183
  router.push(url);
175
184
  setOpenSearch(false);
176
185
  if (location.pathname === url.split("#")[0]) {
177
186
  sidebar.setOpen(false);
178
- } else {
179
- sidebar.closeOnRedirect.current = true;
180
187
  }
181
188
  };
182
189
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
@@ -191,7 +198,7 @@ function Search2({
191
198
  placeholder: text.search
192
199
  }
193
200
  ),
194
- /* @__PURE__ */ jsxs2(CommandList, { className: twMerge(hideList && "hidden"), children: [
201
+ /* @__PURE__ */ jsxs2(CommandList, { className: twMerge(hideResults && "hidden"), children: [
195
202
  /* @__PURE__ */ jsx2(CommandEmpty, { children: text.searchNoResult }),
196
203
  /* @__PURE__ */ jsx2(CommandGroup, { value: "result", children: items.map((item) => /* @__PURE__ */ jsx2(
197
204
  CommandItem,
@@ -209,7 +216,48 @@ function Search2({
209
216
  ] })
210
217
  ] });
211
218
  }
219
+ var itemVariants = cva(
220
+ "rounded-md border px-2 py-0.5 text-xs font-medium text-muted-foreground transition-colors",
221
+ {
222
+ variants: {
223
+ active: {
224
+ true: "bg-accent text-accent-foreground"
225
+ }
226
+ }
227
+ }
228
+ );
229
+ function TagsList({
230
+ tag,
231
+ onTagChange,
232
+ items,
233
+ ...props
234
+ }) {
235
+ return /* @__PURE__ */ jsxs2(
236
+ "div",
237
+ {
238
+ ...props,
239
+ className: twMerge("flex flex-row items-center gap-1", props.className),
240
+ children: [
241
+ items.map((item) => /* @__PURE__ */ jsx2(
242
+ "button",
243
+ {
244
+ type: "button",
245
+ className: twMerge(itemVariants({ active: tag === item.value })),
246
+ onClick: () => {
247
+ onTagChange(item.value);
248
+ },
249
+ tabIndex: -1,
250
+ children: item.name
251
+ },
252
+ item.value
253
+ )),
254
+ props.children
255
+ ]
256
+ }
257
+ );
258
+ }
212
259
 
213
260
  export {
214
- SearchDialog
261
+ SearchDialog,
262
+ TagsList
215
263
  };
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-2KMKNVSN.js";
9
9
  import {
10
10
  buttonVariants
11
- } from "./chunk-VUIQ7ZYI.js";
11
+ } from "./chunk-YSCK5YFO.js";
12
12
  import {
13
13
  twMerge
14
14
  } from "./chunk-TK3TM3MR.js";
@@ -6,12 +6,7 @@ import {
6
6
  } from "./chunk-MLKGABMK.js";
7
7
 
8
8
  // src/components/tabs.tsx
9
- import {
10
- useEffect,
11
- useMemo,
12
- useState,
13
- useCallback
14
- } from "react";
9
+ import { useMemo, useState, useCallback, useLayoutEffect } from "react";
15
10
 
16
11
  // src/components/ui/tabs.tsx
17
12
  var tabs_exports = {};
@@ -99,11 +94,11 @@ function Tabs2({
99
94
  items = [],
100
95
  persist = false,
101
96
  defaultIndex = 0,
102
- children
97
+ ...props
103
98
  }) {
104
99
  const values = useMemo(() => items.map((item) => toValue(item)), [items]);
105
100
  const [value, setValue] = useState(values[defaultIndex]);
106
- useEffect(() => {
101
+ useLayoutEffect(() => {
107
102
  if (!id) return;
108
103
  const onUpdate = (v) => {
109
104
  if (values.includes(v)) setValue(v);
@@ -130,10 +125,11 @@ function Tabs2({
130
125
  {
131
126
  value,
132
127
  onValueChange,
133
- className: "my-4",
128
+ ...props,
129
+ className: twMerge("my-4", props.className),
134
130
  children: [
135
131
  /* @__PURE__ */ jsx2(TabsList, { children: values.map((v, i) => /* @__PURE__ */ jsx2(TabsTrigger, { value: v, children: items[i] }, v)) }),
136
- children
132
+ props.children
137
133
  ]
138
134
  }
139
135
  );
@@ -0,0 +1,13 @@
1
+ // src/utils/use-on-change.ts
2
+ import { useState } from "react";
3
+ function useOnChange(value, onChange) {
4
+ const [prev, setPrev] = useState(value);
5
+ if (prev !== value) {
6
+ onChange(value, prev);
7
+ setPrev(value);
8
+ }
9
+ }
10
+
11
+ export {
12
+ useOnChange
13
+ };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2KMKNVSN.js";
4
4
  import {
5
5
  buttonVariants
6
- } from "./chunk-VUIQ7ZYI.js";
6
+ } from "./chunk-YSCK5YFO.js";
7
7
  import {
8
8
  twMerge
9
9
  } from "./chunk-TK3TM3MR.js";
@@ -24,10 +24,8 @@ var Accordions = forwardRef(({ type = "single", className, defaultValue, ...prop
24
24
  useEffect(() => {
25
25
  const id = window.location.hash.substring(1);
26
26
  if (id.length > 0)
27
- setValue((prev) => {
28
- return type === "single" ? id : [id, ...Array.isArray(prev) ? prev : []];
29
- });
30
- }, [type]);
27
+ setValue((prev) => typeof prev === "string" ? id : [id, ...prev]);
28
+ }, []);
31
29
  return (
32
30
  // @ts-expect-error -- Multiple types
33
31
  /* @__PURE__ */ jsx(
@@ -37,7 +35,7 @@ var Accordions = forwardRef(({ type = "single", className, defaultValue, ...prop
37
35
  ref,
38
36
  value,
39
37
  onValueChange: setValue,
40
- collapsible: true,
38
+ collapsible: type === "single" ? true : void 0,
41
39
  className: twMerge(
42
40
  "divide-y divide-border overflow-hidden rounded-lg border bg-card",
43
41
  className
@@ -10,6 +10,7 @@ var buttonVariants = cva(
10
10
  secondary: "border bg-secondary text-secondary-foreground hover:bg-accent hover:text-accent-foreground"
11
11
  },
12
12
  size: {
13
+ sm: "gap-1 p-0.5 text-xs",
13
14
  icon: "p-1.5 [&_svg]:size-5"
14
15
  }
15
16
  }
@@ -1,11 +1,14 @@
1
+ import {
2
+ useOnChange
3
+ } from "./chunk-V7IGWU5C.js";
4
+
1
5
  // src/contexts/sidebar.tsx
2
6
  import {
3
7
  createContext,
4
8
  useContext,
5
9
  useState,
6
10
  useMemo,
7
- useRef,
8
- useEffect
11
+ useRef
9
12
  } from "react";
10
13
  import { usePathname } from "next/navigation";
11
14
  import { SidebarProvider as BaseProvider } from "fumadocs-core/sidebar";
@@ -19,16 +22,16 @@ function useSidebar() {
19
22
  function SidebarProvider({
20
23
  children
21
24
  }) {
22
- const closeOnRedirect = useRef(false);
25
+ const closeOnRedirect = useRef(true);
23
26
  const [open, setOpen] = useState(false);
24
27
  const [collapsed, setCollapsed] = useState(false);
25
28
  const pathname = usePathname();
26
- useEffect(() => {
29
+ useOnChange(pathname, () => {
27
30
  if (closeOnRedirect.current) {
28
31
  setOpen(false);
29
- closeOnRedirect.current = false;
30
32
  }
31
- }, [pathname]);
33
+ closeOnRedirect.current = true;
34
+ });
32
35
  return /* @__PURE__ */ jsx(
33
36
  SidebarContext.Provider,
34
37
  {
@@ -0,0 +1,89 @@
1
+ import {
2
+ twMerge
3
+ } from "./chunk-TK3TM3MR.js";
4
+
5
+ // src/components/layout/nav.tsx
6
+ import Link from "fumadocs-core/link";
7
+ import {
8
+ useEffect,
9
+ useState
10
+ } from "react";
11
+ import { jsx } from "react/jsx-runtime";
12
+ function NavBox({
13
+ transparentMode = "none",
14
+ ...props
15
+ }) {
16
+ const [transparent, setTransparent] = useState(transparentMode !== "none");
17
+ useEffect(() => {
18
+ if (transparentMode !== "top") return;
19
+ const listener = () => {
20
+ setTransparent(window.scrollY < 10);
21
+ };
22
+ listener();
23
+ window.addEventListener("scroll", listener);
24
+ return () => {
25
+ window.removeEventListener("scroll", listener);
26
+ };
27
+ }, [transparentMode]);
28
+ return /* @__PURE__ */ jsx(
29
+ "header",
30
+ {
31
+ ...props,
32
+ className: twMerge(
33
+ "sticky top-0 z-50 border-b transition-colors",
34
+ transparent ? "border-transparent" : "border-foreground/10 bg-background/60 backdrop-blur-md",
35
+ props.className
36
+ )
37
+ }
38
+ );
39
+ }
40
+ function Title({ title, url = "/" }) {
41
+ return /* @__PURE__ */ jsx(Link, { href: url, className: "inline-flex items-center gap-2.5 font-semibold", children: title });
42
+ }
43
+
44
+ // src/components/layout/theme-toggle.tsx
45
+ import { cva } from "class-variance-authority";
46
+ import { Moon, Sun } from "lucide-react";
47
+ import { useTheme } from "next-themes";
48
+ import { useCallback } from "react";
49
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
50
+ var buttonVariants = cva("size-7 rounded-full p-1.5 text-muted-foreground", {
51
+ variants: {
52
+ dark: {
53
+ true: "dark:bg-accent dark:text-accent-foreground",
54
+ false: "bg-accent text-accent-foreground dark:bg-transparent dark:text-muted-foreground"
55
+ }
56
+ }
57
+ });
58
+ function ThemeToggle({
59
+ className,
60
+ ...props
61
+ }) {
62
+ const { setTheme, resolvedTheme } = useTheme();
63
+ const onToggle = useCallback(() => {
64
+ setTheme(resolvedTheme === "dark" ? "light" : "dark");
65
+ }, [setTheme, resolvedTheme]);
66
+ return /* @__PURE__ */ jsxs(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ className: twMerge(
71
+ "inline-flex items-center rounded-full border p-0.5",
72
+ className
73
+ ),
74
+ "aria-label": "Toggle Theme",
75
+ onClick: onToggle,
76
+ ...props,
77
+ children: [
78
+ /* @__PURE__ */ jsx2(Sun, { className: twMerge(buttonVariants({ dark: false })) }),
79
+ /* @__PURE__ */ jsx2(Moon, { className: twMerge(buttonVariants({ dark: true })) })
80
+ ]
81
+ }
82
+ );
83
+ }
84
+
85
+ export {
86
+ NavBox,
87
+ Title,
88
+ ThemeToggle
89
+ };
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  Accordion,
4
4
  Accordions
5
- } from "../chunk-6JD7NGHG.js";
5
+ } from "../chunk-YKLVLKDA.js";
6
6
  import "../chunk-2KMKNVSN.js";
7
- import "../chunk-VUIQ7ZYI.js";
7
+ import "../chunk-YSCK5YFO.js";
8
8
  import "../chunk-TK3TM3MR.js";
9
9
  import "../chunk-MLKGABMK.js";
10
10
  export {
@@ -1,7 +1,21 @@
1
- import { HTMLAttributes, ReactNode } from 'react';
1
+ import { MouseEventHandler, HTMLAttributes, ReactNode } from 'react';
2
+ export { twMerge as cn } from 'tailwind-merge';
3
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
4
  import { Tabs, Tab } from './tabs.js';
3
5
  import '@radix-ui/react-tabs';
4
6
 
7
+ declare function useOnChange<T>(value: T, onChange: (current: T, previous: T) => void): void;
8
+
9
+ declare function useCopyButton(onCopy: () => void): [checked: boolean, onClick: MouseEventHandler];
10
+
11
+ declare const buttonVariants: (props?: ({
12
+ color?: "outline" | "ghost" | "secondary" | null | undefined;
13
+ size?: "sm" | "icon" | null | undefined;
14
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
15
+ declare const itemVariants: (props?: ({
16
+ active?: boolean | null | undefined;
17
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
18
+
5
19
  declare function Root({ children, className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
6
20
  declare function API({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
7
21
  interface APIInfoProps extends HTMLAttributes<HTMLDivElement> {
@@ -32,7 +46,8 @@ declare function TypeScriptResponse(props: {
32
46
  children: ReactNode;
33
47
  }): React.ReactElement;
34
48
  declare function ObjectCollapsible(props: {
49
+ name: string;
35
50
  children: ReactNode;
36
51
  }): React.ReactElement;
37
52
 
38
- export { API, APIExample, APIInfo, type APIInfoProps, ExampleResponse, ObjectCollapsible, Property, Request, Requests, Response, ResponseTypes, Responses, Root, TypeScriptResponse };
53
+ export { API, APIExample, APIInfo, type APIInfoProps, ExampleResponse, ObjectCollapsible, Property, Request, Requests, Response, ResponseTypes, Responses, Root, TypeScriptResponse, buttonVariants, itemVariants, useCopyButton, useOnChange };
@@ -2,19 +2,27 @@
2
2
  import {
3
3
  Accordion,
4
4
  Accordions
5
- } from "../chunk-6JD7NGHG.js";
6
- import "../chunk-2KMKNVSN.js";
5
+ } from "../chunk-YKLVLKDA.js";
6
+ import {
7
+ useCopyButton
8
+ } from "../chunk-2KMKNVSN.js";
9
+ import {
10
+ useOnChange
11
+ } from "../chunk-V7IGWU5C.js";
7
12
  import {
8
13
  Tab,
9
14
  Tabs
10
- } from "../chunk-NUPTR2L5.js";
11
- import "../chunk-VUIQ7ZYI.js";
15
+ } from "../chunk-QZBW7643.js";
16
+ import {
17
+ buttonVariants,
18
+ itemVariants
19
+ } from "../chunk-YSCK5YFO.js";
12
20
  import {
13
21
  twMerge
14
22
  } from "../chunk-TK3TM3MR.js";
15
23
  import "../chunk-MLKGABMK.js";
16
24
 
17
- // src/components/api.tsx
25
+ // src/components/api-legacy.tsx
18
26
  import { cva } from "class-variance-authority";
19
27
  import { jsx, jsxs } from "react/jsx-runtime";
20
28
  function Root({
@@ -139,7 +147,7 @@ function TypeScriptResponse(props) {
139
147
  return /* @__PURE__ */ jsx(Accordion, { title: "Typescript", children: props.children });
140
148
  }
141
149
  function ObjectCollapsible(props) {
142
- return /* @__PURE__ */ jsx(Accordions, { type: "single", children: /* @__PURE__ */ jsx(Accordion, { title: "Object Type", children: props.children }) });
150
+ return /* @__PURE__ */ jsx(Accordions, { type: "single", children: /* @__PURE__ */ jsx(Accordion, { title: props.name, children: props.children }) });
143
151
  }
144
152
  export {
145
153
  API,
@@ -154,5 +162,10 @@ export {
154
162
  ResponseTypes,
155
163
  Responses,
156
164
  Root,
157
- TypeScriptResponse
165
+ TypeScriptResponse,
166
+ buttonVariants,
167
+ twMerge as cn,
168
+ itemVariants,
169
+ useCopyButton,
170
+ useOnChange
158
171
  };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  buttonVariants
4
- } from "../chunk-VUIQ7ZYI.js";
4
+ } from "../chunk-YSCK5YFO.js";
5
5
  import {
6
6
  twMerge
7
7
  } from "../chunk-TK3TM3MR.js";
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- declare const Callout: React.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title" | "type" | "icon"> & {
4
+ declare const Callout: React.ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title" | "icon" | "type"> & {
5
5
  title?: ReactNode;
6
6
  /**
7
7
  * @defaultValue info
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  CodeBlock,
4
4
  Pre
5
- } from "../chunk-KH555T4I.js";
5
+ } from "../chunk-QQAMPLSA.js";
6
6
  import "../chunk-VYTHQTZE.js";
7
7
  import "../chunk-2KMKNVSN.js";
8
- import "../chunk-VUIQ7ZYI.js";
8
+ import "../chunk-YSCK5YFO.js";
9
9
  import "../chunk-TK3TM3MR.js";
10
10
  import "../chunk-MLKGABMK.js";
11
11
  export {
@@ -1,14 +1,22 @@
1
1
  import { SearchIndex } from 'algoliasearch/lite';
2
2
  import { Options } from 'fumadocs-core/search-algolia/client';
3
3
  import { ReactNode } from 'react';
4
- import { SharedProps } from './search.js';
4
+ import { SharedProps, TagItem } from './search.js';
5
5
  import 'fumadocs-core/search/shared';
6
6
 
7
7
  interface AlgoliaSearchDialogProps extends SharedProps {
8
8
  index: SearchIndex;
9
9
  searchOptions?: Options;
10
10
  footer?: ReactNode;
11
+ defaultTag?: string;
12
+ tags?: TagItem[];
13
+ /**
14
+ * Add the "Powered by Algolia" label, this is useful for free tier users
15
+ *
16
+ * @defaultValue false
17
+ */
18
+ showAlgolia?: boolean;
11
19
  }
12
- declare function AlgoliaSearchDialog({ index, searchOptions, ...props }: AlgoliaSearchDialogProps): React.ReactElement;
20
+ declare function AlgoliaSearchDialog({ index, searchOptions, tags, defaultTag, showAlgolia, ...props }: AlgoliaSearchDialogProps): React.ReactElement;
13
21
 
14
22
  export { type AlgoliaSearchDialogProps, AlgoliaSearchDialog as default };
@@ -1,11 +1,15 @@
1
1
  "use client";
2
2
  import {
3
- SearchDialog
4
- } from "../../chunk-BZ53GHJX.js";
5
- import "../../chunk-3F57TIUQ.js";
3
+ SearchDialog,
4
+ TagsList
5
+ } from "../../chunk-INUQLSIT.js";
6
6
  import "../../chunk-ET4TW6M5.js";
7
+ import "../../chunk-YXSAWF3G.js";
7
8
  import "../../chunk-HLGNIWUN.js";
8
- import "../../chunk-VUIQ7ZYI.js";
9
+ import {
10
+ useOnChange
11
+ } from "../../chunk-V7IGWU5C.js";
12
+ import "../../chunk-YSCK5YFO.js";
9
13
  import "../../chunk-TK3TM3MR.js";
10
14
  import "../../chunk-MLKGABMK.js";
11
15
 
@@ -13,20 +17,50 @@ import "../../chunk-MLKGABMK.js";
13
17
  import {
14
18
  useAlgoliaSearch
15
19
  } from "fumadocs-core/search-algolia/client";
16
- import { jsx } from "react/jsx-runtime";
20
+ import { useState } from "react";
21
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
22
  function AlgoliaSearchDialog({
18
23
  index,
19
24
  searchOptions,
25
+ tags,
26
+ defaultTag,
27
+ showAlgolia = false,
20
28
  ...props
21
29
  }) {
22
- const { search, setSearch, query } = useAlgoliaSearch(index, searchOptions);
30
+ const [tag, setTag] = useState(defaultTag);
31
+ let filters = searchOptions?.filters;
32
+ if (tag) {
33
+ filters = filters ? `tag:${tag} AND (${filters})` : `tag:${tag}`;
34
+ }
35
+ const { search, setSearch, query } = useAlgoliaSearch(index, {
36
+ ...searchOptions,
37
+ filters
38
+ });
39
+ useOnChange(defaultTag, (v) => {
40
+ setTag(v);
41
+ });
23
42
  return /* @__PURE__ */ jsx(
24
43
  SearchDialog,
25
44
  {
26
45
  search,
27
46
  onSearchChange: setSearch,
28
47
  results: query.data ?? [],
29
- ...props
48
+ ...props,
49
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ tags ? /* @__PURE__ */ jsx(TagsList, { tag, onTagChange: setTag, items: tags, children: showAlgolia ? /* @__PURE__ */ jsx(AlgoliaTitle, {}) : null }) : null,
51
+ props.footer
52
+ ] })
53
+ }
54
+ );
55
+ }
56
+ function AlgoliaTitle() {
57
+ return /* @__PURE__ */ jsx(
58
+ "a",
59
+ {
60
+ href: "https://algolia.com",
61
+ rel: "noreferrer noopener",
62
+ className: "ms-auto text-xs text-muted-foreground",
63
+ children: "Search powered by Algolia"
30
64
  }
31
65
  );
32
66
  }
@@ -1,12 +1,16 @@
1
1
  import { ReactNode } from 'react';
2
- import { SharedProps } from './search.js';
2
+ import { SharedProps, TagItem } from './search.js';
3
3
  import 'fumadocs-core/search/shared';
4
4
 
5
5
  interface DefaultSearchDialogProps extends SharedProps {
6
6
  /**
7
7
  * Search tag
8
+ *
9
+ * @deprecated Use Tags API instead
8
10
  */
9
11
  tag?: string;
12
+ defaultTag?: string;
13
+ tags?: TagItem[];
10
14
  /**
11
15
  * Search API URL
12
16
  */
@@ -17,6 +21,6 @@ interface DefaultSearchDialogProps extends SharedProps {
17
21
  delayMs?: number;
18
22
  footer?: ReactNode;
19
23
  }
20
- declare function DefaultSearchDialog({ tag, api, delayMs, ...props }: DefaultSearchDialogProps): React.ReactElement;
24
+ declare function DefaultSearchDialog({ defaultTag, tags, api, delayMs, ...props }: DefaultSearchDialogProps): React.ReactElement;
21
25
 
22
26
  export { type DefaultSearchDialogProps, DefaultSearchDialog as default };