boltdocs 2.7.9 → 2.7.11

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 (174) hide show
  1. package/dist/{cache-DorPMFgW.cjs → cache-Ba-DZQNH.cjs} +1 -1
  2. package/dist/{cache-CQKlT4fI.mjs → cache-BuMZ58L5.mjs} +1 -1
  3. package/dist/chunk-CU-zTemE.cjs +6 -0
  4. package/dist/client/index.cjs +1929 -1
  5. package/dist/client/index.js +1880 -1
  6. package/dist/client/mdx.cjs +7 -1
  7. package/dist/client/mdx.js +7 -1
  8. package/dist/client/primitives.cjs +60 -1
  9. package/dist/client/primitives.js +20 -1
  10. package/dist/docs-layout-BXHV0xw_.cjs +1431 -0
  11. package/dist/docs-layout-DwFndmj5.js +1231 -0
  12. package/dist/doctor-Be7Ly1oM.mjs +21 -0
  13. package/dist/{doctor-D4_Y7M4p.cjs → doctor-CrytFkqW.cjs} +1 -1
  14. package/dist/doctor-jMxWZyLJ.cjs +21 -0
  15. package/dist/generator-CHqxiQhF.cjs +21 -0
  16. package/dist/generator-ClVanhvi.mjs +21 -0
  17. package/dist/icons-dev-3cZMyt8r.cjs +1204 -0
  18. package/dist/icons-dev-Df8OQ481.js +839 -0
  19. package/dist/image-DtrI2cw3.cjs +268 -0
  20. package/dist/image-jxPb-2iV.js +214 -0
  21. package/dist/mdx-BdWkJTeB.cjs +523 -0
  22. package/dist/mdx-UTTLFWJq.js +494 -0
  23. package/dist/meta-loader-CWg2gnbY.mjs +6 -0
  24. package/dist/meta-loader-Cv9O0Pzl.cjs +6 -0
  25. package/dist/node/cli-entry.cjs +1 -1
  26. package/dist/node/cli-entry.mjs +1 -1
  27. package/dist/node/index.cjs +1 -1
  28. package/dist/node/index.mjs +1 -1
  29. package/dist/node/routes/worker.cjs +1 -1
  30. package/dist/node/routes/worker.mjs +1 -1
  31. package/dist/node-BSM4qcDK.cjs +111 -0
  32. package/dist/node-BspZN3R2.mjs +111 -0
  33. package/dist/{package-VfQM94VL.cjs → package-DIIrjuWI.cjs} +1 -1
  34. package/dist/{package-B4MD00N3.mjs → package-K0zsjGIz.mjs} +1 -1
  35. package/dist/{parser-Bh11BsdA.cjs → parser-Aq8LoH-0.cjs} +1 -1
  36. package/dist/{parser-DYRzXWmA.cjs → parser-CdNbqN5y.cjs} +1 -1
  37. package/dist/parser-nE792MLO.mjs +6 -0
  38. package/dist/rolldown-runtime-fkIsjY3S.mjs +6 -0
  39. package/dist/{routes-Co1mRM58.cjs → routes-2k3tbUmC.cjs} +1 -1
  40. package/dist/routes-CpxZIsMM.mjs +6 -0
  41. package/dist/{routes-CHf76Ye4.cjs → routes-DP1vmWRj.cjs} +1 -1
  42. package/dist/search-dialog-BHuIiUC6.js +8 -0
  43. package/dist/search-dialog-BNF10tDl.js +375 -0
  44. package/dist/search-dialog-BwkDuI9R.cjs +220 -0
  45. package/dist/search-dialog-C7xuvyNk.cjs +386 -0
  46. package/dist/search-dialog-CIQg6k8c.cjs +8 -0
  47. package/dist/search-dialog-D-DDN7zJ.js +208 -0
  48. package/dist/utils-CG65J0Sc.mjs +7 -0
  49. package/dist/utils-CKunkU96.cjs +7 -0
  50. package/dist/{worker-pool-BwU8ckrg.cjs → worker-pool-Crbqgw5R.cjs} +1 -1
  51. package/package.json +5 -5
  52. package/dist/chunk-Ds5LZdWN.cjs +0 -6
  53. package/dist/docs-layout-KoWNZc8_.js +0 -6
  54. package/dist/docs-layout-x2yKt2cL.cjs +0 -6
  55. package/dist/doctor-BD1BSB03.mjs +0 -23
  56. package/dist/doctor-BHc9ua6r.cjs +0 -23
  57. package/dist/generator-DGW6pkCC.cjs +0 -22
  58. package/dist/generator-Dv3wEmhZ.mjs +0 -22
  59. package/dist/icons-dev-B_RZIyxu.js +0 -6
  60. package/dist/icons-dev-BlV3wWFT.cjs +0 -6
  61. package/dist/image-BHhTvQzr.cjs +0 -6
  62. package/dist/image-CqKzYD8f.js +0 -6
  63. package/dist/mdx-DudBEac0.js +0 -7
  64. package/dist/mdx-r4cDQxWu.cjs +0 -7
  65. package/dist/meta-loader-0gJ4PtBC.cjs +0 -6
  66. package/dist/meta-loader-9IpAHWDS.mjs +0 -6
  67. package/dist/node-DBaH7kat.mjs +0 -111
  68. package/dist/node-t5C3Q85p.cjs +0 -111
  69. package/dist/parser-9cVdK7w9.mjs +0 -6
  70. package/dist/routes-DwrMa5-z.mjs +0 -6
  71. package/dist/search-dialog-B584t9ZF.js +0 -6
  72. package/dist/search-dialog-BvBopRsZ.cjs +0 -6
  73. package/dist/search-dialog-ByvGScjt.js +0 -6
  74. package/dist/search-dialog-Cyko6TJm.cjs +0 -6
  75. package/dist/search-dialog-D6BNohIJ.js +0 -6
  76. package/dist/search-dialog-DuYTIefy.cjs +0 -6
  77. package/dist/utils-BxNAXhZZ.mjs +0 -7
  78. package/dist/utils-Clzu7jvb.cjs +0 -7
  79. package/src/client/app/config-context.tsx +0 -51
  80. package/src/client/app/doc-page.tsx +0 -38
  81. package/src/client/app/docs-layout.tsx +0 -28
  82. package/src/client/app/head.tsx +0 -122
  83. package/src/client/app/helmet-compat.tsx +0 -36
  84. package/src/client/app/mdx-component.tsx +0 -8
  85. package/src/client/app/mdx-components-context.tsx +0 -72
  86. package/src/client/app/routes-context.tsx +0 -34
  87. package/src/client/app/scroll-handler.tsx +0 -74
  88. package/src/client/app/theme-context.tsx +0 -103
  89. package/src/client/app/ui-context.tsx +0 -42
  90. package/src/client/components/docs-layout-default.tsx +0 -85
  91. package/src/client/components/icons-dev.tsx +0 -282
  92. package/src/client/components/mdx/callout.tsx +0 -97
  93. package/src/client/components/mdx/card.tsx +0 -99
  94. package/src/client/components/mdx/cards.tsx +0 -27
  95. package/src/client/components/mdx/code-block.tsx +0 -184
  96. package/src/client/components/mdx/field.tsx +0 -33
  97. package/src/client/components/mdx/image.tsx +0 -44
  98. package/src/client/components/mdx/index.ts +0 -19
  99. package/src/client/components/mdx/table.tsx +0 -54
  100. package/src/client/components/mdx/typographics.tsx +0 -120
  101. package/src/client/components/mdx/use-code-block.ts +0 -34
  102. package/src/client/components/primitives/breadcrumbs.tsx +0 -54
  103. package/src/client/components/primitives/button-group.tsx +0 -54
  104. package/src/client/components/primitives/button.tsx +0 -6
  105. package/src/client/components/primitives/code-block.tsx +0 -120
  106. package/src/client/components/primitives/docs-layout.tsx +0 -125
  107. package/src/client/components/primitives/error-boundary.tsx +0 -107
  108. package/src/client/components/primitives/heading.tsx +0 -128
  109. package/src/client/components/primitives/helpers/observer.ts +0 -141
  110. package/src/client/components/primitives/image.tsx +0 -26
  111. package/src/client/components/primitives/link.tsx +0 -102
  112. package/src/client/components/primitives/menu.tsx +0 -137
  113. package/src/client/components/primitives/navbar.tsx +0 -466
  114. package/src/client/components/primitives/on-this-page.tsx +0 -430
  115. package/src/client/components/primitives/page-nav.tsx +0 -51
  116. package/src/client/components/primitives/popover.tsx +0 -28
  117. package/src/client/components/primitives/search-dialog.tsx +0 -193
  118. package/src/client/components/primitives/sidebar.tsx +0 -423
  119. package/src/client/components/primitives/skeleton.tsx +0 -26
  120. package/src/client/components/primitives/tabs.tsx +0 -70
  121. package/src/client/components/primitives/tooltip.tsx +0 -81
  122. package/src/client/components/primitives/types.ts +0 -11
  123. package/src/client/components/ui-base/banner.tsx +0 -66
  124. package/src/client/components/ui-base/breadcrumbs.tsx +0 -44
  125. package/src/client/components/ui-base/copy-markdown.tsx +0 -107
  126. package/src/client/components/ui-base/error-boundary.tsx +0 -15
  127. package/src/client/components/ui-base/github-stars.tsx +0 -29
  128. package/src/client/components/ui-base/icons.tsx +0 -240
  129. package/src/client/components/ui-base/index.ts +0 -16
  130. package/src/client/components/ui-base/last-updated.tsx +0 -27
  131. package/src/client/components/ui-base/navbar.tsx +0 -266
  132. package/src/client/components/ui-base/not-found.tsx +0 -26
  133. package/src/client/components/ui-base/on-this-page.tsx +0 -57
  134. package/src/client/components/ui-base/page-nav.tsx +0 -50
  135. package/src/client/components/ui-base/search-dialog.tsx +0 -163
  136. package/src/client/components/ui-base/search-highlight.tsx +0 -10
  137. package/src/client/components/ui-base/sidebar.tsx +0 -92
  138. package/src/client/components/ui-base/tabs.tsx +0 -83
  139. package/src/client/components/ui-base/theme-toggle.tsx +0 -130
  140. package/src/client/components/ui-base/version-i18n.tsx +0 -80
  141. package/src/client/hooks/index.ts +0 -13
  142. package/src/client/hooks/use-analytics.ts +0 -272
  143. package/src/client/hooks/use-breadcrumbs.ts +0 -22
  144. package/src/client/hooks/use-i18n.ts +0 -182
  145. package/src/client/hooks/use-localized-to.ts +0 -113
  146. package/src/client/hooks/use-location.ts +0 -5
  147. package/src/client/hooks/use-navbar.ts +0 -130
  148. package/src/client/hooks/use-page-nav.ts +0 -46
  149. package/src/client/hooks/use-routes.ts +0 -108
  150. package/src/client/hooks/use-search-highlight.ts +0 -185
  151. package/src/client/hooks/use-search.ts +0 -118
  152. package/src/client/hooks/use-sidebar.ts +0 -205
  153. package/src/client/hooks/use-tabs.ts +0 -46
  154. package/src/client/hooks/use-version.ts +0 -111
  155. package/src/client/index.ts +0 -31
  156. package/src/client/mdx.ts +0 -2
  157. package/src/client/primitives.ts +0 -19
  158. package/src/client/ssg/boltdocs-shell.tsx +0 -148
  159. package/src/client/ssg/create-routes.tsx +0 -473
  160. package/src/client/ssg/index.ts +0 -4
  161. package/src/client/ssg/mdx-page.tsx +0 -38
  162. package/src/client/store/boltdocs-context.tsx +0 -137
  163. package/src/client/theme/neutral.css +0 -141
  164. package/src/client/theme/reset.css +0 -189
  165. package/src/client/types.ts +0 -116
  166. package/src/client/utils/cn.ts +0 -6
  167. package/src/client/utils/copy-clipboard.ts +0 -22
  168. package/src/client/utils/get-base-file-path.ts +0 -21
  169. package/src/client/utils/github.ts +0 -121
  170. package/src/client/utils/i18n.ts +0 -23
  171. package/src/client/utils/path.ts +0 -9
  172. package/src/client/utils/react-to-text.ts +0 -34
  173. package/src/client/virtual.d.ts +0 -24
  174. /package/dist/{worker-pool-Bd8Y9KDv.mjs → worker-pool-CGn7DrLb.mjs} +0 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Boltdocs - https://boltdocs.vercel.app
