zudoku 0.65.3 → 0.66.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 (256) hide show
  1. package/dist/app/sentry.js +1 -1
  2. package/dist/config/validators/BuildSchema.js +18 -3
  3. package/dist/config/validators/BuildSchema.js.map +1 -1
  4. package/dist/config/validators/validate.d.ts +45 -3
  5. package/dist/config/validators/validate.js +7 -1
  6. package/dist/config/validators/validate.js.map +1 -1
  7. package/dist/flat-config.d.ts +9 -2
  8. package/dist/lib/components/Mermaid.d.ts +7 -0
  9. package/dist/lib/components/Mermaid.js +42 -0
  10. package/dist/lib/components/Mermaid.js.map +1 -0
  11. package/dist/lib/components/PagefindSearchMeta.d.ts +8 -0
  12. package/dist/lib/components/PagefindSearchMeta.js +7 -0
  13. package/dist/lib/components/PagefindSearchMeta.js.map +1 -0
  14. package/dist/lib/components/Zudoku.js +2 -5
  15. package/dist/lib/components/Zudoku.js.map +1 -1
  16. package/dist/lib/core/RouteGuard.js +1 -1
  17. package/dist/lib/core/RouteGuard.js.map +1 -1
  18. package/dist/lib/core/plugins.d.ts +3 -3
  19. package/dist/lib/oas/parser/index.d.ts +1 -0
  20. package/dist/lib/oas/parser/index.js.map +1 -1
  21. package/dist/lib/plugins/openapi/DownloadSchemaButton.d.ts +3 -0
  22. package/dist/lib/plugins/openapi/DownloadSchemaButton.js +47 -0
  23. package/dist/lib/plugins/openapi/DownloadSchemaButton.js.map +1 -0
  24. package/dist/lib/plugins/openapi/Endpoint.js +3 -6
  25. package/dist/lib/plugins/openapi/Endpoint.js.map +1 -1
  26. package/dist/lib/plugins/openapi/OasProvider.js +22 -13
  27. package/dist/lib/plugins/openapi/OasProvider.js.map +1 -1
  28. package/dist/lib/plugins/openapi/OperationList.js +12 -6
  29. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  30. package/dist/lib/plugins/openapi/OperationListItem.js +2 -2
  31. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  32. package/dist/lib/plugins/openapi/SchemaList.js +2 -1
  33. package/dist/lib/plugins/openapi/SchemaList.js.map +1 -1
  34. package/dist/lib/plugins/openapi/index.js +11 -5
  35. package/dist/lib/plugins/openapi/index.js.map +1 -1
  36. package/dist/lib/plugins/openapi/interfaces.d.ts +16 -13
  37. package/dist/lib/plugins/openapi/playground/Playground.js +1 -1
  38. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  39. package/dist/lib/plugins/openapi/schema/SchemaView.d.ts +1 -1
  40. package/dist/lib/plugins/openapi/schema/SchemaView.js +14 -6
  41. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  42. package/dist/lib/plugins/openapi/schema/utils.d.ts +2 -2
  43. package/dist/lib/plugins/openapi/schema/utils.js.map +1 -1
  44. package/dist/lib/plugins/openapi/util/getRoutes.d.ts +6 -1
  45. package/dist/lib/plugins/openapi/util/getRoutes.js +29 -2
  46. package/dist/lib/plugins/openapi/util/getRoutes.js.map +1 -1
  47. package/dist/lib/plugins/search-pagefind/IndexingDialog.d.ts +3 -0
  48. package/dist/lib/plugins/search-pagefind/IndexingDialog.js +64 -0
  49. package/dist/lib/plugins/search-pagefind/IndexingDialog.js.map +1 -0
  50. package/dist/lib/plugins/search-pagefind/PagefindSearch.js +22 -5
  51. package/dist/lib/plugins/search-pagefind/PagefindSearch.js.map +1 -1
  52. package/dist/lib/plugins/search-pagefind/ResultList.js +5 -4
  53. package/dist/lib/plugins/search-pagefind/ResultList.js.map +1 -1
  54. package/dist/lib/shiki.d.ts +1 -1
  55. package/dist/lib/shiki.js +18 -12
  56. package/dist/lib/shiki.js.map +1 -1
  57. package/dist/lib/ui/Button.d.ts +2 -2
  58. package/dist/lib/ui/Button.js +9 -8
  59. package/dist/lib/ui/Button.js.map +1 -1
  60. package/dist/lib/ui/ButtonGroup.d.ts +11 -0
  61. package/dist/lib/ui/ButtonGroup.js +28 -0
  62. package/dist/lib/ui/ButtonGroup.js.map +1 -0
  63. package/dist/lib/ui/Command.js +2 -2
  64. package/dist/lib/ui/Command.js.map +1 -1
  65. package/dist/lib/ui/DropdownMenu.d.ts +21 -23
  66. package/dist/lib/ui/DropdownMenu.js +47 -32
  67. package/dist/lib/ui/DropdownMenu.js.map +1 -1
  68. package/dist/lib/ui/Kbd.d.ts +3 -0
  69. package/dist/lib/ui/Kbd.js +10 -0
  70. package/dist/lib/ui/Kbd.js.map +1 -0
  71. package/dist/lib/util/MdxComponents.d.ts +1 -0
  72. package/dist/lib/util/MdxComponents.js +2 -0
  73. package/dist/lib/util/MdxComponents.js.map +1 -1
  74. package/dist/lib/util/flattenAllOf.js +27 -4
  75. package/dist/lib/util/flattenAllOf.js.map +1 -1
  76. package/dist/lib/util/flattenAllOf.test.js +67 -12
  77. package/dist/lib/util/flattenAllOf.test.js.map +1 -1
  78. package/dist/vite/api/SchemaManager.d.ts +5 -0
  79. package/dist/vite/api/SchemaManager.js +24 -0
  80. package/dist/vite/api/SchemaManager.js.map +1 -1
  81. package/dist/vite/api/SchemaManager.test.js +67 -0
  82. package/dist/vite/api/SchemaManager.test.js.map +1 -1
  83. package/dist/vite/config.js +8 -2
  84. package/dist/vite/config.js.map +1 -1
  85. package/dist/vite/dev-server.js +25 -0
  86. package/dist/vite/dev-server.js.map +1 -1
  87. package/dist/vite/pagefind-dev-index.d.ts +16 -0
  88. package/dist/vite/pagefind-dev-index.js +68 -0
  89. package/dist/vite/pagefind-dev-index.js.map +1 -0
  90. package/dist/vite/plugin-api.js +41 -3
  91. package/dist/vite/plugin-api.js.map +1 -1
  92. package/dist/vite/prerender/prerender.js +1 -19
  93. package/dist/vite/prerender/prerender.js.map +1 -1
  94. package/dist/vite/prerender/utils.d.ts +2 -0
  95. package/dist/vite/prerender/utils.js +24 -0
  96. package/dist/vite/prerender/utils.js.map +1 -0
  97. package/lib/Button-CynVW1JV.js +53 -0
  98. package/lib/Button-CynVW1JV.js.map +1 -0
  99. package/lib/ClaudeLogo-PxFjou9w.js +69 -0
  100. package/lib/ClaudeLogo-PxFjou9w.js.map +1 -0
  101. package/lib/{Command-CUcrW3qs.js → Command-BpT1iBE6.js} +25 -25
  102. package/lib/Command-BpT1iBE6.js.map +1 -0
  103. package/lib/Drawer-Ci7XwhqT.js.map +1 -1
  104. package/lib/DropdownMenu-C8SX_-S_.js +104 -0
  105. package/lib/DropdownMenu-C8SX_-S_.js.map +1 -0
  106. package/lib/{ErrorAlert-D5LKLFOd.js → ErrorAlert-BqjbNHIn.js} +1017 -1015
  107. package/lib/{ErrorAlert-D5LKLFOd.js.map → ErrorAlert-BqjbNHIn.js.map} +1 -1
  108. package/lib/IndexingDialog-B5zCiUKr.js +100 -0
  109. package/lib/IndexingDialog-B5zCiUKr.js.map +1 -0
  110. package/lib/MdxPage-CVFatbHw.js +210 -0
  111. package/lib/MdxPage-CVFatbHw.js.map +1 -0
  112. package/lib/Mermaid-CIFixY6C.js +102 -0
  113. package/lib/Mermaid-CIFixY6C.js.map +1 -0
  114. package/lib/{OAuthErrorPage-oXnxcJg4.js → OAuthErrorPage-Dup79DJk.js} +7 -7
  115. package/lib/{OAuthErrorPage-oXnxcJg4.js.map → OAuthErrorPage-Dup79DJk.js.map} +1 -1
  116. package/lib/OasProvider-BJeMq29o.js +40 -0
  117. package/lib/OasProvider-BJeMq29o.js.map +1 -0
  118. package/lib/{OperationList-CmMoKpGu.js → OperationList-ff3ZvQsO.js} +1701 -1585
  119. package/lib/OperationList-ff3ZvQsO.js.map +1 -0
  120. package/lib/{RouteGuard-Brz95MSt.js → RouteGuard-BXy13JSz.js} +19 -19
  121. package/lib/{RouteGuard-Brz95MSt.js.map → RouteGuard-BXy13JSz.js.map} +1 -1
  122. package/lib/{RouterError-VGZB_wg4.js → RouterError-CKOZTsDD.js} +3 -3
  123. package/lib/{RouterError-VGZB_wg4.js.map → RouterError-CKOZTsDD.js.map} +1 -1
  124. package/lib/{SchemaList-BykD27ga.js → SchemaList-BSC1KM3v.js} +28 -27
  125. package/lib/SchemaList-BSC1KM3v.js.map +1 -0
  126. package/lib/{SchemaView-Dt6hbCAt.js → SchemaView-CgwJ9gtb.js} +198 -187
  127. package/lib/SchemaView-CgwJ9gtb.js.map +1 -0
  128. package/lib/Select-VmDZ-nKe.js +337 -0
  129. package/lib/Select-VmDZ-nKe.js.map +1 -0
  130. package/lib/{SignUp-D2mmQOkg.js → SignUp-Pm_LGm6T.js} +13 -13
  131. package/lib/{SignUp-D2mmQOkg.js.map → SignUp-Pm_LGm6T.js.map} +1 -1
  132. package/lib/{SyntaxHighlight-C19vH0V_.js → SyntaxHighlight-bkmst3oV.js} +654 -622
  133. package/lib/SyntaxHighlight-bkmst3oV.js.map +1 -0
  134. package/lib/{Toc-CBWfFCVf.js → Toc-TUXNFbKl.js} +2 -2
  135. package/lib/{Toc-CBWfFCVf.js.map → Toc-TUXNFbKl.js.map} +1 -1
  136. package/lib/{ZudokuContext-BUZ5hkWB.js → ZudokuContext-np1wheDl.js} +8 -8
  137. package/lib/{ZudokuContext-BUZ5hkWB.js.map → ZudokuContext-np1wheDl.js.map} +1 -1
  138. package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js +9 -0
  139. package/lib/___vite-browser-external_commonjs-proxy-Cga3HsWk.js.map +1 -0
  140. package/lib/{chunk-PVWAREVJ-BMhpCH5D.js → chunk-PVWAREVJ-dLIqswPy.js} +5 -5
  141. package/lib/{chunk-PVWAREVJ-BMhpCH5D.js.map → chunk-PVWAREVJ-dLIqswPy.js.map} +1 -1
  142. package/lib/{circular-CNHs4gAz.js → circular-XPj_dwqA.js} +2 -2
  143. package/lib/{circular-CNHs4gAz.js.map → circular-XPj_dwqA.js.map} +1 -1
  144. package/lib/createServer-D01nCTNp.js +16693 -0
  145. package/lib/createServer-D01nCTNp.js.map +1 -0
  146. package/lib/{errors-D7xzOd8X.js → errors-B0hNTPFO.js} +3 -3
  147. package/lib/{errors-D7xzOd8X.js.map → errors-B0hNTPFO.js.map} +1 -1
  148. package/lib/{hook-CMeoxziF.js → hook-CvSwcbk6.js} +3 -3
  149. package/lib/{hook-CMeoxziF.js.map → hook-CvSwcbk6.js.map} +1 -1
  150. package/lib/{index-unv8c40u.js → index-Bjc_QsUR.js} +754 -738
  151. package/lib/{index-unv8c40u.js.map → index-Bjc_QsUR.js.map} +1 -1
  152. package/lib/index-CrcNWbel.js.map +1 -1
  153. package/lib/index-DnMgJWrI.js +133 -0
  154. package/lib/index-DnMgJWrI.js.map +1 -0
  155. package/lib/{index-CF7_erXq.js → index-DscsS121.js} +2 -2
  156. package/lib/{index-CF7_erXq.js.map → index-DscsS121.js.map} +1 -1
  157. package/lib/{index-CPws05Tb.js → index-mfkNWYG-.js} +10 -10
  158. package/lib/{index-CPws05Tb.js.map → index-mfkNWYG-.js.map} +1 -1
  159. package/lib/{index.esm-BnYHxCYC.js → index.esm-DtzT_KoE.js} +20 -20
  160. package/lib/{index.esm-BnYHxCYC.js.map → index.esm-DtzT_KoE.js.map} +1 -1
  161. package/lib/{invariant-Bm-FVUQE.js → invariant-CGOLuIIz.js} +3 -3
  162. package/lib/{invariant-Bm-FVUQE.js.map → invariant-CGOLuIIz.js.map} +1 -1
  163. package/lib/{mutation-BSU0xu4m.js → mutation-BlmnL5qL.js} +2 -2
  164. package/lib/{mutation-BSU0xu4m.js.map → mutation-BlmnL5qL.js.map} +1 -1
  165. package/lib/ui/ActionButton.js +1 -1
  166. package/lib/ui/Button.js +25 -24
  167. package/lib/ui/Button.js.map +1 -1
  168. package/lib/ui/ButtonGroup.js +77 -0
  169. package/lib/ui/ButtonGroup.js.map +1 -0
  170. package/lib/ui/Command.js +3 -3
  171. package/lib/ui/Command.js.map +1 -1
  172. package/lib/ui/DropdownMenu.js +227 -140
  173. package/lib/ui/DropdownMenu.js.map +1 -1
  174. package/lib/ui/Kbd.js +32 -0
  175. package/lib/ui/Kbd.js.map +1 -0
  176. package/lib/ui/SyntaxHighlight.js +3 -3
  177. package/lib/zudoku.__internal.js +8 -8
  178. package/lib/zudoku.auth-auth0.js +1 -1
  179. package/lib/zudoku.auth-azureb2c.js +4 -4
  180. package/lib/zudoku.auth-clerk.js +2 -2
  181. package/lib/zudoku.auth-openid.js +5 -5
  182. package/lib/zudoku.auth-supabase.js +5 -5
  183. package/lib/zudoku.components.js +7 -7
  184. package/lib/zudoku.hooks.js +11 -24
  185. package/lib/zudoku.hooks.js.map +1 -1
  186. package/lib/zudoku.mermaid.js +10 -0
  187. package/lib/zudoku.mermaid.js.map +1 -0
  188. package/lib/zudoku.plugin-api-catalog.js +6 -6
  189. package/lib/zudoku.plugin-api-keys.js +223 -198
  190. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  191. package/lib/zudoku.plugin-custom-pages.js +1 -1
  192. package/lib/zudoku.plugin-markdown.js +1 -1
  193. package/lib/zudoku.plugin-openapi.js +3 -3
  194. package/lib/zudoku.plugin-redirect.js +1 -1
  195. package/lib/zudoku.plugin-search-pagefind.js +184 -226
  196. package/lib/zudoku.plugin-search-pagefind.js.map +1 -1
  197. package/lib/zudoku.plugins.js.map +1 -1
  198. package/lib/zudoku.router.js +2 -2
  199. package/package.json +29 -21
  200. package/src/app/sentry.ts +1 -1
  201. package/src/lib/components/Mermaid.tsx +68 -0
  202. package/src/lib/components/PagefindSearchMeta.tsx +14 -0
  203. package/src/lib/components/Zudoku.tsx +4 -7
  204. package/src/lib/core/RouteGuard.tsx +1 -1
  205. package/src/lib/core/plugins.ts +2 -2
  206. package/src/lib/oas/parser/index.ts +2 -0
  207. package/src/lib/plugins/openapi/DownloadSchemaButton.tsx +115 -0
  208. package/src/lib/plugins/openapi/Endpoint.tsx +20 -27
  209. package/src/lib/plugins/openapi/OasProvider.tsx +30 -17
  210. package/src/lib/plugins/openapi/OperationList.tsx +39 -21
  211. package/src/lib/plugins/openapi/OperationListItem.tsx +5 -5
  212. package/src/lib/plugins/openapi/SchemaList.tsx +4 -0
  213. package/src/lib/plugins/openapi/index.tsx +16 -7
  214. package/src/lib/plugins/openapi/interfaces.ts +16 -7
  215. package/src/lib/plugins/openapi/playground/Playground.tsx +1 -1
  216. package/src/lib/plugins/openapi/schema/SchemaView.tsx +36 -27
  217. package/src/lib/plugins/openapi/schema/utils.ts +5 -2
  218. package/src/lib/plugins/openapi/util/getRoutes.tsx +35 -3
  219. package/src/lib/plugins/search-pagefind/IndexingDialog.tsx +163 -0
  220. package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +61 -22
  221. package/src/lib/plugins/search-pagefind/ResultList.tsx +8 -3
  222. package/src/lib/shiki.ts +21 -12
  223. package/src/lib/ui/Button.tsx +10 -10
  224. package/src/lib/ui/ButtonGroup.tsx +82 -0
  225. package/src/lib/ui/Command.tsx +3 -3
  226. package/src/lib/ui/DropdownMenu.tsx +226 -170
  227. package/src/lib/ui/Kbd.tsx +28 -0
  228. package/src/lib/util/MdxComponents.tsx +2 -0
  229. package/src/lib/util/flattenAllOf.test.ts +71 -19
  230. package/src/lib/util/flattenAllOf.ts +29 -8
  231. package/src/shiki/langs/markdown-nix.js +1 -0
  232. package/src/shiki/langs/openscad.js +1 -0
  233. package/dist/vite/create-pagefind-index.d.ts +0 -4
  234. package/dist/vite/create-pagefind-index.js +0 -12
  235. package/dist/vite/create-pagefind-index.js.map +0 -1
  236. package/lib/Button-B3ucvvQw.js +0 -52
  237. package/lib/Button-B3ucvvQw.js.map +0 -1
  238. package/lib/Command-CUcrW3qs.js.map +0 -1
  239. package/lib/DropdownMenu-BZ2NKQ3K.js +0 -126
  240. package/lib/DropdownMenu-BZ2NKQ3K.js.map +0 -1
  241. package/lib/MdxPage-hOCN-u-L.js +0 -240
  242. package/lib/MdxPage-hOCN-u-L.js.map +0 -1
  243. package/lib/OasProvider-CpniNNrW.js +0 -36
  244. package/lib/OasProvider-CpniNNrW.js.map +0 -1
  245. package/lib/OperationList-CmMoKpGu.js.map +0 -1
  246. package/lib/Pagination-lLSoHnxa.js +0 -37
  247. package/lib/Pagination-lLSoHnxa.js.map +0 -1
  248. package/lib/SchemaList-BykD27ga.js.map +0 -1
  249. package/lib/SchemaView-Dt6hbCAt.js.map +0 -1
  250. package/lib/Select-DFRCS31-.js +0 -399
  251. package/lib/Select-DFRCS31-.js.map +0 -1
  252. package/lib/SyntaxHighlight-C19vH0V_.js.map +0 -1
  253. package/lib/createServer-BmcVQAOQ.js +0 -13018
  254. package/lib/createServer-BmcVQAOQ.js.map +0 -1
  255. package/lib/useExposedProps-U3pmsHaG.js +0 -113
  256. package/lib/useExposedProps-U3pmsHaG.js.map +0 -1