3
+ * Copyright (c) 2026 Jesus Alcala
4
+ * Licensed under the MIT License.
5
+ */
6
+ import { A as CornerDownLeft, H as Moon, J as X, K as Sun, N as FileText, P as Hash, U as MoreVertical, _ as Link, h as XSocial, j as ExternalLink, o as Discord, s as Github, t as Bluesky, y as cn } from "./icons-dev-Df8OQ481.js";
7
+ import { useEffect, useState } from "react";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import * as RAC from "react-aria-components";
10
+ import { Button, Dialog, Modal, ModalOverlay, Separator, ToggleButton } from "react-aria-components";
11
+
12
+ //#region src/client/components/primitives/navbar.tsx
13
+ const Navbar = ({ children, className, ...props }) => {
14
+ return /* @__PURE__ */ jsx("header", {
15
+ className: cn("boltdocs-navbar sticky top-0 z-50 w-full", className),
16
+ ...props,
17
+ children
18
+ });
19
+ };
20
+ const NavbarContent = ({ children, className }) => {
21
+ return /* @__PURE__ */ jsx("div", {
22
+ className: cn("mx-auto flex lg:h-navbar max-w-(--breakpoint-3xl) items-center justify-between px-4 md:px-6", className),
23
+ children
24
+ });
25
+ };
26
+ const NavbarLeft = ({ children, className }) => {
27
+ return /* @__PURE__ */ jsx("div", {
28
+ className: cn("flex flex-1 items-center justify-start gap-4 min-w-0", className),
29
+ children
30
+ });
31
+ };
32
+ const NavbarRight = ({ children, className }) => {
33
+ return /* @__PURE__ */ jsx("div", {
34
+ className: cn("flex flex-1 items-center justify-end gap-2 md:gap-4 min-w-0", className),
35
+ children
36
+ });
37
+ };
38
+ const NavbarCenter = ({ children, className }) => {
39
+ return /* @__PURE__ */ jsx("div", {
40
+ className: cn("hidden lg:flex flex-1 justify-center items-center gap-4 px-4 min-w-0 w-full", className),
41
+ children
42
+ });
43
+ };
44
+ const NavbarLogo = ({ src, alt, width = 24, height = 24, className, href = "/" }) => {
45
+ return /* @__PURE__ */ jsx(Link, {
46
+ href,
47
+ className: cn("flex items-center gap-2 shrink-0 outline-none", className),
48
+ children: src ? /* @__PURE__ */ jsx("img", {
49
+ src,
50
+ alt,
51
+ width,
52
+ height,
53
+ className: "h-6 w-6 object-contain"
54
+ }) : null
55
+ });
56
+ };
57
+ const NavbarTitle = ({ children, className, href = "/" }) => {
58
+ return /* @__PURE__ */ jsx(Link, {
59
+ href,
60
+ children: /* @__PURE__ */ jsx("span", {
61
+ className: cn("text-lg font-bold tracking-tight hidden sm:inline-block", className),
62
+ children
63
+ })
64
+ });
65
+ };
66
+ const NavbarLinks = ({ children, className }) => {
67
+ return /* @__PURE__ */ jsx("nav", {
68
+ className: cn("hidden md:flex items-center gap-6 text-sm font-medium", className),
69
+ children
70
+ });
71
+ };
72
+ const NavbarLink = ({ label, href, to, className }) => {
73
+ return /* @__PURE__ */ jsxs(Link, {
74
+ href,
75
+ target: to === "external" ? "_blank" : void 0,
76
+ className: cn("transition-all outline-none", className),
77
+ children: [label, to === "external" && /* @__PURE__ */ jsx("span", {
78
+ className: "ml-1 inline-block",
79
+ children: /* @__PURE__ */ jsx(ExternalLink, { size: 12 })
80
+ })]
81
+ });
82
+ };
83
+ const NavbarDropdown = ({ label, className, children }) => {
84
+ const [isOpen, setIsOpen] = useState(false);
85
+ return /* @__PURE__ */ jsxs("div", {
86
+ className: cn("relative", className),
87
+ onMouseEnter: () => {
88
+ setIsOpen(true);
89
+ },
90
+ onMouseLeave: () => {
91
+ setIsOpen(false);
92
+ },
93
+ children: [/* @__PURE__ */ jsxs("div", {
94
+ className: cn("flex items-center gap-1 outline-none cursor-pointer select-none font-medium text-muted hover:text-body transition-colors"),
95
+ children: [label, /* @__PURE__ */ jsx("svg", {
96
+ className: cn("w-4 h-4 transition-transform", isOpen && "rotate-180"),
97
+ fill: "none",
98
+ viewBox: "0 0 24 24",
99
+ stroke: "currentColor",
100
+ children: /* @__PURE__ */ jsx("path", {
101
+ strokeLinecap: "round",
102
+ strokeLinejoin: "round",
103
+ strokeWidth: 2,
104
+ d: "M19 9l-7 7-7-7"
105
+ })
106
+ })]
107
+ }), isOpen && /* @__PURE__ */ jsx("div", {
108
+ className: "absolute top-full left-0 pt-1 z-[9999]",
109
+ children: /* @__PURE__ */ jsx("div", {
110
+ className: "min-w-[180px] p-1 bg-surface border border-subtle rounded-md shadow-lg",
111
+ children
112
+ })
113
+ })]
114
+ });
115
+ };
116
+ const NavbarDropdownItem = ({ href, label, className }) => {
117
+ return /* @__PURE__ */ jsx(Link, {
118
+ href,
119
+ className: cn("block px-2 py-1.5 rounded hover:bg-surface", className),
120
+ children: label
121
+ });
122
+ };
123
+ const NavbarSearchTriggerDesktop = ({ className, onPress, children }) => {
124
+ return /* @__PURE__ */ jsx(Button, {
125
+ onPress,
126
+ className: cn("hidden lg:flex items-center justify-between gap-2 px-3 py-2 text-sm outline-none cursor-pointer w-full max-w-[720px]", className),
127
+ children
128
+ });
129
+ };
130
+ const NavbarSearchTriggerMobile = ({ className, onPress, children }) => {
131
+ return /* @__PURE__ */ jsx(Button, {
132
+ onPress,
133
+ className: cn("lg:hidden flex h-10 w-10 items-center justify-center outline-none cursor-pointer", className),
134
+ "aria-label": "Search",
135
+ children
136
+ });
137
+ };
138
+ const NavbarSearchTriggerKbd = ({ className }) => {
139
+ const [mounted, setMounted] = useState(false);
140
+ const isMac = mounted && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
141
+ useEffect(() => {
142
+ setMounted(true);
143
+ }, []);
144
+ return /* @__PURE__ */ jsxs("div", {
145
+ className: cn("hidden sm:flex items-center gap-1 pointer-events-none select-none", className),
146
+ children: [/* @__PURE__ */ jsx("kbd", {
147
+ className: "flex items-center justify-center font-mono text-[10px]",
148
+ children: isMac ? "⌘" : "Ctrl"
149
+ }), /* @__PURE__ */ jsx("kbd", {
150
+ className: "flex items-center justify-center font-mono text-[10px]",
151
+ children: "K"
152
+ })]
153
+ });
154
+ };
155
+ const NavbarSearchTrigger = {
156
+ Desktop: NavbarSearchTriggerDesktop,
157
+ Mobile: NavbarSearchTriggerMobile,
158
+ Kbd: NavbarSearchTriggerKbd
159
+ };
160
+ const NavbarTheme = ({ className, theme, onThemeChange }) => {
161
+ return /* @__PURE__ */ jsx(ToggleButton, {
162
+ isSelected: theme === "dark",
163
+ onChange: onThemeChange,
164
+ className: cn("outline-none cursor-pointer", className),
165
+ "aria-label": "Toggle theme",
166
+ children: theme === "dark" ? /* @__PURE__ */ jsx(Sun, { size: 20 }) : /* @__PURE__ */ jsx(Moon, { size: 20 })
167
+ });
168
+ };
169
+ const Icon = ({ name }) => {
170
+ if (name === "github") return /* @__PURE__ */ jsx(Github, {});
171
+ if (name === "discord") return /* @__PURE__ */ jsx(Discord, {});
172
+ if (name === "x") return /* @__PURE__ */ jsx(XSocial, {});
173
+ if (name === "bluesky") return /* @__PURE__ */ jsx(Bluesky, {});
174
+ };
175
+ const NavbarSocials = ({ icon, link, className }) => {
176
+ return /* @__PURE__ */ jsx(Link, {
177
+ href: link,
178
+ target: "_blank",
179
+ rel: "noopener noreferrer",
180
+ className: cn("outline-none", className),
181
+ children: /* @__PURE__ */ jsx(Icon, { name: icon })
182
+ });
183
+ };
184
+ const NavbarSplit = ({ className }) => {
185
+ return /* @__PURE__ */ jsx(Separator, {
186
+ orientation: "vertical",
187
+ className: cn("h-full w-px", className)
188
+ });
189
+ };
190
+ const NavbarMore = ({ onPress, className }) => {
191
+ return /* @__PURE__ */ jsx(Button, {
192
+ onPress,
193
+ className: cn("md:hidden flex items-center justify-center outline-none cursor-pointer", className),
194
+ "aria-label": "More navigation",
195
+ children: /* @__PURE__ */ jsx(MoreVertical, { size: 20 })
196
+ });
197
+ };
198
+ const NavbarMobileMenu = ({ isOpen, onClose, children, className }) => {
199
+ return /* @__PURE__ */ jsx(ModalOverlay, {
200
+ isOpen,
201
+ onOpenChange: (open) => !open && onClose(),
202
+ isDismissable: true,
203
+ className: cn("fixed inset-0 z-60 md:hidden transition-all duration-100", className),
204
+ children: /* @__PURE__ */ jsx(Modal, {
205
+ className: "fixed inset-0 outline-none",
206
+ children: /* @__PURE__ */ jsxs(Dialog, {
207
+ className: "relative h-full outline-none flex flex-col p-6 pt-[calc(1.5rem+env(safe-area-inset-top,0px))] pb-[calc(1.5rem+env(safe-area-inset-bottom,0px))] px-[calc(1.5rem+env(safe-area-inset-left,0px))]",
208
+ children: [/* @__PURE__ */ jsxs("div", {
209
+ className: "flex items-center justify-between mb-6",
210
+ children: [/* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsx(Button, {
211
+ onPress: onClose,
212
+ className: "flex items-center justify-center outline-none cursor-pointer text-muted hover:text-body transition-colors",
213
+ "aria-label": "Close menu",
214
+ children: /* @__PURE__ */ jsx(X, { size: 24 })
215
+ })]
216
+ }), /* @__PURE__ */ jsx("nav", {
217
+ className: "flex-1 overflow-y-auto flex flex-col gap-4",
218
+ children
219
+ })]
220
+ })
221
+ })
222
+ });
223
+ };
224
+ const NavbarMobileLink = ({ label, href, to, onPress, className }) => {
225
+ return /* @__PURE__ */ jsx(Link, {
226
+ href,
227
+ target: to === "external" ? "_blank" : void 0,
228
+ onClick: onPress,
229
+ className: cn("group flex items-center outline-none", className),
230
+ children: label
231
+ });
232
+ };
233
+ Navbar.Root = Navbar;
234
+ Navbar.Left = NavbarLeft;
235
+ Navbar.Right = NavbarRight;
236
+ Navbar.Center = NavbarCenter;
237
+ Navbar.Logo = NavbarLogo;
238
+ Navbar.Title = NavbarTitle;
239
+ Navbar.Links = NavbarLinks;
240
+ Navbar.Link = NavbarLink;
241
+ Navbar.Dropdown = NavbarDropdown;
242
+ Navbar.DropdownItem = NavbarDropdownItem;
243
+ Navbar.SearchTrigger = NavbarSearchTrigger;
244
+ Navbar.Theme = NavbarTheme;
245
+ Navbar.Socials = NavbarSocials;
246
+ Navbar.Split = NavbarSplit;
247
+ Navbar.Content = NavbarContent;
248
+ Navbar.More = NavbarMore;
249
+ Navbar.MobileMenu = NavbarMobileMenu;
250
+ Navbar.MobileLink = NavbarMobileLink;
251
+
252
+ //#endregion
253
+ //#region src/client/components/primitives/search-dialog.tsx
254
+ /**
255
+ * Pure, unstyled SearchDialog Overlay (maps to RAC.ModalOverlay)
256
+ */
257
+ const SearchDialog = ({ className, ...props }) => {
258
+ return /* @__PURE__ */ jsx(RAC.ModalOverlay, {
259
+ className: cn("fixed inset-0 z-100", className),
260
+ ...props
261
+ });
262
+ };
263
+ /**
264
+ * Pure, unstyled SearchDialog Content (maps to RAC.Modal)
265
+ */
266
+ const SearchDialogContent = ({ className, ...props }) => /* @__PURE__ */ jsx(RAC.Modal, {
267
+ className: cn(className),
268
+ ...props
269
+ });
270
+ /**
271
+ * Pure, unstyled SearchDialog Dialog (maps to RAC.Dialog)
272
+ */
273
+ const SearchDialogDialog = ({ className, ...props }) => /* @__PURE__ */ jsx(RAC.Dialog, {
274
+ className: cn("flex flex-col focus:outline-none", className),
275
+ ...props
276
+ });
277
+ /**
278
+ * Pure, unstyled SearchDialog Input Field (maps to RAC.SearchField)
279
+ */
280
+ const SearchDialogField = ({ className, ...props }) => /* @__PURE__ */ jsx(RAC.SearchField, {
281
+ className: cn("flex items-center", className),
282
+ ...props
283
+ });
284
+ /**
285
+ * Pure, unstyled SearchInput (maps to RAC.Input)
286
+ */
287
+ const SearchDialogSearchInput = ({ className, ...props }) => /* @__PURE__ */ jsx(RAC.Input, {
288
+ className: cn("w-full bg-transparent outline-none border-none", className),
289
+ ...props
290
+ });
291
+ /**
292
+ * Pure, unstyled Clear Button (maps to RAC.Button with slot="clear")
293
+ */
294
+ const SearchDialogClearButton = ({ className, ...props }) => /* @__PURE__ */ jsx(RAC.Button, {
295
+ slot: "clear",
296
+ className: cn(className),
297
+ ...props
298
+ });
299
+ /**
300
+ * Pure, unstyled Autocomplete container (maps to RAC.Autocomplete)
301
+ */
302
+ const SearchDialogAutocomplete = ({ children, className, onSelectionChange, ...props }) => {
303
+ const Autocomplete = RAC.Autocomplete;
304
+ return /* @__PURE__ */ jsx("div", {
305
+ className: cn("flex-1 min-h-0", className),
306
+ children: /* @__PURE__ */ jsx(Autocomplete, {
307
+ ...props,
308
+ onSelectionChange,
309
+ className: "flex flex-col min-h-0",
310
+ children
311
+ })
312
+ });
313
+ };
314
+ /**
315
+ * Pure, unstyled List Box (maps to RAC.ListBox)
316
+ */
317
+ const SearchDialogList = ({ children, className, ...props }) => {
318
+ return /* @__PURE__ */ jsx(RAC.ListBox, {
319
+ ...props,
320
+ className: cn("flex-1 overflow-y-auto outline-none min-h-0", className),
321
+ children
322
+ });
323
+ };
324
+ /**
325
+ * Pure, unstyled List Box Item (maps to RAC.ListBoxItem)
326
+ */
327
+ const SearchDialogItemRoot = ({ children, className, ...props }) => {
328
+ return /* @__PURE__ */ jsx(RAC.ListBoxItem, {
329
+ ...props,
330
+ className: cn("group flex items-center outline-none cursor-pointer", className),
331
+ children: (itemProps) => /* @__PURE__ */ jsxs(Fragment, { children: [children, (itemProps.isFocused || itemProps.isSelected) && /* @__PURE__ */ jsxs("div", {
332
+ className: "ml-auto opacity-50 flex items-center gap-1",
333
+ children: [/* @__PURE__ */ jsx("span", {
334
+ className: "text-[10px]",
335
+ children: "Select"
336
+ }), /* @__PURE__ */ jsx(CornerDownLeft, { size: 10 })]
337
+ })] })
338
+ });
339
+ };
340
+ const SearchDialogItemIcon = ({ isHeading, className }) => {
341
+ return /* @__PURE__ */ jsx("div", {
342
+ className: cn("shrink-0", className),
343
+ children: isHeading ? /* @__PURE__ */ jsx(Hash, { size: 18 }) : /* @__PURE__ */ jsx(FileText, { size: 18 })
344
+ });
345
+ };
346
+ const SearchDialogItemTitle = ({ children, className }) => {
347
+ return /* @__PURE__ */ jsx("span", {
348
+ className: cn("block truncate flex-1", className),
349
+ children
350
+ });
351
+ };
352
+ const SearchDialogItemBio = ({ children, className }) => {
353
+ return /* @__PURE__ */ jsx("span", {
354
+ className: cn("ml-2 truncate hidden sm:inline", className),
355
+ children
356
+ });
357
+ };
358
+ SearchDialog.Root = SearchDialog;
359
+ SearchDialog.Overlay = SearchDialog;
360
+ SearchDialog.Content = SearchDialogContent;
361
+ SearchDialog.Dialog = SearchDialogDialog;
362
+ SearchDialog.Autocomplete = SearchDialogAutocomplete;
363
+ SearchDialog.List = SearchDialogList;
364
+ SearchDialog.Input = Object.assign(SearchDialogField, {
365
+ SearchInput: SearchDialogSearchInput,
366
+ Button: SearchDialogClearButton
367
+ });
368
+ SearchDialog.Item = Object.assign(SearchDialogItemRoot, {
369
+ Icon: SearchDialogItemIcon,
370
+ Title: SearchDialogItemTitle,
371
+ Bio: SearchDialogItemBio
372
+ });
373
+
374
+ //#endregion
375
+ export { Navbar as n, SearchDialog as t };
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Boltdocs - https://boltdocs.vercel.app
3
+ * Copyright (c) 2026 Jesus Alcala
4
+ * Licensed under the MIT License.
5
+ */
6
+ const require_icons_dev = require('./icons-dev-3cZMyt8r.cjs');
7
+ const require_search_dialog = require('./search-dialog-C7xuvyNk.cjs');
8
+ let react_router_dom = require("react-router-dom");
9
+ let react = require("react");
10
+ let react_jsx_runtime = require("react/jsx-runtime");
11
+ let flexsearch = require("flexsearch");
12
+ let virtual_boltdocs_search = require("virtual:boltdocs-search");
13
+ virtual_boltdocs_search = require_icons_dev.__toESM(virtual_boltdocs_search);
14
+
15
+ //#region src/client/hooks/use-search.ts
16
+ function useSearch(routes) {
17
+ const { currentLocale, currentVersion } = require_icons_dev.useRoutes();
18
+ const [isOpen, setIsOpen] = (0, react.useState)(false);
19
+ const [query, setQuery] = (0, react.useState)("");
20
+ const [index, setIndex] = (0, react.useState)(null);
21
+ (0, react.useEffect)(() => {
22
+ if (!isOpen || index) return;
23
+ const newIndex = new flexsearch.Index({
24
+ preset: "match",
25
+ tokenize: "full",
26
+ resolution: 9,
27
+ cache: true
28
+ });
29
+ for (const doc of virtual_boltdocs_search.default) newIndex.add(doc.id, `${doc.title} ${doc.content}`);
30
+ setIndex(newIndex);
31
+ }, [isOpen, index]);
32
+ const searchDataMap = (0, react.useMemo)(() => {
33
+ const map = /* @__PURE__ */ new Map();
34
+ for (const doc of virtual_boltdocs_search.default) map.set(doc.id, doc);
35
+ return map;
36
+ }, []);
37
+ return {
38
+ isOpen,
39
+ setIsOpen,
40
+ query,
41
+ setQuery,
42
+ list: (0, react.useMemo)(() => {
43
+ if (!query) return routes.filter((r) => {
44
+ const localeMatch = !currentLocale || r.locale === currentLocale;
45
+ const versionMatch = !currentVersion || r.version === currentVersion;
46
+ return localeMatch && versionMatch;
47
+ }).slice(0, 10).map((r) => ({
48
+ id: r.path,
49
+ title: r.title,
50
+ path: r.path,
51
+ bio: r.description || "",
52
+ groupTitle: r.groupTitle
53
+ }));
54
+ if (!index) return [];
55
+ const searchResults = index.search(query, {
56
+ limit: 20,
57
+ suggest: true
58
+ });
59
+ const results = [];
60
+ const seen = /* @__PURE__ */ new Set();
61
+ for (const id of searchResults) {
62
+ const doc = searchDataMap.get(id);
63
+ if (!doc) continue;
64
+ const localeMatch = !currentLocale || doc.locale === currentLocale;
65
+ const versionMatch = !currentVersion || doc.version === currentVersion;
66
+ if (!localeMatch || !versionMatch) continue;
67
+ if (seen.has(doc.url)) continue;
68
+ seen.add(doc.url);
69
+ results.push({
70
+ id: doc.url,
71
+ title: doc.title,
72
+ path: doc.url,
73
+ bio: doc.display,
74
+ groupTitle: doc.display.split(" > ")[0],
75
+ isHeading: doc.url.includes("#")
76
+ });
77
+ }
78
+ return results.slice(0, 10);
79
+ }, [
80
+ query,
81
+ index,
82
+ currentLocale,
83
+ currentVersion,
84
+ routes,
85
+ searchDataMap
86
+ ]),
87
+ input: {
88
+ value: query,
89
+ onChange: (e) => setQuery(e.target.value)
90
+ }
91
+ };
92
+ }
93
+
94
+ //#endregion
95
+ //#region src/client/components/ui-base/search-dialog.tsx
96
+ function Highlight({ text, query }) {
97
+ if (!query || !text) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: text });
98
+ const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
99
+ const regex = new RegExp(`(${escapedQuery})`, "gi");
100
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: text.split(regex).map((part, i) => regex.test(part) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("mark", {
101
+ className: "bg-primary-500/20 text-primary-600 dark:text-primary-400 font-bold px-0.5 rounded-sm",
102
+ children: part
103
+ }, i) : part) });
104
+ }
105
+ function SearchDialog({ routes }) {
106
+ const { isOpen, setIsOpen, query, setQuery, list } = useSearch(routes);
107
+ const navigate = (0, react_router_dom.useNavigate)();
108
+ (0, react.useEffect)(() => {
109
+ const handleKeyDown = (e) => {
110
+ if ((/Mac/.test(navigator.userAgent) ? e.metaKey : e.ctrlKey) && (e.key === "k" || e.key === "j")) {
111
+ e.preventDefault();
112
+ setIsOpen((prev) => !prev);
113
+ }
114
+ };
115
+ window.addEventListener("keydown", handleKeyDown);
116
+ return () => window.removeEventListener("keydown", handleKeyDown);
117
+ }, [setIsOpen]);
118
+ const handleSelect = (0, react.useCallback)((key) => {
119
+ const path = String(key);
120
+ setIsOpen(false);
121
+ const [baseUrl, hash] = path.split("#");
122
+ navigate(`${baseUrl}${query ? `?hl=${encodeURIComponent(query)}` : ""}${hash ? `#${hash}` : ""}`);
123
+ if (hash) setTimeout(() => {
124
+ const el = document.getElementById(hash);
125
+ if (el) el.scrollIntoView({ behavior: "smooth" });
126
+ }, 100);
127
+ }, [
128
+ navigate,
129
+ setIsOpen,
130
+ query
131
+ ]);
132
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
133
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.Navbar.SearchTrigger.Desktop, {
134
+ onPress: () => setIsOpen(true),
135
+ className: "rounded-xl border border-subtle bg-surface text-muted transition-all duration-200 hover:border-primary-500/50 hover:text-body hover:bg-soft/50 hover:shadow-sm active:scale-[0.98] focus-visible:ring-2 focus-visible:ring-primary-500/30",
136
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
137
+ className: "flex items-center gap-2",
138
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.Search, { size: 16 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
139
+ className: "hidden sm:inline-block",
140
+ children: "Search docs..."
141
+ })]
142
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.Navbar.SearchTrigger.Kbd, { className: "[&_kbd]:bg-main [&_kbd]:border [&_kbd]:border-subtle [&_kbd]:rounded [&_kbd]:px-1.5 [&_kbd]:h-5 [&_kbd]:w-5" })]
143
+ }),
144
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.Navbar.SearchTrigger.Mobile, {
145
+ onPress: () => setIsOpen(true),
146
+ className: "rounded-xl text-muted transition-all duration-200 hover:text-body active:scale-95 focus-visible:ring-2 focus-visible:ring-primary-500/30",
147
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons_dev.Search, { size: 20 })
148
+ }),
149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Overlay, {
150
+ isOpen,
151
+ isDismissable: true,
152
+ onOpenChange: () => setIsOpen(false),
153
+ className: "fixed inset-0 z-100 flex items-center justify-center p-4 bg-black/40 backdrop-blur-xs animate-fade-in",
154
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Content, {
155
+ className: "w-full max-w-lg bg-main border border-subtle shadow-md rounded-2xl overflow-hidden p-6",
156
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Dialog, {
157
+ "aria-label": "Search documentation",
158
+ className: "flex flex-col min-h-0 h-[450px]",
159
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.SearchDialog.Autocomplete, {
160
+ onSelectionChange: handleSelect,
161
+ className: "flex flex-col min-h-0",
162
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.SearchDialog.Input, {
163
+ value: query,
164
+ onChange: setQuery,
165
+ className: "flex items-center gap-2 border border-subtle bg-surface px-4 py-2.5 rounded-xl focus-within:border-primary-500 mb-4",
166
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Input.SearchInput, {
167
+ placeholder: "Search documentation...",
168
+ className: "w-full bg-transparent outline-none text-body text-sm"
169
+ }), query && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Input.Button, {
170
+ onPress: () => setQuery(""),
171
+ className: "text-muted hover:text-body text-xs cursor-pointer select-none",
172
+ children: "✕"
173
+ })]
174
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.List, {
175
+ items: list,
176
+ children: (item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_search_dialog.SearchDialog.Item, {
177
+ onPress: () => handleSelect(item.id),
178
+ textValue: item.title,
179
+ className: "flex items-center gap-3 px-4 py-2 rounded-xl group dark:hover:bg-primary-300/40 hover:bg-primary-200/50 transition-colors duration-100",
180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Item.Icon, {
181
+ isHeading: item.isHeading,
182
+ className: "text-muted group-hover:text-primary-500 group-focus:text-primary-500"
183
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
184
+ className: "flex flex-col justify-center min-w-0",
185
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Item.Title, {
186
+ className: "text-sm font-medium text-body truncate dark:group-hover:text-primary-100",
187
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Highlight, {
188
+ text: item.title,
189
+ query
190
+ })
191
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_search_dialog.SearchDialog.Item.Bio, {
192
+ className: "text-xs text-muted truncate",
193
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Highlight, {
194
+ text: item.bio,
195
+ query
196
+ })
197
+ })]
198
+ })]
199
+ }, item.id)
200
+ })]
201
+ })
202
+ })
203
+ })
204
+ })
205
+ ] });
206
+ }
207
+
208
+ //#endregion
209
+ Object.defineProperty(exports, 'SearchDialog', {
210
+ enumerable: true,
211
+ get: function () {
212
+ return SearchDialog;
213
+ }
214
+ });
215
+ Object.defineProperty(exports, 'useSearch', {
216
+ enumerable: true,
217
+ get: function () {
218
+ return useSearch;
219
+ }
220
+ });