@@ -1,14 +1,15 @@
1
1
  import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
2
2
  import { keepPreviousData, useQuery } from "@tanstack/react-query";
3
- import { useRef, useState } from "react";
3
+ import { ListPlusIcon } from "lucide-react";
4
+ import { lazy, useEffect, useRef, useState } from "react";
4
5
  import { Button } from "zudoku/ui/Button.js";
5
- import { Callout } from "zudoku/ui/Callout.js";
6
6
  import {
7
7
  CommandDialog,
8
8
  CommandEmpty,
9
9
  CommandInput,
10
10
  } from "zudoku/ui/Command.js";
11
11
  import { DialogTitle } from "zudoku/ui/Dialog.js";
12
+ import { Kbd, KbdGroup } from "zudoku/ui/Kbd.js";
12
13
  import { useAuthState } from "../../authentication/state.js";
13
14
  import { useZudoku } from "../../components/context/ZudokuContext.js";
14
15
  import { SEARCH_PROTECTED_SECTION } from "../../core/RouteGuard.js";
@@ -18,6 +19,8 @@ import type { PagefindOptions } from "./index.js";
18
19
  import { ResultList } from "./ResultList.js";
19
20
  import type { Pagefind } from "./types.js";
20
21
 
22
+ const IndexingDialog = lazy(() => import("./IndexingDialog.js"));
23
+
21
24
  const DEFAULT_RANKING = {
22
25
  // Slightly lower than default because API docs tend to have repetitive terms (parameter names, HTTP methods, etc.)
23
26
  termFrequency: 0.8,
@@ -81,6 +84,7 @@ export const PagefindSearch = ({
81
84
  }) => {
82
85
  const { pagefind, error, isError } = usePagefind(options);
83
86
  const [searchTerm, setSearchTerm] = useState("");
87
+ const [selectedValue, setSelectedValue] = useState<string>("");
84
88
  const auth = useAuthState();
85
89
  const context = useZudoku();
86
90
  const inputRef = useRef<HTMLInputElement>(null);
@@ -100,9 +104,24 @@ export const PagefindSearch = ({
100
104
  enabled: !!pagefind && !!searchTerm,
101
105
  });
102
106
 
107
+ useEffect(() => {
108
+ if (!searchResults?.length) return;
109
+
110
+ const firstResult = searchResults.at(0);
111
+ if (!firstResult) return;
112
+
113
+ const firstValue = `${firstResult.meta.title}-${firstResult.url}`;
114
+ setSelectedValue(firstValue);
115
+ }, [searchResults]);
116
+
103
117
  return (
104
118
  <CommandDialog
105
- command={{ shouldFilter: false }}
119
+ command={{
120
+ shouldFilter: false,
121
+ loop: true,
122
+ value: selectedValue,
123
+ onValueChange: setSelectedValue,
124
+ }}
106
125
  content={{ className: "max-w-[750px]" }}
107
126
  open={isOpen}
108
127
  onOpenChange={onClose}
@@ -135,28 +154,48 @@ export const PagefindSearch = ({
135
154
  "Start typing to search"
136
155
  )}
137
156
  </CommandEmpty>
138
- {isError ? (
157
+ {isError && error.message !== "NOT_BUILT_YET" ? (
139
158
  <div className="p-4 text-sm">
140
- {error.message === "NOT_BUILT_YET" ? (
141
- <Callout type="info">
142
- Search is currently not available in development mode by default.
143
- <br />
144
- To still use search in development, run <code>zudoku build</code>{" "}
145
- and copy the <code>dist/pagefind</code> directory to your{" "}
146
- <code>public</code> directory.
147
- </Callout>
148
- ) : (
149
- "An error occurred while loading search."
150
- )}
159
+ An error occurred while loading search.
151
160
  </div>
152
161
  ) : (
153
- <ResultList
154
- basePath={context.options.basePath}
155
- searchResults={searchResults ?? []}
156
- searchTerm={searchTerm}
157
- onClose={onClose}
158
- maxSubResults={options.maxSubResults}
159
- />
162
+ <>
163
+ <ResultList
164
+ basePath={context.options.basePath}
165
+ searchResults={searchResults ?? []}
166
+ searchTerm={searchTerm}
167
+ onClose={onClose}
168
+ maxSubResults={options.maxSubResults}
169
+ />
170
+ <div className="flex justify-between p-2 items-center">
171
+ <div className="flex items-center text-xs text-muted-foreground">
172
+ <KbdGroup className="ms-0 me-1">
173
+ <Kbd>↑</Kbd>
174
+ <Kbd>↓</Kbd>
175
+ </KbdGroup>
176
+ Navigate
177
+ <KbdGroup className="ms-4 me-1">
178
+ <Kbd>↵</Kbd>
179
+ </KbdGroup>
180
+ Select
181
+ <KbdGroup className="ms-4 me-1">
182
+ <Kbd>Esc</Kbd>
183
+ </KbdGroup>
184
+ Close dialog
185
+ </div>
186
+ {import.meta.env.DEV && (
187
+ <IndexingDialog>
188
+ <Button
189
+ variant="outline"
190
+ className="h-7 text-xs text-muted-foreground"
191
+ >
192
+ <ListPlusIcon />
193
+ Build Search Index
194
+ </Button>
195
+ </IndexingDialog>
196
+ )}
197
+ </div>
198
+ </>
160
199
  )}
161
200
  </CommandDialog>
162
201
  );
@@ -35,9 +35,9 @@ export const ResultList = ({
35
35
  const navigate = useNavigate();
36
36
  const commandListRef = useRef<HTMLDivElement | null>(null);
37
37
 
38
- // biome-ignore lint/correctness/useExhaustiveDependencies: Only scroll to top when search term changes
39
38
  useLayoutEffect(() => {
40
- requestIdleCallback(() => {
39
+ if (!searchTerm) return;
40
+ requestAnimationFrame(() => {
41
41
  commandListRef.current?.scrollTo({ top: 0 });
42
42
  });
43
43
  }, [searchTerm]);
@@ -77,6 +77,11 @@ export const ResultList = ({
77
77
  ) : (
78
78
  <FileTextIcon />
79
79
  )}
80
+ {result.meta.category && (
81
+ <span className="text-muted-foreground">
82
+ {result.meta.category} &rsaquo;{" "}
83
+ </span>
84
+ )}
80
85
  {result.meta.title}
81
86
  </Link>
82
87
  </CommandItem>
@@ -98,7 +103,7 @@ export const ResultList = ({
98
103
  <div className="flex flex-col items-start gap-2 ms-2.5 ps-5 border-l border-muted-foreground/50">
99
104
  <span className="font-bold">{subResult.title}</span>
100
105
  <span
101
- className="text-[13px] [&_mark]:bg-primary [&_mark]:text-primary-foreground"
106
+ className="line-clamp-2 text-[13px] [&_mark]:bg-primary [&_mark]:text-primary-foreground"
102
107
  // biome-ignore lint/security/noDangerouslySetInnerHtml: Pagefind provides sanitized HTML
103
108
  dangerouslySetInnerHTML={{ __html: subResult.excerpt }}
104
109
  />
package/src/lib/shiki.ts CHANGED
@@ -25,18 +25,27 @@ export const HIGHLIGHT_CODE_BLOCK_CLASS =
25
25
  "overflow-x-auto scrollbar not-inline";
26
26
 
27
27
  const engine = createJavaScriptRegexEngine({ forgiving: true });
28
- export const highlighter = await createHighlighterCore({
29
- engine,
30
- langAlias: {
31
- markup: "html",
32
- svg: "xml",
33
- mathml: "xml",
34
- atom: "xml",
35
- ssml: "xml",
36
- rss: "xml",
37
- webmanifest: "json",
38
- },
39
- });
28
+
29
+ const shikiPromise = import.meta.hot?.data.shiki
30
+ ? import.meta.hot.data.shiki
31
+ : createHighlighterCore({
32
+ engine,
33
+ langAlias: {
34
+ markup: "html",
35
+ svg: "xml",
36
+ mathml: "xml",
37
+ atom: "xml",
38
+ ssml: "xml",
39
+ rss: "xml",
40
+ webmanifest: "json",
41
+ },
42
+ });
43
+
44
+ if (import.meta.hot) {
45
+ import.meta.hot.data.shiki = shikiPromise;
46
+ }
47
+
48
+ export const highlighter = await shikiPromise;
40
49
 
41
50
  type ThemesRecord = CodeOptionsMultipleThemes<BundledTheme>["themes"];
42
51
 
@@ -4,21 +4,19 @@ import * as React from "react";
4
4
  import { cn } from "../util/cn.js";
5
5
 
6
6
  export const buttonVariants = cva(
7
- "not-prose inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
7
+ "not-prose inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
8
8
  {
9
9
  variants: {
10
10
  variant: {
11
- default:
12
- "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
11
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
12
  destructive:
14
- "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
13
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
15
14
  outline:
16
- "border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
15
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
17
16
  secondary:
18
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
19
- ghost: "hover:bg-accent hover:text-accent-foreground",
20
- "ghost-destructive":
21
- "text-destructive hover:bg-destructive hover:text-destructive-foreground",
17
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
18
+ ghost:
19
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22
20
  link: "text-primary underline-offset-4 hover:underline",
23
21
  expand:
24
22
  "flex gap-1.5 border bg-transparent rounded-xl text-muted-foreground hover:text-foreground",
@@ -29,8 +27,10 @@ export const buttonVariants = cva(
29
27
  lg: "h-10 rounded-md px-8",
30
28
  xl: "h-14 rounded-lg px-10 text-lg",
31
29
  icon: "size-9",
32
- "icon-xs": "size-7",
33
30
  "icon-xxs": "size-5",
31
+ "icon-xs": "size-7",
32
+ "icon-sm": "size-8",
33
+ "icon-lg": "size-10",
34
34
  },
35
35
  },
36
36
  defaultVariants: {
@@ -0,0 +1,82 @@
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { cn } from "../util/cn.js";
4
+ import { Separator } from "./Separator.js";
5
+
6
+ const buttonGroupVariants = cva(
7
+ "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2",
8
+ {
9
+ variants: {
10
+ orientation: {
11
+ horizontal:
12
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
13
+ vertical:
14
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ orientation: "horizontal",
19
+ },
20
+ },
21
+ );
22
+
23
+ function ButtonGroup({
24
+ className,
25
+ orientation,
26
+ ...props
27
+ }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
28
+ return (
29
+ <div
30
+ role="group"
31
+ data-slot="button-group"
32
+ data-orientation={orientation}
33
+ className={cn(buttonGroupVariants({ orientation }), className)}
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function ButtonGroupText({
40
+ className,
41
+ asChild = false,
42
+ ...props
43
+ }: React.ComponentProps<"div"> & {
44
+ asChild?: boolean;
45
+ }) {
46
+ const Comp = asChild ? Slot : "div";
47
+
48
+ return (
49
+ <Comp
50
+ className={cn(
51
+ "bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
52
+ className,
53
+ )}
54
+ {...props}
55
+ />
56
+ );
57
+ }
58
+
59
+ function ButtonGroupSeparator({
60
+ className,
61
+ orientation = "vertical",
62
+ ...props
63
+ }: React.ComponentProps<typeof Separator>) {
64
+ return (
65
+ <Separator
66
+ data-slot="button-group-separator"
67
+ orientation={orientation}
68
+ className={cn(
69
+ "bg-input relative m-0! self-stretch data-[orientation=vertical]:h-auto",
70
+ className,
71
+ )}
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+
77
+ export {
78
+ ButtonGroup,
79
+ ButtonGroupSeparator,
80
+ ButtonGroupText,
81
+ buttonGroupVariants,
82
+ };
@@ -1,6 +1,6 @@
1
1
  import type { DialogProps } from "@radix-ui/react-dialog";
2
2
  import { Command as CommandPrimitive } from "cmdk";
3
- import { Search } from "lucide-react";
3
+ import { SearchIcon } from "lucide-react";
4
4
  import type { ComponentPropsWithoutRef } from "react";
5
5
  import * as React from "react";
6
6
  import { Dialog, DialogContent } from "zudoku/ui/Dialog.js";
@@ -58,8 +58,8 @@ const CommandInput = React.forwardRef<
58
58
  React.ElementRef<typeof CommandPrimitive.Input>,
59
59
  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
60
60
  >(({ className, ...props }, ref) => (
61
- <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
62
- <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
61
+ <div className="flex items-center gap-2 border-b px-3" cmdk-input-wrapper="">
62
+ <SearchIcon className="size-4! shrink-0 opacity-50" />
63
63
  <CommandPrimitive.Input
64
64
  ref={ref}
65
65
  className={cn(